diff --git a/apps/meteor/app/apple/client/index.ts b/apps/meteor/app/apple/client/index.ts deleted file mode 100644 index f2579fed790..00000000000 --- a/apps/meteor/app/apple/client/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { CustomOAuth } from '../../custom-oauth/client/CustomOAuth'; -import { config } from '../lib/config'; - -CustomOAuth.configureOAuthService('apple', config); diff --git a/apps/meteor/app/apple/lib/config.ts b/apps/meteor/app/apple/lib/config.ts index 14f746b19a0..b8fde01054e 100644 --- a/apps/meteor/app/apple/lib/config.ts +++ b/apps/meteor/app/apple/lib/config.ts @@ -1,3 +1,5 @@ +import type { OauthConfig } from '@rocket.chat/core-typings'; + export const config = { serverURL: 'https://appleid.apple.com', authorizePath: '/auth/authorize?response_mode=form_post', @@ -7,4 +9,4 @@ export const config = { mergeUsers: true, accessTokenParam: 'access_token', loginStyle: 'popup', -}; +} as const satisfies OauthConfig; diff --git a/apps/meteor/app/nextcloud/client/index.ts b/apps/meteor/app/nextcloud/client/index.ts deleted file mode 100644 index 1897bf0839a..00000000000 --- a/apps/meteor/app/nextcloud/client/index.ts +++ /dev/null @@ -1 +0,0 @@ -import './useNextcloud'; diff --git a/apps/meteor/client/importPackages.ts b/apps/meteor/client/importPackages.ts index c0579a0c97a..e59345e9a03 100644 --- a/apps/meteor/client/importPackages.ts +++ b/apps/meteor/client/importPackages.ts @@ -1,4 +1,3 @@ -import '../app/apple/client'; import '../app/authorization/client'; import '../app/autotranslate/client'; import '../app/emoji/client'; @@ -7,7 +6,6 @@ import '../app/gitlab/client'; import '../app/license/client'; import '../app/lib/client'; import '../app/livechat-enterprise/client'; -import '../app/nextcloud/client'; import '../app/notifications/client'; import '../app/otr/client'; import '../app/slackbridge/client'; diff --git a/apps/meteor/app/custom-oauth/client/CustomOAuth.ts b/apps/meteor/client/lib/customOAuth/CustomOAuth.ts similarity index 65% rename from apps/meteor/app/custom-oauth/client/CustomOAuth.ts rename to apps/meteor/client/lib/customOAuth/CustomOAuth.ts index 36b02abb5ca..6142115facd 100644 --- a/apps/meteor/app/custom-oauth/client/CustomOAuth.ts +++ b/apps/meteor/client/lib/customOAuth/CustomOAuth.ts @@ -2,25 +2,19 @@ import type { OAuthConfiguration, OauthConfig } from '@rocket.chat/core-typings' import { Random } from '@rocket.chat/random'; import { capitalize } from '@rocket.chat/string-helpers'; import { Accounts } from 'meteor/accounts-base'; -import { Match } from 'meteor/check'; import { Meteor } from 'meteor/meteor'; import { OAuth } from 'meteor/oauth'; -import type { IOAuthProvider } from '../../../client/definitions/IOAuthProvider'; -import { overrideLoginMethod, type LoginCallback } from '../../../client/lib/2fa/overrideLoginMethod'; -import { loginServices } from '../../../client/lib/loginServices'; -import { createOAuthTotpLoginMethod } from '../../../client/meteorOverrides/login/oauth'; import { isURL } from '../../../lib/utils/isURL'; - -// Request custom OAuth credentials for the user -// @param options {optional} -// @param credentialRequestCompleteCallback {Function} Callback function to call on -// completion. Takes one argument, credentialToken on success, or Error on -// error. +import type { IOAuthProvider } from '../../definitions/IOAuthProvider'; +import { createOAuthTotpLoginMethod } from '../../meteorOverrides/login/oauth'; +import { overrideLoginMethod, type LoginCallback } from '../2fa/overrideLoginMethod'; +import { loginServices } from '../loginServices'; +import { CustomOAuthError } from './CustomOAuthError'; const configuredOAuthServices = new Map(); -export class CustomOAuth implements IOAuthProvider { +export class CustomOAuth implements IOAuthProvider { public serverURL: string; public authorizePath: string; @@ -30,14 +24,9 @@ export class CustomOAuth implements IOAuthProvider { public responseType: string; constructor( - public readonly name: string, - options: OauthConfig, + public readonly name: TServiceName, + options: Readonly, ) { - this.name = name; - if (!Match.test(this.name, String)) { - throw new Meteor.Error('CustomOAuth: Name is required and must be String'); - } - this.configure(options); Accounts.oauth.registerService(this.name); @@ -45,26 +34,18 @@ export class CustomOAuth implements IOAuthProvider { this.configureLogin(); } - configure(options: OauthConfig) { - if (!Match.test(options, Object)) { - throw new Meteor.Error('CustomOAuth: Options is required and must be Object'); - } - - if (!Match.test(options.serverURL, String)) { - throw new Meteor.Error('CustomOAuth: Options.serverURL is required and must be String'); - } - - if (!Match.test(options.authorizePath, String)) { - options.authorizePath = '/oauth/authorize'; + configure(options: Readonly) { + if (typeof options !== 'object' || !options) { + throw new CustomOAuthError('options is required and must be object'); } - if (!Match.test(options.scope, String)) { - options.scope = 'openid'; + if (typeof options.serverURL !== 'string') { + throw new CustomOAuthError('options.serverURL is required and must be string'); } this.serverURL = options.serverURL; - this.authorizePath = options.authorizePath; - this.scope = options.scope; + this.authorizePath = options.authorizePath ?? '/oauth/authorize'; + this.scope = options.scope ?? 'openid'; this.responseType = options.responseType || 'code'; if (!isURL(this.authorizePath)) { @@ -73,7 +54,7 @@ export class CustomOAuth implements IOAuthProvider { } configureLogin() { - const loginWithService = `loginWith${capitalize(String(this.name || ''))}` as const; + const loginWithService = `loginWith${capitalize(this.name) as Capitalize}` as const; const loginWithOAuthTokenAndTOTP = createOAuthTotpLoginMethod(this); @@ -125,17 +106,20 @@ export class CustomOAuth implements IOAuthProvider { }); } - static configureOAuthService(serviceName: string, options: OauthConfig): CustomOAuth { + static configureOAuthService( + serviceName: TServiceName, + options: Readonly, + ): CustomOAuth { const existingInstance = configuredOAuthServices.get(serviceName); if (existingInstance) { existingInstance.configure(options); - return existingInstance; + return existingInstance as CustomOAuth; } // If we don't have a reference to the instance for this service and it was already registered on meteor, // then there's nothing we can do to update it if (Accounts.oauth.serviceNames().includes(serviceName)) { - throw new Error(`CustomOAuth service [${serviceName}] already registered, skipping new configuration.`); + throw new CustomOAuthError('service already registered, skipping new configuration', { service: serviceName }); } const instance = new CustomOAuth(serviceName, options); @@ -143,7 +127,10 @@ export class CustomOAuth implements IOAuthProvider { return instance; } - static configureCustomOAuthService(serviceName: string, options: OauthConfig): CustomOAuth | undefined { + static configureCustomOAuthService( + serviceName: TServiceName, + options: Readonly, + ): CustomOAuth | undefined { // Custom OAuth services are configured based on the login service list, so if this ends up being called multiple times, simply ignore it // Non-Custom OAuth services are configured based on code, so if configureOAuthService is called multiple times for them, it's a bug and it should throw. try { diff --git a/apps/meteor/client/lib/customOAuth/CustomOAuthError.ts b/apps/meteor/client/lib/customOAuth/CustomOAuthError.ts new file mode 100644 index 00000000000..cb8966d10b9 --- /dev/null +++ b/apps/meteor/client/lib/customOAuth/CustomOAuthError.ts @@ -0,0 +1,11 @@ +import { RocketChatError } from '../errors/RocketChatError'; + +type CustomOAuthErrorDetails = { + service?: string; +}; + +export class CustomOAuthError extends RocketChatError<'custom-oauth-error', CustomOAuthErrorDetails> { + constructor(reason?: string, details?: CustomOAuthErrorDetails) { + super('custom-oauth-error', details?.service ? `${details.service}: ${reason}` : reason, details); + } +} diff --git a/apps/meteor/client/views/root/AppLayout.tsx b/apps/meteor/client/views/root/AppLayout.tsx index 7cdb800700f..cb671e3fea6 100644 --- a/apps/meteor/client/views/root/AppLayout.tsx +++ b/apps/meteor/client/views/root/AppLayout.tsx @@ -2,6 +2,15 @@ import { useEffect, Suspense, useSyncExternalStore } from 'react'; import DocumentTitleWrapper from './DocumentTitleWrapper'; import PageLoading from './PageLoading'; +import { useAppleOAuth } from './hooks/customOAuth/useAppleOAuth'; +import { useCustomOAuth } from './hooks/customOAuth/useCustomOAuth'; +import { useDolphinOAuth } from './hooks/customOAuth/useDolphinOAuth'; +import { useDrupalOAuth } from './hooks/customOAuth/useDrupalOAuth'; +import { useGitHubEnterpriseOAuth } from './hooks/customOAuth/useGitHubEnterpriseOAuth'; +import { useGitLabOAuth } from './hooks/customOAuth/useGitLabOAuth'; +import { useNextcloudOAuth } from './hooks/customOAuth/useNextcloudOAuth'; +import { useTokenpassOAuth } from './hooks/customOAuth/useTokenpassOAuth'; +import { useWordPressOAuth } from './hooks/customOAuth/useWordPressOAuth'; import { useCodeHighlight } from './hooks/useCodeHighlight'; import { useEscapeKeyStroke } from './hooks/useEscapeKeyStroke'; import { useGoogleTagManager } from './hooks/useGoogleTagManager'; @@ -9,16 +18,9 @@ import { useLoadMissedMessages } from './hooks/useLoadMissedMessages'; import { useLoginViaQuery } from './hooks/useLoginViaQuery'; import { useMessageLinkClicks } from './hooks/useMessageLinkClicks'; import { useSettingsOnLoadSiteUrl } from './hooks/useSettingsOnLoadSiteUrl'; -import { useWordPressOAuth } from './hooks/useWordPressOAuth'; import { useCorsSSLConfig } from '../../../app/cors/client/useCorsSSLConfig'; -import { useDolphin } from '../../../app/dolphin/client/hooks/useDolphin'; -import { useDrupal } from '../../../app/drupal/client/hooks/useDrupal'; import { useEmojiOne } from '../../../app/emoji-emojione/client/hooks/useEmojiOne'; -import { useGitHubEnterpriseAuth } from '../../../app/github-enterprise/client/hooks/useGitHubEnterpriseAuth'; -import { useGitLabAuth } from '../../../app/gitlab/client/hooks/useGitLabAuth'; import { useLivechatEnterprise } from '../../../app/livechat-enterprise/hooks/useLivechatEnterprise'; -import { useNextcloud } from '../../../app/nextcloud/client/useNextcloud'; -import { useTokenPassAuth } from '../../../app/tokenpass/client/hooks/useTokenPassAuth'; import { useIframeLoginListener } from '../../hooks/iframe/useIframeLoginListener'; import { useNotificationPermission } from '../../hooks/notification/useNotificationPermission'; import { useAnalytics } from '../../hooks/useAnalytics'; @@ -26,7 +28,6 @@ import { useAnalyticsEventTracking } from '../../hooks/useAnalyticsEventTracking import { useAutoupdate } from '../../hooks/useAutoupdate'; import { useLoadRoomForAllowedAnonymousRead } from '../../hooks/useLoadRoomForAllowedAnonymousRead'; import { appLayout } from '../../lib/appLayout'; -import { useCustomOAuth } from '../../sidebar/hooks/useCustomOAuth'; import { useRedirectToSetupWizard } from '../../startup/useRedirectToSetupWizard'; const AppLayout = () => { @@ -50,12 +51,13 @@ const AppLayout = () => { useRedirectToSetupWizard(); useSettingsOnLoadSiteUrl(); useLivechatEnterprise(); - useNextcloud(); - useGitLabAuth(); - useGitHubEnterpriseAuth(); - useDrupal(); - useDolphin(); - useTokenPassAuth(); + useNextcloudOAuth(); + useGitLabOAuth(); + useGitHubEnterpriseOAuth(); + useDrupalOAuth(); + useDolphinOAuth(); + useTokenpassOAuth(); + useAppleOAuth(); useWordPressOAuth(); useCustomOAuth(); useCorsSSLConfig(); diff --git a/apps/meteor/client/views/root/hooks/customOAuth/useAppleOAuth.ts b/apps/meteor/client/views/root/hooks/customOAuth/useAppleOAuth.ts new file mode 100644 index 00000000000..5d358124b18 --- /dev/null +++ b/apps/meteor/client/views/root/hooks/customOAuth/useAppleOAuth.ts @@ -0,0 +1,9 @@ +import { config } from '../../../../../app/apple/lib/config'; +import { CustomOAuth } from '../../../../lib/customOAuth/CustomOAuth'; + +/* const Apple =*/ CustomOAuth.configureOAuthService('apple', config); + +export const useAppleOAuth = () => { + // Here we would expect to handle changes in settings, updating the configuration + // accordingly, but it was not implemented yet. +}; diff --git a/apps/meteor/client/sidebar/hooks/useCustomOAuth.ts b/apps/meteor/client/views/root/hooks/customOAuth/useCustomOAuth.ts similarity index 77% rename from apps/meteor/client/sidebar/hooks/useCustomOAuth.ts rename to apps/meteor/client/views/root/hooks/customOAuth/useCustomOAuth.ts index 174cb317343..906b98bbb5f 100644 --- a/apps/meteor/client/sidebar/hooks/useCustomOAuth.ts +++ b/apps/meteor/client/views/root/hooks/customOAuth/useCustomOAuth.ts @@ -1,7 +1,7 @@ import { useEffect } from 'react'; -import { CustomOAuth } from '../../../app/custom-oauth/client/CustomOAuth'; -import { loginServices } from '../../lib/loginServices'; +import { CustomOAuth } from '../../../../lib/customOAuth/CustomOAuth'; +import { loginServices } from '../../../../lib/loginServices'; export const useCustomOAuth = () => { useEffect( diff --git a/apps/meteor/app/dolphin/client/hooks/useDolphin.ts b/apps/meteor/client/views/root/hooks/customOAuth/useDolphinOAuth.ts similarity index 70% rename from apps/meteor/app/dolphin/client/hooks/useDolphin.ts rename to apps/meteor/client/views/root/hooks/customOAuth/useDolphinOAuth.ts index 7ae3266f5a8..7065cfed332 100644 --- a/apps/meteor/app/dolphin/client/hooks/useDolphin.ts +++ b/apps/meteor/client/views/root/hooks/customOAuth/useDolphinOAuth.ts @@ -1,7 +1,8 @@ +import type { OauthConfig } from '@rocket.chat/core-typings'; import { useSetting } from '@rocket.chat/ui-contexts'; import { useEffect } from 'react'; -import { CustomOAuth } from '../../../custom-oauth/client/CustomOAuth'; +import { CustomOAuth } from '../../../../lib/customOAuth/CustomOAuth'; const config = { serverURL: '', @@ -14,18 +15,20 @@ const config = { forOtherUsers: ['services.dolphin.name'], }, accessTokenParam: 'access_token', -}; +} as const satisfies OauthConfig; const Dolphin = CustomOAuth.configureOAuthService('dolphin', config); -export const useDolphin = () => { +export const useDolphinOAuth = () => { const enabled = useSetting('Accounts_OAuth_Dolphin'); const url = useSetting('Accounts_OAuth_Dolphin_URL') as string; useEffect(() => { if (enabled) { - config.serverURL = url; - Dolphin.configure(config); + Dolphin.configure({ + ...config, + serverURL: url, + }); } }, [enabled, url]); }; diff --git a/apps/meteor/app/drupal/client/hooks/useDrupal.ts b/apps/meteor/client/views/root/hooks/customOAuth/useDrupalOAuth.ts similarity index 79% rename from apps/meteor/app/drupal/client/hooks/useDrupal.ts rename to apps/meteor/client/views/root/hooks/customOAuth/useDrupalOAuth.ts index f4808caa78b..f697b9d1e94 100644 --- a/apps/meteor/app/drupal/client/hooks/useDrupal.ts +++ b/apps/meteor/client/views/root/hooks/customOAuth/useDrupalOAuth.ts @@ -2,12 +2,12 @@ import type { OauthConfig } from '@rocket.chat/core-typings'; import { useSetting } from '@rocket.chat/ui-contexts'; import { useEffect } from 'react'; -import { CustomOAuth } from '../../../custom-oauth/client/CustomOAuth'; +import { CustomOAuth } from '../../../../lib/customOAuth/CustomOAuth'; // Drupal Server CallBack URL needs to be http(s)://{rocketchat.server}[:port]/_oauth/drupal // In RocketChat -> Administration the URL needs to be http(s)://{drupal.server}/ -const config: OauthConfig = { +const config = { serverURL: '', identityPath: '/oauth2/UserInfo', authorizePath: '/oauth2/authorize', @@ -21,17 +21,19 @@ const config: OauthConfig = { forOtherUsers: ['services.drupal.name'], }, accessTokenParam: 'access_token', -}; +} as const satisfies OauthConfig; const Drupal = CustomOAuth.configureOAuthService('drupal', config); -export const useDrupal = () => { +export const useDrupalOAuth = () => { const drupalUrl = useSetting('API_Drupal_URL') as string; useEffect(() => { if (drupalUrl) { - config.serverURL = drupalUrl; - Drupal.configure(config); + Drupal.configure({ + ...config, + serverURL: drupalUrl, + }); } }, [drupalUrl]); }; diff --git a/apps/meteor/app/github-enterprise/client/hooks/useGitHubEnterpriseAuth.ts b/apps/meteor/client/views/root/hooks/customOAuth/useGitHubEnterpriseOAuth.ts similarity index 77% rename from apps/meteor/app/github-enterprise/client/hooks/useGitHubEnterpriseAuth.ts rename to apps/meteor/client/views/root/hooks/customOAuth/useGitHubEnterpriseOAuth.ts index 79af68ef234..50b02b67e3c 100644 --- a/apps/meteor/app/github-enterprise/client/hooks/useGitHubEnterpriseAuth.ts +++ b/apps/meteor/client/views/root/hooks/customOAuth/useGitHubEnterpriseOAuth.ts @@ -2,12 +2,12 @@ import type { OauthConfig } from '@rocket.chat/core-typings'; import { useSetting } from '@rocket.chat/ui-contexts'; import { useEffect } from 'react'; -import { CustomOAuth } from '../../../custom-oauth/client/CustomOAuth'; +import { CustomOAuth } from '../../../../lib/customOAuth/CustomOAuth'; // GitHub Enterprise Server CallBack URL needs to be http(s)://{rocketchat.server}[:port]/_oauth/github_enterprise // In RocketChat -> Administration the URL needs to be http(s)://{github.enterprise.server}/ -const config: OauthConfig = { +const config = { serverURL: '', identityPath: '/api/v3/user', authorizePath: '/login/oauth/authorize', @@ -16,17 +16,19 @@ const config: OauthConfig = { forLoggedInUser: ['services.github-enterprise'], forOtherUsers: ['services.github-enterprise.username'], }, -}; +} as const satisfies OauthConfig; const GitHubEnterprise = CustomOAuth.configureOAuthService('github_enterprise', config); -export const useGitHubEnterpriseAuth = () => { +export const useGitHubEnterpriseOAuth = () => { const githubApiUrl = useSetting('API_GitHub_Enterprise_URL') as string; useEffect(() => { if (githubApiUrl) { - config.serverURL = githubApiUrl; - GitHubEnterprise.configure(config); + GitHubEnterprise.configure({ + ...config, + serverURL: githubApiUrl, + }); } }, [githubApiUrl]); }; diff --git a/apps/meteor/app/gitlab/client/hooks/useGitLabAuth.ts b/apps/meteor/client/views/root/hooks/customOAuth/useGitLabOAuth.ts similarity index 65% rename from apps/meteor/app/gitlab/client/hooks/useGitLabAuth.ts rename to apps/meteor/client/views/root/hooks/customOAuth/useGitLabOAuth.ts index c5776723e49..9651f252fd0 100644 --- a/apps/meteor/app/gitlab/client/hooks/useGitLabAuth.ts +++ b/apps/meteor/client/views/root/hooks/customOAuth/useGitLabOAuth.ts @@ -2,9 +2,9 @@ import type { OauthConfig } from '@rocket.chat/core-typings'; import { useSetting } from '@rocket.chat/ui-contexts'; import { useEffect } from 'react'; -import { CustomOAuth } from '../../../custom-oauth/client/CustomOAuth'; +import { CustomOAuth } from '../../../../lib/customOAuth/CustomOAuth'; -const config: OauthConfig = { +const config = { serverURL: 'https://gitlab.com', identityPath: '/api/v4/user', scope: 'read_user', @@ -14,28 +14,21 @@ const config: OauthConfig = { forOtherUsers: ['services.gitlab.username'], }, accessTokenParam: 'access_token', -}; +} as const satisfies OauthConfig; const Gitlab = CustomOAuth.configureOAuthService('gitlab', config); -export const useGitLabAuth = () => { +export const useGitLabOAuth = () => { const gitlabApiUrl = useSetting('API_Gitlab_URL') as string; const gitlabIdentiry = useSetting('Accounts_OAuth_Gitlab_identity_path') as string; const gitlabMergeUsers = useSetting('Accounts_OAuth_Gitlab_merge_users', false); useEffect(() => { - if (gitlabApiUrl) { - config.serverURL = gitlabApiUrl.trim().replace(/\/*$/, ''); - } - - if (gitlabIdentiry) { - config.identityPath = gitlabIdentiry.trim() || config.identityPath; - } - - if (gitlabMergeUsers) { - config.mergeUsers = true; - } - - Gitlab.configure(config); + Gitlab.configure({ + ...config, + ...(gitlabApiUrl && { serverURL: gitlabApiUrl.trim().replace(/\/*$/, '') }), + ...(gitlabIdentiry && { identityPath: gitlabIdentiry.trim() || config.identityPath }), + ...(gitlabMergeUsers && { mergeUsers: true }), + }); }, [gitlabApiUrl, gitlabIdentiry, gitlabMergeUsers]); }; diff --git a/apps/meteor/app/nextcloud/client/useNextcloud.ts b/apps/meteor/client/views/root/hooks/customOAuth/useNextcloudOAuth.ts similarity index 72% rename from apps/meteor/app/nextcloud/client/useNextcloud.ts rename to apps/meteor/client/views/root/hooks/customOAuth/useNextcloudOAuth.ts index 580d72e92a4..5c6f390ae91 100644 --- a/apps/meteor/app/nextcloud/client/useNextcloud.ts +++ b/apps/meteor/client/views/root/hooks/customOAuth/useNextcloudOAuth.ts @@ -2,9 +2,9 @@ import type { OauthConfig } from '@rocket.chat/core-typings'; import { useSetting } from '@rocket.chat/ui-contexts'; import { useEffect } from 'react'; -import { CustomOAuth } from '../../custom-oauth/client/CustomOAuth'; +import { CustomOAuth } from '../../../../lib/customOAuth/CustomOAuth'; -const config: OauthConfig = { +const config = { serverURL: '', tokenPath: '/index.php/apps/oauth2/api/v1/token', tokenSentVia: 'header', @@ -15,17 +15,19 @@ const config: OauthConfig = { forLoggedInUser: ['services.nextcloud'], forOtherUsers: ['services.nextcloud.name'], }, -}; +} as const satisfies OauthConfig; const Nextcloud = CustomOAuth.configureOAuthService('nextcloud', config); -export const useNextcloud = (): void => { +export const useNextcloudOAuth = (): void => { const nextcloudURL = useSetting('Accounts_OAuth_Nextcloud_URL') as string; useEffect(() => { if (nextcloudURL) { - config.serverURL = nextcloudURL.trim().replace(/\/*$/, ''); - Nextcloud.configure(config); + Nextcloud.configure({ + ...config, + serverURL: nextcloudURL.trim().replace(/\/*$/, ''), + }); } }, [nextcloudURL]); }; diff --git a/apps/meteor/app/tokenpass/client/hooks/useTokenPassAuth.tsx b/apps/meteor/client/views/root/hooks/customOAuth/useTokenpassOAuth.ts similarity index 73% rename from apps/meteor/app/tokenpass/client/hooks/useTokenPassAuth.tsx rename to apps/meteor/client/views/root/hooks/customOAuth/useTokenpassOAuth.ts index 26dbe3a900e..a3e8be3f374 100644 --- a/apps/meteor/app/tokenpass/client/hooks/useTokenPassAuth.tsx +++ b/apps/meteor/client/views/root/hooks/customOAuth/useTokenpassOAuth.ts @@ -2,9 +2,9 @@ import type { OauthConfig } from '@rocket.chat/core-typings'; import { useSetting } from '@rocket.chat/ui-contexts'; import { useEffect } from 'react'; -import { CustomOAuth } from '../../../custom-oauth/client/CustomOAuth'; +import { CustomOAuth } from '../../../../lib/customOAuth/CustomOAuth'; -const config: OauthConfig = { +const config = { serverURL: '', identityPath: '/oauth/user', authorizePath: '/oauth/authorize', @@ -18,18 +18,19 @@ const config: OauthConfig = { forOtherUsers: ['services.tokenpass.name'], }, accessTokenParam: 'access_token', -}; +} as const satisfies OauthConfig; const Tokenpass = CustomOAuth.configureOAuthService('tokenpass', config); -export const useTokenPassAuth = () => { +export const useTokenpassOAuth = () => { const setting = useSetting('API_Tokenpass_URL') as string | undefined; useEffect(() => { - if (!setting) { - return; - } - config.serverURL = setting; - Tokenpass.configure(config); + if (!setting) return; + + Tokenpass.configure({ + ...config, + serverURL: setting, + }); }, [setting]); }; diff --git a/apps/meteor/client/views/root/hooks/useWordPressOAuth.ts b/apps/meteor/client/views/root/hooks/customOAuth/useWordPressOAuth.ts similarity index 93% rename from apps/meteor/client/views/root/hooks/useWordPressOAuth.ts rename to apps/meteor/client/views/root/hooks/customOAuth/useWordPressOAuth.ts index c6b90d741c1..1ba4d3f1c17 100644 --- a/apps/meteor/client/views/root/hooks/useWordPressOAuth.ts +++ b/apps/meteor/client/views/root/hooks/customOAuth/useWordPressOAuth.ts @@ -2,16 +2,16 @@ import type { OauthConfig } from '@rocket.chat/core-typings'; import { useSetting } from '@rocket.chat/ui-contexts'; import { useEffect } from 'react'; -import { CustomOAuth } from '../../../../app/custom-oauth/client/CustomOAuth'; +import { CustomOAuth } from '../../../../lib/customOAuth/CustomOAuth'; -const configDefault: OauthConfig = { +const configDefault = { serverURL: '', addAutopublishFields: { forLoggedInUser: ['services.wordpress'], forOtherUsers: ['services.wordpress.user_login'], }, accessTokenParam: 'access_token', -}; +} as const satisfies OauthConfig; const WordPress = CustomOAuth.configureOAuthService('wordpress', configDefault); @@ -22,7 +22,7 @@ const configureServerType = ( tokenPath?: string, authorizePath?: string, scope?: string, -) => { +): OauthConfig => { switch (serverType) { case 'custom': { return { diff --git a/packages/core-typings/src/ICustomOAuthConfig.ts b/packages/core-typings/src/ICustomOAuthConfig.ts index ff695865cf9..385cac5e773 100644 --- a/packages/core-typings/src/ICustomOAuthConfig.ts +++ b/packages/core-typings/src/ICustomOAuthConfig.ts @@ -14,4 +14,5 @@ export type OauthConfig = { usernameField?: string; mergeUsers?: boolean; responseType?: string; + loginStyle?: 'popup' | 'redirect'; };