Started work on OAuth support.
This commit is contained in:
parent
0d54e39ace
commit
906d43d367
|
@ -502,6 +502,7 @@
|
|||
<Folder Include="typings\globals\node-forge\" />
|
||||
<Folder Include="typings\globals\nodemailer\" />
|
||||
<Folder Include="typings\globals\node\" />
|
||||
<Folder Include="typings\globals\passport\" />
|
||||
<Folder Include="views\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -512,6 +513,7 @@
|
|||
<TypeScriptCompile Include="typings\globals\node-forge\index.d.ts" />
|
||||
<TypeScriptCompile Include="typings\globals\nodemailer\index.d.ts" />
|
||||
<TypeScriptCompile Include="typings\globals\node\index.d.ts" />
|
||||
<TypeScriptCompile Include="typings\globals\passport\index.d.ts" />
|
||||
<TypeScriptCompile Include="typings\index.d.ts" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -2537,9 +2537,10 @@ function mainStart() {
|
|||
// Lowercase the auth value if present
|
||||
for (var i in config.domains) { if (typeof config.domains[i].auth == 'string') { config.domains[i].auth = config.domains[i].auth.toLowerCase(); } }
|
||||
|
||||
// Check if Windows SSPI and YubiKey OTP will be used
|
||||
// Check if Windows SSPI, LDAP, Passport and YubiKey OTP will be used
|
||||
var sspi = false;
|
||||
var ldap = false;
|
||||
var passport = null;
|
||||
var allsspi = true;
|
||||
var yubikey = false;
|
||||
var recordingIndex = false;
|
||||
|
@ -2549,6 +2550,12 @@ function mainStart() {
|
|||
for (var i in config.domains) {
|
||||
if (config.domains[i].yubikey != null) { yubikey = true; }
|
||||
if (config.domains[i].auth == 'ldap') { ldap = true; }
|
||||
if ((typeof config.domains[i].authstrategies == 'object')) {
|
||||
if (passport == null) { passport = ['passport']; }
|
||||
if ((typeof config.domains[i].authstrategies.twitter == 'object') && (typeof config.domains[i].authstrategies.twitter.apikey == 'string') && (typeof config.domains[i].authstrategies.twitter.apisecret == 'string') && (passport.indexOf('passport-twitter') == -1)) { passport.push('passport-twitter'); }
|
||||
if ((typeof config.domains[i].authstrategies.google == 'object') && (typeof config.domains[i].authstrategies.google.clientid == 'string') && (typeof config.domains[i].authstrategies.google.clientsecret == 'string') && (passport.indexOf('passport-google-oauth20') == -1)) { passport.push('passport-google-oauth20'); }
|
||||
if ((typeof config.domains[i].authstrategies.github == 'object') && (typeof config.domains[i].authstrategies.github.clientid == 'string') && (typeof config.domains[i].authstrategies.github.clientsecret == 'string') && (passport.indexOf('passport-github2') == -1)) { passport.push('passport-github2'); }
|
||||
}
|
||||
if ((config.domains[i].sessionrecording != null) && (config.domains[i].sessionrecording.index == true)) { recordingIndex = true; }
|
||||
}
|
||||
|
||||
|
@ -2559,6 +2566,7 @@ function mainStart() {
|
|||
var modules = ['ws', 'cbor', 'nedb', 'https', 'yauzl', 'xmldom', 'ipcheck', 'express', 'archiver', 'multiparty', 'node-forge', 'express-ws', 'compression', 'body-parser', 'connect-redis', 'cookie-session', 'express-handlebars'];
|
||||
if (require('os').platform() == 'win32') { modules.push('node-windows'); if (sspi == true) { modules.push('node-sspi'); } } // Add Windows modules
|
||||
if (ldap == true) { modules.push('ldapauth-fork'); }
|
||||
if (passport != null) { modules.push(...passport); }
|
||||
if (recordingIndex == true) { modules.push('image-size'); } // Need to get the remote desktop JPEG sizes to index the recodring file.
|
||||
if (config.letsencrypt != null) { if (nodeVersion < 8) { addServerWarning("Let's Encrypt support requires Node v8.x or higher.", !args.launch); } else { modules.push('acme-client'); } } // Add acme-client module
|
||||
if (config.settings.mqtt != null) { modules.push('aedes'); } // Add MQTT Modules
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 741 B |
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 844 B |
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
|
@ -70,6 +70,13 @@
|
|||
Don't have an account? <a onclick="return xgo(2,event);" href="#" style=cursor:pointer>Create one</a>.
|
||||
</div>
|
||||
<input id=loginformargs name="urlargs" type="hidden" value="" />
|
||||
<div id="authStrategies" style="display:none">
|
||||
<hr />
|
||||
<div style="margin-bottom:8px">Log in using an existing account</div>
|
||||
<a id="auth-twitter" href="auth-twitter" style="display:none"><img src="images/login/twitter32.png" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using Twitter" /></a>
|
||||
<a id="auth-google" href="auth-google" style="display:none"><img src="images/login/google32.png" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using Google" /></a>
|
||||
<a id="auth-github" href="auth-github" style="display:none"><img src="images/login/github32.png" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using GitHub" /></a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div id=createpanel style="display:none;position:relative">
|
||||
|
@ -302,6 +309,7 @@
|
|||
var otpemail = (decodeURIComponent('{{{otpemail}}}') === 'true');
|
||||
var otpsms = (decodeURIComponent('{{{otpsms}}}') === 'true');
|
||||
var twoFactorCookieDays = parseInt('{{{twoFactorCookieDays}}}');
|
||||
var authStrategies = '{{{authStrategies}}}'.split(',');
|
||||
|
||||
function startup() {
|
||||
// Display the right server message
|
||||
|
@ -368,6 +376,14 @@
|
|||
QV('createPanelHint', passRequirements.hint === true);
|
||||
QV('resetpasswordpanelHint', passRequirements.hint === true);
|
||||
|
||||
// Setup authentication strategies
|
||||
if (authStrategies != '') {
|
||||
QV('authStrategies', true);
|
||||
if (authStrategies.indexOf('twitter') >= 0) { QV('auth-twitter', true); }
|
||||
if (authStrategies.indexOf('google') >= 0) { QV('auth-google', true); }
|
||||
if (authStrategies.indexOf('github') >= 0) { QV('auth-github', true); }
|
||||
}
|
||||
|
||||
// Display the welcome text
|
||||
if (welcomeText) {
|
||||
QH('welcomeText', welcomeText);
|
||||
|
|
83
webserver.js
83
webserver.js
|
@ -1982,8 +1982,16 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||
var twoFactorCookieDays = 30;
|
||||
if (typeof domain.twofactorcookiedurationdays == 'number') { twoFactorCookieDays = domain.twofactorcookiedurationdays; }
|
||||
|
||||
// See what authentication strategies we have
|
||||
var authStrategies = [];
|
||||
if (typeof domain.authstrategies == 'object') {
|
||||
if ((typeof domain.authstrategies.twitter == 'object') && (typeof domain.authstrategies.twitter.apikey == 'string') && (typeof domain.authstrategies.twitter.apisecret == 'string')) { authStrategies.push('twitter'); }
|
||||
if ((typeof domain.authstrategies.google == 'object') && (typeof domain.authstrategies.google.clientid == 'string') && (typeof domain.authstrategies.google.clientsecret == 'string')) { authStrategies.push('google'); }
|
||||
if ((typeof domain.authstrategies.github == 'object') && (typeof domain.authstrategies.github.clientid == 'string') && (typeof domain.authstrategies.github.clientsecret == 'string')) { authStrategies.push('github'); }
|
||||
}
|
||||
|
||||
// Render the login page
|
||||
render(req, res, getRenderPage('login', req, domain), getRenderArgs({ loginmode: loginmode, rootCertLink: getRootCertLink(), newAccount: newAccountsAllowed, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, footer: (domain.footer == null) ? '' : domain.footer, hkey: encodeURIComponent(hardwareKeyChallenge), messageid: msgid, passhint: passhint, welcometext: domain.welcometext ? encodeURIComponent(domain.welcometext).split('\'').join('\\\'') : null, hwstate: hwstate, otpemail: otpemail, otpsms: otpsms, twoFactorCookieDays: twoFactorCookieDays }, req, domain));
|
||||
render(req, res, getRenderPage('login', req, domain), getRenderArgs({ loginmode: loginmode, rootCertLink: getRootCertLink(), newAccount: newAccountsAllowed, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, footer: (domain.footer == null) ? '' : domain.footer, hkey: encodeURIComponent(hardwareKeyChallenge), messageid: msgid, passhint: passhint, welcometext: domain.welcometext ? encodeURIComponent(domain.welcometext).split('\'').join('\\\'') : null, hwstate: hwstate, otpemail: otpemail, otpsms: otpsms, twoFactorCookieDays: twoFactorCookieDays, authStrategies: authStrategies.join(',') }, req, domain));
|
||||
}
|
||||
|
||||
// Handle a post request on the root
|
||||
|
@ -3917,7 +3925,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||
if (parent.multiServer != null) { obj.app.ws('/meshserver.ashx', function (ws, req) { parent.multiServer.CreatePeerInServer(parent.multiServer, ws, req); }); }
|
||||
for (var i in parent.config.domains) {
|
||||
if (parent.config.domains[i].dns != null) { continue; } // This is a subdomain with a DNS name, no added HTTP bindings needed.
|
||||
var url = parent.config.domains[i].url;
|
||||
var domain = parent.config.domains[i];
|
||||
var url = domain.url;
|
||||
obj.app.get(url, handleRootRequest);
|
||||
obj.app.post(url, handleRootPostRequest);
|
||||
obj.app.get(url + 'backup.zip', handleBackupRequest);
|
||||
|
@ -3969,7 +3978,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||
}
|
||||
});
|
||||
});
|
||||
if (parent.config.domains[i].agentinvitecodes == true) {
|
||||
if (domain.agentinvitecodes == true) {
|
||||
obj.app.get(url + 'invite', handleInviteRequest);
|
||||
obj.app.post(url + 'invite', handleInviteRequest);
|
||||
}
|
||||
|
@ -3979,6 +3988,74 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||
obj.app.get(url + 'pluginHandler.js', obj.handlePluginJS);
|
||||
}
|
||||
|
||||
// Setup passport if needed
|
||||
if (typeof domain.authstrategies == 'object') {
|
||||
const passport = domain.passport = require('passport');
|
||||
if ((typeof domain.authstrategies.twitter == 'object') && (typeof domain.authstrategies.twitter.apikey == 'string') && (typeof domain.authstrategies.twitter.apisecret == 'string')) {
|
||||
const TwitterStrategy = require('passport-twitter');
|
||||
passport.use(new TwitterStrategy({
|
||||
consumerKey: domain.authstrategies.twitter.apikey,
|
||||
consumerSecret: domain.authstrategies.twitter.apisecret,
|
||||
callbackURL: url + 'auth-twitter-callback'
|
||||
},
|
||||
function (token, tokenSecret, profile, cb) {
|
||||
console.log('Twitter1', token, tokenSecret, profile);
|
||||
//User.findOrCreate({ twitterId: profile.id }, function (err, user) { return cb(err, user); });
|
||||
}
|
||||
));
|
||||
obj.app.get(url + 'auth-twitter', domain.passport.authenticate('twitter'));
|
||||
obj.app.get(url + 'https://alt.meshcentral.com',
|
||||
domain.passport.authenticate('twitter', { failureRedirect: '/' }),
|
||||
function (req, res) {
|
||||
// Successful authentication, redirect home.
|
||||
console.log('Twitter2');
|
||||
res.redirect('/');
|
||||
});
|
||||
}
|
||||
if ((typeof domain.authstrategies.google == 'object') && (typeof domain.authstrategies.google.clientid == 'string') && (typeof domain.authstrategies.google.clientsecret == 'string')) {
|
||||
const GoogleStrategy = require('passport-google-oauth20');
|
||||
passport.use(new GoogleStrategy({
|
||||
clientID: domain.authstrategies.google.clientid,
|
||||
clientSecret: domain.authstrategies.google.clientsecret,
|
||||
callbackURL: url + 'auth-google-callback'
|
||||
},
|
||||
function (token, tokenSecret, profile, cb) {
|
||||
console.log('Google1', token, tokenSecret, profile);
|
||||
//User.findOrCreate({ googleId: profile.id }, function (err, user) { return cb(err, user); });
|
||||
}
|
||||
));
|
||||
obj.app.get(url + 'auth-google', domain.passport.authenticate('google'));
|
||||
obj.app.get(url + 'auth-google-callback',
|
||||
domain.passport.authenticate('google', { failureRedirect: '/' }),
|
||||
function (req, res) {
|
||||
// Successful authentication, redirect home.
|
||||
console.log('Google2');
|
||||
res.redirect('/');
|
||||
});
|
||||
}
|
||||
if ((typeof domain.authstrategies.github == 'object') && (typeof domain.authstrategies.github.clientid == 'string') && (typeof domain.authstrategies.github.clientsecret == 'string')) {
|
||||
const GitHubStrategy = require('passport-github2');
|
||||
passport.use(new GitHubStrategy({
|
||||
clientID: domain.authstrategies.github.clientid,
|
||||
clientSecret: domain.authstrategies.github.clientsecret,
|
||||
callbackURL: url + 'auth-github-callback'
|
||||
},
|
||||
function (token, tokenSecret, profile, cb) {
|
||||
console.log('GitHub1', token, tokenSecret, profile);
|
||||
//User.findOrCreate({ githubId: profile.id }, function (err, user) { return cb(err, user); });
|
||||
}
|
||||
));
|
||||
obj.app.get(url + 'auth-github', domain.passport.authenticate('github', { scope: ['user:email'] }));
|
||||
obj.app.get(url + 'auth-github-callback',
|
||||
domain.passport.authenticate('google', { failureRedirect: '/' }),
|
||||
function (req, res) {
|
||||
// Successful authentication, redirect home.
|
||||
console.log('GitHub2');
|
||||
res.redirect('/');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Server redirects
|
||||
if (parent.config.domains[i].redirects) { for (var j in parent.config.domains[i].redirects) { if (j[0] != '_') { obj.app.get(url + j, obj.handleDomainRedirect); } } }
|
||||
|
||||
|
|
Loading…
Reference in New Issue