@volcanicminds/typeorm 2.2.11 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,19 @@
1
1
  /* eslint-disable no-useless-catch */
2
2
  /* eslint-disable @typescript-eslint/no-explicit-any */
3
3
  import * as Crypto from 'crypto'
4
+ import { QueryRunner } from 'typeorm'
4
5
  import { ServiceError } from '../util/error.js'
5
6
  import { executeCountQuery, executeFindQuery } from '../query.js'
6
7
 
8
+ /**
9
+ * Returns the appropriate token repository.
10
+ * If a runner is provided (multi-tenant context), uses the runner's manager.
11
+ * Otherwise falls back to the global repository (single-tenant/default).
12
+ */
13
+ function getTokenRepo(runner?: QueryRunner) {
14
+ return runner ? runner.manager.getRepository(global.entity.Token) : global.repository.tokens
15
+ }
16
+
7
17
  export function isImplemented() {
8
18
  return true
9
19
  }
@@ -12,7 +22,7 @@ export async function isValidToken(data: typeof global.entity.Token) {
12
22
  return !!data && (!!data._id || !!data.id) && !!data.externalId && !!data.name
13
23
  }
14
24
 
15
- export async function createToken(data: typeof global.entity.Token) {
25
+ export async function createToken(data: typeof global.entity.Token, runner?: QueryRunner) {
16
26
  const { name, description } = data
17
27
 
18
28
  if (!name) {
@@ -20,14 +30,14 @@ export async function createToken(data: typeof global.entity.Token) {
20
30
  }
21
31
 
22
32
  try {
33
+ const repo = getTokenRepo(runner)
23
34
  let externalId, token
24
35
  do {
25
36
  externalId = Crypto.randomUUID({ disableEntropyCache: true })
26
-
27
- token = await global.repository.tokens.findOneBy({ externalId: externalId })
37
+ token = await repo.findOneBy({ externalId: externalId })
28
38
  } while (token != null)
29
39
 
30
- token = await global.entity.Token.create({
40
+ const newToken = repo.create({
31
41
  ...data,
32
42
  name: name,
33
43
  description: description,
@@ -36,94 +46,95 @@ export async function createToken(data: typeof global.entity.Token) {
36
46
  externalId: externalId
37
47
  } as typeof global.entity.Token)
38
48
 
39
- return await global.entity.Token.save(token)
49
+ return repo.save(newToken)
40
50
  } catch (error) {
41
51
  throw error
42
52
  }
43
53
  }
44
54
 
45
- export async function resetExternalId(id: string) {
55
+ export async function resetExternalId(id: string, runner?: QueryRunner) {
46
56
  if (!id) {
47
57
  throw new ServiceError('Invalid parameters', 400)
48
58
  }
49
59
 
50
60
  try {
61
+ const repo = getTokenRepo(runner)
51
62
  let externalId, token
52
63
  do {
53
64
  externalId = Crypto.randomUUID({ disableEntropyCache: true })
54
- token = await global.repository.tokens.findOneBy({ externalId: externalId })
65
+ token = await repo.findOneBy({ externalId: externalId })
55
66
  } while (token != null)
56
67
 
57
- // TODO: use externalId instead id
58
- return await updateTokenById(id, { externalId: externalId })
68
+ return await updateTokenById(id, { externalId: externalId }, runner)
59
69
  } catch (error) {
60
70
  if (error?.code == 23505) {
61
- throw new Error('External ID not changed')
71
+ throw new ServiceError('External ID not changed', 409)
62
72
  }
63
73
  throw error
64
74
  }
65
75
  }
66
76
 
67
- export async function updateTokenById(id: string, token: typeof global.entity.Token) {
77
+ export async function updateTokenById(id: string, token: typeof global.entity.Token, runner?: QueryRunner) {
68
78
  if (!id || !token) {
69
79
  throw new ServiceError('Invalid parameters', 400)
70
80
  }
71
81
  try {
72
- const tokenEx = await global.repository.tokens.findOneById(id)
82
+ const repo = getTokenRepo(runner)
83
+ const tokenEx = await repo.findOneBy({ id: id })
73
84
  if (!tokenEx) {
74
85
  throw new ServiceError('Token not found', 404)
75
86
  }
76
- const merged = global.repository.tokens.merge(tokenEx, token)
77
- return await global.entity.Token.save(merged)
87
+ const merged = repo.merge(tokenEx, token)
88
+ return repo.save(merged)
78
89
  } catch (error) {
79
90
  throw error
80
91
  }
81
92
  }
82
93
 
83
- export async function retrieveTokenById(id: string) {
94
+ export async function retrieveTokenById(id: string, runner?: QueryRunner) {
84
95
  if (!id) {
85
96
  throw new ServiceError('Invalid parameters', 400)
86
97
  }
87
98
  try {
88
- return await global.repository.tokens.findOneById(id)
99
+ return await getTokenRepo(runner).findOneBy({ id: id })
89
100
  } catch (error) {
90
101
  throw error
91
102
  }
92
103
  }
93
104
 
94
- export async function retrieveTokenByExternalId(externalId: string) {
105
+ export async function retrieveTokenByExternalId(externalId: string, runner?: QueryRunner) {
95
106
  if (!externalId) {
96
107
  throw new ServiceError('Invalid parameters', 400)
97
108
  }
98
109
  try {
99
- return await global.repository.tokens.findOneBy({ externalId: externalId })
110
+ return await getTokenRepo(runner).findOneBy({ externalId: externalId })
100
111
  } catch (error) {
101
112
  throw error
102
113
  }
103
114
  }
104
115
 
105
- export async function blockTokenById(id: string, reason: string) {
106
- return updateTokenById(id, { blocked: true, blockedAt: new Date(), blockedReason: reason })
116
+ export async function blockTokenById(id: string, reason: string, runner?: QueryRunner) {
117
+ return updateTokenById(id, { blocked: true, blockedAt: new Date(), blockedReason: reason }, runner)
107
118
  }
108
119
 
109
- export async function unblockTokenById(id: string) {
110
- return updateTokenById(id, { blocked: false, blockedAt: new Date(), blockedReason: null })
120
+ export async function unblockTokenById(id: string, runner?: QueryRunner) {
121
+ return updateTokenById(id, { blocked: false, blockedAt: new Date(), blockedReason: null }, runner)
111
122
  }
112
123
 
113
- export async function countQuery(data: any) {
114
- return await executeCountQuery(global.repository.tokens, data, {})
124
+ export async function countQuery(data: any, runner?: QueryRunner) {
125
+ return await executeCountQuery(getTokenRepo(runner), data, {})
115
126
  }
116
127
 
117
- export async function findQuery(data: any) {
118
- return await executeFindQuery(global.repository.tokens, {}, data)
128
+ export async function findQuery(data: any, runner?: QueryRunner) {
129
+ return await executeFindQuery(getTokenRepo(runner), {}, data)
119
130
  }
120
131
 
121
- export async function removeTokenById(id: string) {
132
+ export async function removeTokenById(id: string, runner?: QueryRunner) {
122
133
  if (!id) {
123
134
  throw new ServiceError('Invalid parameters', 400)
124
135
  }
125
136
  try {
126
- return await global.repository.tokens.delete(id)
137
+ return await getTokenRepo(runner).delete(id)
127
138
  } catch (error) {
128
139
  throw error
129
140
  }
@@ -2,10 +2,20 @@
2
2
  /* eslint-disable @typescript-eslint/no-explicit-any */
3
3
  import * as bcrypt from 'bcrypt'
4
4
  import * as Crypto from 'crypto'
5
+ import { QueryRunner } from 'typeorm'
5
6
  import { ServiceError } from '../util/error.js'
6
7
  import { executeCountQuery, executeFindQuery } from '../query.js'
7
8
  import { encrypt, decrypt } from '../util/crypto.js'
8
9
 
10
+ /**
11
+ * Returns the appropriate user repository.
12
+ * If a runner is provided (multi-tenant context), uses the runner's manager.
13
+ * Otherwise falls back to the global repository (single-tenant/default).
14
+ */
15
+ function getUserRepo(runner?: QueryRunner) {
16
+ return runner ? runner.manager.getRepository(global.entity.User) : global.repository.users
17
+ }
18
+
9
19
  export function isImplemented() {
10
20
  return true
11
21
  }
@@ -14,7 +24,7 @@ export async function isValidUser(data: typeof global.entity.User) {
14
24
  return !!data && (!!data._id || !!data.id) && !!data.externalId && !!data.email && !!data.password
15
25
  }
16
26
 
17
- export async function createUser(data: typeof global.entity.User) {
27
+ export async function createUser(data: typeof global.entity.User, runner?: QueryRunner) {
18
28
  const { username, email, password } = data
19
29
 
20
30
  if (!email || !password) {
@@ -25,14 +35,15 @@ export async function createUser(data: typeof global.entity.User) {
25
35
  const hashedPassword = await bcrypt.hash(password, salt)
26
36
 
27
37
  try {
38
+ const repo = getUserRepo(runner)
28
39
  let externalId, user
29
40
  do {
30
41
  externalId = Crypto.randomUUID({ disableEntropyCache: true })
31
42
 
32
- user = await global.repository.users.findOneBy({ externalId: externalId })
43
+ user = await repo.findOneBy({ externalId: externalId })
33
44
  } while (user != null)
34
45
 
35
- user = await global.entity.User.create({
46
+ const newUser = repo.create({
36
47
  ...data,
37
48
  passwordChangedAt: new Date(),
38
49
  confirmed: false,
@@ -49,7 +60,7 @@ export async function createUser(data: typeof global.entity.User) {
49
60
  mfaRecoveryCodes: []
50
61
  } as typeof global.entity.User)
51
62
 
52
- return await global.entity.User.save(user)
63
+ return getUserRepo(runner).save(newUser)
53
64
  } catch (error) {
54
65
  if (error?.code == 23505) {
55
66
  throw new ServiceError('Email or username already registered', 409)
@@ -58,24 +69,24 @@ export async function createUser(data: typeof global.entity.User) {
58
69
  }
59
70
  }
60
71
 
61
- export async function deleteUser(id: string) {
72
+ export async function deleteUser(id: string, runner?: QueryRunner) {
62
73
  if (!id) {
63
74
  throw new ServiceError('Invalid parameters', 400)
64
75
  }
65
76
 
66
77
  try {
67
- const userEx = await retrieveUserById(id)
78
+ const userEx = await retrieveUserById(id, runner)
68
79
  if (!userEx) {
69
80
  throw new ServiceError('User not found', 404)
70
81
  }
71
82
 
72
- return global.entity.User.delete(id)
83
+ return getUserRepo(runner).delete(id)
73
84
  } catch (error) {
74
85
  throw error
75
86
  }
76
87
  }
77
88
 
78
- export async function resetExternalId(id: string) {
89
+ export async function resetExternalId(id: string, runner?: QueryRunner) {
79
90
  if (!id) {
80
91
  throw new ServiceError('Invalid parameters', 400)
81
92
  }
@@ -84,10 +95,10 @@ export async function resetExternalId(id: string) {
84
95
  let externalId, user
85
96
  do {
86
97
  externalId = Crypto.randomUUID({ disableEntropyCache: true })
87
- user = await global.repository.users.findOneBy({ externalId: externalId })
98
+ user = await getUserRepo(runner).findOneBy({ externalId: externalId })
88
99
  } while (user != null)
89
100
 
90
- return await updateUserById(id, { externalId: externalId })
101
+ return await updateUserById(id, { externalId: externalId }, runner)
91
102
  } catch (error) {
92
103
  if (error?.code == 23505) {
93
104
  throw new ServiceError('External ID not changed', 409)
@@ -96,83 +107,84 @@ export async function resetExternalId(id: string) {
96
107
  }
97
108
  }
98
109
 
99
- export async function updateUserById(id: string, user: typeof global.entity.User) {
110
+ export async function updateUserById(id: string, user: typeof global.entity.User, runner?: QueryRunner) {
100
111
  if (!id || !user) {
101
112
  throw new ServiceError('Invalid parameters', 400)
102
113
  }
103
114
  try {
104
- const userEx = await retrieveUserById(id)
115
+ const repo = getUserRepo(runner)
116
+ const userEx = await retrieveUserById(id, runner)
105
117
  if (!userEx) {
106
118
  throw new ServiceError('User not found', 404)
107
119
  }
108
- const merged = global.repository.users.merge(userEx, user)
109
- return await global.entity.User.save(merged)
120
+ const merged = repo.merge(userEx, user)
121
+ return repo.save(merged)
110
122
  } catch (error) {
111
123
  throw error
112
124
  }
113
125
  }
114
126
 
115
- export async function retrieveUserById(id: string) {
127
+ export async function retrieveUserById(id: string, runner?: QueryRunner) {
116
128
  if (!id) {
117
129
  throw new ServiceError('Invalid parameters', 400)
118
130
  }
119
131
  try {
120
- return await global.repository.users.findOneById(id)
132
+ return await getUserRepo(runner).findOneBy({ id: id })
121
133
  } catch (error) {
122
134
  throw error
123
135
  }
124
136
  }
125
137
 
126
- export async function retrieveUserByEmail(email: string) {
138
+ export async function retrieveUserByEmail(email: string, runner?: QueryRunner) {
127
139
  if (!email) {
128
140
  throw new ServiceError('Invalid parameters', 400)
129
141
  }
130
142
  try {
131
- return await global.repository.users.findOneBy({ email: email })
143
+ return await getUserRepo(runner).findOneBy({ email: email })
132
144
  } catch (error) {
133
145
  throw error
134
146
  }
135
147
  }
136
148
 
137
- export async function retrieveUserByUsername(username: string) {
149
+ export async function retrieveUserByUsername(username: string, runner?: QueryRunner) {
138
150
  if (!username) {
139
151
  throw new ServiceError('Invalid parameters', 400)
140
152
  }
141
153
  try {
142
- return await global.repository.users.findOneBy({ username })
154
+ return await getUserRepo(runner).findOneBy({ username })
143
155
  } catch (error) {
144
156
  throw error
145
157
  }
146
158
  }
147
159
 
148
- export async function retrieveUserByConfirmationToken(code: string) {
160
+ export async function retrieveUserByConfirmationToken(code: string, runner?: QueryRunner) {
149
161
  if (!code) {
150
162
  throw new ServiceError('Invalid parameters', 400)
151
163
  }
152
164
  try {
153
- return await global.repository.users.findOneBy({ confirmationToken: code })
165
+ return await getUserRepo(runner).findOneBy({ confirmationToken: code })
154
166
  } catch (error) {
155
167
  throw error
156
168
  }
157
169
  }
158
170
 
159
- export async function retrieveUserByResetPasswordToken(code: string) {
171
+ export async function retrieveUserByResetPasswordToken(code: string, runner?: QueryRunner) {
160
172
  if (!code) {
161
173
  throw new ServiceError('Invalid parameters', 400)
162
174
  }
163
175
  try {
164
- return await global.repository.users.findOneBy({ resetPasswordToken: code })
176
+ return await getUserRepo(runner).findOneBy({ resetPasswordToken: code })
165
177
  } catch (error) {
166
178
  throw error
167
179
  }
168
180
  }
169
181
 
170
- export async function retrieveUserByExternalId(externalId: string) {
182
+ export async function retrieveUserByExternalId(externalId: string, runner?: QueryRunner) {
171
183
  if (!externalId) {
172
184
  throw new ServiceError('Invalid parameters', 400)
173
185
  }
174
186
  try {
175
- return await global.repository.users.findOne({
187
+ return await getUserRepo(runner).findOne({
176
188
  where: { externalId: externalId },
177
189
  cache: global.cacheTimeout
178
190
  })
@@ -181,12 +193,12 @@ export async function retrieveUserByExternalId(externalId: string) {
181
193
  }
182
194
  }
183
195
 
184
- export async function retrieveUserByPassword(email: string, password: string) {
196
+ export async function retrieveUserByPassword(email: string, password: string, runner?: QueryRunner) {
185
197
  if (!email || !password) {
186
198
  throw new ServiceError('Invalid parameters', 400)
187
199
  }
188
200
  try {
189
- const user = await global.repository.users.findOneBy({ email: email })
201
+ const user = await getUserRepo(runner).findOneBy({ email: email })
190
202
  if (!user) {
191
203
  throw new Error('Wrong credentials')
192
204
  }
@@ -197,17 +209,18 @@ export async function retrieveUserByPassword(email: string, password: string) {
197
209
  }
198
210
  }
199
211
 
200
- export async function changePassword(email: string, password: string, oldPassword: string) {
212
+ export async function changePassword(email: string, password: string, oldPassword: string, runner?: QueryRunner) {
201
213
  if (!email || !password || !oldPassword) {
202
214
  throw new ServiceError('Invalid parameters', 400)
203
215
  }
204
216
  try {
205
- const user = await global.repository.users.findOneBy({ email: email })
217
+ const repo = getUserRepo(runner)
218
+ const user = await repo.findOneBy({ email: email })
206
219
  const match = await bcrypt.compare(oldPassword, user.password)
207
220
  if (match) {
208
221
  const salt = await bcrypt.genSalt(12)
209
222
  const hashedPassword = await bcrypt.hash(password, salt)
210
- return await global.entity.User.save({ ...user, passwordChangedAt: new Date(), password: hashedPassword })
223
+ return repo.save({ ...user, passwordChangedAt: new Date(), password: hashedPassword })
211
224
  }
212
225
  throw new ServiceError('Password not changed', 400)
213
226
  } catch (error) {
@@ -215,15 +228,16 @@ export async function changePassword(email: string, password: string, oldPasswor
215
228
  }
216
229
  }
217
230
 
218
- export async function forgotPassword(email: string) {
231
+ export async function forgotPassword(email: string, runner?: QueryRunner) {
219
232
  if (!email) {
220
233
  throw new ServiceError('Invalid parameters', 400)
221
234
  }
222
235
  try {
223
- const user = await global.repository.users.findOneBy({ email: email })
236
+ const repo = getUserRepo(runner)
237
+ const user = await repo.findOneBy({ email: email })
224
238
 
225
239
  if (user) {
226
- return await global.entity.User.save({
240
+ return repo.save({
227
241
  ...user,
228
242
  resetPasswordTokenAt: new Date(),
229
243
  resetPasswordToken: Crypto.randomBytes(64).toString('hex')
@@ -235,19 +249,20 @@ export async function forgotPassword(email: string) {
235
249
  }
236
250
  }
237
251
 
238
- export async function resetPassword(user: typeof global.entity.User, password: string) {
252
+ export async function resetPassword(user: typeof global.entity.User, password: string, runner?: QueryRunner) {
239
253
  if (!user || !password || !user?.email) {
240
254
  throw new ServiceError('Invalid parameters', 400)
241
255
  }
242
256
  try {
243
- const userEx = await global.repository.users.findOneBy({ email: user.email })
257
+ const repo = getUserRepo(runner)
258
+ const userEx = await repo.findOneBy({ email: user.email })
244
259
  if (!userEx) {
245
260
  throw new Error('Wrong credentials')
246
261
  }
247
262
 
248
263
  const salt = await bcrypt.genSalt(12)
249
264
  const hashedPassword = await bcrypt.hash(password, salt)
250
- return await global.entity.User.save({
265
+ return repo.save({
251
266
  ...userEx,
252
267
  passwordChangedAt: new Date(),
253
268
  confirmed: true,
@@ -260,23 +275,23 @@ export async function resetPassword(user: typeof global.entity.User, password: s
260
275
  }
261
276
  }
262
277
 
263
- export async function userConfirmation(user: typeof global.entity.User) {
278
+ export async function userConfirmation(user: typeof global.entity.User, runner?: QueryRunner) {
264
279
  if (!user) {
265
280
  throw new ServiceError('Invalid parameters', 400)
266
281
  }
267
282
  try {
268
- return await global.entity.User.save({ ...user, confirmed: true, confirmedAt: new Date(), confirmationToken: null })
283
+ return getUserRepo(runner).save({ ...user, confirmed: true, confirmedAt: new Date(), confirmationToken: null })
269
284
  } catch (error) {
270
285
  throw error
271
286
  }
272
287
  }
273
288
 
274
- export async function blockUserById(id: string, reason: string) {
275
- return updateUserById(id, { blocked: true, blockedAt: new Date(), blockedReason: reason })
289
+ export async function blockUserById(id: string, reason: string, runner?: QueryRunner) {
290
+ return updateUserById(id, { blocked: true, blockedAt: new Date(), blockedReason: reason }, runner)
276
291
  }
277
292
 
278
- export async function unblockUserById(id: string) {
279
- return updateUserById(id, { blocked: false, blockedAt: new Date(), blockedReason: null })
293
+ export async function unblockUserById(id: string, runner?: QueryRunner) {
294
+ return updateUserById(id, { blocked: false, blockedAt: new Date(), blockedReason: null }, runner)
280
295
  }
281
296
 
282
297
  export function isPasswordToBeChanged(user: typeof global.entity.User) {
@@ -302,38 +317,46 @@ export function isPasswordToBeChanged(user: typeof global.entity.User) {
302
317
  return false
303
318
  }
304
319
 
305
- export async function countQuery(data: any) {
306
- return await executeCountQuery(global.repository.users, data)
320
+ export async function countQuery(data: any, runner?: QueryRunner) {
321
+ return await executeCountQuery(getUserRepo(runner), data)
307
322
  }
308
323
 
309
- export async function findQuery(data: any) {
310
- return await executeFindQuery(global.repository.users, {}, data)
324
+ export async function findQuery(data: any, runner?: QueryRunner) {
325
+ return await executeFindQuery(getUserRepo(runner), {}, data)
311
326
  }
312
327
 
313
- export async function disableUserById(id: string) {
314
- await updateUserById(id, { blocked: true, blockedAt: new Date(), blockedReason: 'User disabled to unregister' })
315
- return resetExternalId(id)
328
+ export async function disableUserById(id: string, runner?: QueryRunner) {
329
+ await updateUserById(
330
+ id,
331
+ { blocked: true, blockedAt: new Date(), blockedReason: 'User disabled to unregister' },
332
+ runner
333
+ )
334
+ return resetExternalId(id, runner)
316
335
  }
317
336
 
318
337
  // MFA Persistence Methods
319
338
 
320
- export async function saveMfaSecret(userId: string, secret: string) {
339
+ export async function saveMfaSecret(userId: string, secret: string, runner?: QueryRunner) {
321
340
  if (!userId || !secret) {
322
341
  throw new ServiceError('Invalid parameters', 400)
323
342
  }
324
343
  const encryptedSecret = encrypt(secret)
325
344
 
326
- await updateUserById(userId, {
327
- mfaSecret: encryptedSecret,
328
- mfaType: 'TOTP'
329
- })
345
+ await updateUserById(
346
+ userId,
347
+ {
348
+ mfaSecret: encryptedSecret,
349
+ mfaType: 'TOTP'
350
+ },
351
+ runner
352
+ )
330
353
  return true
331
354
  }
332
355
 
333
- export async function retrieveMfaSecret(userId: string) {
356
+ export async function retrieveMfaSecret(userId: string, runner?: QueryRunner) {
334
357
  if (!userId) throw new ServiceError('Invalid parameters', 400)
335
358
 
336
- const user = await global.repository.users
359
+ const user = await getUserRepo(runner)
337
360
  .createQueryBuilder('user')
338
361
  .addSelect('user.mfaSecret')
339
362
  .where('user.id = :id', { id: userId })
@@ -344,22 +367,20 @@ export async function retrieveMfaSecret(userId: string) {
344
367
  return decrypt(user.mfaSecret)
345
368
  }
346
369
 
347
- export async function enableMfa(userId: string) {
370
+ export async function enableMfa(userId: string, runner?: QueryRunner) {
348
371
  if (!userId) throw new ServiceError('Invalid parameters', 400)
349
- return await updateUserById(userId, { mfaEnabled: true })
372
+ return await updateUserById(userId, { mfaEnabled: true }, runner)
350
373
  }
351
374
 
352
- export async function disableMfa(userId: string) {
375
+ export async function disableMfa(userId: string, runner?: QueryRunner) {
353
376
  if (!userId) throw new ServiceError('Invalid parameters', 400)
354
- return await updateUserById(userId, { mfaEnabled: false, mfaSecret: null, mfaRecoveryCodes: [] })
377
+ return await updateUserById(userId, { mfaEnabled: false, mfaSecret: null, mfaRecoveryCodes: [] }, runner)
355
378
  }
356
379
 
357
- export async function forceDisableMfaForAdmin(email: string) {
380
+ export async function forceDisableMfaForAdmin(email: string, runner?: QueryRunner) {
358
381
  if (!email) return false
359
382
 
360
- const userRepo = global.repository.users
361
-
362
- const user = await userRepo.findOneBy({ email: email })
383
+ const user = await getUserRepo(runner).findOneBy({ email: email })
363
384
  if (!user) {
364
385
  return false
365
386
  }
@@ -372,11 +393,15 @@ export async function forceDisableMfaForAdmin(email: string) {
372
393
  return false
373
394
  }
374
395
 
375
- await updateUserById(user.id, {
376
- mfaEnabled: false,
377
- mfaSecret: null,
378
- mfaRecoveryCodes: []
379
- })
396
+ await updateUserById(
397
+ user.id,
398
+ {
399
+ mfaEnabled: false,
400
+ mfaSecret: null,
401
+ mfaRecoveryCodes: []
402
+ },
403
+ runner
404
+ )
380
405
 
381
406
  return true
382
407
  }
package/lib/query.ts CHANGED
@@ -12,7 +12,8 @@ import {
12
12
  MoreThan,
13
13
  MoreThanOrEqual,
14
14
  LessThan,
15
- LessThanOrEqual
15
+ LessThanOrEqual,
16
+ QueryRunner
16
17
  } from 'typeorm'
17
18
  import yn from './util/yn.js'
18
19
  import * as log from './util/logger.js'
@@ -278,10 +279,17 @@ export async function executeFindQuery(
278
279
  }
279
280
  }
280
281
 
281
- export async function executeFindView(viewEntity: any, data: any = {}, extraWhere: any = {}, extraOptions: any = {}) {
282
+ export async function executeFindView(
283
+ viewEntity: any,
284
+ data: any = {},
285
+ extraWhere: any = {},
286
+ extraOptions: any = {},
287
+ runner?: QueryRunner
288
+ ) {
282
289
  const extra = applyQuery(data, extraWhere, null)
290
+ const manager = runner ? runner.manager : global.connection.manager
283
291
 
284
- const [records = [], totalCount] = await global.connection.manager.findAndCount(viewEntity, {
292
+ const [records = [], totalCount] = await manager.findAndCount(viewEntity, {
285
293
  ...extra,
286
294
  ...extraOptions
287
295
  })
@@ -303,9 +311,10 @@ export async function executeCountQuery(repo: any, data = {}, extraWhere: any =
303
311
  return await repo.count(isMongo(repo) ? where : { where: where })
304
312
  }
305
313
 
306
- export async function executeCountView(viewEntity: any, data = {}, extraWhere: any = {}) {
314
+ export async function executeCountView(viewEntity: any, data = {}, extraWhere: any = {}, runner?: QueryRunner) {
307
315
  const { where = {} } = applyQuery(data, extraWhere, null)
308
- return await global.connection.manager.count(viewEntity, { where: where })
316
+ const manager = runner ? runner.manager : global.connection.manager
317
+ return await manager.count(viewEntity, { where: where })
309
318
  }
310
319
 
311
320
  function getType(repo) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volcanicminds/typeorm",
3
- "version": "2.2.11",
3
+ "version": "2.3.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "TypeORM for the volcanic (minds) backend",