"use strict"; const config = require('config'); const redis = require('../helpers/redis'); const express = require('express'); const crypto = require('crypto'); const router = express.Router(); const mailer = require('../helpers/mailer'); const _ = require('underscore'); const fs = require('fs') const SamlStrategy = require('passport-saml').Strategy const passport = require('passport') const Saml2js = require('saml2js'); const db = require('../models/db'); const Sequelize = require('sequelize'); const Op = Sequelize.Op; const uuidv4 = require('uuid/v4'); // =========== PASSPORT ======= passport.serializeUser(function (user, done) { done(null, user); }); passport.deserializeUser(function (user, done) { done(null, user); }); var samlStrategy = new SamlStrategy({ // URL that goes from the Identity Provider -> Service Provider callbackUrl: config.path, entryPoint: config.entryPoint, issuer: config.issuer, identifierFormat: null, validateInResponseTo: false, disableRequestedAuthnContext: true }, function (profile, done) { return done(null, { id: profile.nameID, idFormat: profile.nameIDFormat, email: profile.email, firstName: profile.givenName, lastName: profile.sn }); }); passport.use(samlStrategy); // to generate Service Provider's XML metadata router.get('/saml/metadata', function(req, res) { res.type('application/xml'); var spMetadata = samlStrategy.generateServiceProviderMetadata(fs.readFileSync('/cert/certificate.pem', 'utf8')); res.status(200).send(spMetadata); } ); router.post('/saml/SSO', passport.authenticate('saml', { failureRedirect: '/login', failureFlash: true}), function(req, res){ const xmlResponse = req.body.SAMLResponse; const parser = new Saml2js(xmlResponse); const response = parser.toObject(); const email = response["mail"]; console.log(parser.toJSON()); console.log("Nickname "+ response["givenName"]) const nickname = response["givenName"]; //check, if user exists, if not create. db.User.findAll({where: {email: email}}) .then(users => { if (users.length == 0) { crypto.randomBytes(16, function(ex, buf) { var token = buf.toString('hex'); var u = { _id: uuidv4(), email: email, account_type: "email", nickname: nickname, password_hash: "00000", prefs_language: req.i18n.locale, confirmation_token: token }; db.User.create(u) .error(err => { res.sendStatus(400); }) .then(u => { var homeFolder = { _id: uuidv4(), name: req.i18n.__("home"), space_type: "folder", creator_id: u._id }; db.Space.create(homeFolder) .error(err => { res.sendStatus(400); }) .then(homeFolder => { u.home_folder_id = homeFolder._id; u.save() .then(() => { // home folder created, // auto accept pending invites db.Membership.update({ "state": "active" }, { where: { "email_invited": u.email, "state": "pending" } }); res.status(201).json({}); }) .error(err => { res.status(400).json(err); }); }) }); }); } }).then(user =>{ db.User.findOne({where: {email: email}}) .error(err => { res.sendStatus(404); }) .then(user => { crypto.randomBytes(48, function(ex, buf) { var token = buf.toString('hex'); var session = { user_id: user._id, token: token, ip: req.ip, device: "web", created_at: new Date(), url : "/" }; db.Session.create(session) .error(err => { console.error("Error creating Session:",err); res.redirect(500, "/"); }) .then(() => { var domain = (process.env.NODE_ENV == "production") ? new URL(config.get('endpoint')).hostname : req.headers.hostname; console.log("session set successfully"); res.cookie('sdsession', token, { domain: domain, httpOnly: true }); res.redirect(302, "/") }); }); }); }); }); router.get('/', (req, res) => { res.render('index', { config:config, user:req.user }); }); router.get('/ping', (req, res) => { res.status(200).json({"status": "ok"}) }); router.get('/spaces', (req, res) => { res.render('spacedeck', { config:config, user:req.user }); }); router.get('/not_found', (req, res) => { res.render('not_found', {}); }); router.get('/confirm/:token', (req, res) => { res.render('spacedeck', { config:config, user:req.user }); }); router.get('/folders/:id', (req, res) => { res.render('spacedeck', { config:config, user:req.user }); }); router.get('/signup', (req, res) => { res.render('spacedeck', { config:config, user:req.user }); }); router.get('/accept/:id', (req, res) => { res.render('spacedeck', { config:config, user:req.user }); }); router.get('/password-reset', (req, res) => { res.render('spacedeck', { config:config, user:req.user }); }); router.get('/password-confirm/:token', (req, res) => { res.render('spacedeck', { config:config, user:req.user }); }); router.get('/de/*', (req, res) => { res.redirect("/t/de"); }); router.get('/de', (req, res) => { res.redirect("/t/de"); }); router.get('/fr/*', (req, res) => { res.redirect("/t/fr"); }); router.get('/fr', (req, res) => { res.redirect("/t/fr"); }); router.get('/oc/*', (req, res) => { res.redirect("/t/oc"); }); router.get('/oc', (req, res) => { res.redirect("/t/oc"); }); router.get('/en/*', (req, res) => { res.redirect("/t/en"); }); router.get('/en', (req, res) => { res.redirect("/t/end"); }); router.get('/account', (req, res) => { res.render('spacedeck'); }); router.get('/login', passport.authenticate('saml', { successRedirect: '/', failureRedirect: '/login' }) ); // res.render('spacedeck', { config:config, user:req.user }); //}); router.get('/logout', (req, res) => { res.render('spacedeck', { config:config, user:req.user }); }); router.get('/t/:id', (req, res) => { res.cookie('spacedeck_locale', req.params.id, { maxAge: 900000, httpOnly: true }); var path = "/"; if (req.query.r=="login" || req.query.r=="signup") { path = "/"+req.query.r; } res.redirect(path); }); router.get('/s/:hash', (req, res) => { var hash = req.params.hash; if (hash.split("-").length > 0) { hash = hash.split("-")[0]; } db.Space.findOne({where: {"edit_hash": hash}}).then(function (space) { if (space) { if (req.accepts('text/html')){ res.redirect("/spaces/"+space._id + "?spaceAuth=" + hash); } else { res.status(200).json(space); } } else { if (req.accepts('text/html')) { res.status(404).render('not_found', {}); } else { res.status(404).json({}); } } }); }); router.get('/spaces/:id', (req, res) => { res.render('spacedeck', { config:config, user:req.user }); }); module.exports = {router: router, passport:passport};