You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
339 lines
11 KiB
339 lines
11 KiB
3 years ago
|
var createError = require('http-errors');
|
||
|
var express = require('express');
|
||
|
var path = require('path');
|
||
|
var cookieParser = require('cookie-parser');
|
||
|
var logger = require('morgan');
|
||
|
var i18n = require('./i18n');
|
||
|
var jwt = require('jsonwebtoken');
|
||
|
const expressSesssion = require('express-session');
|
||
|
const passport = require('passport');
|
||
|
const { Issuer, Strategy } = require('openid-client');
|
||
|
|
||
|
|
||
|
|
||
|
require('dotenv').config();
|
||
|
|
||
|
var app = express();
|
||
|
|
||
|
app.locals.metricsCache = {};
|
||
|
|
||
|
var indexRouter = require('./routes/index');
|
||
|
|
||
|
// view engine setup
|
||
|
app.set('views', path.join(__dirname, 'views'));
|
||
|
app.set('view engine', 'ejs');
|
||
|
|
||
|
app.use(i18n);
|
||
|
|
||
|
app.use(logger('dev'));
|
||
|
app.use(express.json());
|
||
|
app.use(express.urlencoded({ extended: false }));
|
||
|
app.use(cookieParser());
|
||
|
app.use(express.static(path.join(__dirname, 'public')));
|
||
|
|
||
|
// Proxy HTTP
|
||
|
const {bootstrap} = require('global-agent');
|
||
|
bootstrap();
|
||
|
//
|
||
|
|
||
|
const homepage = process.env.HOME_PATH ? process.env.HOME_PATH + '/index' : 'Home/index';
|
||
|
|
||
|
if (process.env.OID_USE !== undefined && process.env.OID_USE == "true") { // if using openid connect
|
||
|
Issuer.discover(process.env.OID_URL) // oid provider address
|
||
|
.then(criiptoIssuer => {
|
||
|
var client = new criiptoIssuer.Client({
|
||
|
//authorization_signed_response_alg: 'RS512',
|
||
|
id_token_signed_response_alg: process.env.OID_ALG, // openid provider supported algorithm
|
||
|
client_id: process.env.OID_APP_ID, // openid provider app id
|
||
|
client_secret: process.env.OID_SECRET, // openid provider secret
|
||
|
redirect_uris: [process.env.OID_REDIRECT_URI], // redirect url after auth
|
||
|
post_logout_redirect_uris: [process.env.OID_LOGOUT_URI], // redirect after logout
|
||
|
response_type: "code" // response type, "code" is what works the best
|
||
|
});
|
||
|
|
||
|
|
||
|
app.use( // tell the app to use a server side session to store the user infos and other usefull stuff
|
||
|
expressSesssion({
|
||
|
secret: 'keyboard cat',
|
||
|
resave: false,
|
||
|
saveUninitialized: true
|
||
|
})
|
||
|
);
|
||
|
|
||
|
app.use(passport.initialize()); // initialize the passport (auth middleware)
|
||
|
app.use(passport.session()); // tell passport to use our session to store it's infos
|
||
|
|
||
|
passport.use( // define the oidc strategy
|
||
|
'oidc',
|
||
|
new Strategy({
|
||
|
client,
|
||
|
params: {
|
||
|
scope: "openid email profile userinfo" // scope we'll be able to access
|
||
|
}
|
||
|
}, (tokenSet, userinfo, done) => {
|
||
|
//return done(null, tokenSet.claims());
|
||
|
done(null, { ...tokenSet.claims(), token: tokenSet.access_token, ...userinfo });
|
||
|
})
|
||
|
);
|
||
|
|
||
|
// handles serialization and deserialization of authenticated user
|
||
|
passport.serializeUser(function(user, done) {
|
||
|
done(null, user);
|
||
|
});
|
||
|
passport.deserializeUser(function(user, done) {
|
||
|
done(null, user);
|
||
|
});
|
||
|
|
||
|
// start authentication request
|
||
|
// app.get('/auth', (req, res, next) => { // default path where we redirect user to when we want to begin the auth flow
|
||
|
|
||
|
|
||
|
// passport.authenticate('oidc')(req, res, next);
|
||
|
// });
|
||
|
|
||
|
// start authentication request
|
||
|
//app.get('/auth/*', (req, res, next) => { // default path where we redirect user to when we want to begin the auth flow
|
||
|
|
||
|
//let roomname = req.url.split("?").shift()
|
||
|
//roomname = roomname.split("/")[2];
|
||
|
//console.log(roomname);
|
||
|
//req.session.room = roomname;
|
||
|
|
||
|
//passport.authenticate('oidc')(req, res, next);
|
||
|
//});
|
||
|
|
||
|
app.get('/', function(req, res, next) { // root path, just a check in the session to see if we need to show a login/logout button based on if we're authenticated or not
|
||
|
req.session.room = '';
|
||
|
if (req.user) {
|
||
|
res.render(homepage, {
|
||
|
from_electron: req.query.from_electron,
|
||
|
authentified: true
|
||
|
});
|
||
|
} else {
|
||
|
res.render(homepage, {
|
||
|
from_electron: req.query.from_electron,
|
||
|
authentified: false
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// authentication callback, where the oidc provider hand us the user back after login
|
||
|
app.get('/auth/callback', (req, res, next) => {
|
||
|
passport.authenticate('oidc', function(err, user, info) {
|
||
|
if (err) {
|
||
|
return next(err);
|
||
|
}
|
||
|
if (!user) {
|
||
|
return res.redirect('/');
|
||
|
}
|
||
|
req.logIn(user, function(err) {
|
||
|
if (err) {
|
||
|
return next(err);
|
||
|
}
|
||
|
|
||
|
if (typeof req.session.room !== 'undefined' && req.session.room) { // check were really in a room
|
||
|
req.session.room_jwt = req.session.room; // keep the room the jwt token was generated for
|
||
|
|
||
|
let firstnameClaim = process.env.OID_FIRSTNAME_CLAIM || 'given_name';
|
||
|
let lastnameClaim = process.env.OID_LASTNAME_CLAIM || 'family_name';
|
||
|
let emailClaim = process.env.OID_EMAIL_CLAIM || 'email';
|
||
|
|
||
|
|
||
|
let name = (user[firstnameClaim] + ' ' + user[lastnameClaim]).trim();
|
||
|
let email = user[emailClaim];
|
||
|
|
||
|
var token = jwt.sign({ // generate the jwt based on the info in the session
|
||
|
"context": {
|
||
|
"user": {
|
||
|
"name": name,
|
||
|
"email": email,
|
||
|
},
|
||
|
},
|
||
|
"aud": "jitsi",
|
||
|
"iss": process.env.JWT_APP_ID,
|
||
|
"sub": process.env.JITSI_DOMAIN, // jitsi domain
|
||
|
"room": "*"
|
||
|
}, process.env.JWT_SECRET);
|
||
|
req.session.jitsi_jwt = token;
|
||
|
|
||
|
|
||
|
return res.redirect("https:" + "//" + req.headers.host + "/" + req.session.room); // redirect to the room
|
||
|
} else {
|
||
|
return res.redirect("https:" + "//" + req.headers.host + "/"); // redirect to root path
|
||
|
}
|
||
|
});
|
||
|
})(req, res, next);
|
||
|
});
|
||
|
|
||
|
// start authentication request
|
||
|
// app.get('/auth/*', (req, res, next) => { // default path where we redirect user to when we want to begin the auth flow
|
||
|
|
||
|
// let roomname = req.url.split("?").shift()
|
||
|
// roomname = roomname.split("/")[2];
|
||
|
// console.log(roomname);
|
||
|
// req.session.room = roomname;
|
||
|
|
||
|
// passport.authenticate('oidc')(req, res, next);
|
||
|
// });
|
||
|
|
||
|
app.get('/auth/:room', (req, res, next) => { // default path where we redirect user to when we want to begin the auth flow
|
||
|
|
||
|
var stringHelper = require('./lib/Shared/StringHelper');
|
||
|
var room = stringHelper.customEncodeURIComponent(req.params['room']);
|
||
|
// let roomname = req.url.split("?").shift()
|
||
|
// roomname = roomname.split("/")[2];
|
||
|
console.log(room);
|
||
|
req.session.room = room;
|
||
|
|
||
|
passport.authenticate('oidc')(req, res, next);
|
||
|
});
|
||
|
|
||
|
// start logout request
|
||
|
app.get('/logout', (req, res) => {
|
||
|
req.session.room = '';
|
||
|
req.session.jitsi_jwt = '';
|
||
|
req.session.room_jwt = '';
|
||
|
res.redirect(client.endSessionUrl());
|
||
|
});
|
||
|
|
||
|
// logout callback, where the oidc provider hand us the user back after logout
|
||
|
app.get('/logout/callback', (req, res) => {
|
||
|
// clears the persisted user from the local storage
|
||
|
req.logout();
|
||
|
// redirects the user to a public route
|
||
|
res.redirect('/');
|
||
|
});
|
||
|
|
||
|
const api = require('./lib/Api/index');
|
||
|
app.get('/Api/metrics', api.metrics)
|
||
|
|
||
|
const room = require('./lib/Room/index');
|
||
|
app.post('/Room/Rate', room.rate);
|
||
|
|
||
|
app.get('/:room', (req, res, next) => {
|
||
|
|
||
|
var stringHelper = require('./lib/Shared/StringHelper');
|
||
|
|
||
|
var room = stringHelper.customEncodeURIComponent(req.params['room']);
|
||
|
req.session.room = room;
|
||
|
|
||
|
if (req.query.embedded == '1' || req.query.embedded == '1/') {
|
||
|
res.sendFile('/usr/share/jitsi-meet/index.html');
|
||
|
} else {
|
||
|
if (req.query.guest == '1' || req.query.guest == '1/') {
|
||
|
res.render('Room/index', {
|
||
|
room: room,
|
||
|
from_electron: req.query.from_electron,
|
||
|
jwt: req.query.jwt,
|
||
|
enable_auth_modal: false,
|
||
|
authentified: false
|
||
|
});
|
||
|
} else {
|
||
|
if (req.user) {
|
||
|
|
||
|
if (req.query.jwt) {
|
||
|
res.render('Room/index', {
|
||
|
room: room,
|
||
|
from_electron: req.query.from_electron,
|
||
|
jwt: req.query.jwt,
|
||
|
enable_auth_modal: false,
|
||
|
authentified: true
|
||
|
});
|
||
|
} else {
|
||
|
if (req.session.room_jwt != room || req.session.jitsi_jwt == '') {
|
||
|
res.redirect("https:" + "//" + req.headers.host + "/auth/" + room);
|
||
|
} else {
|
||
|
res.render('Room/index', {
|
||
|
room: room,
|
||
|
from_electron: req.query.from_electron,
|
||
|
jwt: req.session.jitsi_jwt,
|
||
|
enable_auth_modal: false,
|
||
|
authentified: true
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
if (req.query.jwt) {
|
||
|
res.render('Room/index', {
|
||
|
room: room,
|
||
|
from_electron: req.query.from_electron,
|
||
|
jwt: req.query.jwt,
|
||
|
enable_auth_modal: false,
|
||
|
authentified: false
|
||
|
});
|
||
|
} else {
|
||
|
res.render('Room/index', {
|
||
|
room: room,
|
||
|
from_electron: req.query.from_electron,
|
||
|
jwt: req.query.jwt,
|
||
|
enable_auth_modal: true,
|
||
|
authentified: false
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
});
|
||
|
} else { // if not using openid connect, we dont bother with aditional paths
|
||
|
/* GET welcome page. */
|
||
|
app.get('/', function(req, res, next) {
|
||
|
res.render(homepage, {
|
||
|
from_electron: req.query.from_electron,
|
||
|
enable_auth_modal: false,
|
||
|
authentified: false
|
||
|
});
|
||
|
});
|
||
|
|
||
|
const api = require('./lib/Api/index');
|
||
|
app.get('/Api/metrics', api.metrics)
|
||
|
|
||
|
const room = require('./lib/Room/index');
|
||
|
app.post('/Room/Rate', room.rate);
|
||
|
|
||
|
app.get('/:room', (req, res, next) => {
|
||
|
|
||
|
var stringHelper = require('./lib/Shared/StringHelper');
|
||
|
|
||
|
var room = stringHelper.customEncodeURIComponent(req.params['room']);
|
||
|
|
||
|
if (req.query.embedded == '1' || req.query.embedded == '1/') {
|
||
|
res.sendFile('/usr/share/jitsi-meet/index.html');
|
||
|
} else {
|
||
|
res.render('Room/index', {
|
||
|
room: room,
|
||
|
from_electron: req.query.from_electron,
|
||
|
jwt: req.query.jwt,
|
||
|
enable_auth_modal: false,
|
||
|
authentified: false
|
||
|
});
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
// catch 404 and forward to error handler
|
||
|
app.use(function(req, res, next) {
|
||
|
next(createError(404));
|
||
|
});
|
||
|
|
||
|
// error handler
|
||
|
app.use(function(err, req, res, next) {
|
||
|
// set locals, only providing error in development
|
||
|
res.locals.message = err.message;
|
||
|
res.locals.error = req.app.get('env') === 'development' ? err : {};
|
||
|
|
||
|
// render the error page
|
||
|
res.status(err.status || 500);
|
||
|
res.render('Shared/error', {
|
||
|
from_electron: req.query.from_electron
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
module.exports = app;
|