apps/meteor/app/lib/server/functions/checkUsernameAvailability.ts
import { Team } from '@rocket.chat/core-services';
import { Users } from '@rocket.chat/models';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { Meteor } from 'meteor/meteor';
import _ from 'underscore';
import { settings } from '../../../settings/server';
import { validateName } from './validateName';
let usernameBlackList: RegExp[] = [];
const toRegExp = (username: string): RegExp => new RegExp(`^${escapeRegExp(username).trim()}$`, 'i');
settings.watch('Accounts_BlockedUsernameList', (value: string) => {
usernameBlackList = ['all', 'here'].concat(value.split(',')).map(toRegExp);
});
const usernameIsBlocked = (username: string, usernameBlackList: RegExp[]): boolean | number =>
usernameBlackList.length && usernameBlackList.some((restrictedUsername) => restrictedUsername.test(escapeRegExp(username).trim()));
export const checkUsernameAvailabilityWithValidation = async function (userId: string, username: string): Promise<boolean> {
if (!username) {
throw new Meteor.Error('error-invalid-username', 'Invalid username', { method: 'setUsername' });
}
const user = await Users.findOneById(userId, { projection: { username: 1 } });
if (!user) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'setUsername' });
}
if (user.username && !settings.get('Accounts_AllowUsernameChange')) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'setUsername' });
}
if (user.username === username) {
return true;
}
return checkUsernameAvailability(username);
};
export const checkUsernameAvailability = async function (username: string): Promise<boolean> {
if (usernameIsBlocked(username, usernameBlackList) || !validateName(username)) {
throw new Meteor.Error('error-blocked-username', `${_.escape(username)} is blocked and can't be used!`, {
method: 'checkUsernameAvailability',
field: username,
});
}
// Make sure no users are using this username
const existingUser = await Users.findOneByUsernameIgnoringCase(username, {
projection: { _id: 1 },
});
if (existingUser) {
return false;
}
// Make sure no teams are using this username
const existingTeam = await Team.getOneByName(toRegExp(username), { projection: { _id: 1 } });
if (existingTeam) {
return false;
}
return true;
};