diff --git a/.changeset/perfect-pianos-yawn.md b/.changeset/perfect-pianos-yawn.md new file mode 100644 index 000000000000..349bca33ecf7 --- /dev/null +++ b/.changeset/perfect-pianos-yawn.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/presence': minor +--- + +Add peak connections monitoring and methods to get and reset the counter diff --git a/.changeset/rich-dogs-smell.md b/.changeset/rich-dogs-smell.md new file mode 100644 index 000000000000..be27db28e227 --- /dev/null +++ b/.changeset/rich-dogs-smell.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': minor +--- + +Fix typing indicator of Apps user diff --git a/.changeset/slow-coats-shout.md b/.changeset/slow-coats-shout.md new file mode 100644 index 000000000000..4a226e84d161 --- /dev/null +++ b/.changeset/slow-coats-shout.md @@ -0,0 +1,7 @@ +--- +"@rocket.chat/meteor": minor +--- + +Add the daily and monthly peaks of concurrent connections to statistics + - Added `dailyPeakConnections` statistic for monitoring the daily peak of concurrent connections in a workspace; + - Added `maxMonthlyPeakConnections` statistic for monitoring the last 30 days peak of concurrent connections in a workspace; diff --git a/.changeset/weak-cameras-pay.md b/.changeset/weak-cameras-pay.md new file mode 100644 index 000000000000..724f3af69a29 --- /dev/null +++ b/.changeset/weak-cameras-pay.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +Fixed issue with message read receipts not being created when accessing a room the first time diff --git a/apps/meteor/app/apps/server/bridges/messages.ts b/apps/meteor/app/apps/server/bridges/messages.ts index d75a0c244674..e4d09018176d 100644 --- a/apps/meteor/app/apps/server/bridges/messages.ts +++ b/apps/meteor/app/apps/server/bridges/messages.ts @@ -103,7 +103,11 @@ export class AppMessageBridge extends MessageBridge { protected async typing({ scope, id, username, isTyping }: ITypingDescriptor): Promise { switch (scope) { case 'room': - notifications.notifyRoom(id, 'typing', username!, isTyping); + if (!username) { + throw new Error('Invalid username'); + } + + notifications.notifyRoom(id, 'user-activity', username, isTyping ? ['user-typing'] : []); return; default: throw new Error('Unrecognized typing scope provided'); diff --git a/apps/meteor/app/cas/server/cas_server.js b/apps/meteor/app/cas/server/cas_server.js index 25d3b9fdd698..60880c77d4f4 100644 --- a/apps/meteor/app/cas/server/cas_server.js +++ b/apps/meteor/app/cas/server/cas_server.js @@ -257,7 +257,7 @@ Accounts.registerLoginHandler('cas', async (options) => { if (roomName) { let room = await Rooms.findOneByNameAndType(roomName, 'c'); if (!room) { - room = await createRoom('c', roomName, user.username); + room = await createRoom('c', roomName, user); } } } diff --git a/apps/meteor/app/irc/server/irc-bridge/peerHandlers/joinedChannel.js b/apps/meteor/app/irc/server/irc-bridge/peerHandlers/joinedChannel.js index 0968eacc5340..bb5053ffdd71 100644 --- a/apps/meteor/app/irc/server/irc-bridge/peerHandlers/joinedChannel.js +++ b/apps/meteor/app/irc/server/irc-bridge/peerHandlers/joinedChannel.js @@ -16,7 +16,7 @@ export default async function handleJoinedChannel(args) { let room = await Rooms.findOneByName(args.roomName); if (!room) { - const createdRoom = await createRoom('c', args.roomName, user.username, []); + const createdRoom = await createRoom('c', args.roomName, user, []); room = await Rooms.findOne({ _id: createdRoom.rid }); this.log(`${user.username} created room ${args.roomName}`); diff --git a/apps/meteor/app/slackbridge/server/RocketAdapter.js b/apps/meteor/app/slackbridge/server/RocketAdapter.js index d0ef8157137d..f76c33fa1f81 100644 --- a/apps/meteor/app/slackbridge/server/RocketAdapter.js +++ b/apps/meteor/app/slackbridge/server/RocketAdapter.js @@ -295,7 +295,7 @@ export default class RocketAdapter { try { const isPrivate = slackChannel.is_private; - const rocketChannel = await createRoom(isPrivate ? 'p' : 'c', slackChannel.name, rocketUserCreator.username, rocketUsers); + const rocketChannel = await createRoom(isPrivate ? 'p' : 'c', slackChannel.name, rocketUserCreator, rocketUsers); slackChannel.rocketId = rocketChannel.rid; } catch (e) { if (!hasRetried) { diff --git a/apps/meteor/app/statistics/server/lib/statistics.ts b/apps/meteor/app/statistics/server/lib/statistics.ts index 64543deb88a1..1d60def846b5 100644 --- a/apps/meteor/app/statistics/server/lib/statistics.ts +++ b/apps/meteor/app/statistics/server/lib/statistics.ts @@ -1,7 +1,7 @@ import { log } from 'console'; import os from 'os'; -import { Analytics, Team, VideoConf } from '@rocket.chat/core-services'; +import { Analytics, Team, VideoConf, Presence } from '@rocket.chat/core-services'; import type { IRoom, IStats } from '@rocket.chat/core-typings'; import { UserStatus } from '@rocket.chat/core-typings'; import { @@ -579,6 +579,11 @@ export const statistics = { const defaultLoggedInCustomScript = (await Settings.findOneById('Custom_Script_Logged_In'))?.packageValue; statistics.loggedInCustomScriptChanged = settings.get('Custom_Script_Logged_In') !== defaultLoggedInCustomScript; + statistics.dailyPeakConnections = await Presence.getPeakConnections(true); + + const peak = await Statistics.findMonthlyPeakConnections(); + statistics.maxMonthlyPeakConnections = Math.max(statistics.dailyPeakConnections, peak?.dailyPeakConnections || 0); + statistics.matrixFederation = await getMatrixFederationStatistics(); // Omnichannel call stats diff --git a/apps/meteor/client/views/admin/info/DeploymentCard.stories.tsx b/apps/meteor/client/views/admin/info/DeploymentCard.stories.tsx index 41709d247f8b..d3242e68ae2c 100644 --- a/apps/meteor/client/views/admin/info/DeploymentCard.stories.tsx +++ b/apps/meteor/client/views/admin/info/DeploymentCard.stories.tsx @@ -272,6 +272,8 @@ export default { totalWebRTCCalls: 0, uncaughtExceptionsCount: 0, push: 0, + dailyPeakConnections: 0, + maxMonthlyPeakConnections: 0, matrixFederation: { enabled: false, }, diff --git a/apps/meteor/client/views/admin/info/InformationPage.stories.tsx b/apps/meteor/client/views/admin/info/InformationPage.stories.tsx index 29c0c00d5814..d05c0f7372a2 100644 --- a/apps/meteor/client/views/admin/info/InformationPage.stories.tsx +++ b/apps/meteor/client/views/admin/info/InformationPage.stories.tsx @@ -302,6 +302,8 @@ export default { totalWebRTCCalls: 0, uncaughtExceptionsCount: 0, push: 0, + dailyPeakConnections: 0, + maxMonthlyPeakConnections: 0, matrixFederation: { enabled: false, }, diff --git a/apps/meteor/client/views/admin/info/UsageCard.stories.tsx b/apps/meteor/client/views/admin/info/UsageCard.stories.tsx index a65e645b17d0..4c6cc871ede7 100644 --- a/apps/meteor/client/views/admin/info/UsageCard.stories.tsx +++ b/apps/meteor/client/views/admin/info/UsageCard.stories.tsx @@ -250,6 +250,8 @@ export default { totalWebRTCCalls: 0, uncaughtExceptionsCount: 0, push: 0, + dailyPeakConnections: 0, + maxMonthlyPeakConnections: 0, matrixFederation: { enabled: false, }, diff --git a/apps/meteor/ee/server/api/licenses.ts b/apps/meteor/ee/server/api/licenses.ts index ff5c3fcc3e47..b7ac3ba81e9c 100644 --- a/apps/meteor/ee/server/api/licenses.ts +++ b/apps/meteor/ee/server/api/licenses.ts @@ -25,10 +25,13 @@ API.v1.addRoute( API.v1.addRoute( 'licenses.info', - { authRequired: true, validateParams: isLicensesInfoProps, permissionsRequired: ['view-privileged-setting'] }, + { authRequired: true, validateParams: isLicensesInfoProps }, { async get() { - const data = await License.getInfo(Boolean(this.queryParams.loadValues)); + const unrestrictedAccess = await hasPermissionAsync(this.userId, 'view-privileged-setting'); + const loadCurrentValues = unrestrictedAccess && Boolean(this.queryParams.loadValues); + + const data = await License.getInfo({ limits: unrestrictedAccess, license: unrestrictedAccess, currentValues: loadCurrentValues }); return API.v1.success({ data }); }, diff --git a/apps/meteor/server/cron/statistics.ts b/apps/meteor/server/cron/statistics.ts index 27c1fc064e25..7e7dea6adbc7 100644 --- a/apps/meteor/server/cron/statistics.ts +++ b/apps/meteor/server/cron/statistics.ts @@ -37,5 +37,7 @@ export async function statsCron(logger: Logger): Promise { const now = new Date(); - await cronJobs.add(name, `12 ${now.getHours()} * * *`, async () => generateStatistics(logger)); + await cronJobs.add(name, `12 ${now.getHours()} * * *`, async () => { + await generateStatistics(logger); + }); } diff --git a/apps/meteor/server/lib/readMessages.ts b/apps/meteor/server/lib/readMessages.ts index 00bf04bd3449..d7c8cf559288 100644 --- a/apps/meteor/server/lib/readMessages.ts +++ b/apps/meteor/server/lib/readMessages.ts @@ -6,7 +6,7 @@ import { callbacks } from '../../lib/callbacks'; export async function readMessages(rid: IRoom['_id'], uid: IUser['_id'], readThreads: boolean): Promise { await callbacks.run('beforeReadMessages', rid, uid); - const projection = { ls: 1, tunread: 1, alert: 1 }; + const projection = { ls: 1, tunread: 1, alert: 1, ts: 1 }; const sub = await Subscriptions.findOneByRoomIdAndUserId(rid, uid, { projection }); if (!sub) { throw new Error('error-invalid-subscription'); @@ -19,5 +19,6 @@ export async function readMessages(rid: IRoom['_id'], uid: IUser['_id'], readThr await NotificationQueue.clearQueueByUserId(uid); - callbacks.runAsync('afterReadMessages', rid, { uid, lastSeen: sub.ls }); + const lastSeen = sub.ls || sub.ts; + callbacks.runAsync('afterReadMessages', rid, { uid, lastSeen }); } diff --git a/apps/meteor/server/models/raw/Statistics.ts b/apps/meteor/server/models/raw/Statistics.ts index 1ad0ab993910..bad44ee07c23 100644 --- a/apps/meteor/server/models/raw/Statistics.ts +++ b/apps/meteor/server/models/raw/Statistics.ts @@ -25,4 +25,25 @@ export class StatisticsRaw extends BaseRaw implements IStatisticsModel { ).toArray(); return records?.[0]; } + + async findMonthlyPeakConnections() { + const oneMonthAgo = new Date(); + oneMonthAgo.setDate(oneMonthAgo.getDate() - 30); + oneMonthAgo.setHours(0, 0, 0, 0); + + return this.findOne>( + { + createdAt: { $gte: oneMonthAgo }, + }, + { + sort: { + dailyPeakConnections: -1, + }, + projection: { + dailyPeakConnections: 1, + createdAt: 1, + }, + }, + ); + } } diff --git a/apps/meteor/tests/end-to-end/api/20-licenses.js b/apps/meteor/tests/end-to-end/api/20-licenses.js index 993428d34409..302011addef9 100644 --- a/apps/meteor/tests/end-to-end/api/20-licenses.js +++ b/apps/meteor/tests/end-to-end/api/20-licenses.js @@ -105,6 +105,52 @@ describe('licenses', function () { }); }); + describe('[/licenses.info]', () => { + it('should fail if not logged in', (done) => { + request + .get(api('licenses.info')) + .expect('Content-Type', 'application/json') + .expect(401) + .expect((res) => { + expect(res.body).to.have.property('status', 'error'); + expect(res.body).to.have.property('message'); + }) + .end(done); + }); + + it('should return limited information if user is unauthorized', (done) => { + request + .get(api('licenses.info')) + .set(unauthorizedUserCredentials) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('data').and.to.be.an('object'); + expect(res.body.data).to.not.have.property('license'); + expect(res.body.data).to.have.property('tags').and.to.be.an('array'); + }) + .end(done); + }); + + it('should return unrestricted info if user is logged in and is authorized', (done) => { + request + .get(api('licenses.info')) + .set(credentials) + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('data').and.to.be.an('object'); + if (process.env.IS_EE) { + expect(res.body.data).to.have.property('license').and.to.be.an('object'); + } + expect(res.body.data).to.have.property('tags').and.to.be.an('array'); + }) + + .end(done); + }); + }); + describe('[/licenses.isEnterprise]', () => { it('should fail if not logged in', (done) => { request diff --git a/ee/packages/license/babel.config.json b/ee/packages/license/babel.config.json deleted file mode 100644 index e154c0813530..000000000000 --- a/ee/packages/license/babel.config.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "presets": ["@babel/preset-typescript"], - "plugins": [ - [ - "transform-inline-environment-variables", - { - "include": ["LICENSE_PUBLIC_KEY_V3"] - } - ] - ] -} diff --git a/ee/packages/license/package.json b/ee/packages/license/package.json index 6810f53e40dd..ec79532a9680 100644 --- a/ee/packages/license/package.json +++ b/ee/packages/license/package.json @@ -3,18 +3,11 @@ "version": "0.0.1", "private": true, "devDependencies": { - "@babel/cli": "^7.23.0", - "@babel/core": "^7.23.0", - "@babel/preset-env": "^7.22.20", - "@babel/preset-typescript": "^7.23.0", "@swc/core": "^1.3.66", "@swc/jest": "^0.2.26", - "@types/babel__core": "^7", - "@types/babel__preset-env": "^7", "@types/bcrypt": "^5.0.0", "@types/jest": "~29.5.3", "@types/ws": "^8.5.5", - "babel-plugin-transform-inline-environment-variables": "^0.4.4", "eslint": "~8.45.0", "jest": "~29.6.1", "jest-environment-jsdom": "~29.6.1", @@ -29,7 +22,7 @@ "testunit": "jest", "build": "npm run build:types && npm run build:js", "build:types": "tsc --emitDeclarationOnly", - "build:js": "babel src --out-dir dist --extensions \".ts,.tsx\" --source-maps inline", + "build:js": "rm -rf dist && tsc -p tsconfig.json", "dev": "tsc -p tsconfig.json --watch --preserveWatchOutput" }, "main": "./dist/index.js", diff --git a/ee/packages/license/src/definition/LicenseInfo.ts b/ee/packages/license/src/definition/LicenseInfo.ts new file mode 100644 index 000000000000..7de3c0cfbdd6 --- /dev/null +++ b/ee/packages/license/src/definition/LicenseInfo.ts @@ -0,0 +1,10 @@ +import type { ILicenseTag } from './ILicenseTag'; +import type { ILicenseV3, LicenseLimitKind } from './ILicenseV3'; +import type { LicenseModule } from './LicenseModule'; + +export type LicenseInfo = { + license?: ILicenseV3; + activeModules: LicenseModule[]; + limits: Record; + tags: ILicenseTag[]; +}; diff --git a/ee/packages/license/src/index.ts b/ee/packages/license/src/index.ts index 77e2976f156a..9707a41d96ab 100644 --- a/ee/packages/license/src/index.ts +++ b/ee/packages/license/src/index.ts @@ -1,5 +1,5 @@ -import type { ILicenseV3, LicenseLimitKind } from './definition/ILicenseV3'; -import type { LicenseModule } from './definition/LicenseModule'; +import type { LicenseLimitKind } from './definition/ILicenseV3'; +import type { LicenseInfo } from './definition/LicenseInfo'; import type { LimitContext } from './definition/LimitContext'; import { getAppsConfig, getMaxActiveUsers, getUnmodifiedLicenseAndModules } from './deprecated'; import { onLicense } from './events/deprecated'; @@ -24,6 +24,7 @@ export * from './definition/ILicenseTag'; export * from './definition/ILicenseV2'; export * from './definition/ILicenseV3'; export * from './definition/LicenseBehavior'; +export * from './definition/LicenseInfo'; export * from './definition/LicenseLimit'; export * from './definition/LicenseModule'; export * from './definition/LicensePeriod'; @@ -49,11 +50,7 @@ interface License { onBehaviorTriggered: typeof onBehaviorTriggered; revalidateLicense: () => Promise; - getInfo: (loadCurrentValues: boolean) => Promise<{ - license: ILicenseV3 | undefined; - activeModules: LicenseModule[]; - limits: Record; - }>; + getInfo: (info: { limits: boolean; currentValues: boolean; license: boolean }) => Promise; // Deprecated: onLicense: typeof onLicense; diff --git a/ee/packages/license/src/license.ts b/ee/packages/license/src/license.ts index 8449d4136810..d24d91287d1e 100644 --- a/ee/packages/license/src/license.ts +++ b/ee/packages/license/src/license.ts @@ -4,6 +4,7 @@ import { type ILicenseTag } from './definition/ILicenseTag'; import type { ILicenseV2 } from './definition/ILicenseV2'; import type { ILicenseV3, LicenseLimitKind } from './definition/ILicenseV3'; import type { BehaviorWithContext } from './definition/LicenseBehavior'; +import type { LicenseInfo } from './definition/LicenseInfo'; import type { LicenseModule } from './definition/LicenseModule'; import type { LicenseValidationOptions } from './definition/LicenseValidationOptions'; import type { LimitContext } from './definition/LimitContext'; @@ -291,17 +292,22 @@ export class LicenseManager extends Emitter { return isBehaviorsInResult(validationResult, ['prevent_action']); } - public async getInfo(loadCurrentValues = false): Promise<{ - license: ILicenseV3 | undefined; - activeModules: LicenseModule[]; - limits: Record; - }> { + public async getInfo({ + limits: includeLimits, + currentValues: loadCurrentValues, + license: includeLicense, + }: { + limits: boolean; + currentValues: boolean; + license: boolean; + }): Promise { const activeModules = getModules.call(this); const license = this.getLicense(); // Get all limits present in the license and their current value const limits = ( (license && + includeLimits && (await Promise.all( globalLimitKinds .map((limitKey) => ({ @@ -322,9 +328,10 @@ export class LicenseManager extends Emitter { ).reduce((prev, curr) => ({ ...prev, ...curr }), {}); return { - license, + license: (includeLicense && license) || undefined, activeModules, limits: limits as Record, + tags: license?.information.tags || [], }; } } diff --git a/ee/packages/license/src/token.ts b/ee/packages/license/src/token.ts index 2a9836a48303..46daaef83974 100644 --- a/ee/packages/license/src/token.ts +++ b/ee/packages/license/src/token.ts @@ -7,7 +7,7 @@ import type { ILicenseV3 } from './definition/ILicenseV3'; const PUBLIC_LICENSE_KEY_V2 = 'LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUFxV1Nza2Q5LzZ6Ung4a3lQY2ljcwpiMzJ3Mnd4VnV3N3lCVDk2clEvOEQreU1lQ01POXdTU3BIYS85bkZ5d293RXRpZ3B0L3dyb1BOK1ZHU3didHdQCkZYQmVxRWxCbmRHRkFsODZlNStFbGlIOEt6L2hHbkNtSk5tWHB4RUsyUkUwM1g0SXhzWVg3RERCN010eC9pcXMKY2pCL091dlNCa2ppU2xlUzdibE5JVC9kQTdLNC9DSjNvaXUwMmJMNEV4Y2xDSGVwenFOTWVQM3dVWmdweE9uZgpOT3VkOElYWUs3M3pTY3VFOEUxNTdZd3B6Q0twVmFIWDdaSmY4UXVOc09PNVcvYUlqS2wzTDYyNjkrZUlPRXJHCndPTm1hSG56Zmc5RkxwSmh6Z3BPMzhhVm43NnZENUtLakJhaldza1krNGEyZ1NRbUtOZUZxYXFPb3p5RUZNMGUKY0ZXWlZWWjNMZWg0dkVNb1lWUHlJeng5Nng4ZjIveW1QbmhJdXZRdjV3TjRmeWVwYTdFWTVVQ2NwNzF6OGtmUAo0RmNVelBBMElEV3lNaWhYUi9HNlhnUVFaNEdiL3FCQmh2cnZpSkNGemZZRGNKZ0w3RmVnRllIUDNQR0wwN1FnCnZMZXZNSytpUVpQcnhyYnh5U3FkUE9rZ3VyS2pWclhUVXI0QTlUZ2lMeUlYNVVsSnEzRS9SVjdtZk9xWm5MVGEKU0NWWEhCaHVQbG5DR1pSMDFUb1RDZktoTUcxdTBDRm5MMisxNWhDOWZxT21XdjlRa2U0M3FsSjBQZ0YzVkovWAp1eC9tVHBuazlnbmJHOUpIK21mSDM5Um9GdlROaW5Zd1NNdll6dXRWT242OXNPemR3aERsYTkwbDNBQ2g0eENWCks3Sk9YK3VIa29OdTNnMmlWeGlaVU0wQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo='; -const PUBLIC_LICENSE_KEY_V3 = process.env.PUBLIC_LICENSE_KEY_V3 || PUBLIC_LICENSE_KEY_V2; +const PUBLIC_LICENSE_KEY_V3 = PUBLIC_LICENSE_KEY_V2; let TEST_KEYS: [string, string] | undefined = undefined; diff --git a/ee/packages/presence/src/Presence.ts b/ee/packages/presence/src/Presence.ts index fb656fc3e158..5bd69e1f4fc8 100755 --- a/ee/packages/presence/src/Presence.ts +++ b/ee/packages/presence/src/Presence.ts @@ -19,6 +19,8 @@ export class Presence extends ServiceClass implements IPresence { private connsPerInstance = new Map(); + private peakConnections = 0; + constructor() { super(); @@ -35,6 +37,7 @@ export class Presence extends ServiceClass implements IPresence { if (diff?.hasOwnProperty('extraInformation.conns')) { this.connsPerInstance.set(id, diff['extraInformation.conns']); + this.peakConnections = Math.max(this.peakConnections, this.getTotalConnections()); this.validateAvailability(); } }); @@ -251,4 +254,16 @@ export class Presence extends ServiceClass implements IPresence { private getTotalConnections(): number { return Array.from(this.connsPerInstance.values()).reduce((acc, conns) => acc + conns, 0); } + + getPeakConnections(reset = false): number { + const peak = this.peakConnections; + if (reset) { + this.resetPeakConnections(); + } + return peak; + } + + resetPeakConnections(): void { + this.peakConnections = 0; + } } diff --git a/packages/core-services/src/types/IPresence.ts b/packages/core-services/src/types/IPresence.ts index 197f9b685cf8..5f7c57d67995 100644 --- a/packages/core-services/src/types/IPresence.ts +++ b/packages/core-services/src/types/IPresence.ts @@ -19,4 +19,6 @@ export interface IPresence extends IServiceClass { updateUserPresence(uid: string): Promise; toggleBroadcast(enabled: boolean): void; getConnectionCount(): { current: number; max: number }; + getPeakConnections(reset?: boolean): number; + resetPeakConnections(): void; } diff --git a/packages/core-typings/src/IStats.ts b/packages/core-typings/src/IStats.ts index 443cbfb23957..7fd5cd8218bc 100644 --- a/packages/core-typings/src/IStats.ts +++ b/packages/core-typings/src/IStats.ts @@ -219,6 +219,8 @@ export interface IStats { totalWebRTCCalls: number; uncaughtExceptionsCount: number; push: number; + dailyPeakConnections: number; + maxMonthlyPeakConnections: number; matrixFederation: { enabled: boolean; }; diff --git a/packages/model-typings/src/models/IStatisticsModel.ts b/packages/model-typings/src/models/IStatisticsModel.ts index ac84a49525b3..fe4534eaee0f 100644 --- a/packages/model-typings/src/models/IStatisticsModel.ts +++ b/packages/model-typings/src/models/IStatisticsModel.ts @@ -4,4 +4,5 @@ import type { IBaseModel } from './IBaseModel'; export interface IStatisticsModel extends IBaseModel { findLast(): Promise; + findMonthlyPeakConnections(): Promise | null>; } diff --git a/packages/rest-typings/src/v1/licenses.ts b/packages/rest-typings/src/v1/licenses.ts index 87c0106f6d3f..d229ca49f1fc 100644 --- a/packages/rest-typings/src/v1/licenses.ts +++ b/packages/rest-typings/src/v1/licenses.ts @@ -1,4 +1,4 @@ -import type { ILicenseV2, ILicenseV3, LicenseLimitKind } from '@rocket.chat/license'; +import type { ILicenseV2, ILicenseV3, LicenseInfo } from '@rocket.chat/license'; import Ajv from 'ajv'; const ajv = new Ajv({ @@ -45,11 +45,7 @@ export type LicensesEndpoints = { }; '/v1/licenses.info': { GET: (params: licensesInfoProps) => { - data: { - license: ILicenseV3 | undefined; - activeModules: string[]; - limits: Record; - }; + data: LicenseInfo; }; }; '/v1/licenses.add': { diff --git a/yarn.lock b/yarn.lock index b4e4af200f30..ce6dc859fc3d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -966,33 +966,6 @@ __metadata: languageName: node linkType: hard -"@babel/cli@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/cli@npm:7.23.0" - dependencies: - "@jridgewell/trace-mapping": ^0.3.17 - "@nicolo-ribaudo/chokidar-2": 2.1.8-no-fsevents.3 - chokidar: ^3.4.0 - commander: ^4.0.1 - convert-source-map: ^2.0.0 - fs-readdir-recursive: ^1.1.0 - glob: ^7.2.0 - make-dir: ^2.1.0 - slash: ^2.0.0 - peerDependencies: - "@babel/core": ^7.0.0-0 - dependenciesMeta: - "@nicolo-ribaudo/chokidar-2": - optional: true - chokidar: - optional: true - bin: - babel: ./bin/babel.js - babel-external-helpers: ./bin/babel-external-helpers.js - checksum: beeb189560bf9c4ea951ef637eefa5214654678fb09c4aaa6695921037059c1e1553c610fe95fbd19a9cdfd9f5598a812fc13df40a6b9a9ea899e43fc6c42052 - languageName: node - linkType: hard - "@babel/code-frame@npm:7.12.11": version: 7.12.11 resolution: "@babel/code-frame@npm:7.12.11" @@ -1043,7 +1016,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.1.0, @babel/core@npm:^7.11.6, @babel/core@npm:^7.12.10, @babel/core@npm:^7.12.3, @babel/core@npm:^7.20.7, @babel/core@npm:^7.21.4, @babel/core@npm:^7.23.0, @babel/core@npm:^7.7.5": +"@babel/core@npm:^7.1.0, @babel/core@npm:^7.11.6, @babel/core@npm:^7.12.10, @babel/core@npm:^7.12.3, @babel/core@npm:^7.20.7, @babel/core@npm:^7.21.4, @babel/core@npm:^7.7.5": version: 7.23.0 resolution: "@babel/core@npm:7.23.0" dependencies: @@ -2513,7 +2486,7 @@ __metadata: languageName: node linkType: hard -"@babel/preset-env@npm:^7.12.11, @babel/preset-env@npm:^7.22.20, @babel/preset-env@npm:~7.22.10, @babel/preset-env@npm:~7.22.9": +"@babel/preset-env@npm:^7.12.11, @babel/preset-env@npm:~7.22.10, @babel/preset-env@npm:~7.22.9": version: 7.22.20 resolution: "@babel/preset-env@npm:7.22.20" dependencies: @@ -2645,7 +2618,7 @@ __metadata: languageName: node linkType: hard -"@babel/preset-typescript@npm:^7.12.7, @babel/preset-typescript@npm:^7.23.0": +"@babel/preset-typescript@npm:^7.12.7": version: 7.23.0 resolution: "@babel/preset-typescript@npm:7.23.0" dependencies: @@ -4588,13 +4561,6 @@ __metadata: languageName: node linkType: hard -"@nicolo-ribaudo/chokidar-2@npm:2.1.8-no-fsevents.3": - version: 2.1.8-no-fsevents.3 - resolution: "@nicolo-ribaudo/chokidar-2@npm:2.1.8-no-fsevents.3" - checksum: ee55cc9241aeea7eb94b8a8551bfa4246c56c53bc71ecda0a2104018fcc328ba5723b33686bdf9cc65d4df4ae65e8016b89e0bbdeb94e0309fe91bb9ced42344 - languageName: node - linkType: hard - "@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1": version: 5.1.1-v1 resolution: "@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1" @@ -8474,21 +8440,14 @@ __metadata: version: 0.0.0-use.local resolution: "@rocket.chat/license@workspace:ee/packages/license" dependencies: - "@babel/cli": ^7.23.0 - "@babel/core": ^7.23.0 - "@babel/preset-env": ^7.22.20 - "@babel/preset-typescript": ^7.23.0 "@rocket.chat/core-typings": "workspace:^" "@rocket.chat/jwt": "workspace:^" "@rocket.chat/logger": "workspace:^" "@swc/core": ^1.3.66 "@swc/jest": ^0.2.26 - "@types/babel__core": ^7 - "@types/babel__preset-env": ^7 "@types/bcrypt": ^5.0.0 "@types/jest": ~29.5.3 "@types/ws": ^8.5.5 - babel-plugin-transform-inline-environment-variables: ^0.4.4 bcrypt: ^5.0.1 eslint: ~8.45.0 jest: ~29.6.1 @@ -15433,13 +15392,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-transform-inline-environment-variables@npm:^0.4.4": - version: 0.4.4 - resolution: "babel-plugin-transform-inline-environment-variables@npm:0.4.4" - checksum: fa361287411301237fd8ce332aff4f8e8ccb8db30e87a2ddc7224c8bf7cd792eda47aca24dc2e09e70bce4c027bc8cbe22f4999056be37a25d2472945df21ef5 - languageName: node - linkType: hard - "babel-polyfill@npm:^6.2.0": version: 6.26.0 resolution: "babel-polyfill@npm:6.26.0" @@ -16964,7 +16916,7 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:3.5.3, chokidar@npm:>=3.0.0 <4.0.0, chokidar@npm:^3.4.0, chokidar@npm:^3.4.1, chokidar@npm:^3.4.2, chokidar@npm:^3.5.1, chokidar@npm:^3.5.3": +"chokidar@npm:3.5.3, chokidar@npm:>=3.0.0 <4.0.0, chokidar@npm:^3.4.1, chokidar@npm:^3.4.2, chokidar@npm:^3.5.1, chokidar@npm:^3.5.3": version: 3.5.3 resolution: "chokidar@npm:3.5.3" dependencies: @@ -17513,7 +17465,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:^4.0.0, commander@npm:^4.0.1, commander@npm:^4.1.1": +"commander@npm:^4.0.0, commander@npm:^4.1.1": version: 4.1.1 resolution: "commander@npm:4.1.1" checksum: d7b9913ff92cae20cb577a4ac6fcc121bd6223319e54a40f51a14740a681ad5c574fd29a57da478a5f234a6fa6c52cbf0b7c641353e03c648b1ae85ba670b977 @@ -22120,13 +22072,6 @@ __metadata: languageName: node linkType: hard -"fs-readdir-recursive@npm:^1.1.0": - version: 1.1.0 - resolution: "fs-readdir-recursive@npm:1.1.0" - checksum: 29d50f3d2128391c7fc9fd051c8b7ea45bcc8aa84daf31ef52b17218e20bfd2bd34d02382742801954cc8d1905832b68227f6b680a666ce525d8b6b75068ad1e - languageName: node - linkType: hard - "fs-write-stream-atomic@npm:^1.0.8": version: 1.0.10 resolution: "fs-write-stream-atomic@npm:1.0.10"