SSO Fixes.
Ylian Saint-Hilaire committed
May 27, 2020 at 00:52 UTC
4014973228aea439453463562bc99386bc3c8d71
1 file changed
+44
-31
webserver.js
+44
-31
@@ -251,7 +251,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
251
else if (j.startsWith('user/') && (obj.users[j] == null)) { delete mesh.links[j]; } // Device group has a link to a user that does not exist
252
}
253
}
254
- }
254
+ }
255
256
// Perform user link cleanup
257
for (var i in obj.users) {
@@ -378,7 +378,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
378
}
379
if ('[object Array]' == Object.prototype.toString.call(email)) {
380
// mail may be multivalued in ldap in which case, answer is an array. Use the 1st value.
381
- email=email[0];
381
+ email = email[0];
382
}
383
if (email) { email = email.toLowerCase(); } // it seems some code otherwhere also lowercase the emailaddress. be compatible.
384
@@ -412,7 +412,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
412
}
413
// Check if user email has changed
414
var emailreason = null;
415
- if (user.email && ! email) { // email unset in ldap => unset
415
+ if (user.email && !email) { // email unset in ldap => unset
416
delete user.email;
417
delete user.emailVerified;
418
emailreason = 'Unset email (no more email in LDAP)'
@@ -448,7 +448,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
448
}
449
if ('[object Array]' == Object.prototype.toString.call(email)) {
450
// mail may be multivalued in ldap in which case, answer would be an array. Use the 1st one.
451
- email=email[0];
451
+ email = email[0];
452
}
453
if (email) { email = email.toLowerCase(); } // it seems some code otherwhere also lowercase the emailaddress. be compatible.
454
var username = xxuser['displayName'];
@@ -501,7 +501,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
501
}
502
// Check if user email has changed
503
var emailreason = null;
504
- if (user.email && ! email) { // email unset in ldap => unset
504
+ if (user.email && !email) { // email unset in ldap => unset
505
delete user.email;
506
delete user.emailVerified;
507
emailreason = 'Unset email (no more email in LDAP)'
@@ -2010,7 +2010,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2010
}
2011
}
2012
if (skip2factor == false) { features += 0x00040000; } // Force 2-factor auth
2013
- }
2013
+ }
2014
if ((domain.auth == 'sspi') || (domain.auth == 'ldap')) { features += 0x00080000; } // LDAP or SSPI in use, warn that users must login first before adding a user to a group.
2015
if (domain.amtacmactivation) { features += 0x00100000; } // Intel AMT ACM activation/upgrade is possible
2016
if (domain.usernameisemail) { features += 0x00200000; } // Username is email address
@@ -4208,8 +4208,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4208
// Twitter
4209
if ((typeof domain.authstrategies.twitter == 'object') && (typeof domain.authstrategies.twitter.clientid == 'string') && (typeof domain.authstrategies.twitter.clientsecret == 'string')) {
4210
const TwitterStrategy = require('passport-twitter');
4211
- var options = { consumerKey: domain.authstrategies.twitter.clientid, consumerSecret: domain.authstrategies.twitter.clientsecret };
4212
- if (typeof domain.authstrategies.twitter.callbackurl == 'string') { options.callbackURL = domain.authstrategies.twitter.callbackurl; } else { options.path = url + 'auth-twitter-callback'; }
4211
+ var options = {
4212
+ consumerKey: domain.authstrategies.twitter.clientid,
4213
+ consumerSecret: domain.authstrategies.twitter.clientsecret,
4214
+ callbackURL: (typeof domain.authstrategies.twitter.callbackurl == 'string') ? domain.authstrategies.twitter.callbackurl : (url + 'auth-twitter-callback')
4215
+ };
4216
parent.debug('web', 'Adding Twitter SSO with options: ' + JSON.stringify(options));
4217
passport.use(new TwitterStrategy(options,
4218
function (token, tokenSecret, profile, cb) {
@@ -4242,8 +4245,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4245
// Google
4246
if ((typeof domain.authstrategies.google == 'object') && (typeof domain.authstrategies.google.clientid == 'string') && (typeof domain.authstrategies.google.clientsecret == 'string')) {
4247
const GoogleStrategy = require('passport-google-oauth20');
4245
- var options = { clientID: domain.authstrategies.google.clientid, clientSecret: domain.authstrategies.google.clientsecret };
4246
- if (typeof domain.authstrategies.google.callbackurl == 'string') { options.callbackURL = domain.authstrategies.google.callbackurl; } else { options.path = url + 'auth-google-callback'; }
4248
+ var options = {
4249
+ clientID: domain.authstrategies.google.clientid,
4250
+ clientSecret: domain.authstrategies.google.clientsecret,
4251
+ callbackURL: (typeof domain.authstrategies.google.callbackurl == 'string') ? domain.authstrategies.google.callbackurl : (url + 'auth-google-callback')
4252
+ };
4253
parent.debug('web', 'Adding Google SSO with options: ' + JSON.stringify(options));
4254
passport.use(new GoogleStrategy(options,
4255
function (token, tokenSecret, profile, cb) {
@@ -4268,8 +4274,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4274
// Github
4275
if ((typeof domain.authstrategies.github == 'object') && (typeof domain.authstrategies.github.clientid == 'string') && (typeof domain.authstrategies.github.clientsecret == 'string')) {
4276
const GitHubStrategy = require('passport-github2');
4271
- var options = { clientID: domain.authstrategies.github.clientid, clientSecret: domain.authstrategies.github.clientsecret };
4272
- if (typeof domain.authstrategies.github.callbackurl == 'string') { options.callbackURL = domain.authstrategies.github.callbackurl; } else { options.path = url + 'auth-github-callback'; }
4277
+ var options = {
4278
+ clientID: domain.authstrategies.github.clientid,
4279
+ clientSecret: domain.authstrategies.github.clientsecret,
4280
+ callbackURL: (typeof domain.authstrategies.github.callbackurl == 'string') ? domain.authstrategies.github.callbackurl : (url + 'auth-github-callback')
4281
+ };
4282
parent.debug('web', 'Adding Github SSO with options: ' + JSON.stringify(options));
4283
passport.use(new GitHubStrategy(options,
4284
function (token, tokenSecret, profile, cb) {
@@ -4296,9 +4305,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4305
const RedditStrategy = require('passport-reddit');
4306
var options = {
4307
clientID: domain.authstrategies.reddit.clientid,
4299
- clientSecret: domain.authstrategies.reddit.clientsecret
4308
+ clientSecret: domain.authstrategies.reddit.clientsecret,
4309
+ callbackURL: (typeof domain.authstrategies.reddit.callbackurl == 'string') ? domain.authstrategies.reddit.callbackurl : (url + 'auth-reddit-callback')
4310
};
4301
- if (typeof domain.authstrategies.reddit.callbackurl == 'string') { options.callbackURL = domain.authstrategies.reddit.callbackurl; } else { options.path = url + 'auth-reddit-callback'; }
4311
parent.debug('web', 'Adding Reddit SSO with options: ' + JSON.stringify(options));
4312
passport.use(new RedditStrategy.Strategy(options,
4313
function (token, tokenSecret, profile, cb) {
@@ -4341,10 +4350,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4350
var options = {
4351
clientID: domain.authstrategies.azure.clientid,
4352
clientSecret: domain.authstrategies.azure.clientsecret,
4344
- tenant: domain.authstrategies.azure.tenantid
4353
+ tenant: domain.authstrategies.azure.tenantid,
4354
+ callbackURL: (typeof domain.authstrategies.azure.callbackurl == 'string') ? domain.authstrategies.azure.callbackurl : (url + 'auth-azure-callback')
4355
};
4346
- if (typeof domain.authstrategies.azure.callbackurl == 'string') { options.callbackURL = domain.authstrategies.azure.callbackurl; } else { options.path = url + 'auth-azure-callback'; }
4347
- if (typeof domain.authstrategies.azure.forceauthn != 'undefined') { options.forceAuthn = domain.authstrategies.azure.forceauthn; }
4356
parent.debug('web', 'Adding Azure SSO with options: ' + JSON.stringify(options));
4357
passport.use('azure', new AzureOAuth2Strategy(options,
4358
function (accessToken, refreshtoken, params, profile, done) {
@@ -4395,9 +4403,10 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4403
if (cert == null) {
4404
console.log('ERROR: Unable to read SAML IdP certificate: ' + domain.authstrategies.saml.cert);
4405
} else {
4398
- var options = { entryPoint: domain.authstrategies.saml.idpurl, issuer: 'meshcentral' };
4399
- if (typeof domain.authstrategies.saml.callbackurl == 'string') { options.callbackURL = domain.authstrategies.saml.callbackurl; } else { options.path = url + 'auth-saml-callback'; }
4400
- if (typeof domain.authstrategies.saml.forceauthn != 'undefined') { options.forceAuthn = domain.authstrategies.saml.forceauthn; }
4406
+ var options = {
4407
+ path: (typeof domain.authstrategies.saml.callbackurl == 'string') ? domain.authstrategies.saml.callbackurl : (url + 'auth-saml-callback'),
4408
+ entryPoint: domain.authstrategies.saml.idpurl, issuer: 'meshcentral'
4409
+ };
4410
parent.debug('web', 'Adding SAML SSO with options: ' + JSON.stringify(options));
4411
if (typeof domain.authstrategies.saml.entityid == 'string') { options.issuer = domain.authstrategies.saml.entityid; }
4412
options.cert = cert.toString().split('-----BEGIN CERTIFICATE-----').join('').split('-----END CERTIFICATE-----').join('');
@@ -4435,9 +4444,10 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4444
if (cert == null) {
4445
console.log('ERROR: Unable to read Intel SAML IdP certificate: ' + domain.authstrategies.intel.cert);
4446
} else {
4438
- var options = { entryPoint: domain.authstrategies.intel.idpurl, issuer: 'meshcentral' };
4439
- if (typeof domain.authstrategies.intel.callbackurl == 'string') { options.callbackURL = domain.authstrategies.intel.callbackurl; } else { options.path = url + 'auth-intel-callback'; }
4440
- if (typeof domain.authstrategies.intel.forceauthn != 'undefined') { options.forceAuthn = domain.authstrategies.intel.forceauthn; }
4447
+ var options = {
4448
+ path: (typeof domain.authstrategies.intel.callbackurl == 'string') ? domain.authstrategies.intel.callbackurl : (url + 'auth-intel-callback'),
4449
+ entryPoint: domain.authstrategies.intel.idpurl, issuer: 'meshcentral'
4450
+ };
4451
parent.debug('web', 'Adding Intel SSO with options: ' + JSON.stringify(options));
4452
if (typeof domain.authstrategies.intel.entityid == 'string') { options.issuer = domain.authstrategies.intel.entityid; }
4453
options.cert = cert.toString().split('-----BEGIN CERTIFICATE-----').join('').split('-----END CERTIFICATE-----').join('');
@@ -4477,8 +4487,10 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4487
if (cert == null) {
4488
console.log('ERROR: Unable to read JumpCloud IdP certificate: ' + domain.authstrategies.jumpcloud.cert);
4489
} else {
4480
- var options = { entryPoint: domain.authstrategies.jumpcloud.idpurl, issuer: 'meshcentral' };
4481
- if (typeof domain.authstrategies.jumpcloud.callbackurl == 'string') { options.callbackURL = domain.authstrategies.jumpcloud.callbackurl; } else { options.path = url + 'auth-jumpcloud-callback'; }
4490
+ var options = {
4491
+ path: (typeof domain.authstrategies.jumpcloud.callbackurl == 'string') ? domain.authstrategies.jumpcloud.callbackurl : (url + 'auth-jumpcloud-callback'),
4492
+ entryPoint: domain.authstrategies.jumpcloud.idpurl, issuer: 'meshcentral'
4493
+ };
4494
parent.debug('web', 'Adding JumpCloud SSO with options: ' + JSON.stringify(options));
4495
if (typeof domain.authstrategies.jumpcloud.entityid == 'string') { options.issuer = domain.authstrategies.jumpcloud.entityid; }
4496
options.cert = cert.toString().split('-----BEGIN CERTIFICATE-----').join('').split('-----END CERTIFICATE-----').join('');
@@ -4704,20 +4716,20 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4716
try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'tokenrequired', sms2fa: sms2fa, sms2fasent: true })); ws.close(); } catch (e) { }
4717
} else {
4718
// Ask for a login token
4707
- parent.debug('web', 'Asking for login token');
4719
+ parent.debug('web', 'Asking for login token');
4720
try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'tokenrequired', email2fa: email2fa })); ws.close(); } catch (e) { }
4721
}
4722
} else {
4723
checkUserOneTimePassword(req, domain, user, req.query.token, null, function (result) {
4724
if (result == false) {
4725
// Failed, ask for a login token again
4714
- parent.debug('web', 'Invalid login token, asking again');
4726
+ parent.debug('web', 'Invalid login token, asking again');
4727
try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'tokenrequired', email2fa: email2fa })); ws.close(); } catch (e) { }
4728
} else {
4729
// We are authenticated with 2nd factor.
4730
// Check email verification
4731
if (emailcheck && (user.email != null) && (user.emailVerified !== true)) {
4720
- parent.debug('web', 'Invalid login, asking for email validation');
4732
+ parent.debug('web', 'Invalid login, asking for email validation');
4733
try { ws.send(JSON.stringify({ action: 'close', cause: 'emailvalidation', msg: 'emailvalidationrequired', email2fa: email2fa, email2fasent: true })); ws.close(); } catch (e) { }
4734
} else {
4735
func(ws, req, domain, user);
@@ -4728,7 +4740,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4740
} else {
4741
// Check email verification
4742
if (emailcheck && (user.email != null) && (user.emailVerified !== true)) {
4731
- parent.debug('web', 'Invalid login, asking for email validation');
4743
+ parent.debug('web', 'Invalid login, asking for email validation');
4744
try { ws.send(JSON.stringify({ action: 'close', cause: 'emailvalidation', msg: 'emailvalidationrequired', email2fa: email2fa, email2fasent: true })); ws.close(); } catch (e) { }
4745
} else {
4746
// We are authenticated
@@ -4824,7 +4836,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4836
try { ws.send(JSON.stringify({ action: 'close', cause: 'emailvalidation', msg: 'emailvalidationrequired', email2fa: email2fa, email2fasent: true })); ws.close(); } catch (e) { }
4837
} else {
4838
func(ws, req, domain, user);
4827
- } }
4839
+ }
4840
+ }
4841
} else {
4842
// Failed to authenticate, see if a default user is active
4843
if (obj.args.user && obj.users['user/' + domain.id + '/' + obj.args.user.toLowerCase()]) {
@@ -5543,7 +5556,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
5556
}
5557
5558
// Returns a list of acceptable languages in order
5546
- obj.getLanguageCodes = function(req) {
5559
+ obj.getLanguageCodes = function (req) {
5560
// If a user set a localization, use that
5561
if ((req.query.lang == null) && (req.session != null) && (req.session.userid)) {
5562
var user = obj.users[req.session.userid];