diff --git a/public/styles/style.css b/public/styles/style.css
index 1e571a3c..697f5fde 100644
--- a/public/styles/style.css
+++ b/public/styles/style.css
@@ -803,6 +803,21 @@ NoMeshesPanel img {
background-color:#44F;
}
+.userAuthStrategyLogo {
+ text-align:center;
+ position:absolute;
+ right:20px;
+ top:140px;
+ width:64px;
+ height:64px;
+ color:#FFF;
+ padding:2px;
+ background-color:#FFF;
+ border-radius:20px;
+ box-shadow: 2px 2px 10px black;
+ z-index:1;
+}
+
#xdevices {
max-height: calc(100vh - 242px);
overflow-y: auto;
diff --git a/sample-config.json b/sample-config.json
index a954f780..9605c233 100644
--- a/sample-config.json
+++ b/sample-config.json
@@ -157,6 +157,29 @@
"_maxRecordingSizeMegabytes": 3,
"__protocols__": "Is an array: 1 = Terminal, 2 = Desktop, 5 = Files, 100 = Intel AMT WSMAN, 101 = Intel AMT Redirection",
"protocols": [ 1, 2, 101 ]
+ },
+ "_authStrategies": {
+ "__comment__" : "This section is used to allow users to login using other accounts. You will need to get an API key from the services and register callback URL's",
+ "twitter": {
+ "__callbackurl": "https://server/auth-twitter-callback",
+ "apikey": "xxxxxxxxxxxxxxxxxxxxxxx",
+ "apisecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ "google": {
+ "__callbackurl": "https://server/auth-google-callback",
+ "clientid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
+ "clientsecret": "xxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ "github": {
+ "__callbackurl": "https://server/auth-github-callback",
+ "clientid": "xxxxxxxxxxxxxxxxxxxxxxx",
+ "clientsecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ "reddit": {
+ "__callbackurl": "https://server/auth-reddit-callback",
+ "clientid": "xxxxxxxxxxxxxxxxxxxxxxx",
+ "clientsecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ }
}
},
"_customer1": {
diff --git a/views/default.handlebars b/views/default.handlebars
index d26b59d0..c4f32683 100644
--- a/views/default.handlebars
+++ b/views/default.handlebars
@@ -885,7 +885,8 @@
|
-
+ |
+
@@ -9928,9 +9929,9 @@
if ((users == null) || ((features & 4) != 0)) { QH('p3users', ''); return; }
// Sort the list of user id's
- var sortedUserIds = [], maxUsers = 100, hiddenUsers = 0;
- for (var i in users) { sortedUserIds.push(i); }
- sortedUserIds.sort();
+ var sortedUsers = [], maxUsers = 100, hiddenUsers = 0;
+ for (var i in users) { sortedUsers.push(users[i]); }
+ sortedUsers.sort(nameSort);
// Get search
var userSearch = Q('UserSearchInput').value.toLowerCase();
@@ -9949,8 +9950,8 @@
for (var i=0;i= 0)) ||
@@ -9967,8 +9968,8 @@
}
addHeader = true;
// Offline users
- for (var i in sortedUserIds) {
- var user = users[sortedUserIds[i]], sessions = null;
+ for (var i in sortedUsers) {
+ var user = sortedUsers[i], sessions = null;
if (wssessions != null) { sessions = wssessions[user._id]; }
if ((sessions == null) &&
((userSearch != null) && ((userSearch == '') || (user.name.toLowerCase().indexOf(userSearch) >= 0)) ||
@@ -10859,6 +10860,15 @@
Q('MainUserImage').classList.remove('gray');
if (activeSessions == 0) { Q('MainUserImage').classList.add('gray'); }
+ // Add user auth strategy
+ var shortuserid = user._id.split('/')[2];
+ if (shortuserid.startsWith('~twitter:')) { QV('p30userAuthServiceLogo', true); Q('p30userAuthServiceLogo').src = 'images/login/twitter64.png';; }
+ else if (shortuserid.startsWith('~google:')) { QV('p30userAuthServiceLogo', true); Q('p30userAuthServiceLogo').src = 'images/login/google64.png';; }
+ else if (shortuserid.startsWith('~github:')) { QV('p30userAuthServiceLogo', true); Q('p30userAuthServiceLogo').src = 'images/login/github64.png';; }
+ else if (shortuserid.startsWith('~reddit:')) { QV('p30userAuthServiceLogo', true); Q('p30userAuthServiceLogo').src = 'images/login/reddit64.png';; }
+ else if (shortuserid.startsWith('~intel:')) { QV('p30userAuthServiceLogo', true); Q('p30userAuthServiceLogo').src = 'images/login/intel64.png';; }
+ else { QV('p30userAuthServiceLogo', false); }
+
// Server permissions
var msg = [], premsg = '';
if ((user.siteadmin != null) && ((user.siteadmin & 32) != 0) && (user.siteadmin != 0xFFFFFFFF)) { premsg = ' '; msg.push("Locked account"); }
@@ -11979,7 +11989,7 @@
if ((xxcurrentView == 11) && (desktop != null) && (desktop.m.recordedData != null)) { deskRecordSession(); }
// If we are trying to go to "My Users" and we are not a user manager, move to recordings
- if ((x == 4) && (users == null) || ((features & 4) != 0)) { x = 52; }
+ if (((x == 4) && ((userinfo.siteadmin & 2) == 0)) || ((features & 4) != 0)) { x = 52; }
// Edit this line when adding a new screen
for (var i = 0; i < 53; i++) { QV('p' + i, i == x); }
diff --git a/webserver.js b/webserver.js
index 11311345..47c4730e 100644
--- a/webserver.js
+++ b/webserver.js
@@ -4043,6 +4043,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
passport.serializeUser(function (user, done) { done(null, user.id); });
passport.deserializeUser(function (id, done) { done(null, { id: id }); });
obj.app.use(passport.initialize());
+ //obj.app.use(passport.session());
// Twitter
if ((typeof domain.authstrategies.twitter == 'object') && (typeof domain.authstrategies.twitter.apikey == 'string') && (typeof domain.authstrategies.twitter.apisecret == 'string')) {
@@ -4055,7 +4056,17 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
}
));
obj.app.get(url + 'auth-twitter', domain.passport.authenticate('twitter'));
- obj.app.get(url + 'auth-twitter-callback', domain.passport.authenticate('twitter', { failureRedirect: '/' }), handleStrategyLogin);
+ obj.app.get(url + 'auth-twitter-callback', function (req, res, next) {
+ if ((Object.keys(req.session).length == 0) && (req.query.nmr == null)) {
+ // This is an empty session likely due to the 302 redirection, redirect again (this is a bit of a hack).
+ var url = req.url;
+ if (url.indexOf('?') >= 0) { url += '&nmr=1'; } else { url += '?nmr=1'; } // Add this to the URL to prevent redirect loop.
+ res.set('Content-Type', 'text/html');
+ res.end('');
+ } else {
+ domain.passport.authenticate('twitter', { failureRedirect: '/' })(req, res, next);
+ }
+ }, handleStrategyLogin);
}
// Google
@@ -4096,19 +4107,27 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
return cb(null, user);
}
));
- obj.app.get(url + 'auth-reddit', function(req, res, next) {
- domain.passport.authenticate('reddit', { state: 'rcookie', duration: 'permanent' })(req, res, next); // TODO: Replace 'rcookie' with a time-limited cookie
+ obj.app.get(url + 'auth-reddit', function (req, res, next) {
+ req.session.rstate = obj.crypto.randomBytes(32).toString('hex');
+ domain.passport.authenticate('reddit', { state: req.session.rstate, duration: 'permanent' })(req, res, next); // TODO: Replace 'rcookie' with a time-limited cookie
});
- obj.app.get(url + 'auth-reddit-callback',
- function(req, res, next) {
- if (req.query.state == 'rcookie') {
+ obj.app.get(url + 'auth-reddit-callback', function (req, res, next) {
+ if ((Object.keys(req.session).length == 0) && (req.query.nmr == null)) {
+ // This is an empty session likely due to the 302 redirection, redirect again (this is a bit of a hack).
+ var url = req.url;
+ if (url.indexOf('?') >= 0) { url += '&nmr=1'; } else { url += '?nmr=1'; } // Add this to the URL to prevent redirect loop.
+ res.set('Content-Type', 'text/html');
+ res.end('');
+ } else {
+ if (req.query.state == req.session.rstate) {
delete req.session.rstate;
domain.passport.authenticate('reddit', { failureRedirect: '/' })(req, res, next);
} else {
delete req.session.rstate;
next(new Error(403));
}
- }, handleStrategyLogin);
+ }
+ }, handleStrategyLogin);
}
}
|