refactor: remove Users from fibers 11 (#28740)

pull/28751/head
Marcos Spessatto Defendi 3 years ago committed by GitHub
parent 90238b9c15
commit 3129e8b59b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      apps/meteor/app/api/server/api.ts
  2. 2
      apps/meteor/app/api/server/middlewares/authentication.ts
  3. 18
      apps/meteor/app/meteor-accounts-saml/server/methods/samlLogout.ts
  4. 12
      apps/meteor/app/oauth2-server-config/server/admin/methods/updateOAuthApp.ts
  5. 19
      apps/meteor/app/oauth2-server-config/server/oauth/oauth2-server.ts
  6. 9
      apps/meteor/app/oembed/server/jumpToMessage.ts
  7. 4
      apps/meteor/app/push-notifications/server/lib/PushNotification.ts
  8. 4
      apps/meteor/app/search/server/methods.ts
  9. 4
      apps/meteor/app/search/server/search.internalService.ts
  10. 96
      apps/meteor/app/search/server/service/SearchResultValidationService.ts
  11. 6
      apps/meteor/app/slashcommands-help/server/server.ts
  12. 5
      apps/meteor/app/slashcommands-hide/server/hide.ts
  13. 5
      apps/meteor/app/slashcommands-inviteall/server/server.ts
  14. 6
      apps/meteor/app/slashcommands-kick/server/server.ts
  15. 4
      apps/meteor/app/slashcommands-leave/server/leave.ts
  16. 6
      apps/meteor/app/slashcommands-msg/server/server.ts
  17. 4
      apps/meteor/app/slashcommands-mute/server/mute.ts
  18. 4
      apps/meteor/app/slashcommands-mute/server/unmute.ts
  19. 6
      apps/meteor/app/slashcommands-status/server/status.ts
  20. 8
      apps/meteor/app/smarsh-connector/server/functions/generateEml.js
  21. 80
      apps/meteor/app/statistics/server/lib/getServicesStatistics.ts
  22. 2
      apps/meteor/app/statistics/server/lib/statistics.ts

@ -890,11 +890,9 @@ const getUserAuth = function _getUserAuth(...args: any[]): {
this.bodyParams = JSON.parse(this.bodyParams.payload);
}
for (let i = 0; i < (API.v1?.authMethods || []).length; i++) {
const method = API.v1?.authMethods?.[i];
for await (const method of API.v1?.authMethods || []) {
if (typeof method === 'function') {
const result = method.apply(this, args);
const result = await method.apply(this, args);
if (!invalidResults.includes(result)) {
return result;
}

@ -19,7 +19,7 @@ export function authenticationMiddleware(config: AuthenticationMiddlewareConfig
if (userId && authToken) {
req.user = (await Users.findOneByIdAndLoginToken(userId as string, hashLoginToken(authToken as string))) || undefined;
} else {
req.user = oAuth2ServerAuth(req)?.user;
req.user = (await oAuth2ServerAuth(req))?.user;
}
if (config.rejectUnauthorized && !req.user) {

@ -1,7 +1,7 @@
import { Meteor } from 'meteor/meteor';
import type { ServerMethods } from '@rocket.chat/ui-contexts';
import { Users } from '@rocket.chat/models';
import { Users } from '../../../models/server';
import { SAMLServiceProvider } from '../lib/ServiceProvider';
import { SAMLUtils } from '../lib/Utils';
import type { IServiceProviderOptions } from '../definition/IServiceProviderOptions';
@ -28,21 +28,22 @@ function getSamlServiceProviderOptions(provider: string): IServiceProviderOption
declare module '@rocket.chat/ui-contexts' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
samlLogout(provider: string): void;
samlLogout(provider: string): Promise<void>;
}
}
Meteor.methods<ServerMethods>({
samlLogout(provider: string) {
async samlLogout(provider: string) {
const userId = Meteor.userId();
// Make sure the user is logged in before we initiate SAML Logout
if (!Meteor.userId()) {
if (!userId) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'samlLogout' });
}
const providerConfig = getSamlServiceProviderOptions(provider);
SAMLUtils.log({ msg: 'Logout request', providerConfig });
// This query should respect upcoming array of SAML logins
const user = Users.getSAMLByIdAndSAMLProvider(Meteor.userId(), provider);
const user = await Users.getSAMLByIdAndSAMLProvider(userId, provider);
if (!user?.services?.saml) {
return;
}
@ -52,6 +53,11 @@ Meteor.methods<ServerMethods>({
const _saml = new SAMLServiceProvider(providerConfig);
if (!nameID || !idpSession) {
SAMLUtils.log({ msg: 'No NameID or idpSession found for user', userId });
return;
}
const request = _saml.generateLogoutRequest({
nameID: nameID || idpSession,
sessionIndex: idpSession,
@ -63,7 +69,7 @@ Meteor.methods<ServerMethods>({
// request.request: actual XML SAML Request
// request.id: comminucation id which will be mentioned in the ResponseTo field of SAMLResponse
Users.setSamlInResponseTo(Meteor.userId(), request.id);
await Users.setSamlInResponseTo(userId, request.id);
const result = _saml.syncRequestToUrl(request.request, 'logout');
SAMLUtils.log(`SAML Logout Request ${result}`);

@ -1,16 +1,18 @@
import { Meteor } from 'meteor/meteor';
import { OAuthApps } from '@rocket.chat/models';
import { OAuthApps, Users } from '@rocket.chat/models';
import type { IOAuthApps } from '@rocket.chat/core-typings';
import type { ServerMethods } from '@rocket.chat/ui-contexts';
import { hasPermissionAsync } from '../../../../authorization/server/functions/hasPermission';
import { Users } from '../../../../models/server';
import { parseUriList } from '../functions/parseUriList';
declare module '@rocket.chat/ui-contexts' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
updateOAuthApp(applicationId: IOAuthApps['_id'], application: Pick<IOAuthApps, 'name' | 'redirectUri' | 'active'>): IOAuthApps | null;
updateOAuthApp(
applicationId: IOAuthApps['_id'],
application: Pick<IOAuthApps, 'name' | 'redirectUri' | 'active'>,
): Promise<IOAuthApps | null>;
}
}
@ -63,8 +65,8 @@ Meteor.methods<ServerMethods>({
active: application.active,
redirectUri,
_updatedAt: new Date(),
_updatedBy: Users.findOne(this.userId, {
fields: {
_updatedBy: await Users.findOneById(this.userId, {
projection: {
username: 1,
},
}),

@ -4,9 +4,8 @@ import { WebApp } from 'meteor/webapp';
import { OAuth2Server } from 'meteor/rocketchat:oauth2-server';
import type { Request, Response } from 'express';
import type { IUser } from '@rocket.chat/core-typings';
import { OAuthApps } from '@rocket.chat/models';
import { OAuthApps, Users } from '@rocket.chat/models';
import { Users } from '../../../models/server';
import { API } from '../../../api/server';
const oauth2server = new OAuth2Server({
@ -26,10 +25,10 @@ function getAccessToken(accessToken: string): any {
});
}
export function oAuth2ServerAuth(partialRequest: {
export async function oAuth2ServerAuth(partialRequest: {
headers: Record<string, any>;
query: Record<string, any>;
}): { user: IUser } | undefined {
}): Promise<{ user: IUser } | undefined> {
const headerToken = partialRequest.headers.authorization?.replace('Bearer ', '');
const queryToken = partialRequest.query.access_token;
@ -40,7 +39,7 @@ export function oAuth2ServerAuth(partialRequest: {
return;
}
const user = Users.findOne(accessToken.userId);
const user = await Users.findOneById(accessToken.userId);
if (user == null) {
return;
@ -54,7 +53,7 @@ oauth2server.routes.disable('x-powered-by');
WebApp.connectHandlers.use(oauth2server.app);
oauth2server.routes.get('/oauth/userinfo', function (req: Request, res: Response) {
oauth2server.routes.get('/oauth/userinfo', async function (req: Request, res: Response) {
if (req.headers.authorization == null) {
return res.sendStatus(401).send('No token');
}
@ -63,15 +62,15 @@ oauth2server.routes.get('/oauth/userinfo', function (req: Request, res: Response
if (token == null) {
return res.sendStatus(401).send('Invalid Token');
}
const user = Users.findOneById(token.userId);
const user = await Users.findOneById(token.userId);
if (user == null) {
return res.sendStatus(401).send('Invalid Token');
}
return res.send({
sub: user._id,
name: user.name,
email: user.emails[0].address,
email_verified: user.emails[0].verified,
email: user.emails?.[0].address,
email_verified: user.emails?.[0].verified,
department: '',
birthdate: '',
preffered_username: user.username,
@ -80,6 +79,6 @@ oauth2server.routes.get('/oauth/userinfo', function (req: Request, res: Response
});
});
API.v1.addAuthMethod(function () {
API.v1.addAuthMethod(async function () {
return oAuth2ServerAuth(this.request);
});

@ -4,10 +4,10 @@ import QueryString from 'querystring';
import { Meteor } from 'meteor/meteor';
import type { IMessage, MessageAttachment } from '@rocket.chat/core-typings';
import { isQuoteAttachment } from '@rocket.chat/core-typings';
import { Messages } from '@rocket.chat/models';
import { Messages, Users } from '@rocket.chat/models';
import { createQuoteAttachment } from '../../../lib/createQuoteAttachment';
import { Rooms, Users } from '../../models/server';
import { Rooms } from '../../models/server';
import { settings } from '../../settings/server';
import { callbacks } from '../../../lib/callbacks';
import { canAccessRoomAsync } from '../../authorization/server/functions/canAccessRoom';
@ -42,7 +42,10 @@ callbacks.add(
return msg;
}
const currentUser = Users.findOneById(msg.u._id);
const currentUser = await Users.findOneById(msg.u._id);
if (!currentUser) {
return msg;
}
for await (const item of msg.urls) {
// if the URL doesn't belong to the current server, skip

@ -1,10 +1,10 @@
import { Meteor } from 'meteor/meteor';
import type { IMessage, IPushNotificationConfig, IRoom, IUser } from '@rocket.chat/core-typings';
import { Users } from '@rocket.chat/models';
import { Push } from '../../../push/server';
import { settings } from '../../../settings/server';
import { metrics } from '../../../metrics/server';
import { Users } from '../../../models/server';
import { RocketChatAssets } from '../../../assets/server';
import { replaceMentionedUsernamesWithFullNames, parseMessageTextPerUser } from '../../../lib/server/functions/notifications';
import { callbacks } from '../../../../lib/callbacks';
@ -123,7 +123,7 @@ class PushNotification {
message: IMessage;
room: IRoom;
}): Promise<NotificationPayload> {
const sender = Users.findOne(message.u._id, { fields: { username: 1, name: 1 } });
const sender = await Users.findOneById(message.u._id, { projection: { username: 1, name: 1 } });
if (!sender) {
throw new Error('Message sender not found');
}

@ -56,13 +56,13 @@ Meteor.methods<ServerMethods>({
SearchLogger.debug({ msg: 'search', text, context, payload });
return new Promise((resolve, reject) => {
searchProviderService.activeProvider?.search(text, context, payload, (error, data) => {
searchProviderService.activeProvider?.search(text, context, payload, async (error, data) => {
if (error) {
reject(error);
return;
}
resolve(validationService.validateSearchResult(data));
resolve(await validationService.validateSearchResult(data));
});
});
},

@ -1,6 +1,6 @@
import { api, ServiceClassInternal } from '@rocket.chat/core-services';
import { Users } from '@rocket.chat/models';
import { Users } from '../../models/server';
import { settings } from '../../settings/server';
import { searchProviderService } from './service';
import { searchEventService } from './events';
@ -19,7 +19,7 @@ class Search extends ServiceClassInternal {
return;
}
const user = data ?? Users.findOneById(id);
const user = data ?? (await Users.findOneById(id));
searchEventService.promoteEvent('user.save', id, user);
});

@ -1,40 +1,40 @@
import { Meteor } from 'meteor/meteor';
import mem from 'mem';
import type { IRoom, IUser } from '@rocket.chat/core-typings';
import { Users, Rooms } from '@rocket.chat/models';
import { SearchLogger } from '../logger/logger';
import { canAccessRoomAsync } from '../../../authorization/server';
import { Users, Rooms } from '../../../models/server';
import type { IRawSearchResult, ISearchResult } from '../model/ISearchResult';
import { isTruthy } from '../../../../lib/isTruthy';
export class SearchResultValidationService {
private getSubscription = mem((rid: IRoom['_id'], uid?: IUser['_id']) => {
private getSubscription = mem(async (rid: IRoom['_id'], uid?: IUser['_id']) => {
if (!rid) {
return;
}
const room = Rooms.findOneById(rid) as IRoom | undefined;
const room = await Rooms.findOneById(rid);
if (!room) {
return;
}
if (!uid || !Promise.await(canAccessRoomAsync(room, { _id: uid }))) {
if (!uid || !(await canAccessRoomAsync(room, { _id: uid }))) {
return;
}
return room;
});
private getUser = mem((uid: IUser['_id']) => {
private getUser = mem(async (uid: IUser['_id']) => {
if (!uid) {
return;
}
return Users.findOneById(uid, { fields: { username: 1 } }) as IUser | undefined;
return Users.findOneById(uid, { projection: { username: 1 } });
});
validateSearchResult(result: IRawSearchResult): ISearchResult {
async validateSearchResult(result: IRawSearchResult): Promise<ISearchResult> {
const uid = Meteor.userId() ?? undefined;
const validatedResult: ISearchResult = {};
@ -42,49 +42,53 @@ export class SearchResultValidationService {
// get subscription for message
if (result.message) {
validatedResult.message = {
docs: result.message.docs
.map((msg) => {
const user = this.getUser(msg.u._id);
const subscription = this.getSubscription(msg.rid, uid);
if (subscription) {
SearchLogger.debug(`user ${uid} can access ${msg.rid}`);
return {
...msg,
user: msg.u._id,
r: { name: subscription.name, t: subscription.t },
username: user?.username,
valid: true,
};
}
SearchLogger.debug(`user ${uid} can NOT access ${msg.rid}`);
return undefined;
})
.filter(isTruthy),
docs: (
await Promise.all(
result.message.docs.map(async (msg) => {
const user = await this.getUser(msg.u._id);
const subscription = await this.getSubscription(msg.rid, uid);
if (subscription) {
SearchLogger.debug(`user ${uid} can access ${msg.rid}`);
return {
...msg,
user: msg.u._id,
r: { name: subscription.name, t: subscription.t },
username: user?.username,
valid: true,
};
}
SearchLogger.debug(`user ${uid} can NOT access ${msg.rid}`);
return undefined;
}),
)
).filter(isTruthy),
};
}
if (result.room) {
result.room.docs = result.room.docs
.map((room) => {
const subscription = this.getSubscription(room._id, uid);
if (!subscription) {
SearchLogger.debug(`user ${uid} can NOT access ${room._id}`);
return undefined;
}
SearchLogger.debug(`user ${uid} can access ${room._id}`);
return {
...room,
valid: true,
t: subscription.t,
name: subscription.name,
};
})
.filter(isTruthy);
result.room.docs = (
await Promise.all(
result.room.docs.map(async (room) => {
const subscription = await this.getSubscription(room._id, uid);
if (!subscription) {
SearchLogger.debug(`user ${uid} can NOT access ${room._id}`);
return undefined;
}
SearchLogger.debug(`user ${uid} can access ${room._id}`);
return {
...room,
valid: true,
t: subscription.t,
name: subscription.name,
};
}),
)
).filter(isTruthy);
}
return validatedResult;

@ -1,10 +1,10 @@
import { Meteor } from 'meteor/meteor';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { api } from '@rocket.chat/core-services';
import { Users } from '@rocket.chat/models';
import { settings } from '../../settings/server';
import { slashCommands } from '../../utils/lib/slashCommand';
import { Users } from '../../models/server';
/*
* Help is a named function that will replace /help commands
@ -18,9 +18,9 @@ interface IHelpCommand {
slashCommands.add({
command: 'help',
callback: function Help(_command, _params, item): void {
callback: async function Help(_command, _params, item): Promise<void> {
const userId = Meteor.userId() as string;
const user = Users.findOneById(userId);
const user = await Users.findOneById(userId);
const keys: IHelpCommand[] = [
{

@ -1,10 +1,9 @@
import { Meteor } from 'meteor/meteor';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { api } from '@rocket.chat/core-services';
import { Subscriptions, Rooms } from '@rocket.chat/models';
import { Subscriptions, Users, Rooms } from '@rocket.chat/models';
import { settings } from '../../settings/server';
import { Users } from '../../models/server';
import { slashCommands } from '../../utils/server';
/*
@ -21,7 +20,7 @@ slashCommands.add({
return;
}
const user = Users.findOneById(userId);
const user = await Users.findOneById(userId);
if (!user) {
return;

@ -7,9 +7,8 @@ import { Meteor } from 'meteor/meteor';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import type { ISubscription, SlashCommand } from '@rocket.chat/core-typings';
import { api } from '@rocket.chat/core-services';
import { Subscriptions, Rooms } from '@rocket.chat/models';
import { Subscriptions, Users, Rooms } from '@rocket.chat/models';
import { Users } from '../../models/server';
import { slashCommands } from '../../utils/lib/slashCommand';
import { settings } from '../../settings/server';
@ -34,7 +33,7 @@ function inviteAll<T extends string>(type: T): SlashCommand<T>['callback'] {
return;
}
const user = Users.findOneById(userId);
const user = await Users.findOneById(userId);
const lng = user?.language || settings.get('Language') || 'en';
const baseChannel = type === 'to' ? await Rooms.findOneById(item.rid) : await Rooms.findOneByName(channel);

@ -2,8 +2,8 @@
import { Meteor } from 'meteor/meteor';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { api } from '@rocket.chat/core-services';
import { Users } from '@rocket.chat/models';
import { Users } from '../../models/server';
import { settings } from '../../settings/server';
import { slashCommands } from '../../utils/lib/slashCommand';
@ -15,10 +15,10 @@ slashCommands.add({
return;
}
const userId = Meteor.userId() as string;
const user = Users.findOneById(userId);
const user = await Users.findOneById(userId);
const lng = user?.language || settings.get('Language') || 'en';
const kickedUser = Users.findOneByUsernameIgnoringCase(username);
const kickedUser = await Users.findOneByUsernameIgnoringCase(username);
if (kickedUser == null) {
void api.broadcast('notify.ephemeralMessage', userId, item.rid, {

@ -2,10 +2,10 @@ import { Meteor } from 'meteor/meteor';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import type { SlashCommand } from '@rocket.chat/core-typings';
import { api } from '@rocket.chat/core-services';
import { Users } from '@rocket.chat/models';
import { slashCommands } from '../../utils/lib/slashCommand';
import { settings } from '../../settings/server';
import { Users } from '../../models/server';
/*
* Leave is a named function that will replace /leave commands
@ -19,7 +19,7 @@ const Leave: SlashCommand<'leave'>['callback'] = async function Leave(_command,
if (typeof error !== 'string') {
return;
}
const user = Users.findOneById(userId);
const user = await Users.findOneById(userId);
void api.broadcast('notify.ephemeralMessage', userId, item.rid, {
msg: TAPi18n.__(error, { lng: user?.language || settings.get('Language') || 'en' }),
});

@ -2,10 +2,10 @@ import { Meteor } from 'meteor/meteor';
import { Random } from '@rocket.chat/random';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { api } from '@rocket.chat/core-services';
import { Users } from '@rocket.chat/models';
import { slashCommands } from '../../utils/lib/slashCommand';
import { settings } from '../../settings/server';
import { Users } from '../../models/server';
/*
* Msg is a named function that will replace /msg commands
@ -26,9 +26,9 @@ slashCommands.add({
const message = trimmedParams.slice(separator + 1);
const targetUsernameOrig = trimmedParams.slice(0, separator);
const targetUsername = targetUsernameOrig.replace('@', '');
const targetUser = Users.findOneByUsernameIgnoringCase(targetUsername);
const targetUser = await Users.findOneByUsernameIgnoringCase(targetUsername);
if (targetUser == null) {
const user = Users.findOneById(userId, { fields: { language: 1 } });
const user = await Users.findOneById(userId, { projection: { language: 1 } });
void api.broadcast('notify.ephemeralMessage', userId, item.rid, {
msg: TAPi18n.__('Username_doesnt_exist', {
postProcess: 'sprintf',

@ -1,10 +1,10 @@
import { Meteor } from 'meteor/meteor';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { api } from '@rocket.chat/core-services';
import { Users } from '@rocket.chat/models';
import { slashCommands } from '../../utils/lib/slashCommand';
import { settings } from '../../settings/server';
import { Users } from '../../models/server';
/*
* Mute is a named function that will replace /mute commands
@ -19,7 +19,7 @@ slashCommands.add({
}
const userId = Meteor.userId() as string;
const mutedUser = Users.findOneByUsernameIgnoringCase(username);
const mutedUser = await Users.findOneByUsernameIgnoringCase(username);
if (mutedUser == null) {
void api.broadcast('notify.ephemeralMessage', userId, item.rid, {
msg: TAPi18n.__('Username_doesnt_exist', {

@ -1,9 +1,9 @@
import { Meteor } from 'meteor/meteor';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { api } from '@rocket.chat/core-services';
import { Users } from '@rocket.chat/models';
import { slashCommands } from '../../utils/lib/slashCommand';
import { Users } from '../../models/server';
import { settings } from '../../settings/server';
/*
@ -18,7 +18,7 @@ slashCommands.add({
return;
}
const userId = Meteor.userId() as string;
const unmutedUser = Users.findOneByUsernameIgnoringCase(username);
const unmutedUser = await Users.findOneByUsernameIgnoringCase(username);
if (unmutedUser == null) {
void api.broadcast('notify.ephemeralMessage', userId, item.rid, {
msg: TAPi18n.__('Username_doesnt_exist', {

@ -1,18 +1,18 @@
import { Meteor } from 'meteor/meteor';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { api } from '@rocket.chat/core-services';
import { Users } from '@rocket.chat/models';
import { slashCommands } from '../../utils/lib/slashCommand';
import { settings } from '../../settings/server';
import { Users } from '../../models/server';
slashCommands.add({
command: 'status',
callback: async function Status(_command: 'status', params, item): Promise<void> {
const userId = Meteor.userId() as string;
await Meteor.callAsync('setUserStatus', null, params, (err: Meteor.Error) => {
const user = userId && Users.findOneById(userId, { fields: { language: 1 } });
await Meteor.callAsync('setUserStatus', null, params, async (err: Meteor.Error) => {
const user = await Users.findOneById(userId, { projection: { language: 1 } });
const lng = user?.language || settings.get('Language') || 'en';
if (err) {

@ -1,10 +1,10 @@
import { Meteor } from 'meteor/meteor';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import moment from 'moment';
import { Messages, SmarshHistory } from '@rocket.chat/models';
import { Messages, SmarshHistory, Users } from '@rocket.chat/models';
import { settings } from '../../../settings/server';
import { Rooms, Users } from '../../../models/server';
import { Rooms } from '../../../models/server';
import { MessageTypes } from '../../../ui-utils/server';
import { smarsh } from '../lib/rocketchat';
import 'moment-timezone';
@ -50,7 +50,7 @@ smarsh.generateEml = () => {
room: room.name ? `#${room.name}` : `Direct Message Between: ${room.usernames.join(' & ')}`,
};
await Messages.find(query).forEach((message) => {
await Messages.find(query).forEach(async (message) => {
rows.push(opentr);
// The timestamp
@ -60,7 +60,7 @@ smarsh.generateEml = () => {
// The sender
rows.push(open20td);
const sender = Users.findOne({ _id: message.u._id });
const sender = await Users.findOne({ _id: message.u._id });
if (data.users.indexOf(sender._id) === -1) {
data.users.push(sender._id);
}

@ -1,43 +1,47 @@
import { MongoInternals } from 'meteor/mongo';
import { Users } from '@rocket.chat/models';
import { readSecondaryPreferred } from '../../../../server/database/readSecondaryPreferred';
import { settings } from '../../../settings/server';
import { Users } from '../../../models/server';
const { db } = MongoInternals.defaultRemoteCollectionDriver().mongo;
function getCustomOAuthServices(): Record<
string,
{
enabled: boolean;
mergeRoles: boolean;
users: number;
}
async function getCustomOAuthServices(): Promise<
Record<
string,
{
enabled: boolean;
mergeRoles: boolean;
users: number;
}
>
> {
const readPreference = readSecondaryPreferred(db);
const customOauth = settings.getByRegexp(/Accounts_OAuth_Custom-[^-]+$/im);
return Object.fromEntries(
Object.entries(customOauth).map(([key, value]) => {
const name = key.replace('Accounts_OAuth_Custom-', '');
return [
name,
{
enabled: Boolean(value),
mergeRoles: settings.get<boolean>(`Accounts_OAuth_Custom-${name}-merge_roles`),
users: Users.countActiveUsersByService(name, { readPreference }),
},
];
}),
await Promise.all(
Object.entries(customOauth).map(async ([key, value]) => {
const name = key.replace('Accounts_OAuth_Custom-', '');
return [
name,
{
enabled: Boolean(value),
mergeRoles: settings.get<boolean>(`Accounts_OAuth_Custom-${name}-merge_roles`),
users: await Users.countActiveUsersByService(name, { readPreference }),
},
];
}),
),
);
}
export function getServicesStatistics(): Record<string, unknown> {
export async function getServicesStatistics(): Promise<Record<string, unknown>> {
const readPreference = readSecondaryPreferred(db);
return {
ldap: {
users: Users.countActiveUsersByService('ldap', { readPreference }),
users: await Users.countActiveUsersByService('ldap', { readPreference }),
enabled: settings.get('LDAP_Enable'),
loginFallback: settings.get('LDAP_Login_Fallback'),
encryption: settings.get('LDAP_Encryption'),
@ -62,7 +66,7 @@ export function getServicesStatistics(): Record<string, unknown> {
},
saml: {
enabled: settings.get('SAML_Custom_Default'),
users: Users.countActiveUsersByService('saml', { readPreference }),
users: await Users.countActiveUsersByService('saml', { readPreference }),
signatureValidationType: settings.get('SAML_Custom_Default_signature_validation_type'),
generateUsername: settings.get('SAML_Custom_Default_generate_username'),
updateSubscriptionsOnLogin: settings.get('SAML_Custom_Default_channels_update'),
@ -70,68 +74,68 @@ export function getServicesStatistics(): Record<string, unknown> {
},
cas: {
enabled: settings.get('CAS_enabled'),
users: Users.countActiveUsersByService('cas', { readPreference }),
users: await Users.countActiveUsersByService('cas', { readPreference }),
allowUserCreation: settings.get('CAS_Creation_User_Enabled'),
alwaysSyncUserData: settings.get('CAS_Sync_User_Data_Enabled'),
},
oauth: {
apple: {
enabled: settings.get('Accounts_OAuth_Apple'),
users: Users.countActiveUsersByService('apple', { readPreference }),
users: await Users.countActiveUsersByService('apple', { readPreference }),
},
dolphin: {
enabled: settings.get('Accounts_OAuth_Dolphin'),
users: Users.countActiveUsersByService('dolphin', { readPreference }),
users: await Users.countActiveUsersByService('dolphin', { readPreference }),
},
drupal: {
enabled: settings.get('Accounts_OAuth_Drupal'),
users: Users.countActiveUsersByService('drupal', { readPreference }),
users: await Users.countActiveUsersByService('drupal', { readPreference }),
},
facebook: {
enabled: settings.get('Accounts_OAuth_Facebook'),
users: Users.countActiveUsersByService('facebook', { readPreference }),
users: await Users.countActiveUsersByService('facebook', { readPreference }),
},
github: {
enabled: settings.get('Accounts_OAuth_Github'),
users: Users.countActiveUsersByService('github', { readPreference }),
users: await Users.countActiveUsersByService('github', { readPreference }),
},
githubEnterprise: {
enabled: settings.get('Accounts_OAuth_GitHub_Enterprise'),
users: Users.countActiveUsersByService('github_enterprise', { readPreference }),
users: await Users.countActiveUsersByService('github_enterprise', { readPreference }),
},
gitlab: {
enabled: settings.get('Accounts_OAuth_Gitlab'),
users: Users.countActiveUsersByService('gitlab', { readPreference }),
users: await Users.countActiveUsersByService('gitlab', { readPreference }),
},
google: {
enabled: settings.get('Accounts_OAuth_Google'),
users: Users.countActiveUsersByService('google', { readPreference }),
users: await Users.countActiveUsersByService('google', { readPreference }),
},
linkedin: {
enabled: settings.get('Accounts_OAuth_Linkedin'),
users: Users.countActiveUsersByService('linkedin', { readPreference }),
users: await Users.countActiveUsersByService('linkedin', { readPreference }),
},
meteor: {
enabled: settings.get('Accounts_OAuth_Meteor'),
users: Users.countActiveUsersByService('meteor', { readPreference }),
users: await Users.countActiveUsersByService('meteor', { readPreference }),
},
nextcloud: {
enabled: settings.get('Accounts_OAuth_Nextcloud'),
users: Users.countActiveUsersByService('nextcloud', { readPreference }),
users: await Users.countActiveUsersByService('nextcloud', { readPreference }),
},
tokenpass: {
enabled: settings.get('Accounts_OAuth_Tokenpass'),
users: Users.countActiveUsersByService('tokenpass', { readPreference }),
users: await Users.countActiveUsersByService('tokenpass', { readPreference }),
},
twitter: {
enabled: settings.get('Accounts_OAuth_Twitter'),
users: Users.countActiveUsersByService('twitter', { readPreference }),
users: await Users.countActiveUsersByService('twitter', { readPreference }),
},
wordpress: {
enabled: settings.get('Accounts_OAuth_Wordpress'),
users: Users.countActiveUsersByService('wordpress', { readPreference }),
users: await Users.countActiveUsersByService('wordpress', { readPreference }),
},
custom: getCustomOAuthServices(),
custom: await getCustomOAuthServices(),
},
};
}

@ -416,7 +416,7 @@ export const statistics = {
);
statistics.apps = getAppsStatistics();
statistics.services = getServicesStatistics();
statistics.services = await getServicesStatistics();
statistics.importer = getImporterStatistics();
statistics.videoConf = await VideoConf.getStatistics();

Loading…
Cancel
Save