-
Notifications
You must be signed in to change notification settings - Fork 7.1k
/
users.ts
135 lines (111 loc) · 3.97 KB
/
users.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import Container from 'typedi';
import { hash } from 'bcryptjs';
import { AuthIdentity } from '@db/entities/AuthIdentity';
import type { GlobalRole, User } from '@db/entities/User';
import { AuthIdentityRepository } from '@db/repositories/authIdentity.repository';
import { UserRepository } from '@db/repositories/user.repository';
import { TOTPService } from '@/Mfa/totp.service';
import { MfaService } from '@/Mfa/mfa.service';
import { randomApiKey, randomEmail, randomName, randomValidPassword } from '../random';
// pre-computed bcrypt hash for the string 'password', using `await hash('password', 10)`
const passwordHash = '$2a$10$njedH7S6V5898mj6p0Jr..IGY9Ms.qNwR7RbSzzX9yubJocKfvGGK';
/** Store a new user object, defaulting to a `member` */
export async function newUser(attributes: Partial<User> = {}): Promise<User> {
const { email, password, firstName, lastName, role, ...rest } = attributes;
return Container.get(UserRepository).create({
email: email ?? randomEmail(),
password: password ? await hash(password, 1) : passwordHash,
firstName: firstName ?? randomName(),
lastName: lastName ?? randomName(),
role: role ?? 'global:member',
...rest,
});
}
/** Store a user object in the DB */
export async function createUser(attributes: Partial<User> = {}): Promise<User> {
const user = await newUser(attributes);
user.computeIsOwner();
return await Container.get(UserRepository).save(user);
}
export async function createLdapUser(attributes: Partial<User>, ldapId: string): Promise<User> {
const user = await createUser(attributes);
await Container.get(AuthIdentityRepository).save(AuthIdentity.create(user, ldapId, 'ldap'));
return user;
}
export async function createUserWithMfaEnabled(
data: { numberOfRecoveryCodes: number } = { numberOfRecoveryCodes: 10 },
) {
const email = randomEmail();
const password = randomValidPassword();
const toptService = new TOTPService();
const secret = toptService.generateSecret();
const mfaService = Container.get(MfaService);
const recoveryCodes = mfaService.generateRecoveryCodes(data.numberOfRecoveryCodes);
const { encryptedSecret, encryptedRecoveryCodes } = mfaService.encryptSecretAndRecoveryCodes(
secret,
recoveryCodes,
);
return {
user: await createUser({
mfaEnabled: true,
password,
email,
mfaSecret: encryptedSecret,
mfaRecoveryCodes: encryptedRecoveryCodes,
}),
rawPassword: password,
rawSecret: secret,
rawRecoveryCodes: recoveryCodes,
};
}
export async function createOwner() {
return await createUser({ role: 'global:owner' });
}
export async function createMember() {
return await createUser({ role: 'global:member' });
}
export async function createAdmin() {
return await createUser({ role: 'global:admin' });
}
export async function createUserShell(role: GlobalRole): Promise<User> {
const shell: Partial<User> = { role };
if (role !== 'global:owner') {
shell.email = randomEmail();
}
return await Container.get(UserRepository).save(shell);
}
/**
* Create many users in the DB, defaulting to a `member`.
*/
export async function createManyUsers(
amount: number,
attributes: Partial<User> = {},
): Promise<User[]> {
const users = await Promise.all(
Array(amount)
.fill(0)
.map(async () => await newUser(attributes)),
);
return await Container.get(UserRepository).save(users);
}
export async function addApiKey(user: User): Promise<User> {
user.apiKey = randomApiKey();
return await Container.get(UserRepository).save(user);
}
export const getAllUsers = async () =>
await Container.get(UserRepository).find({
relations: ['authIdentities'],
});
export const getUserById = async (id: string) =>
await Container.get(UserRepository).findOneOrFail({
where: { id },
relations: ['authIdentities'],
});
export const getLdapIdentities = async () =>
await Container.get(AuthIdentityRepository).find({
where: { providerType: 'ldap' },
relations: ['user'],
});
export async function getGlobalOwner() {
return await Container.get(UserRepository).findOneByOrFail({ role: 'global:owner' });
}