RocketChat/Rocket.Chat

View on GitHub
apps/meteor/server/lib/oauth/updateOAuthServices.ts

Summary

Maintainability
C
1 day
Test Coverage
import type {
    FacebookOAuthConfiguration,
    ILoginServiceConfiguration,
    LinkedinOAuthConfiguration,
    OAuthConfiguration,
    TwitterOAuthConfiguration,
} from '@rocket.chat/core-typings';
import { LoginServiceConfiguration } from '@rocket.chat/models';

import { CustomOAuth } from '../../../app/custom-oauth/server/custom_oauth_server';
import {
    notifyOnLoginServiceConfigurationChanged,
    notifyOnLoginServiceConfigurationChangedByService,
} from '../../../app/lib/server/lib/notifyListener';
import { settings } from '../../../app/settings/server/cached';
import { logger } from './logger';

export async function updateOAuthServices(): Promise<void> {
    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-', '');
        }

        const serviceKey = serviceName.toLowerCase();

        if (value === true) {
            const data: Partial<ILoginServiceConfiguration & Omit<OAuthConfiguration, '_id'>> = {
                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(serviceKey, {
                    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 as FacebookOAuthConfiguration).appId = data.clientId as string;
                delete data.clientId;
            }
            if (serviceName === 'Twitter') {
                (data as TwitterOAuthConfiguration).consumerKey = data.clientId as string;
                delete data.clientId;
            }

            if (serviceName === 'Linkedin') {
                (data as LinkedinOAuthConfiguration).clientConfig = {
                    requestPermissions: ['openid', 'email', 'profile'],
                };
            }

            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');
            }

            await LoginServiceConfiguration.createOrUpdateService(serviceKey, data);
            void notifyOnLoginServiceConfigurationChangedByService(serviceKey);
        } else {
            const service = await LoginServiceConfiguration.findOneByService(serviceName, { projection: { _id: 1 } });
            if (service?._id) {
                const { deletedCount } = await LoginServiceConfiguration.removeService(service._id);
                if (deletedCount > 0) {
                    void notifyOnLoginServiceConfigurationChanged({ _id: service._id }, 'removed');
                }
            }
        }
    }
}