RocketChat/Rocket.Chat

View on GitHub
ee/packages/license/src/validation/validateLimits.ts

Summary

Maintainability
A
1 hr
Test Coverage
import type { ILicenseV3, LicenseLimitKind, BehaviorWithContext, LicenseValidationOptions } from '@rocket.chat/core-typings';

import { isLimitAllowed, isBehaviorAllowed } from '../isItemAllowed';
import type { LicenseManager } from '../license';
import { logger } from '../logger';
import { getCurrentValueForLicenseLimit } from './getCurrentValueForLicenseLimit';
import { getResultingBehavior } from './getResultingBehavior';
import { logKind } from './logKind';
import { validateLimit } from './validateLimit';

export async function validateLimits(
    this: LicenseManager,
    limits: ILicenseV3['limits'],
    options: LicenseValidationOptions,
): Promise<BehaviorWithContext[]> {
    const limitKeys = (Object.keys(limits) as LicenseLimitKind[]).filter((limit) => isLimitAllowed(limit, options));
    return (
        await Promise.all(
            limitKeys.map(async (limitKey) => {
                // Filter the limit list before running any query in the database so we don't end up loading some value we won't use.
                const limitList = limits[limitKey]?.filter(({ behavior, max }) => max >= 0 && isBehaviorAllowed(behavior, options));
                if (!limitList?.length) {
                    return [];
                }

                const extraCount = options.context?.[limitKey]?.extraCount ?? 0;
                const currentValue = (await getCurrentValueForLicenseLimit.call(this, limitKey, options.context?.[limitKey])) + extraCount;

                return limitList
                    .filter(({ max, behavior }) => validateLimit(max, currentValue, behavior, extraCount))
                    .map((limit) => {
                        if (!options.suppressLog) {
                            switch (logKind(limit.behavior)) {
                                case 'error':
                                    logger.error({
                                        msg: 'Limit validation failed',
                                        kind: limitKey,
                                        limit,
                                    });
                                    break;
                                case 'info':
                                    logger.info({
                                        msg: 'Limit validation failed',
                                        kind: limitKey,
                                        limit,
                                    });
                                    break;
                            }
                        }
                        return getResultingBehavior(limit, { reason: 'limit', limit: limitKey });
                    });
            }),
        )
    ).flat();
}