Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions apps/meteor/app/api/server/v1/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ API.v1.get(
},
async function action() {
const oAuthServicesEnabled = await LoginServiceConfigurationModel.find({}, { projection: { secret: 0 } }).toArray();
const isPassportFlowEnabled = settings.get<boolean>('Accounts_OAuth_Use_Modern_Flow');

return API.v1.success({
services: oAuthServicesEnabled.map((service) => {
Expand All @@ -195,7 +196,7 @@ API.v1.get(
}

if ((service as OAuthConfiguration).custom || (service.service && service.service === 'wordpress')) {
return { ...service, hideButtonOnMobile: true };
return { ...service, hideButtonOnMobile: isPassportFlowEnabled };
}

return {
Expand All @@ -209,7 +210,7 @@ API.v1.get(
buttonColor: service.buttonColor || '',
buttonLabelColor: service.buttonLabelColor || '',
custom: false,
hideButtonOnMobile: true,
hideButtonOnMobile: isPassportFlowEnabled,
};
}),
});
Expand Down
22 changes: 19 additions & 3 deletions apps/meteor/app/dolphin/server/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import _ from 'underscore';
import { callbacks } from '../../../server/lib/callbacks';
import { beforeCreateUserCallback } from '../../../server/lib/callbacks/beforeCreateUserCallback';
import { addPassportCustomOAuth } from '../../../server/lib/oauth/addPassportCustomOAuth';
import { CustomOAuth } from '../../custom-oauth/server/custom_oauth_server';
import { settings } from '../../settings/server';

const config: Partial<OAuthConfiguration> = {
Expand All @@ -22,6 +23,8 @@ const config: Partial<OAuthConfiguration> = {
accessTokenParam: 'access_token',
};

const Dolphin = new CustomOAuth('dolphin', config);

function DolphinOnCreateUser(options: any, user?: IUser) {
// TODO: callbacks Fix this
if (user?.services?.dolphin?.NickName) {
Expand All @@ -46,14 +49,27 @@ const configureDolphinOAuth = () => {
return;
}

addPassportCustomOAuth('dolphin', { ...config, serverURL, clientId, clientSecret });
const completeConfig = { ...config, serverURL, clientId, clientSecret };

if (settings.get<boolean>('Accounts_OAuth_Use_Modern_Flow')) {
addPassportCustomOAuth('dolphin', completeConfig);
return;
}

Dolphin.configure(completeConfig);
};

Meteor.startup(async () => {
const updateConfig = () => _.debounce(configureDolphinOAuth, 300);
const updateConfig = _.debounce(configureDolphinOAuth, 300);

settings.watchMultiple(
['Accounts_OAuth_Dolphin', 'Accounts_OAuth_Dolphin_URL', 'Accounts_OAuth_Dolphin_id', 'Accounts_OAuth_Dolphin_secret'],
[
'Accounts_OAuth_Dolphin',
'Accounts_OAuth_Dolphin_URL',
'Accounts_OAuth_Dolphin_id',
'Accounts_OAuth_Dolphin_secret',
'Accounts_OAuth_Use_Modern_Flow',
],
updateConfig,
);

Expand Down
21 changes: 19 additions & 2 deletions apps/meteor/app/drupal/server/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import passport from 'passport';
import _ from 'underscore';

import { addPassportCustomOAuth } from '../../../server/lib/oauth/addPassportCustomOAuth';
import { CustomOAuth } from '../../custom-oauth/server/custom_oauth_server';
import { settings } from '../../settings/server';

const config: Partial<OAuthConfiguration> = {
serverURL: '',
identityPath: '/oauth2/UserInfo',
authorizePath: '/oauth2/authorize',
tokenPath: '/oauth2/token',
Expand All @@ -21,6 +23,8 @@ const config: Partial<OAuthConfiguration> = {
accessTokenParam: 'access_token',
};

const Drupal = new CustomOAuth('drupal', config);

const configureDrupalOAuth = () => {
passport.unuse('drupal');
const enabled = settings.get<boolean>('Accounts_OAuth_Drupal');
Expand All @@ -36,14 +40,27 @@ const configureDrupalOAuth = () => {
return;
}

addPassportCustomOAuth('drupal', { ...config, serverURL, clientId, clientSecret });
const completeConfig = { ...config, serverURL, clientId, clientSecret };

if (settings.get<boolean>('Accounts_OAuth_Use_Modern_Flow')) {
addPassportCustomOAuth('drupal', completeConfig);
return;
}

Drupal.configure(completeConfig);
};

Meteor.startup(() => {
const updateConfig = _.debounce(configureDrupalOAuth, 300);

settings.watchMultiple(
['Accounts_OAuth_Drupal', 'API_Drupal_URL', 'Accounts_OAuth_Drupal_id', 'Accounts_OAuth_Drupal_secret'],
[
'Accounts_OAuth_Drupal',
'API_Drupal_URL',
'Accounts_OAuth_Drupal_id',
'Accounts_OAuth_Drupal_secret',
'Accounts_OAuth_Use_Modern_Flow',
],
updateConfig,
);
});
13 changes: 12 additions & 1 deletion apps/meteor/app/gitlab/server/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import passport from 'passport';
import _ from 'underscore';

import { addPassportCustomOAuth } from '../../../server/lib/oauth/addPassportCustomOAuth';
import { CustomOAuth } from '../../custom-oauth/server/custom_oauth_server';
import { settings } from '../../settings/server';

const config: Partial<OAuthConfiguration> = {
Expand All @@ -18,6 +19,8 @@ const config: Partial<OAuthConfiguration> = {
accessTokenParam: 'access_token',
};

const Gitlab = new CustomOAuth('gitlab', config);

const configureGitlabOAuth = () => {
passport.unuse('gitlab');

Expand All @@ -36,7 +39,14 @@ const configureGitlabOAuth = () => {
return;
}

addPassportCustomOAuth('gitlab', { ...config, clientId, clientSecret, serverURL, identityPath, mergeUsers });
const completeConfig = { ...config, clientId, clientSecret, serverURL, identityPath, mergeUsers };

if (settings.get<boolean>('Accounts_OAuth_Use_Modern_Flow')) {
addPassportCustomOAuth('gitlab', completeConfig);
return;
}

Gitlab.configure(completeConfig);
Comment thread
yash-rajpal marked this conversation as resolved.
};

Meteor.startup(() => {
Expand All @@ -50,6 +60,7 @@ Meteor.startup(() => {
'Accounts_OAuth_Gitlab_secret',
'Accounts_OAuth_Gitlab_identity_path',
'Accounts_OAuth_Gitlab_merge_users',
'Accounts_OAuth_Use_Modern_Flow',
],
updateConfig,
);
Expand Down
28 changes: 21 additions & 7 deletions apps/meteor/app/nextcloud/server/lib.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import type { OAuthConfiguration } from '@rocket.chat/core-typings';
import { Meteor } from 'meteor/meteor';
import passport from 'passport';

import { addPassportCustomOAuth } from '../../../server/lib/oauth/addPassportCustomOAuth';
import { CustomOAuth } from '../../custom-oauth/server/custom_oauth_server';
import { settings } from '../../settings/server/cached';

const NEXTCLOUD_PATHS = {
serverURL: '',
tokenPath: '/index.php/apps/oauth2/api/v1/token',
tokenSentVia: 'header' as OAuthConfiguration['tokenSentVia'],
authorizePath: '/index.php/apps/oauth2/authorize',
Expand All @@ -16,7 +19,10 @@ const NEXTCLOUD_PATHS = {
},
};

const Nextcloud = new CustomOAuth('nextcloud', NEXTCLOUD_PATHS);

function configureNextcloudOAuth(): void {
passport.unuse('nextcloud');
Comment thread
yash-rajpal marked this conversation as resolved.
const enabled = settings.get<boolean>('Accounts_OAuth_Nextcloud');
if (!enabled) {
return;
Expand All @@ -30,17 +36,25 @@ function configureNextcloudOAuth(): void {
return;
}

addPassportCustomOAuth('nextcloud', {
...NEXTCLOUD_PATHS,
serverURL,
clientId,
clientSecret,
});
const config = { ...NEXTCLOUD_PATHS, serverURL, clientId, clientSecret };

if (settings.get<boolean>('Accounts_OAuth_Use_Modern_Flow')) {
addPassportCustomOAuth('nextcloud', config);
return;
}

Nextcloud.configure(config);
}

Meteor.startup(() => {
settings.watchMultiple(
['Accounts_OAuth_Nextcloud', 'Accounts_OAuth_Nextcloud_URL', 'Accounts_OAuth_Nextcloud_id', 'Accounts_OAuth_Nextcloud_secret'],
[
'Accounts_OAuth_Nextcloud',
'Accounts_OAuth_Nextcloud_URL',
'Accounts_OAuth_Nextcloud_id',
'Accounts_OAuth_Nextcloud_secret',
'Accounts_OAuth_Use_Modern_Flow',
],
configureNextcloudOAuth,
);
});
21 changes: 19 additions & 2 deletions apps/meteor/app/wordpress/server/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import passport from 'passport';
import _ from 'underscore';

import { addPassportCustomOAuth } from '../../../server/lib/oauth/addPassportCustomOAuth';
import { CustomOAuth } from '../../custom-oauth/server/custom_oauth_server';
import { settings } from '../../settings/server';

const config: Partial<OAuthConfiguration> = {
Expand All @@ -20,6 +21,8 @@ const config: Partial<OAuthConfiguration> = {

const serviceKey = 'wordpress';

const WordPress = new CustomOAuth(serviceKey, config);

const fillSettings = _.debounce(async (): Promise<void> => {
config.serverURL = settings.get('API_Wordpress_URL');
if (!config.serverURL) {
Expand Down Expand Up @@ -66,7 +69,20 @@ const fillSettings = _.debounce(async (): Promise<void> => {
break;
}

addPassportCustomOAuth(serviceKey, config);
const clientId = settings.get<string>('Accounts_OAuth_Wordpress_id');
const clientSecret = settings.get<string>('Accounts_OAuth_Wordpress_secret');

if (!clientId || !clientSecret) {
return;
Comment thread
yash-rajpal marked this conversation as resolved.
}

const completeConfig = { ...config, clientId, clientSecret };

if (settings.get<boolean>('Accounts_OAuth_Use_Modern_Flow')) {
Comment thread
tassoevan marked this conversation as resolved.
addPassportCustomOAuth(serviceKey, completeConfig);
} else {
WordPress.configure(completeConfig);
}

const enabled = settings.get('Accounts_OAuth_Wordpress');
if (enabled) {
Expand All @@ -86,5 +102,6 @@ const fillSettings = _.debounce(async (): Promise<void> => {
}, 1000);

Meteor.startup(() => {
return settings.watchByRegex(/(API\_Wordpress\_URL)?(Accounts\_OAuth\_Wordpress\_)?/, () => fillSettings());
settings.watchByRegex(/(API\_Wordpress\_URL)?(Accounts\_OAuth\_Wordpress\_)?/, () => fillSettings());
settings.watch('Accounts_OAuth_Use_Modern_Flow', () => fillSettings());
});
4 changes: 4 additions & 0 deletions apps/meteor/server/configuration/configurePassport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ export const configurePassport = (settings: ICachedSettings) => {
});

settings.watchByRegex(/^(Accounts_OAuth_)[a-z0-9_]+$/i, () => {
if (settings.get<boolean>('Accounts_OAuth_Use_Modern_Flow')) {
return;
}

const services = getOAuthServices(settings);
const oauthServiceConfigs = createOAuthServiceConfig(settings, services);
configureOAuthServices(oauthServiceConfigs, settings);
Expand Down
10 changes: 9 additions & 1 deletion apps/meteor/server/lib/oauth/addPassportCustomOAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,15 @@ export const addPassportCustomOAuth = (serviceName: string, config: Partial<OAut

oAuthRouter.get(
`/_oauth/${serviceName}`,
passport.authenticate(serviceName, { failureRedirect: '/login', failureFlash: true, failWithError: true, keepSessionInfo: true }),
(_req, _res, next) => {
const isPassportFlowEnabled = settings.get<boolean>('Accounts_OAuth_Use_Modern_Flow');
if (isPassportFlowEnabled) {
next();
} else {
next('router');
}
},
passport.authenticate(serviceName, { failureRedirect: '/login', failWithError: true, keepSessionInfo: true }),
passportOAuthCallback(siteUrl),
);
};
10 changes: 9 additions & 1 deletion apps/meteor/server/lib/oauth/configureOAuthServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,15 @@ export const configureOAuthServices = (oauthServiceConfig: OAuthServiceConfig[],
);
oAuthRouter.get(
`/_oauth/${config.provider}`,
Comment thread
yash-rajpal marked this conversation as resolved.
passport.authenticate(config.provider, { failureRedirect: '/login', failureFlash: true, failWithError: true, keepSessionInfo: true }),
(_req, _res, next) => {
const isPassportFlowEnabled = settings.get<boolean>('Accounts_OAuth_Use_Modern_Flow');
if (isPassportFlowEnabled) {
next();
} else {
next('router');
Comment thread
yash-rajpal marked this conversation as resolved.
}
},
passport.authenticate(config.provider, { failureRedirect: '/login', failWithError: true, keepSessionInfo: true }),
passportOAuthCallback(siteUrl),
);
});
Expand Down
4 changes: 4 additions & 0 deletions apps/meteor/server/lib/oauth/updateOAuthServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ 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) {
if (key === 'Accounts_OAuth_Use_Modern_Flow') {
continue;
}

logger.debug({ oauth_updated: key });
let serviceName = key.replace('Accounts_OAuth_', '');
if (serviceName === 'Meteor') {
Expand Down
7 changes: 7 additions & 0 deletions apps/meteor/server/settings/oauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ import { settingsRegistry } from '../../app/settings/server';

export const createOauthSettings = () =>
settingsRegistry.addGroup('OAuth', async function () {
await this.add('Accounts_OAuth_Use_Modern_Flow', true, {
Comment thread
yash-rajpal marked this conversation as resolved.
type: 'boolean',
public: true,
i18nLabel: 'Accounts_OAuth_Use_Modern_Flow_Label',
i18nDescription: 'Accounts_OAuth_Use_Modern_Flow_Description',
});

await this.section('Drupal', async function () {
const enableQuery = {
_id: 'Accounts_OAuth_Drupal',
Expand Down
4 changes: 4 additions & 0 deletions packages/i18n/src/locales/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,8 @@
"Accounts_OAuth_Wordpress_server_type_wordpress_com": "Wordpress.com",
"Accounts_OAuth_Wordpress_server_type_wp_oauth_server": "WP OAuth Server Plugin",
"Accounts_OAuth_Wordpress_token_path": "Token Path",
"Accounts_OAuth_Use_Modern_Flow_Label": "Use Modern OAuth Flow",
"Accounts_OAuth_Use_Modern_Flow_Description": "When enabled, OAuth authentication uses the modern Passport-based flow with system browser support on mobile and deep-link callbacks (recommended). When disabled, the original Meteor OAuth implementation is used for backward compatibility.",
"Accounts_PasswordReset": "Password Reset",
"Accounts_Password_Policy_AtLeastOneLowercase": "At Least One Lowercase",
"Accounts_Password_Policy_AtLeastOneLowercase_Description": "Enforce that a password contain at least one lowercase character.",
Expand Down Expand Up @@ -3156,6 +3158,7 @@
"Leave_the_current_channel": "Leave the current channel",
"Leave_the_description_field_blank_if_you_dont_want_to_show_the_role": "Leave the description field blank if you don't want to show the role",
"Left": "Left",
"Legacy_Meteor_OAuth": "Legacy Meteor OAuth",
"Let_moderators_know_what_the_issue_is": "Let moderators know what the issue is",
"Let_them_know": "Let them know",
"Lets_get_you_new_one_": "Let's get you a new one!",
Expand Down Expand Up @@ -3664,6 +3667,7 @@
"Moderation_User_deactivated": "User deactivated",
"Moderation_User_deleted_warning": "The user who sent the message(s) no longer exists or has been removed.",
"Moderators": "Moderators",
"Modern_OAuth_System_Browser_and_Deep_Links_Recommended": "Modern OAuth (System Browser & Deep Links) (Recommended)",
"Monday": "Monday",
"MongoDB": "MongoDB",
"MongoDB_Deprecated": "MongoDB Deprecated",
Expand Down
11 changes: 9 additions & 2 deletions packages/web-ui-registration/src/LoginServices.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ const LoginServices = ({
const { t } = useTranslation();
const services = useLoginServices();
const showFormLogin = useSetting('Accounts_ShowFormLogin');
const enableModernOAuthFlow = useSetting('Accounts_OAuth_Use_Modern_Flow', true);

const isDesktopApp = !!window.RocketChatDesktop?.openInBrowser;
const isDesktopApp = !!window.RocketChatDesktop?.openInBrowser && enableModernOAuthFlow;

const servicesToShow = useMemo(
() => (isDesktopApp ? services.filter(({ service }) => servicesToBeShownOnDesktop.includes(service)) : services),
Expand Down Expand Up @@ -52,7 +53,13 @@ const LoginServices = ({
{servicesToShow.length > 0 && (
<ButtonGroup vertical stretch small>
{servicesToShow.map((service) => (
<LoginServicesButton disabled={disabled} key={service.service} {...service} setError={setError} />
<LoginServicesButton
disabled={disabled}
key={service.service}
{...service}
setError={setError}
enableModernOAuthFlow={enableModernOAuthFlow}
/>
))}
</ButtonGroup>
)}
Expand Down
Loading
Loading