The communications platform that puts data protection first.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
Rocket.Chat/apps/meteor/app/lib/server/startup/oAuthServicesUpdate.js

206 lines
8.2 KiB

import { ServiceConfiguration } from 'meteor/service-configuration';
import _ from 'underscore';
import { CustomOAuth } from '../../../custom-oauth/server/custom_oauth_server';
import { Logger } from '../../../logger/server';
import { settings } from '../../../settings/server';
import { addOAuthService } from '../functions/addOAuthService';
const logger = new Logger('rocketchat:lib');
async function _OAuthServicesUpdate() {
const services = settings.getByRegexp(/^(Accounts_OAuth_|Accounts_OAuth_Custom-)[a-z0-9_]+$/i);
const filteredServices = services.filter(([, value]) => typeof value === 'boolean');
for await (const [key, value] of filteredServices) {
logger.debug({ oauth_updated: key });
let serviceName = key.replace('Accounts_OAuth_', '');
if (serviceName === 'Meteor') {
serviceName = 'meteor-developer';
}
if (/Accounts_OAuth_Custom-/.test(key)) {
serviceName = key.replace('Accounts_OAuth_Custom-', '');
}
if (value === true) {
const data = {
clientId: settings.get(`${key}_id`),
secret: settings.get(`${key}_secret`),
};
if (/Accounts_OAuth_Custom-/.test(key)) {
data.custom = true;
data.clientId = settings.get(`${key}-id`);
data.secret = settings.get(`${key}-secret`);
data.serverURL = settings.get(`${key}-url`);
data.tokenPath = settings.get(`${key}-token_path`);
data.identityPath = settings.get(`${key}-identity_path`);
data.authorizePath = settings.get(`${key}-authorize_path`);
data.scope = settings.get(`${key}-scope`);
data.accessTokenParam = settings.get(`${key}-access_token_param`);
data.buttonLabelText = settings.get(`${key}-button_label_text`);
data.buttonLabelColor = settings.get(`${key}-button_label_color`);
data.loginStyle = settings.get(`${key}-login_style`);
data.buttonColor = settings.get(`${key}-button_color`);
data.tokenSentVia = settings.get(`${key}-token_sent_via`);
data.identityTokenSentVia = settings.get(`${key}-identity_token_sent_via`);
data.keyField = settings.get(`${key}-key_field`);
data.usernameField = settings.get(`${key}-username_field`);
data.emailField = settings.get(`${key}-email_field`);
data.nameField = settings.get(`${key}-name_field`);
data.avatarField = settings.get(`${key}-avatar_field`);
data.rolesClaim = settings.get(`${key}-roles_claim`);
data.groupsClaim = settings.get(`${key}-groups_claim`);
data.channelsMap = settings.get(`${key}-groups_channel_map`);
data.channelsAdmin = settings.get(`${key}-channels_admin`);
data.mergeUsers = settings.get(`${key}-merge_users`);
data.mergeUsersDistinctServices = settings.get(`${key}-merge_users_distinct_services`);
data.mapChannels = settings.get(`${key}-map_channels`);
data.mergeRoles = settings.get(`${key}-merge_roles`);
data.rolesToSync = settings.get(`${key}-roles_to_sync`);
data.showButton = settings.get(`${key}-show_button`);
new CustomOAuth(serviceName.toLowerCase(), {
serverURL: data.serverURL,
tokenPath: data.tokenPath,
identityPath: data.identityPath,
authorizePath: data.authorizePath,
scope: data.scope,
loginStyle: data.loginStyle,
tokenSentVia: data.tokenSentVia,
identityTokenSentVia: data.identityTokenSentVia,
keyField: data.keyField,
usernameField: data.usernameField,
emailField: data.emailField,
nameField: data.nameField,
avatarField: data.avatarField,
rolesClaim: data.rolesClaim,
groupsClaim: data.groupsClaim,
mapChannels: data.mapChannels,
channelsMap: data.channelsMap,
channelsAdmin: data.channelsAdmin,
mergeUsers: data.mergeUsers,
mergeUsersDistinctServices: data.mergeUsersDistinctServices,
mergeRoles: data.mergeRoles,
rolesToSync: data.rolesToSync,
accessTokenParam: data.accessTokenParam,
showButton: data.showButton,
});
}
if (serviceName === 'Facebook') {
data.appId = data.clientId;
delete data.clientId;
}
if (serviceName === 'Twitter') {
data.consumerKey = data.clientId;
delete data.clientId;
}
if (serviceName === 'Linkedin') {
data.clientConfig = {
requestPermissions: ['r_liteprofile', 'r_emailaddress'],
};
}
if (serviceName === 'Nextcloud') {
data.buttonLabelText = settings.get('Accounts_OAuth_Nextcloud_button_label_text');
data.buttonLabelColor = settings.get('Accounts_OAuth_Nextcloud_button_label_color');
data.buttonColor = settings.get('Accounts_OAuth_Nextcloud_button_color');
}
// If there's no data other than the service name, then put the service name in the data object so the operation won't fail
const keys = Object.keys(data).filter((key) => data[key] !== undefined);
if (!keys.length) {
data.service = serviceName.toLowerCase();
}
await ServiceConfiguration.configurations.upsertAsync(
{
service: serviceName.toLowerCase(),
},
{
$set: data,
},
);
} else {
await ServiceConfiguration.configurations.removeAsync({
service: serviceName.toLowerCase(),
});
}
}
}
const OAuthServicesUpdate = _.debounce(_OAuthServicesUpdate, 2000);
async function OAuthServicesRemove(_id) {
const serviceName = _id.replace('Accounts_OAuth_Custom-', '');
return ServiceConfiguration.configurations.removeAsync({
service: serviceName.toLowerCase(),
});
}
settings.watchByRegex(/^Accounts_OAuth_.+/, function () {
return OAuthServicesUpdate(); // eslint-disable-line new-cap
});
settings.watchByRegex(/^Accounts_OAuth_Custom-[a-z0-9_]+/, function (key, value) {
if (!value) {
return OAuthServicesRemove(key); // eslint-disable-line new-cap
}
});
async function customOAuthServicesInit() {
// Add settings for custom OAuth providers to the settings so they get
// automatically added when they are defined in ENV variables
for await (const key of Object.keys(process.env)) {
if (/Accounts_OAuth_Custom_[a-zA-Z0-9_-]+$/.test(key)) {
// Most all shells actually prohibit the usage of - in environment variables
// So this will allow replacing - with _ and translate it back to the setting name
let name = key.replace('Accounts_OAuth_Custom_', '');
if (name.indexOf('_') > -1) {
name = name.replace(name.substr(name.indexOf('_')), '');
}
const serviceKey = `Accounts_OAuth_Custom_${name}`;
if (key === serviceKey) {
const values = {
enabled: process.env[`${serviceKey}`] === 'true',
clientId: process.env[`${serviceKey}_id`],
clientSecret: process.env[`${serviceKey}_secret`],
serverURL: process.env[`${serviceKey}_url`],
tokenPath: process.env[`${serviceKey}_token_path`],
identityPath: process.env[`${serviceKey}_identity_path`],
authorizePath: process.env[`${serviceKey}_authorize_path`],
scope: process.env[`${serviceKey}_scope`],
accessTokenParam: process.env[`${serviceKey}_access_token_param`],
buttonLabelText: process.env[`${serviceKey}_button_label_text`],
buttonLabelColor: process.env[`${serviceKey}_button_label_color`],
loginStyle: process.env[`${serviceKey}_login_style`],
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`],
rolesClaim: process.env[`${serviceKey}_roles_claim`],
groupsClaim: process.env[`${serviceKey}_groups_claim`],
channelsMap: process.env[`${serviceKey}_groups_channel_map`],
channelsAdmin: process.env[`${serviceKey}_channels_admin`],
mergeUsers: process.env[`${serviceKey}_merge_users`] === 'true',
mergeUsersDistinctServices: process.env[`${serviceKey}_merge_users_distinct_services`] === 'true',
mapChannels: process.env[`${serviceKey}_map_channels`],
mergeRoles: process.env[`${serviceKey}_merge_roles`] === 'true',
rolesToSync: process.env[`${serviceKey}_roles_to_sync`],
showButton: process.env[`${serviceKey}_show_button`] === 'true',
avatarField: process.env[`${serviceKey}_avatar_field`],
};
await addOAuthService(name, values);
}
}
}
}
await customOAuthServicesInit();