Skip to content

Commit

Permalink
refactor syncWorkspace
Browse files Browse the repository at this point in the history
  • Loading branch information
ggazzo committed Sep 13, 2023
1 parent f19b6b6 commit fb1bbf7
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 147 deletions.
27 changes: 27 additions & 0 deletions apps/meteor/app/cloud/server/functions/getWorkspaceAccessToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,33 @@ export async function getWorkspaceAccessToken(forceNew = false, scope = '', save
return accessToken.token;
}

export class CloudWorkspaceAccessTokenError extends Error {
constructor() {
super('Could not get workspace access token');
}
}

export async function getWorkspaceAccessTokenOrThrow(forceNew = false, scope = '', save = true): Promise<string> {
const token = await getWorkspaceAccessToken(forceNew, scope, save);

if (!token) {
throw new CloudWorkspaceAccessTokenError();
}

return token;
}

export const generateWorkspaceBearerHttpHeaderOrThrow = async (
forceNew = false,
scope = '',
save = true,
): Promise<{ Authorization: string }> => {
const token = await getWorkspaceAccessTokenOrThrow(forceNew, scope, save);
return {
Authorization: `Bearer ${token}`,
};
};

export const generateWorkspaceBearerHttpHeader = async (
forceNew = false,
scope = '',
Expand Down
60 changes: 24 additions & 36 deletions apps/meteor/app/cloud/server/functions/getWorkspaceLicense.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,52 @@ import { callbacks } from '../../../../lib/callbacks';
import { SystemLogger } from '../../../../server/lib/logger/system';
import { settings } from '../../../settings/server';
import { LICENSE_VERSION } from '../license';
import { getWorkspaceAccessToken } from './getWorkspaceAccessToken';
import { generateWorkspaceBearerHttpHeaderOrThrow } from './getWorkspaceAccessToken';
import { handleResponse } from './supportedVersionsToken/supportedVersionsToken';

export async function getWorkspaceLicense(): Promise<{ updated: boolean; license: string }> {
const currentLicense = await Settings.findOne('Cloud_Workspace_License');

const cachedLicenseReturn = async () => {
const license = currentLicense?.value as string;
if (license) {
await callbacks.run('workspaceLicenseChanged', license);
}
export async function getWorkspaceLicense() {
const token = await generateWorkspaceBearerHttpHeaderOrThrow();

return { updated: false, license };
};
const currentLicense = await Settings.findOne('Cloud_Workspace_License');

const token = await getWorkspaceAccessToken();
if (!token) {
return cachedLicenseReturn();
// TODO: check if this is the correct way to handle this
// If there is no license, in theory, it should be a new workspace non registered
// in this case the `generateWorkspaceBearerHttpHeaderOrThrow` show throw an error before
// so in theory, this should never happen
if (!currentLicense?._updatedAt) {
throw new Error('Failed to retrieve current license');
}

let licenseResult;
try {
const request = await fetch(`${settings.get('Cloud_Workspace_Registration_Client_Uri')}/license`, {
const request = await handleResponse(
fetch(`${settings.get('Cloud_Workspace_Registration_Client_Uri')}/license`, {
headers: {
Authorization: `Bearer ${token}`,
...token,
},
params: {
version: LICENSE_VERSION,
},
});

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

licenseResult = await request.json();
} catch (err: any) {
if (!request.success) {
SystemLogger.error({
msg: 'Failed to update license from Rocket.Chat Cloud',
url: '/license',
err,
err: request.error,
});

return cachedLicenseReturn();
if (currentLicense.value) {
return callbacks.run('workspaceLicenseChanged', currentLicense.value);
}
return;
}

const remoteLicense = licenseResult;

if (!currentLicense || !currentLicense._updatedAt) {
throw new Error('Failed to retrieve current license');
}
const remoteLicense = request.result as any;

if (remoteLicense.updatedAt <= currentLicense._updatedAt) {
return cachedLicenseReturn();
return callbacks.run('workspaceLicenseChanged', currentLicense.value);
}

await Settings.updateValueById('Cloud_Workspace_License', remoteLicense.license);

await callbacks.run('workspaceLicenseChanged', remoteLicense.license);

return { updated: true, license: remoteLicense.license };
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ export const handleResponse = async <T>(promise: Promise<Response>) => {
(async () => {
const request = await promise;
if (!request.ok) {
throw new Error((await request.json()).error);
if (request.size > 0) {
throw new Error((await request.json()).error);
}
throw new Error(request.statusText);
}

return request.json();
Expand Down
110 changes: 0 additions & 110 deletions apps/meteor/app/cloud/server/functions/syncWorkspace.ts

This file was deleted.

17 changes: 17 additions & 0 deletions apps/meteor/app/cloud/server/functions/syncWorkspace/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { CloudWorkspaceAccessTokenError } from '../getWorkspaceAccessToken';
import { getWorkspaceLicense } from '../getWorkspaceLicense';
import { getCachedSupportedVersionsToken } from '../supportedVersionsToken/supportedVersionsToken';
import { syncCloudData } from './syncCloudData';

export async function syncWorkspace() {
try {
await syncCloudData();
await getWorkspaceLicense();
} catch (error) {
if (error instanceof CloudWorkspaceAccessTokenError) {
// TODO: Remove License if there is no access token
}
}

await getCachedSupportedVersionsToken.reset();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { NPS, Banner } from '@rocket.chat/core-services';
import { Settings } from '@rocket.chat/models';
import { serverFetch as fetch } from '@rocket.chat/server-fetch';

import { SystemLogger } from '../../../../../server/lib/logger/system';
import { getAndCreateNpsSurvey } from '../../../../../server/services/nps/getAndCreateNpsSurvey';
import { settings } from '../../../../settings/server';
import { buildWorkspaceRegistrationData } from '../buildRegistrationData';
import { generateWorkspaceBearerHttpHeaderOrThrow } from '../getWorkspaceAccessToken';
import { handleResponse } from '../supportedVersionsToken/supportedVersionsToken';

export async function syncCloudData() {
const info = await buildWorkspaceRegistrationData(undefined);

const token = await generateWorkspaceBearerHttpHeaderOrThrow(true);

const request = await handleResponse(
fetch(`${settings.get('Cloud_Workspace_Registration_Client_Uri')}/client`, {
headers: {
...token,
},
body: info,
method: 'POST',
}),
);

if (!request.success) {
return SystemLogger.error({
msg: 'Failed to sync with Rocket.Chat Cloud',
url: '/client',
err: request.error,
});
}

const data = request.result as any;
if (!data) {
return true;
}

if (data.publicKey) {
await Settings.updateValueById('Cloud_Workspace_PublicKey', data.publicKey);
}

if (data.trial?.trialId) {
await Settings.updateValueById('Cloud_Workspace_Had_Trial', true);
}

if (data.nps) {
const { id: npsId, expireAt } = data.nps;

const startAt = new Date(data.nps.startAt);

await NPS.create({
npsId,
startAt,
expireAt: new Date(expireAt),
createdBy: {
_id: 'rocket.cat',
username: 'rocket.cat',
},
});

const now = new Date();

if (startAt.getFullYear() === now.getFullYear() && startAt.getMonth() === now.getMonth() && startAt.getDate() === now.getDate()) {
await getAndCreateNpsSurvey(npsId);
}
}

// add banners
if (data.banners) {
for await (const banner of data.banners) {
const { createdAt, expireAt, startAt } = banner;

await Banner.create({
...banner,
createdAt: new Date(createdAt),
expireAt: new Date(expireAt),
startAt: new Date(startAt),
});
}
}

return true;
}

0 comments on commit fb1bbf7

Please sign in to comment.