diff --git a/app/custom-oauth/server/custom_oauth_server.js b/app/custom-oauth/server/custom_oauth_server.js index ad0f6b92c1be5..bd698fd90c2b8 100644 --- a/app/custom-oauth/server/custom_oauth_server.js +++ b/app/custom-oauth/server/custom_oauth_server.js @@ -73,6 +73,7 @@ export class CustomOAuth { this.identityPath = options.identityPath; this.tokenSentVia = options.tokenSentVia; this.identityTokenSentVia = options.identityTokenSentVia; + this.keyField = options.keyField; this.usernameField = (options.usernameField || '').trim(); this.emailField = (options.emailField || '').trim(); this.nameField = (options.nameField || '').trim(); @@ -334,7 +335,14 @@ export class CustomOAuth { } if (serviceData.username) { - const user = Users.findOneByUsernameAndServiceNameIgnoringCase(serviceData.username, serviceData._id, serviceName); + let user = undefined; + + if (this.keyField === 'username') { + user = Users.findOneByUsernameAndServiceNameIgnoringCase(serviceData.username, serviceData._id, serviceName); + } else if (this.keyField === 'email') { + user = Users.findOneByEmailAddressAndServiceNameIgnoringCase(serviceData.email, serviceData._id, serviceName); + } + if (!user) { return; } diff --git a/app/lib/server/functions/addOAuthService.js b/app/lib/server/functions/addOAuthService.js index 065152841499d..f1117cc11d635 100644 --- a/app/lib/server/functions/addOAuthService.js +++ b/app/lib/server/functions/addOAuthService.js @@ -8,9 +8,9 @@ export function addOAuthService(name, values = {}) { name = name.toLowerCase().replace(/[^a-z0-9_]/g, ''); name = s.capitalize(name); settings.add(`Accounts_OAuth_Custom-${ name }` , values.enabled || false , { type: 'boolean', group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'Accounts_OAuth_Custom_Enable', persistent: true }); - settings.add(`Accounts_OAuth_Custom-${ name }-url` , values.serverURL || '' , { type: 'string' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'URL', persistent: true }); + settings.add(`Accounts_OAuth_Custom-${ name }-url` , values.serverURL || '' , { type: 'string' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'URL', persistent: true }); settings.add(`Accounts_OAuth_Custom-${ name }-token_path` , values.tokenPath || '/oauth/token' , { type: 'string' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'Accounts_OAuth_Custom_Token_Path', persistent: true }); - settings.add(`Accounts_OAuth_Custom-${ name }-token_sent_via` , values.tokenSentVia || 'payload' , { type: 'select' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'Accounts_OAuth_Custom_Token_Sent_Via', persistent: true, values: [{ key: 'header', i18nLabel: 'Header' }, { key: 'payload', i18nLabel: 'Payload' }] }); + settings.add(`Accounts_OAuth_Custom-${ name }-token_sent_via` , values.tokenSentVia || 'payload' , { type: 'select' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'Accounts_OAuth_Custom_Token_Sent_Via', persistent: true, values: [{ key: 'header', i18nLabel: 'Header' }, { key: 'payload', i18nLabel: 'Payload' }] }); settings.add(`Accounts_OAuth_Custom-${ name }-identity_token_sent_via`, values.identityTokenSentVia || 'default' , { type: 'select' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'Accounts_OAuth_Custom_Identity_Token_Sent_Via', persistent: true, values: [{ key: 'default', i18nLabel: 'Same_As_Token_Sent_Via' }, { key: 'header', i18nLabel: 'Header' }, { key: 'payload', i18nLabel: 'Payload' }] }); settings.add(`Accounts_OAuth_Custom-${ name }-identity_path` , values.identityPath || '/me' , { type: 'string' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'Accounts_OAuth_Custom_Identity_Path', persistent: true }); settings.add(`Accounts_OAuth_Custom-${ name }-authorize_path` , values.authorizePath || '/oauth/authorize' , { type: 'string' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'Accounts_OAuth_Custom_Authorize_Path', persistent: true }); @@ -22,6 +22,7 @@ export function addOAuthService(name, values = {}) { settings.add(`Accounts_OAuth_Custom-${ name }-button_label_text` , values.buttonLabelText || '' , { type: 'string' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'Accounts_OAuth_Custom_Button_Label_Text', persistent: true }); settings.add(`Accounts_OAuth_Custom-${ name }-button_label_color` , values.buttonLabelColor || '#FFFFFF' , { type: 'string' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'Accounts_OAuth_Custom_Button_Label_Color', persistent: true }); settings.add(`Accounts_OAuth_Custom-${ name }-button_color` , values.buttonColor || '#1d74f5' , { type: 'string' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'Accounts_OAuth_Custom_Button_Color', persistent: true }); + settings.add(`Accounts_OAuth_Custom-${ name }-key_field` , values.keyField || 'username' , { type: 'select' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'Accounts_OAuth_Custom_Key_Field', persistent: true, values: [{ key: 'username', i18nLabel: 'Username' }, { key: 'email', i18nLabel: 'Email' }] }); settings.add(`Accounts_OAuth_Custom-${ name }-username_field` , values.usernameField || '' , { type: 'string' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'Accounts_OAuth_Custom_Username_Field', persistent: true }); settings.add(`Accounts_OAuth_Custom-${ name }-email_field` , values.emailField || '' , { type: 'string' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'Accounts_OAuth_Custom_Email_Field', persistent: true }); settings.add(`Accounts_OAuth_Custom-${ name }-name_field` , values.nameField || '' , { type: 'string' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'Accounts_OAuth_Custom_Name_Field', persistent: true }); diff --git a/app/lib/server/methods/removeOAuthService.js b/app/lib/server/methods/removeOAuthService.js index 4f83a1008bdbb..a60e791f1c1f4 100644 --- a/app/lib/server/methods/removeOAuthService.js +++ b/app/lib/server/methods/removeOAuthService.js @@ -34,6 +34,7 @@ Meteor.methods({ settings.removeById(`Accounts_OAuth_Custom-${ name }-button_label_color`); settings.removeById(`Accounts_OAuth_Custom-${ name }-button_color`); settings.removeById(`Accounts_OAuth_Custom-${ name }-login_style`); + settings.removeById(`Accounts_OAuth_Custom-${ name }-key_field`); settings.removeById(`Accounts_OAuth_Custom-${ name }-username_field`); settings.removeById(`Accounts_OAuth_Custom-${ name }-email_field`); settings.removeById(`Accounts_OAuth_Custom-${ name }-name_field`); diff --git a/app/lib/server/startup/oAuthServicesUpdate.js b/app/lib/server/startup/oAuthServicesUpdate.js index e09af1551e565..402534e237152 100644 --- a/app/lib/server/startup/oAuthServicesUpdate.js +++ b/app/lib/server/startup/oAuthServicesUpdate.js @@ -49,6 +49,7 @@ function _OAuthServicesUpdate() { data.buttonColor = settings.get(`${ service.key }-button_color`); data.tokenSentVia = settings.get(`${ service.key }-token_sent_via`); data.identityTokenSentVia = settings.get(`${ service.key }-identity_token_sent_via`); + data.keyField = settings.get(`${ service.key }-key_field`); data.usernameField = settings.get(`${ service.key }-username_field`); data.emailField = settings.get(`${ service.key }-email_field`); data.nameField = settings.get(`${ service.key }-name_field`); @@ -71,6 +72,7 @@ function _OAuthServicesUpdate() { loginStyle: data.loginStyle, tokenSentVia: data.tokenSentVia, identityTokenSentVia: data.identityTokenSentVia, + keyField: data.keyField, usernameField: data.usernameField, emailField: data.emailField, nameField: data.nameField, @@ -177,6 +179,7 @@ function customOAuthServicesInit() { buttonColor: process.env[`${ serviceKey }_button_color`], tokenSentVia: process.env[`${ serviceKey }_token_sent_via`], identityTokenSentVia: process.env[`${ serviceKey }_identity_token_sent_via`], + keyField: process.env[`${ serviceKey }_key_field`], usernameField: process.env[`${ serviceKey }_username_field`], nameField: process.env[`${ serviceKey }_name_field`], emailField: process.env[`${ serviceKey }_email_field`], diff --git a/app/models/server/models/Users.js b/app/models/server/models/Users.js index 36826d1465a1d..f8545308af92f 100644 --- a/app/models/server/models/Users.js +++ b/app/models/server/models/Users.js @@ -586,6 +586,15 @@ export class Users extends Base { return this.findOne(query, options); } + findOneByEmailAddressAndServiceNameIgnoringCase(emailAddress, userId, serviceName, options) { + const query = { + 'emails.address': String(emailAddress).trim().toLowerCase(), + [`services.${ serviceName }.id`]: userId, + }; + + return this.findOne(query, options); + } + findOneByUsername(username, options) { const query = { username }; diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 2235b6ad19424..2eeada65f6e21 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -105,6 +105,7 @@ "Accounts_OAuth_Custom_id": "Id", "Accounts_OAuth_Custom_Identity_Path": "Identity Path", "Accounts_OAuth_Custom_Identity_Token_Sent_Via": "Identity Token Sent Via", + "Accounts_OAuth_Custom_Key_Field": "Key Field", "Accounts_OAuth_Custom_Login_Style": "Login Style", "Accounts_OAuth_Custom_Map_Channels": "Map Roles/Groups to channels", "Accounts_OAuth_Custom_Merge_Roles": "Merge Roles from SSO", diff --git a/server/startup/migrations/index.js b/server/startup/migrations/index.js index c2de2a86bdae7..1aba72ee9c455 100644 --- a/server/startup/migrations/index.js +++ b/server/startup/migrations/index.js @@ -212,4 +212,5 @@ import './v212'; import './v213'; import './v214'; import './v215'; +import './v216'; import './xrun'; diff --git a/server/startup/migrations/v216.js b/server/startup/migrations/v216.js new file mode 100644 index 0000000000000..2074d65036f38 --- /dev/null +++ b/server/startup/migrations/v216.js @@ -0,0 +1,42 @@ +import { Migrations } from '../../../app/migrations'; +import { Settings } from '../../../app/models'; + +Migrations.add({ + version: 216, + up() { + Settings.find({ _id: /Accounts_OAuth_Custom/, i18nLabel: 'Accounts_OAuth_Custom_Enable' }).forEach(function(customOauth) { + const parts = customOauth._id.split('-'); + const name = parts[1]; + const id = `Accounts_OAuth_Custom-${ name }-key_field`; + if (!Settings.findOne({ _id: id })) { + Settings.insert({ + _id: id, + type: 'select', + group: 'OAuth', + section: `Custom OAuth: ${ name }`, + i18nLabel: 'Accounts_OAuth_Custom_Key_Field', + persistent: true, + values: [ + { + key: 'username', + i18nLabel: 'Username', + }, + { + key: 'email', + i18nLabel: 'Email', + }, + ], + packageValue: 'username', + valueSource: 'packageValue', + ts: new Date(), + hidden: false, + blocked: false, + sorter: 103, + i18nDescription: `Accounts_OAuth_Custom-${ name }-key_field_Description`, + createdAt: new Date(), + value: 'username', + }); + } + }); + }, +});