Skip to content

Commit

Permalink
chore: refactor cloud sync (#30401)
Browse files Browse the repository at this point in the history
  • Loading branch information
tassoevan authored and debdutdeb committed Oct 26, 2023
1 parent 06bf779 commit 36dd047
Show file tree
Hide file tree
Showing 42 changed files with 758 additions and 279 deletions.
24 changes: 12 additions & 12 deletions apps/meteor/app/cloud/server/functions/buildRegistrationData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { settings } from '../../../settings/server';
import { statistics } from '../../../statistics/server';
import { LICENSE_VERSION } from '../license';

type WorkspaceRegistrationData<T> = {
export type WorkspaceRegistrationData<T> = {
uniqueId: string;
workspaceId: SettingValue;
address: SettingValue;
Expand All @@ -14,11 +14,11 @@ type WorkspaceRegistrationData<T> = {
seats: number;
allowMarketing: SettingValue;
accountName: SettingValue;
organizationType: unknown;
industry: unknown;
orgSize: unknown;
country: unknown;
language: unknown;
organizationType: string;
industry: string;
orgSize: string;
country: string;
language: string;
agreePrivacyTerms: SettingValue;
website: SettingValue;
siteName: SettingValue;
Expand Down Expand Up @@ -61,15 +61,15 @@ export async function buildWorkspaceRegistrationData<T extends string | undefine
seats,
allowMarketing,
accountName,
organizationType,
industry,
orgSize,
country,
language,
organizationType: String(organizationType),
industry: String(industry),
orgSize: String(orgSize),
country: String(country),
language: String(language),
agreePrivacyTerms,
website,
siteName,
workspaceType,
workspaceType: String(workspaceType),
deploymentMethod: stats.deploy.method,
deploymentPlatform: stats.deploy.platform,
version: stats.version,
Expand Down
85 changes: 54 additions & 31 deletions apps/meteor/app/cloud/server/functions/connectWorkspace.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,73 @@
import { serverFetch as fetch } from '@rocket.chat/server-fetch';

import { CloudWorkspaceConnectionError } from '../../../../lib/errors/CloudWorkspaceConnectionError';
import { SystemLogger } from '../../../../server/lib/logger/system';
import { settings } from '../../../settings/server';
import { getRedirectUri } from './getRedirectUri';
import { saveRegistrationData } from './saveRegistrationData';

const fetchRegistrationDataPayload = async ({
token,
body,
}: {
token: string;
body: {
email: string;
client_name: string;
redirect_uris: string[];
};
}) => {
const cloudUrl = settings.get<string>('Cloud_Url');
const response = await fetch(`${cloudUrl}/api/oauth/clients`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
},
body,
});

if (!response.ok) {
try {
const { error } = await response.json();
throw new CloudWorkspaceConnectionError(`Failed to connect to Rocket.Chat Cloud: ${error}`);
} catch (error) {
throw new CloudWorkspaceConnectionError(`Failed to connect to Rocket.Chat Cloud: ${response.statusText}`);
}
}

const payload = await response.json();

if (!payload) {
return undefined;
}

return payload;
};

export async function connectWorkspace(token: string) {
// shouldn't get here due to checking this on the method
// but this is just to double check
if (!token) {
return new Error('Invalid token; the registration token is required.');
throw new CloudWorkspaceConnectionError('Invalid registration token');
}

const redirectUri = getRedirectUri();
try {
const redirectUri = getRedirectUri();

const regInfo = {
email: settings.get('Organization_Email'),
client_name: settings.get('Site_Name'),
redirect_uris: [redirectUri],
};
const body = {
email: settings.get<string>('Organization_Email'),
client_name: settings.get<string>('Site_Name'),
redirect_uris: [redirectUri],
};

const cloudUrl = settings.get('Cloud_Url');
let result;
try {
const request = await fetch(`${cloudUrl}/api/oauth/clients`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
},
body: regInfo,
});
const payload = await fetchRegistrationDataPayload({ token, body });

if (!request.ok) {
throw new Error((await request.json()).error);
if (!payload) {
return false;
}

result = await request.json();
} catch (err: any) {
await saveRegistrationData(payload);

return true;
} catch (err) {
SystemLogger.error({
msg: 'Failed to Connect with Rocket.Chat Cloud',
url: '/api/oauth/clients',
Expand All @@ -45,12 +76,4 @@ export async function connectWorkspace(token: string) {

return false;
}

if (!result) {
return false;
}

await saveRegistrationData(result);

return true;
}
22 changes: 11 additions & 11 deletions apps/meteor/app/cloud/server/functions/finishOAuthAuthorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ export async function finishOAuthAuthorization(code: string, state: string) {
});
}

const cloudUrl = settings.get<string>('Cloud_Url');
const clientId = settings.get<string>('Cloud_Workspace_Client_Id');
const clientSecret = settings.get<string>('Cloud_Workspace_Client_Secret');

const scope = userScopes.join(' ');

let result;
let payload;
try {
const request = await fetch(`${cloudUrl}/api/oauth/token`, {
const cloudUrl = settings.get<string>('Cloud_Url');
const response = await fetch(`${cloudUrl}/api/oauth/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
params: new URLSearchParams({
Expand All @@ -35,11 +35,11 @@ export async function finishOAuthAuthorization(code: string, state: string) {
}),
});

if (!request.ok) {
throw new Error((await request.json()).error);
if (!response.ok) {
throw new Error((await response.json()).error);
}

result = await request.json();
payload = await response.json();
} catch (err) {
SystemLogger.error({
msg: 'Failed to finish OAuth authorization with Rocket.Chat Cloud',
Expand All @@ -51,7 +51,7 @@ export async function finishOAuthAuthorization(code: string, state: string) {
}

const expiresAt = new Date();
expiresAt.setSeconds(expiresAt.getSeconds() + result.expires_in);
expiresAt.setSeconds(expiresAt.getSeconds() + payload.expires_in);

const uid = Meteor.userId();
if (!uid) {
Expand All @@ -65,11 +65,11 @@ export async function finishOAuthAuthorization(code: string, state: string) {
{
$set: {
'services.cloud': {
accessToken: result.access_token,
accessToken: payload.access_token,
expiresAt,
scope: result.scope,
tokenType: result.token_type,
refreshToken: result.refresh_token,
scope: payload.scope,
tokenType: payload.token_type,
refreshToken: payload.refresh_token,
},
},
},
Expand Down
18 changes: 9 additions & 9 deletions apps/meteor/app/cloud/server/functions/getConfirmationPoll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ import { SystemLogger } from '../../../../server/lib/logger/system';
import { settings } from '../../../settings/server';

export async function getConfirmationPoll(deviceCode: string): Promise<CloudConfirmationPollData> {
const cloudUrl = settings.get('Cloud_Url');

let result;
let payload;
try {
const request = await fetch(`${cloudUrl}/api/v2/register/workspace/poll`, { params: { token: deviceCode } });
if (!request.ok) {
throw new Error((await request.json()).error);
const cloudUrl = settings.get<string>('Cloud_Url');
const response = await fetch(`${cloudUrl}/api/v2/register/workspace/poll`, { params: { token: deviceCode } });

if (!response.ok) {
throw new Error((await response.json()).error);
}

result = await request.json();
payload = await response.json();
} catch (err: any) {
SystemLogger.error({
msg: 'Failed to get confirmation poll from Rocket.Chat Cloud',
Expand All @@ -25,9 +25,9 @@ export async function getConfirmationPoll(deviceCode: string): Promise<CloudConf
throw err;
}

if (!result) {
if (!payload) {
throw new Error('Failed to retrieve registration confirmation poll data');
}

return result;
return payload;
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,11 @@ export async function getWorkspaceAccessTokenWithScope(scope = '') {
scope = workspaceScopes.join(' ');
}

const cloudUrl = settings.get<string>('Cloud_Url');
// eslint-disable-next-line @typescript-eslint/naming-convention
const client_secret = settings.get<string>('Cloud_Workspace_Client_Secret');
const redirectUri = getRedirectUri();

let authTokenResult;
let payload;
try {
const body = new URLSearchParams();
body.append('client_id', client_id);
Expand All @@ -40,12 +39,13 @@ export async function getWorkspaceAccessTokenWithScope(scope = '') {
body.append('grant_type', 'client_credentials');
body.append('redirect_uri', redirectUri);

const result = await fetch(`${cloudUrl}/api/oauth/token`, {
const cloudUrl = settings.get<string>('Cloud_Url');
const response = await fetch(`${cloudUrl}/api/oauth/token`, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
method: 'POST',
body,
});
authTokenResult = await result.json();
payload = await response.json();
} catch (err: any) {
SystemLogger.error({
msg: 'Failed to get Workspace AccessToken from Rocket.Chat Cloud',
Expand All @@ -64,10 +64,10 @@ export async function getWorkspaceAccessTokenWithScope(scope = '') {
}

const expiresAt = new Date();
expiresAt.setSeconds(expiresAt.getSeconds() + authTokenResult.expires_in);
expiresAt.setSeconds(expiresAt.getSeconds() + payload.expires_in);

tokenResponse.expiresAt = expiresAt;
tokenResponse.token = authTokenResult.access_token;
tokenResponse.token = payload.access_token;

return tokenResponse;
}
Loading

0 comments on commit 36dd047

Please sign in to comment.