Skip to content

Commit

Permalink
refactor: LoginServiceConfiguration entity out of DB Watcher (#32373)
Browse files Browse the repository at this point in the history
Co-authored-by: Diego Sampaio <8591547+sampaiodiego@users.noreply.github.com>
  • Loading branch information
ricardogarim and sampaiodiego committed May 15, 2024
1 parent 4b8c215 commit 3ed5bda
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 21 deletions.
62 changes: 54 additions & 8 deletions apps/meteor/app/lib/server/lib/notifyListener.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import { api, dbWatchersDisabled } from '@rocket.chat/core-services';
import type { IPermission, IRocketChatRecord, IRoom, ISetting, IPbxEvent, IRole, IIntegration } from '@rocket.chat/core-typings';
import { Rooms, Permissions, Settings, PbxEvents, Roles, Integrations } from '@rocket.chat/models';
import type {
IRocketChatRecord,
IRoom,
ILoginServiceConfiguration,
ISetting,
IRole,
IPermission,
IIntegration,
IPbxEvent,
LoginServiceConfiguration as LoginServiceConfigurationData,
} from '@rocket.chat/core-typings';
import { Rooms, Permissions, Settings, PbxEvents, Roles, Integrations, LoginServiceConfiguration } from '@rocket.chat/models';

type ClientAction = 'inserted' | 'updated' | 'removed';

Expand Down Expand Up @@ -28,6 +38,7 @@ export async function notifyOnRoomChangedById<T extends IRocketChatRecord>(
}

const eligibleIds = Array.isArray(ids) ? ids : [ids];

const items = Rooms.findByIds(eligibleIds);

for await (const item of items) {
Expand Down Expand Up @@ -112,10 +123,11 @@ export async function notifyOnPbxEventChangedById<T extends IPbxEvent>(
}

const item = await PbxEvents.findOneById(id);

if (item) {
void api.broadcast('watch.pbxevents', { clientAction, id, data: item });
if (!item) {
return;
}

void api.broadcast('watch.pbxevents', { clientAction, id, data: item });
}

export async function notifyOnRoleChanged<T extends IRole>(role: T, clientAction: 'removed' | 'changed' = 'changed'): Promise<void> {
Expand All @@ -142,6 +154,39 @@ export async function notifyOnRoleChangedById<T extends IRole>(
void notifyOnRoleChanged(role, clientAction);
}

export async function notifyOnLoginServiceConfigurationChanged<T extends ILoginServiceConfiguration>(
service: Partial<T> & Pick<T, '_id'>,
clientAction: ClientAction = 'updated',
): Promise<void> {
if (!dbWatchersDisabled) {
return;
}

void api.broadcast('watch.loginServiceConfiguration', {
clientAction,
id: service._id,
data: service,
});
}

export async function notifyOnLoginServiceConfigurationChangedByService<T extends ILoginServiceConfiguration>(
service: T['service'],
clientAction: ClientAction = 'updated',
): Promise<void> {
if (!dbWatchersDisabled) {
return;
}

const item = await LoginServiceConfiguration.findOneByService<Omit<LoginServiceConfigurationData, 'secret'>>(service, {
projection: { secret: 0 },
});
if (!item) {
return;
}

void notifyOnLoginServiceConfigurationChanged(item, clientAction);
}

export async function notifyOnIntegrationChanged<T extends IIntegration>(data: T, clientAction: ClientAction = 'updated'): Promise<void> {
if (!dbWatchersDisabled) {
return;
Expand All @@ -159,10 +204,11 @@ export async function notifyOnIntegrationChangedById<T extends IIntegration>(
}

const item = await Integrations.findOneById(id);

if (item) {
void api.broadcast('watch.integrations', { clientAction, id: item._id, data: item });
if (!item) {
return;
}

void api.broadcast('watch.integrations', { clientAction, id: item._id, data: item });
}

export async function notifyOnIntegrationChangedByUserId<T extends IIntegration>(
Expand Down
19 changes: 18 additions & 1 deletion apps/meteor/app/meteor-accounts-saml/server/lib/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { LoginServiceConfiguration } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';

import { SystemLogger } from '../../../../server/lib/logger/system';
import {
notifyOnLoginServiceConfigurationChanged,
notifyOnLoginServiceConfigurationChangedByService,
} from '../../../lib/server/lib/notifyListener';
import { settings, settingsRegistry } from '../../../settings/server';
import type { IServiceProviderOptions } from '../definition/IServiceProviderOptions';
import { SAMLUtils } from './Utils';
Expand Down Expand Up @@ -117,9 +121,22 @@ export const loadSamlServiceProviders = async function (): Promise<void> {
const samlConfigs = getSamlConfigs(key);
SAMLUtils.log(key);
await LoginServiceConfiguration.createOrUpdateService(serviceName, samlConfigs);
void notifyOnLoginServiceConfigurationChangedByService(serviceName);
return configureSamlService(samlConfigs);
}
await LoginServiceConfiguration.removeService(serviceName);

const service = await LoginServiceConfiguration.findOneByService(serviceName, { projection: { _id: 1 } });
if (!service?._id) {
return false;
}

const { deletedCount } = await LoginServiceConfiguration.removeService(service._id);
if (!deletedCount) {
return false;
}

void notifyOnLoginServiceConfigurationChanged({ _id: service._id }, 'removed');

return false;
}),
)
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/server/database/watchCollections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export function getWatchCollections(): string[] {
Users.getCollectionName(),
LivechatInquiry.getCollectionName(),
LivechatDepartmentAgents.getCollectionName(),
LoginServiceConfiguration.getCollectionName(),
InstanceStatus.getCollectionName(),
IntegrationHistory.getCollectionName(),
EmailInbox.getCollectionName(),
Expand All @@ -50,6 +49,7 @@ export function getWatchCollections(): string[] {
collections.push(PbxEvents.getCollectionName());
collections.push(Integrations.getCollectionName());
collections.push(Permissions.getCollectionName());
collections.push(LoginServiceConfiguration.getCollectionName());
}

if (onlyCollections.length > 0) {
Expand Down
13 changes: 12 additions & 1 deletion apps/meteor/server/lib/oauth/updateOAuthServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import type {
import { LoginServiceConfiguration } from '@rocket.chat/models';

import { CustomOAuth } from '../../../app/custom-oauth/server/custom_oauth_server';
import {
notifyOnLoginServiceConfigurationChanged,
notifyOnLoginServiceConfigurationChangedByService,
} from '../../../app/lib/server/lib/notifyListener';
import { settings } from '../../../app/settings/server/cached';
import { logger } from './logger';

Expand Down Expand Up @@ -113,8 +117,15 @@ export async function updateOAuthServices(): Promise<void> {
}

await LoginServiceConfiguration.createOrUpdateService(serviceKey, data);
void notifyOnLoginServiceConfigurationChangedByService(serviceKey);
} else {
await LoginServiceConfiguration.removeService(serviceKey);
const service = await LoginServiceConfiguration.findOneByService(serviceName, { projection: { _id: 1 } });
if (service?._id) {
const { deletedCount } = await LoginServiceConfiguration.removeService(service._id);
if (deletedCount > 0) {
void notifyOnLoginServiceConfigurationChanged({ _id: service._id }, 'removed');
}
}
}
}
}
15 changes: 10 additions & 5 deletions apps/meteor/server/models/raw/LoginServiceConfiguration.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { LoginServiceConfiguration, RocketChatRecordDeleted } from '@rocket.chat/core-typings';
import type { ILoginServiceConfigurationModel } from '@rocket.chat/model-typings';
import type { Collection, Db, DeleteResult } from 'mongodb';
import type { Collection, Db, DeleteResult, Document, FindOptions } from 'mongodb';

import { BaseRaw } from './BaseRaw';

Expand All @@ -15,7 +15,7 @@ export class LoginServiceConfigurationRaw extends BaseRaw<LoginServiceConfigurat
}

async createOrUpdateService(
serviceName: string,
serviceName: LoginServiceConfiguration['service'],
serviceData: Partial<LoginServiceConfiguration>,
): Promise<LoginServiceConfiguration['_id']> {
const service = serviceName.toLowerCase();
Expand Down Expand Up @@ -44,9 +44,14 @@ export class LoginServiceConfigurationRaw extends BaseRaw<LoginServiceConfigurat
return existing._id;
}

async removeService(serviceName: string): Promise<DeleteResult> {
const service = serviceName.toLowerCase();
async removeService(_id: LoginServiceConfiguration['_id']): Promise<DeleteResult> {
return this.deleteOne({ _id });
}

return this.deleteOne({ service });
async findOneByService<P extends Document = LoginServiceConfiguration>(
serviceName: LoginServiceConfiguration['service'],
options?: FindOptions<P>,
): Promise<P | null> {
return this.findOne({ service: serviceName.toLowerCase() }, options);
}
}
2 changes: 1 addition & 1 deletion packages/core-services/src/events/Events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ type LoginServiceConfigurationEvent = {
}
| {
clientAction: Omit<ClientAction, 'removed'>;
data: Partial<ILoginServiceConfiguration>;
data: Omit<Partial<ILoginServiceConfiguration>, 'secret'> & { secret?: never };
}
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import type { LoginServiceConfiguration } from '@rocket.chat/core-typings';
import type { DeleteResult } from 'mongodb';
import type { DeleteResult, Document, FindOptions } from 'mongodb';

import type { IBaseModel } from './IBaseModel';

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ILoginServiceConfigurationModel extends IBaseModel<LoginServiceConfiguration> {
createOrUpdateService(serviceName: string, serviceData: Partial<LoginServiceConfiguration>): Promise<LoginServiceConfiguration['_id']>;
removeService(serviceName: string): Promise<DeleteResult>;
createOrUpdateService(
serviceName: LoginServiceConfiguration['service'],
serviceData: Partial<LoginServiceConfiguration>,
): Promise<LoginServiceConfiguration['_id']>;
removeService(_id: LoginServiceConfiguration['_id']): Promise<DeleteResult>;
findOneByService<P extends Document = LoginServiceConfiguration>(
serviceName: LoginServiceConfiguration['service'],
options?: FindOptions<P>,
): Promise<P | null>;
}

0 comments on commit 3ed5bda

Please sign in to comment.