Skip to content

Commit

Permalink
fix: store the scopes when fetching new tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustrb committed Oct 21, 2024
1 parent ce283bf commit 19f8ba8
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 57 deletions.
3 changes: 2 additions & 1 deletion apps/meteor/app/api/server/v1/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,8 @@ API.v1.addRoute(
const settingsIds: string[] = [];

if (this.bodyParams.setDeploymentAs === 'new-workspace') {
await WorkspaceCredentials.unsetCredentialByScope();
await WorkspaceCredentials.removeAllCredentials();

settingsIds.push(
'Cloud_Service_Agree_PrivacyTerms',
'Cloud_Workspace_Id',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,18 @@ export async function getWorkspaceAccessToken(forceNew = false, scope = '', save
return '';
}

const workspaceCredentials = await WorkspaceCredentials.getCredentialByScope(scope);
if (!workspaceCredentials) {
throw new CloudWorkspaceAccessTokenError();
}
const scopes = scope === '' ? [] : [scope];

if (!hasWorkspaceAccessTokenExpired(workspaceCredentials) && !forceNew) {
const workspaceCredentials = await WorkspaceCredentials.getCredentialByScopes(scopes);
if (workspaceCredentials && !hasWorkspaceAccessTokenExpired(workspaceCredentials) && !forceNew) {
return workspaceCredentials.accessToken;
}

const accessToken = await getWorkspaceAccessTokenWithScope(scope, throwOnError);

if (save) {
await WorkspaceCredentials.updateCredentialByScope({
scope,
await WorkspaceCredentials.updateCredentialByScopes({
scopes: accessToken.scopes,
accessToken: accessToken.token,
expirationDate: accessToken.expiresAt,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ import { CloudWorkspaceAccessTokenError } from './getWorkspaceAccessToken';
import { removeWorkspaceRegistrationInfo } from './removeWorkspaceRegistrationInfo';
import { retrieveRegistrationStatus } from './retrieveRegistrationStatus';

export async function getWorkspaceAccessTokenWithScope(scope = '', throwOnError = false) {
type WorkspaceAccessTokenWithScope = {
token: string;
expiresAt: Date;
scopes: string[];
};

export async function getWorkspaceAccessTokenWithScope(scope = '', throwOnError = false): Promise<WorkspaceAccessTokenWithScope> {
const { workspaceRegistered } = await retrieveRegistrationStatus();

const tokenResponse = { token: '', expiresAt: new Date() };
const tokenResponse = { token: '', expiresAt: new Date(), scopes: [] };

if (!workspaceRegistered) {
return tokenResponse;
Expand All @@ -23,9 +29,7 @@ export async function getWorkspaceAccessTokenWithScope(scope = '', throwOnError
return tokenResponse;
}

if (scope === '') {
scope = workspaceScopes.join(' ');
}
const scopes = scope === '' ? workspaceScopes.join(' ') : scope;

// eslint-disable-next-line @typescript-eslint/naming-convention
const client_secret = settings.get<string>('Cloud_Workspace_Client_Secret');
Expand All @@ -36,7 +40,7 @@ export async function getWorkspaceAccessTokenWithScope(scope = '', throwOnError
const body = new URLSearchParams();
body.append('client_id', client_id);
body.append('client_secret', client_secret);
body.append('scope', scope);
body.append('scope', scopes);
body.append('grant_type', 'client_credentials');
body.append('redirect_uri', redirectUri);

Expand All @@ -62,6 +66,7 @@ export async function getWorkspaceAccessTokenWithScope(scope = '', throwOnError
return {
token: payload.access_token,
expiresAt,
scopes: scope === '' ? [...workspaceScopes] : [scope],
};
} catch (err: any) {
if (err instanceof CloudWorkspaceAccessTokenError) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { applyLicense } from '@rocket.chat/license';
import { Settings, WorkspaceCredentials } from '@rocket.chat/models';
import { Settings } from '@rocket.chat/models';

import { notifyOnSettingChangedById } from '../../../lib/server/lib/notifyListener';
import { settings } from '../../../settings/server';
Expand Down Expand Up @@ -59,12 +59,6 @@ async function saveRegistrationDataBase({
{ _id: 'Cloud_Workspace_Registration_Client_Uri', value: registration_client_uri },
];

await WorkspaceCredentials.updateCredentialByScope({
scope: '',
accessToken: '',
expirationDate: new Date(0),
});

const promises = [...settingsData.map(({ _id, value }) => Settings.updateValueById(_id, value))];

(await Promise.all(promises)).forEach((value, index) => {
Expand Down
27 changes: 7 additions & 20 deletions apps/meteor/server/models/raw/WorkspaceCredentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,49 +13,36 @@ export class WorkspaceCredentialsRaw extends BaseRaw<IWorkspaceCredentials> impl
return [{ key: { scopes: 1, expirationDate: 1, accessToken: 1 }, unique: true }];
}

getCredentialByScope(scope = ''): Promise<IWorkspaceCredentials | null> {
getCredentialByScopes(scopes: string[] = []): Promise<IWorkspaceCredentials | null> {
const query: Filter<IWorkspaceCredentials> = {
scopes: {
$all: [scope],
$size: 1,
$eq: scopes,
},
};

return this.findOne(query);
}

unsetCredentialByScope(scope = ''): Promise<DeleteResult> {
const query: Filter<IWorkspaceCredentials> = {
scopes: {
$all: [scope],
$size: 1,
},
};

return this.deleteOne(query);
}

updateCredentialByScope({
scope,
updateCredentialByScopes({
scopes,
accessToken,
expirationDate,
}: {
scope: string;
scopes: string[];
accessToken: string;
expirationDate: Date;
}): Promise<UpdateResult> {
const record = {
$set: {
scopes: [scope],
scopes,
accessToken,
expirationDate,
},
};

const query: Filter<IWorkspaceCredentials> = {
scopes: {
$all: [scope],
$size: 1,
$eq: scopes,
},
};

Expand Down
15 changes: 2 additions & 13 deletions apps/meteor/server/startup/migrations/v316.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
import { Settings, WorkspaceCredentials } from '@rocket.chat/models';
import { Settings } from '@rocket.chat/models';

import { addMigration } from '../../lib/migrations';

addMigration({
version: 316,
name: 'Remove Cloud_Workspace_Access_Token and Cloud_Workspace_Access_Token_Expires_At from the settings collection and add to the WorkspaceCredentials collection',
name: 'Remove Cloud_Workspace_Access_Token and Cloud_Workspace_Access_Token_Expires_At from the settings collection',
async up() {
const workspaceCredentials = await WorkspaceCredentials.getCredentialByScope();
if (workspaceCredentials) {
return;
}

const accessToken = ((await Settings.getValueById('Cloud_Workspace_Access_Token')) as string) || '';
const expirationDate = ((await Settings.getValueById('Cloud_Workspace_Access_Token_Expires_At')) as Date) || new Date(0);

Expand All @@ -21,11 +16,5 @@ addMigration({
if (expirationDate) {
await Settings.removeById('Cloud_Workspace_Access_Token_Expires_At');
}

await WorkspaceCredentials.updateCredentialByScope({
scope: '',
accessToken,
expirationDate,
});
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import type { DeleteResult, UpdateResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';

export interface IWorkspaceCredentialsModel extends IBaseModel<IWorkspaceCredentials> {
getCredentialByScope(scope?: string): Promise<IWorkspaceCredentials | null>;
unsetCredentialByScope(scope?: string): Promise<DeleteResult>;
updateCredentialByScope(credentials: { scope: string; accessToken: string; expirationDate: Date }): Promise<UpdateResult>;
getCredentialByScopes(scopes?: string[]): Promise<IWorkspaceCredentials | null>;
updateCredentialByScopes(credentials: { scopes: string[]; accessToken: string; expirationDate: Date }): Promise<UpdateResult>;
removeAllCredentials(): Promise<DeleteResult>;
}

0 comments on commit 19f8ba8

Please sign in to comment.