RocketChat/Rocket.Chat

View on GitHub
apps/meteor/imports/personal-access-tokens/server/api/methods/generateToken.ts

Summary

Maintainability
A
0 mins
Test Coverage
import { Meteor } from 'meteor/meteor';
import { Random } from '@rocket.chat/random';
import { Accounts } from 'meteor/accounts-base';
import type { ServerMethods } from '@rocket.chat/ddp-client';
import { Users } from '@rocket.chat/models';

import { hasPermissionAsync } from '../../../../../app/authorization/server/functions/hasPermission';
import { twoFactorRequired } from '../../../../../app/2fa/server/twoFactorRequired';

declare module '@rocket.chat/ddp-client' {
    // eslint-disable-next-line @typescript-eslint/naming-convention
    interface ServerMethods {
        'personalAccessTokens:generateToken'(params: { tokenName: string; bypassTwoFactor: boolean }): Promise<string>;
    }
}

Meteor.methods<ServerMethods>({
    'personalAccessTokens:generateToken': twoFactorRequired(async function ({ tokenName, bypassTwoFactor }) {
        const uid = Meteor.userId();
        if (!uid) {
            throw new Meteor.Error('not-authorized', 'Not Authorized', {
                method: 'personalAccessTokens:generateToken',
            });
        }
        if (!(await hasPermissionAsync(uid, 'create-personal-access-tokens'))) {
            throw new Meteor.Error('not-authorized', 'Not Authorized', {
                method: 'personalAccessTokens:generateToken',
            });
        }

        const token = Random.secret();
        const tokenExist = await Users.findPersonalAccessTokenByTokenNameAndUserId({
            userId: uid,
            tokenName,
        });
        if (tokenExist) {
            throw new Meteor.Error('error-token-already-exists', 'A token with this name already exists', {
                method: 'personalAccessTokens:generateToken',
            });
        }

        await Users.addPersonalAccessTokenToUser({
            userId: uid,
            loginTokenObject: {
                hashedToken: Accounts._hashLoginToken(token),
                type: 'personalAccessToken',
                createdAt: new Date(),
                lastTokenPart: token.slice(-6),
                name: tokenName,
                bypassTwoFactor,
            },
        });
        return token;
    }),
});