First working OAuth support for Twitter, Google, GitHub, Reddit.
Ylian Saint-Hilaire committed
May 14, 2020 at 17:06 UTC
4c12273c3ce5f6930da6c9c3736a74ae7d227859
7 files changed
+78
-55
package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "meshcentral",
3
- "version": "0.5.32",
3
+ "version": "0.5.33",
4
"keywords": [
5
"Remote Management",
6
"Intel AMT",
public/styles/style.css
+1
-1
@@ -807,7 +807,7 @@ NoMeshesPanel img {
807
text-align:center;
808
position:absolute;
809
right:20px;
810
- top:140px;
810
+ top:125px;
811
width:64px;
812
height:64px;
813
color:#FFF;
sample-config.json
+2
-2
@@ -162,8 +162,8 @@
162
"__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",
163
"twitter": {
164
"__callbackurl": "https://server/auth-twitter-callback",
165
- "apikey": "xxxxxxxxxxxxxxxxxxxxxxx",
166
- "apisecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
165
+ "clientid": "xxxxxxxxxxxxxxxxxxxxxxx",
166
+ "clientsecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
167
},
168
"google": {
169
"__callbackurl": "https://server/auth-google-callback",
translate/translate.json
+27
-21
@@ -1891,7 +1891,7 @@
1891
"ru": "Действия учетной записи",
1892
"zh-chs": "帳戶動作",
1893
"xloc": [
1894
- "default-mobile.handlebars->container->page_content->column_l->p3->p3info->1->p3AccountActions->3->0"
1894
+ "default-mobile.handlebars->container->page_content->column_l->p3->p3info->1->p3AccountActions->p2AccountActions->1->0"
1895
]
1896
},
1897
{
@@ -2800,7 +2800,7 @@
2800
"ru": "Admin PowerShell",
2801
"zh-chs": "管理員PowerShell",
2802
"xloc": [
2803
- "default.handlebars->termShellContextMenu->cxtermps",
2803
+ "default.handlebars->termShellContextMenu->3",
2804
"xterm.handlebars->termShellContextMenu->cxtermps"
2805
]
2806
},
@@ -2835,7 +2835,7 @@
2835
"ru": "Admin Shell",
2836
"zh-chs": "管理員外殼",
2837
"xloc": [
2838
- "default.handlebars->termShellContextMenu->cxtermnorm->0",
2838
+ "default.handlebars->termShellContextMenu->1->0",
2839
"xterm.handlebars->termShellContextMenu->cxtermnorm->0"
2840
]
2841
},
@@ -3346,7 +3346,7 @@
3346
"ru": "Поменять порт",
3347
"zh-chs": "備用端口",
3348
"xloc": [
3349
- "default.handlebars->altPortContextMenu->cxaltport->0"
3349
+ "default.handlebars->altPortContextMenu->1"
3350
]
3351
},
3352
{
@@ -4023,7 +4023,7 @@
4023
"nl": "Vraag toestemming",
4024
"zh-chs": "询问同意",
4025
"xloc": [
4026
- "default.handlebars->deskConnectContextMenu->cxdeskuc->0"
4026
+ "default.handlebars->deskConnectContextMenu->3"
4027
]
4028
},
4029
{
@@ -4037,7 +4037,7 @@
4037
"nl": "Vraag toestemming + informatiebalk",
4038
"zh-chs": "询问同意+酒吧",
4039
"xloc": [
4040
- "default.handlebars->deskConnectContextMenu->cxdeskuc->0"
4040
+ "default.handlebars->deskConnectContextMenu->1"
4041
]
4042
},
4043
{
@@ -5066,7 +5066,7 @@
5066
"ru": "Смена email",
5067
"zh-chs": "更改電子郵件地址",
5068
"xloc": [
5069
- "default-mobile.handlebars->container->page_content->column_l->p3->p3info->1->p3AccountActions->5->5->changeEmailId->0",
5069
+ "default-mobile.handlebars->container->page_content->column_l->p3->p3info->1->p3AccountActions->p2AccountActions->3->5->changeEmailId->0",
5070
"default.handlebars->container->column_l->p2->p2info->p2AccountActions->3->p2AccountPassActions->accountChangeEmailAddressSpan->0"
5071
]
5072
},
@@ -5084,7 +5084,7 @@
5084
"ru": "Смена пароля",
5085
"zh-chs": "更改密碼",
5086
"xloc": [
5087
- "default-mobile.handlebars->container->page_content->column_l->p3->p3info->1->p3AccountActions->5->7->0",
5087
+ "default-mobile.handlebars->container->page_content->column_l->p3->p3info->1->p3AccountActions->p2AccountActions->3->7->0",
5088
"default.handlebars->container->column_l->p2->p2info->p2AccountActions->3->p2AccountPassActions->3"
5089
]
5090
},
@@ -7440,7 +7440,7 @@
7440
"default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3",
7441
"default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3",
7442
"default.handlebars->container->dialog->idx_dlgButtonBar->5",
7443
- "default.handlebars->filesContextMenu->cxfiledelete->0",
7443
+ "default.handlebars->filesContextMenu->5",
7444
"player.handlebars->p11->dialog->idx_dlgButtonBar->5",
7445
"xterm.handlebars->p11->dialog->idx_dlgButtonBar->5"
7446
]
@@ -7630,7 +7630,7 @@
7630
"ru": "Удалить учетную запись",
7631
"zh-chs": "刪除帳戶",
7632
"xloc": [
7633
- "default-mobile.handlebars->container->page_content->column_l->p3->p3info->1->p3AccountActions->5->9->0",
7633
+ "default-mobile.handlebars->container->page_content->column_l->p3->p3info->1->p3AccountActions->p2AccountActions->3->9->0",
7634
"default.handlebars->25->1442",
7635
"default.handlebars->container->column_l->p2->p2info->p2AccountActions->3->p2AccountPassActions->7"
7636
]
@@ -9502,7 +9502,7 @@
9502
"zh-chs": "編輯",
9503
"xloc": [
9504
"default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3",
9505
- "default.handlebars->filesContextMenu->cxfileedit->0"
9505
+ "default.handlebars->filesContextMenu->3"
9506
]
9507
},
9508
{
@@ -15554,7 +15554,7 @@
15554
"ru": "Вход в оболочку",
15555
"zh-chs": "登錄外殼",
15556
"xloc": [
15557
- "default.handlebars->termShellContextMenuLinux->cxtermps",
15557
+ "default.handlebars->termShellContextMenuLinux->5",
15558
"xterm.handlebars->termShellContextMenuLinux->cxtermps"
15559
]
15560
},
@@ -16215,7 +16215,7 @@
16215
"nl": "Beheer telefoonnummer",
16216
"zh-chs": "管理电话号码",
16217
"xloc": [
16218
- "default-mobile.handlebars->container->page_content->column_l->p3->p3info->1->p3AccountActions->5->1->managePhoneNumber2->0",
16218
+ "default-mobile.handlebars->container->page_content->column_l->p3->p3info->1->p3AccountActions->p2AccountActions->3->1->managePhoneNumber2->0",
16219
"default-mobile.handlebars->container->page_content->column_l->p3->p3info->1->p3AccountActions->p2AccountSecurity->3->managePhoneNumber1->0",
16220
"default.handlebars->container->column_l->p2->p2info->p2AccountActions->3->managePhoneNumber2->0",
16221
"default.handlebars->container->column_l->p2->p2info->p2AccountSecurity->3->managePhoneNumber1->1->0"
@@ -19159,7 +19159,7 @@
19159
"zh-chs": "打开播放器...",
19160
"xloc": [
19161
"default.handlebars->container->column_l->p52->3->1->0->3->1",
19162
- "default.handlebars->deskPlayerContextMenu->cxopenplayer->0"
19162
+ "default.handlebars->deskPlayerContextMenu->1"
19163
]
19164
},
19165
{
@@ -20474,6 +20474,12 @@
20474
"default.handlebars->25->137"
20475
]
20476
},
20477
+ {
20478
+ "en": "Privacy Bar",
20479
+ "xloc": [
20480
+ "default.handlebars->deskConnectContextMenu->5"
20481
+ ]
20482
+ },
20483
{
20484
"cs": "Správa procesů",
20485
"de": "Prozesskontrolle",
@@ -21723,7 +21729,7 @@
21729
"default.handlebars->25->756",
21730
"default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3",
21731
"default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3",
21726
- "default.handlebars->filesContextMenu->cxfilerename->0"
21732
+ "default.handlebars->filesContextMenu->1"
21733
]
21734
},
21735
{
@@ -22125,7 +22131,7 @@
22131
"ru": "Root Shell",
22132
"zh-chs": "根殼",
22133
"xloc": [
22128
- "default.handlebars->termShellContextMenuLinux->cxtermnorm->0",
22134
+ "default.handlebars->termShellContextMenuLinux->1->0",
22135
"xterm.handlebars->termShellContextMenuLinux->cxtermnorm->0"
22136
]
22137
},
@@ -27628,7 +27634,7 @@
27634
"ru": "User PowerShell",
27635
"zh-chs": "用戶PowerShell",
27636
"xloc": [
27631
- "default.handlebars->termShellContextMenu->cxtermups",
27637
+ "default.handlebars->termShellContextMenu->7",
27638
"xterm.handlebars->termShellContextMenu->cxtermups"
27639
]
27640
},
@@ -27663,8 +27669,8 @@
27669
"ru": "User Shell",
27670
"zh-chs": "用戶外殼",
27671
"xloc": [
27666
- "default.handlebars->termShellContextMenu->cxtermunorm",
27667
- "default.handlebars->termShellContextMenuLinux->cxtermps",
27672
+ "default.handlebars->termShellContextMenu->5",
27673
+ "default.handlebars->termShellContextMenuLinux->3",
27674
"xterm.handlebars->termShellContextMenu->cxtermunorm",
27675
"xterm.handlebars->termShellContextMenuLinux->cxtermps"
27676
]
@@ -28005,7 +28011,7 @@
28011
"ru": "Подтвердить email",
28012
"zh-chs": "驗證郵件",
28013
"xloc": [
28008
- "default-mobile.handlebars->container->page_content->column_l->p3->p3info->1->p3AccountActions->5->3->verifyEmailId->0",
28014
+ "default-mobile.handlebars->container->page_content->column_l->p3->p3info->1->p3AccountActions->p2AccountActions->3->3->verifyEmailId->0",
28015
"default.handlebars->container->column_l->p2->p2info->p2AccountActions->3->verifyEmailId->0"
28016
]
28017
},
@@ -31092,4 +31098,4 @@
31098
]
31099
}
31100
]
31095
-}
31101
+}
\ No newline at end of file
views/default-mobile.handlebars
+12
-9
@@ -296,7 +296,7 @@
296
<div style="margin-left:8px">
297
<div id="p3AccountActions">
298
<div id="p2AccountSecurity" style="display:none">
299
- <p><strong>Account Security</strong></p>
299
+ <p><strong>Account Security</strong></p>
300
<div style="margin-left:9px;margin-bottom:8px">
301
<div id="managePhoneNumber1" style="margin-top:5px;display:none"><a onclick="account_managePhone()" style="cursor:pointer">Manage phone number</a> <span id="authPhoneNumberCheck"><strong>✓</strong></span></div>
302
<div id="manageEmail2FA" style="margin-top:5px;display:none"><a onclick="account_manageAuthEmail()" style="cursor:pointer">Manage email authentication</a> <span id="authEmailSetupCheck"><strong>✓</strong></span></div>
@@ -304,15 +304,17 @@
304
<div id="manageOtp" style="margin-top:5px;display:none"><a onclick="account_manageOtp(0)" style="cursor:pointer">Manage backup codes</a> <span id="authCodesSetupCheck"><strong>✓</strong></span></div>
305
</div>
306
</div>
307
- <p><strong>Account Actions</strong></p>
308
- <div style="margin-left:9px;margin-bottom:8px">
309
- <div style="margin-top:5px"><span id="managePhoneNumber2" style="display:none"><a onclick="account_managePhone()" style="cursor:pointer">Manage phone number</a></span></div>
310
- <div style="margin-top:5px"><span id="verifyEmailId" style="display:none"><a onclick="account_showVerifyEmail()" style="cursor:pointer">Verify email</a></span></div>
311
- <div style="margin-top:5px"><span id="changeEmailId" style="display:none"><a onclick="account_showChangeEmail()" style="cursor:pointer">Change email address</a></span></div>
312
- <div style="margin-top:5px"><a onclick="account_showChangePassword()" style="cursor:pointer">Change password</a><span id="p2nextPasswordUpdateTime"></span></div>
313
- <div style="margin-top:5px"><a onclick="account_showDeleteAccount()" style="cursor:pointer">Delete account</a></div>
314
- </div>
307
+ <div id="p2AccountActions" style="display:none">
308
+ <p><strong>Account Actions</strong></p>
309
+ <div style="margin-left:9px;margin-bottom:8px">
310
+ <div style="margin-top:5px"><span id="managePhoneNumber2" style="display:none"><a onclick="account_managePhone()" style="cursor:pointer">Manage phone number</a></span></div>
311
+ <div style="margin-top:5px"><span id="verifyEmailId" style="display:none"><a onclick="account_showVerifyEmail()" style="cursor:pointer">Verify email</a></span></div>
312
+ <div style="margin-top:5px"><span id="changeEmailId" style="display:none"><a onclick="account_showChangeEmail()" style="cursor:pointer">Change email address</a></span></div>
313
+ <div style="margin-top:5px"><a onclick="account_showChangePassword()" style="cursor:pointer">Change password</a><span id="p2nextPasswordUpdateTime"></span></div>
314
+ <div style="margin-top:5px"><a onclick="account_showDeleteAccount()" style="cursor:pointer">Delete account</a></div>
315
+ </div>
316
<br style=clear:both />
317
+ </div>
318
</div>
319
<strong>Device Groups</strong>
320
<span id="p3createMeshLink1">( <a onclick=account_createMesh() style=cursor:pointer><img src="images/icon-addnew.png" width=12 height=12 border=0 /> New</a> )</span>
@@ -766,6 +768,7 @@
768
QV('authAppSetupCheck', userinfo.otpsecret == 1);
769
//QV('authKeySetupCheck', userinfo.otphkeys > 0);
770
QV('authCodesSetupCheck', userinfo.otpkeys > 0);
771
+ QV('p2AccountActions', ((features & 4) == 0) && (serverinfo.domainauth == false) && (userinfo != null) && (userinfo._id.split('/')[2].startsWith('~') == false));
772
773
// On the mobile app, don't allow group creation (for now).
774
QV('p3createMeshLink1', false);
views/default.handlebars
+8
-9
@@ -1664,7 +1664,7 @@
1664
QV('managePhoneNumber1', (features & 0x02000000) && (features & 0x04000000));
1665
QV('managePhoneNumber2', (features & 0x02000000) && !(features & 0x04000000));
1666
QV('manageEmail2FA', features & 0x00800000);
1667
- QV('p2AccountPassActions', ((features & 4) == 0) && (serverinfo.domainauth == false)); // Hide Account Actions if in single user mode or domain authentication
1667
+ QV('p2AccountPassActions', ((features & 4) == 0) && (serverinfo.domainauth == false) && (userinfo != null) && (userinfo._id.split('/')[2].startsWith('~') == false)); // Hide Account Actions if in single user mode or domain authentication
1668
//QV('p2AccountImage', ((features & 4) == 0) && (serverinfo.domainauth == false)); // If account actions are not visible, also remove the image on that panel
1669
QV('p2ServerActions', siteRights & 21);
1670
QV('LeftMenuMyServer', siteRights & 21); // 16 + 4 + 1
@@ -1678,8 +1678,7 @@
1678
if (currentNode != null) { gotoDevice(currentNode._id, xxcurrentView, true); }
1679
1680
// Update user management state
1681
- if ((userinfo.siteadmin & 2) != 0)
1682
- {
1681
+ if ((userinfo.siteadmin & 2) != 0) {
1682
// We are user administrator
1683
if (users == null) { meshserver.send({ action: 'users' }); }
1684
if (wssessions == null) { meshserver.send({ action: 'wssessioncount' }); }
@@ -2368,7 +2367,7 @@
2367
case 'accountremove': {
2368
// An account was removed
2369
if (users == null) break;
2371
- delete users['user/' + domain + '/' + message.event.username.toLowerCase()];
2370
+ delete users[message.event.userid];
2371
masterUpdate(16384);
2372
break;
2373
}
@@ -2657,10 +2656,10 @@
2656
case 'wssessioncount': {
2657
// Update the active web socket session count for a user
2658
if (wssessions != null) {
2660
- if (message.event.count == 0 && wssessions['user/' + domain + '/' + message.event.username.toLowerCase()]) {
2661
- delete wssessions['user/' + domain + '/' + message.event.username.toLowerCase()];
2659
+ if (message.event.count == 0 && wssessions[message.event.userid]) {
2660
+ delete wssessions[message.event.userid];
2661
} else {
2663
- wssessions['user/' + domain + '/' + message.event.username.toLowerCase()] = message.event.count;
2662
+ wssessions[message.event.userid] = message.event.count;
2663
}
2664
masterUpdate(16384);
2665
}
@@ -2668,8 +2667,8 @@
2667
}
2668
case 'login': {
2669
// Update the last login time
2671
- if (users != null && users['user/' + domain + '/' + message.event.username.toLowerCase()]) {
2672
- users['user/' + domain + '/' + message.event.username.toLowerCase()].login = Math.floor(new Date(message.event.time).getTime() / 1000);
2670
+ if (users != null && users[message.event.userid]) {
2671
+ users[message.event.userid].login = Math.floor(new Date(message.event.time).getTime() / 1000);
2672
}
2673
break;
2674
}
webserver.js
+27
-12
@@ -1688,15 +1688,30 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1688
const userid = req.user.id;
1689
var user = obj.users[userid];
1690
if (user == null) {
1691
- // Create the user
1692
- parent.debug('web', 'handleStrategyLogin: creating new user: ' + userid);
1693
- user = { type: 'user', _id: userid, name: req.user.name, email: req.user.email, domain: domain.id };
1694
- if (req.user.email != null) { user.email = req.user.email; user.emailVerified = true; }
1695
- obj.users[userid] = user;
1696
- obj.db.SetUser(user);
1697
- // TODO: Event user creation
1698
- req.session.userid = req.user.id;
1699
- req.session.domainid = domain.id;
1691
+ if (domain.newaccounts == true) {
1692
+ // Create the user
1693
+ parent.debug('web', 'handleStrategyLogin: creating new user: ' + userid);
1694
+ user = { type: 'user', _id: userid, name: req.user.name, email: req.user.email, creation: Math.floor(Date.now() / 1000), domain: domain.id };
1695
+ if (req.user.email != null) { user.email = req.user.email; user.emailVerified = true; }
1696
+ obj.users[userid] = user;
1697
+ obj.db.SetUser(user);
1698
+
1699
+ // Event user creation
1700
+ var targets = ['*', 'server-users'];
1701
+ var event = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountcreate', msg: 'Account created, username is ' + user.name, domain: domain.id };
1702
+ if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to create the user. Another event will come.
1703
+ parent.DispatchEvent(targets, obj, event);
1704
+
1705
+ req.session.userid = req.user.id;
1706
+ req.session.domainid = domain.id;
1707
+ } else {
1708
+ // New users not allowed
1709
+ parent.debug('web', 'handleStrategyLogin: Can\'t create new accounts');
1710
+ req.session.loginmode = '1';
1711
+ req.session.messageid = 100; // Unable to create account.
1712
+ res.redirect(domain.url + getQueryPortion(req));
1713
+ return;
1714
+ }
1715
} else {
1716
// Login success
1717
var userChange = false;
@@ -2032,7 +2047,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2047
// See what authentication strategies we have
2048
var authStrategies = [];
2049
if (typeof domain.authstrategies == 'object') {
2035
- if ((typeof domain.authstrategies.twitter == 'object') && (typeof domain.authstrategies.twitter.apikey == 'string') && (typeof domain.authstrategies.twitter.apisecret == 'string')) { authStrategies.push('twitter'); }
2050
+ if ((typeof domain.authstrategies.twitter == 'object') && (typeof domain.authstrategies.twitter.clientid == 'string') && (typeof domain.authstrategies.twitter.clientsecret == 'string')) { authStrategies.push('twitter'); }
2051
if ((typeof domain.authstrategies.google == 'object') && (typeof domain.authstrategies.google.clientid == 'string') && (typeof domain.authstrategies.google.clientsecret == 'string')) { authStrategies.push('google'); }
2052
if ((typeof domain.authstrategies.github == 'object') && (typeof domain.authstrategies.github.clientid == 'string') && (typeof domain.authstrategies.github.clientsecret == 'string')) { authStrategies.push('github'); }
2053
if ((typeof domain.authstrategies.reddit == 'object') && (typeof domain.authstrategies.reddit.clientid == 'string') && (typeof domain.authstrategies.reddit.clientsecret == 'string')) { authStrategies.push('reddit'); }
@@ -4046,9 +4061,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4061
//obj.app.use(passport.session());
4062
4063
// Twitter
4049
- if ((typeof domain.authstrategies.twitter == 'object') && (typeof domain.authstrategies.twitter.apikey == 'string') && (typeof domain.authstrategies.twitter.apisecret == 'string')) {
4064
+ if ((typeof domain.authstrategies.twitter == 'object') && (typeof domain.authstrategies.twitter.clientid == 'string') && (typeof domain.authstrategies.twitter.clientsecret == 'string')) {
4065
const TwitterStrategy = require('passport-twitter');
4051
- passport.use(new TwitterStrategy({ consumerKey: domain.authstrategies.twitter.apikey, consumerSecret: domain.authstrategies.twitter.apisecret, callbackURL: url + 'auth-twitter-callback' },
4066
+ passport.use(new TwitterStrategy({ consumerKey: domain.authstrategies.twitter.clientid, consumerSecret: domain.authstrategies.twitter.clientsecret, callbackURL: url + 'auth-twitter-callback' },
4067
function (token, tokenSecret, profile, cb) {
4068
var user = { id: 'user/' + domain.id + '/~twitter:' + profile.id, name: profile.displayName };
4069
if ((typeof profile.emails == 'object') && (profile.emails[0] != null) && (typeof profile.emails[0].value == 'string')) { user.email = profile.emails[0].value; }