Skip to content

Commit

Permalink
Create APIs and add info to reports
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigok committed Sep 16, 2023
1 parent 64a9847 commit 263a5f4
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 44 deletions.
76 changes: 75 additions & 1 deletion apps/meteor/app/api/server/v1/misc.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import crypto from 'crypto';

import type { IUser } from '@rocket.chat/core-typings';
import { Users } from '@rocket.chat/models';
import { Settings, Users } from '@rocket.chat/models';
import {
isShieldSvgProps,
isSpotlightProps,
isDirectoryProps,
isMethodCallProps,
isMethodCallAnonProps,
isFingerprintProps,
isMeteorCall,
validateParamsPwGetPolicyRest,
} from '@rocket.chat/rest-typings';
Expand All @@ -16,6 +17,7 @@ import EJSON from 'ejson';
import { check } from 'meteor/check';
import { DDPRateLimiter } from 'meteor/ddp-rate-limiter';
import { Meteor } from 'meteor/meteor';
import { v4 as uuidv4 } from 'uuid';

import { i18n } from '../../../../server/lib/i18n';
import { SystemLogger } from '../../../../server/lib/logger/system';
Expand Down Expand Up @@ -643,3 +645,75 @@ API.v1.addRoute(
},
},
);

/**
* @openapi
* /api/v1/fingerprint:
* post:
* description: Update Fingerprint definition as a new workspace or update of configuration
* security:
* $ref: '#/security/authenticated'
* requestBody:
* content:
* application/json:
* schema:
* type: object
* properties:
* setDeploymentAs:
* type: string
* example: |
* {
* "setDeploymentAs": "new-workspace"
* }
* responses:
* 200:
* description: Workspace successfully configured
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ApiSuccessV1'
* default:
* description: Unexpected error
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ApiFailureV1'
*/
API.v1.addRoute(
'fingerprint',
{
authRequired: true,
validateParams: isFingerprintProps,
},
{
async post() {
check(this.bodyParams, {
setDeploymentAs: String,
});

if (this.bodyParams.setDeploymentAs === 'new-workspace') {
await Promise.all([
Settings.resetValueById('uniqueID', process.env.DEPLOYMENT_ID || uuidv4()),
// Settings.resetValueById('Cloud_Url'),
Settings.resetValueById('Cloud_Service_Agree_PrivacyTerms'),
Settings.resetValueById('Cloud_Workspace_Id'),
Settings.resetValueById('Cloud_Workspace_Name'),
Settings.resetValueById('Cloud_Workspace_Client_Id'),
Settings.resetValueById('Cloud_Workspace_Client_Secret'),
Settings.resetValueById('Cloud_Workspace_Client_Secret_Expires_At'),
Settings.resetValueById('Cloud_Workspace_Registration_Client_Uri'),
Settings.resetValueById('Cloud_Workspace_PublicKey'),
Settings.resetValueById('Cloud_Workspace_License'),
Settings.resetValueById('Cloud_Workspace_Had_Trial'),
Settings.resetValueById('Cloud_Workspace_Access_Token'),
Settings.resetValueById('Cloud_Workspace_Access_Token_Expires_At', new Date(0)),
Settings.resetValueById('Cloud_Workspace_Registration_State'),
]);
}

await Settings.updateValueById('Deployment_FingerPrint_Verified', true);

return API.v1.success({});
},
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export async function buildWorkspaceRegistrationData<T extends string | undefine
const npsEnabled = settings.get('NPS_survey_enabled');
const agreePrivacyTerms = settings.get('Cloud_Service_Agree_PrivacyTerms');
const setupWizardState = settings.get('Show_Setup_Wizard');
const deploymentFingerprintHash = settings.get('Deployment_FingerPrint_Hash');
const deploymentFingerprintVerified = settings.get('Deployment_FingerPrint_Verified');

const firstUser = await Users.getOldest({ projection: { name: 1, emails: 1 } });
const contactName = firstUser?.name || '';
Expand All @@ -54,6 +56,8 @@ export async function buildWorkspaceRegistrationData<T extends string | undefine

return {
uniqueId: stats.uniqueId,
deploymentFingerprintHash
deploymentFingerprintVerified
workspaceId,
address,
contactName,
Expand Down
3 changes: 3 additions & 0 deletions apps/meteor/app/statistics/server/lib/statistics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ export const statistics = {
statistics.installedAt = uniqueID.createdAt.toISOString();
}

statistics.deploymentFingerprintHash = settings.get('Deployment_FingerPrint_Hash');
statistics.deploymentFingerprintVerified = settings.get('Deployment_FingerPrint_Verified');

if (Info) {
statistics.version = Info.version;
statistics.tag = Info.tag;
Expand Down
11 changes: 6 additions & 5 deletions apps/meteor/client/startup/rootUrlChange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,16 @@ Meteor.startup(() => {

const updateWorkspace = (): void => {
imperativeModal.close();
console.log('updateWorkspace');
void sdk.rest.post('/v1/fingerprint', { setDeploymentAs: 'updated-configuration' }).then(() => {
dispatchToastMessage({ type: 'success', message: t('Saved') });
});
};

const setNewWorkspace = (): void => {
imperativeModal.close();
console.log('setNewWorkspace');
// void sdk.call('saveSetting', 'Site_Url', currentUrl).then(() => {
// dispatchToastMessage({ type: 'success', message: t('Saved') });
// });
void sdk.rest.post('/v1/fingerprint', { setDeploymentAs: 'new-workspace' }).then(() => {
dispatchToastMessage({ type: 'success', message: t('Saved') });
});
};

const openModal = (): void => {
Expand Down
19 changes: 19 additions & 0 deletions apps/meteor/server/models/raw/Settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,25 @@ export class SettingsRaw extends BaseRaw<ISetting> implements ISettingsModel {
return this.updateOne(query, update);
}

async resetValueById(
_id: string,
value?: (ISetting['value'] extends undefined ? never : ISetting['value']) | null,
): Promise<Document | UpdateResult | undefined> {
if (value == null) {
const record = await this.findOneById(_id);
if (record) {
const prop = record.valueSource || 'packageValue';
value = record[prop];
}
}

if (value == null) {
return;
}

return this.updateValueById(_id, value);
}

async incrementValueById(_id: ISetting['_id'], value = 1): Promise<Document | UpdateResult> {
return this.updateOne(
{
Expand Down
43 changes: 6 additions & 37 deletions apps/meteor/server/settings/misc.ts
Original file line number Diff line number Diff line change
@@ -1,62 +1,34 @@
import crypto from 'crypto';

// import { MongoInternals } from 'meteor/mongo';
import { Logger } from '@rocket.chat/logger';
import { Settings } from '@rocket.chat/models';
import { v4 as uuidv4 } from 'uuid';

import { settingsRegistry, settings } from '../../app/settings/server';

interface Fingerprint {
site_url: string;
db_connection_string: string;
}

// TODO:
// Apis to set as new deploy or update
// On update list variables to re generate / cleanup
// Modal to request action
// Process on site_url change

const logger = new Logger('FingerPrint');

const generateFingerprint = function () {
const siteUrl = settings.get('Site_Url');
const dbConnectionString = process.env.MONGO_URL;

const fingerprint = `${siteUrl}${dbConnectionString}`;
console.log(fingerprint);
return crypto.createHash('sha256').update(fingerprint).digest('base64');
};

const updateFingerprint = async function (fingerprint: string, verified: boolean) {
await Settings.updateOne(
{ _id: 'Deployment_FingerPrint_Hash' },
{
$set: {
value: fingerprint,
},
},
);

await Settings.updateOne(
{ _id: 'Deployment_FingerPrint_Verified' },
{
$set: {
value: verified,
},
},
);
await Settings.updateValueById('Deployment_FingerPrint_Hash', fingerprint);

await Settings.updateValueById('Deployment_FingerPrint_Verified', verified);
};

const verifyFingerPrint = async function () {
const DeploymentFingerPrintRecordHash = await Settings.getValueById('Deployment_FingerPrint_Hash');

const fingerprint = generateFingerprint();

console.log(DeploymentFingerPrintRecordHash);
if (!DeploymentFingerPrintRecordHash) {
logger.info('Generating fingerprint for the first time');
logger.info('Generating fingerprint for the first time', fingerprint);
await updateFingerprint(fingerprint, true);
return;
}
Expand Down Expand Up @@ -86,16 +58,13 @@ export const createMiscSettings = async () => {

await settingsRegistry.add('Deployment_FingerPrint_Hash', '', {
public: false,
blocked: true,
// hidden: true,
// secret: true,
readonly: true,
});

await settingsRegistry.add('Deployment_FingerPrint_Verified', false, {
type: 'boolean',
public: true,
blocked: true,
// hidden: true,
readonly: true,
});

await verifyFingerPrint();
Expand Down
2 changes: 1 addition & 1 deletion packages/core-typings/src/ISetting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export interface ISettingBase {
hidden?: boolean;
modules?: Array<string>;
invalidValue?: SettingValue;
valueSource?: string;
valueSource?: 'packageValue' | 'processEnvValue';
secret?: boolean;
i18nDescription?: string;
autocomplete?: boolean;
Expand Down
2 changes: 2 additions & 0 deletions packages/core-typings/src/IStats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export interface IStats {
_id: string;
wizard: Record<string, unknown>;
uniqueId: string;
deploymentFingerprintHash: string;
deploymentFingerprintVerified: boolean;
installedAt?: string;
version?: string;
tag?: string;
Expand Down
5 changes: 5 additions & 0 deletions packages/model-typings/src/models/ISettingsModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ export interface ISettingsModel extends IBaseModel<ISetting> {
value: (ISetting['value'] extends undefined ? never : ISetting['value']) | null,
): Promise<Document | UpdateResult>;

resetValueById(
_id: string,
value?: (ISetting['value'] extends undefined ? never : ISetting['value']) | null,
): Promise<Document | UpdateResult | undefined>;

incrementValueById(_id: ISetting['_id'], value?: number): Promise<Document | UpdateResult>;

updateOptionsById<T extends ISetting = ISetting>(
Expand Down
22 changes: 22 additions & 0 deletions packages/rest-typings/src/v1/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,22 @@ const MethodCallAnonSchema = {

export const isMethodCallAnonProps = ajv.compile<MethodCallAnon>(MethodCallAnonSchema);

type Fingerprint = { setDeploymentAs: 'new-workspace' | 'updated-configuration' };

const FingerprintSchema = {
type: 'object',
properties: {
setDeploymentAs: {
type: 'string',
enum: ['new-workspace', 'updated-configuration'],
},
},
required: ['setDeploymentAs'],
additionalProperties: false,
};

export const isFingerprintProps = ajv.compile<Fingerprint>(FingerprintSchema);

type PwGetPolicyReset = { token: string };

const PwGetPolicyResetSchema = {
Expand Down Expand Up @@ -229,6 +245,12 @@ export type MiscEndpoints = {
};
};

'/v1/fingerprint': {
POST: (params: Fingerprint) => {
success: boolean;
};
};

'/v1/smtp.check': {
GET: () => {
isSMTPConfigured: boolean;
Expand Down

0 comments on commit 263a5f4

Please sign in to comment.