@flowerforce/flowerbase 1.7.6-beta.8 → 1.7.6-beta.9

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 +1 @@
1
- {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAuCzC;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,iBAsZjE"}
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AA4CzC;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,iBAmajE"}
@@ -49,14 +49,22 @@ function localUserPassController(app) {
49
49
  const resetMaxAttempts = constants_1.DEFAULT_CONFIG.AUTH_RESET_MAX_ATTEMPTS;
50
50
  const refreshTokenTtlMs = constants_1.DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000;
51
51
  const resolveLocalUserpassProvider = () => { var _a; return (_a = constants_1.AUTH_CONFIG.authProviders) === null || _a === void 0 ? void 0 : _a['local-userpass']; };
52
+ const invalidPasswordError = {
53
+ error: 'unauthorized',
54
+ error_code: 'InvalidPassword'
55
+ };
52
56
  try {
53
- yield authDb.collection(resetPasswordCollection).createIndex({ createdAt: 1 }, { expireAfterSeconds: resetPasswordTtlSeconds });
57
+ yield authDb
58
+ .collection(resetPasswordCollection)
59
+ .createIndex({ createdAt: 1 }, { expireAfterSeconds: resetPasswordTtlSeconds });
54
60
  }
55
61
  catch (error) {
56
62
  console.error('Failed to ensure reset password TTL index', error);
57
63
  }
58
64
  try {
59
- yield authDb.collection(refreshTokensCollection).createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 });
65
+ yield authDb
66
+ .collection(refreshTokensCollection)
67
+ .createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 });
60
68
  }
61
69
  catch (error) {
62
70
  console.error('Failed to ensure refresh token TTL index', error);
@@ -80,8 +88,10 @@ function localUserPassController(app) {
80
88
  const services = state_1.StateManager.select('services');
81
89
  const currentFunction = functionsList[resetPasswordConfig.resetFunctionName];
82
90
  const baseArgs = { token, tokenId, email, password, username: email };
83
- const args = Array.isArray(extraArguments) ? [baseArgs, ...extraArguments] : [baseArgs];
84
- const response = yield (0, context_1.GenerateContext)({
91
+ const args = Array.isArray(extraArguments)
92
+ ? [baseArgs, ...extraArguments]
93
+ : [baseArgs];
94
+ const response = (yield (0, context_1.GenerateContext)({
85
95
  args,
86
96
  app,
87
97
  rules: {},
@@ -91,7 +101,7 @@ function localUserPassController(app) {
91
101
  functionsList,
92
102
  services,
93
103
  runAsSystem: true
94
- });
104
+ }));
95
105
  const resetStatus = response === null || response === void 0 ? void 0 : response.status;
96
106
  if (resetStatus === 'success') {
97
107
  if (!password) {
@@ -138,13 +148,17 @@ function localUserPassController(app) {
138
148
  }
139
149
  let result;
140
150
  try {
141
- result = yield (0, handleUserRegistration_1.default)(app, { run_as_system: true, provider: handleUserRegistration_model_1.PROVIDER.LOCAL_USERPASS })({
151
+ result = yield (0, handleUserRegistration_1.default)(app, {
152
+ run_as_system: true,
153
+ provider: handleUserRegistration_model_1.PROVIDER.LOCAL_USERPASS
154
+ })({
142
155
  email: req.body.email.toLowerCase(),
143
156
  password: req.body.password
144
157
  });
145
158
  }
146
159
  catch (error) {
147
- if (error instanceof Error && error.message === 'This email address is already used') {
160
+ if (error instanceof Error &&
161
+ error.message === 'This email address is already used') {
148
162
  res.status(409).send({
149
163
  error: 'name already in use',
150
164
  error_code: 'AccountNameInUse'
@@ -179,10 +193,10 @@ function localUserPassController(app) {
179
193
  res.status(429).send({ message: 'Too many requests' });
180
194
  return;
181
195
  }
182
- const existing = yield authDb.collection(authCollection).findOne({
196
+ const existing = (yield authDb.collection(authCollection).findOne({
183
197
  confirmationToken: req.body.token,
184
198
  confirmationTokenId: req.body.tokenId
185
- });
199
+ }));
186
200
  if (!existing) {
187
201
  res.status(500);
188
202
  throw new Error(utils_1.AUTH_ERRORS.INVALID_TOKEN);
@@ -220,11 +234,13 @@ function localUserPassController(app) {
220
234
  email: req.body.username
221
235
  });
222
236
  if (!authUser) {
223
- throw new Error(utils_1.AUTH_ERRORS.INVALID_CREDENTIALS);
237
+ res.status(401);
238
+ return invalidPasswordError;
224
239
  }
225
240
  const passwordMatches = yield (0, crypto_1.comparePassword)(req.body.password, authUser.password);
226
241
  if (!passwordMatches) {
227
- throw new Error(utils_1.AUTH_ERRORS.INVALID_CREDENTIALS);
242
+ res.status(401);
243
+ return invalidPasswordError;
228
244
  }
229
245
  const user = user_id_field && userCollection
230
246
  ? yield customUserDb
@@ -246,7 +262,9 @@ function localUserPassController(app) {
246
262
  expiresAt: new Date(Date.now() + refreshTokenTtlMs),
247
263
  revokedAt: null
248
264
  });
249
- yield authDb.collection(authCollection).updateOne({ _id: authUser._id }, { $set: { lastLoginAt: now } });
265
+ yield authDb
266
+ .collection(authCollection)
267
+ .updateOne({ _id: authUser._id }, { $set: { lastLoginAt: now } });
250
268
  return {
251
269
  access_token: this.createAccessToken(userWithCustomData),
252
270
  refresh_token: refreshToken,
@@ -15,12 +15,16 @@ export type LoginSuccessDto = {
15
15
  export type ErrorResponseDto = {
16
16
  message: string;
17
17
  };
18
+ export type InvalidPasswordResponseDto = {
19
+ error: 'unauthorized';
20
+ error_code: 'InvalidPassword';
21
+ };
18
22
  export interface RegistrationDto {
19
23
  Body: RegisterUserDto;
20
24
  }
21
25
  export interface LoginDto {
22
26
  Body: LoginUserDto;
23
- Reply: LoginSuccessDto | ErrorResponseDto;
27
+ Reply: LoginSuccessDto | ErrorResponseDto | InvalidPasswordResponseDto;
24
28
  }
25
29
  export interface ResetPasswordSendDto {
26
30
  Body: {
@@ -1 +1 @@
1
- {"version":3,"file":"dtos.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/dtos.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,eAAe,CAAA;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,EAAE,eAAe,GAAG,gBAAgB,CAAA;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;CACF;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,QAAQ,EAAE,MAAM,CAAA;QAChB,SAAS,CAAC,EAAE,OAAO,EAAE,CAAA;KACtB,CAAA;CACF;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;CACF;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;CACF"}
1
+ {"version":3,"file":"dtos.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/dtos.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,KAAK,EAAE,cAAc,CAAA;IACrB,UAAU,EAAE,iBAAiB,CAAA;CAC9B,CAAA;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,eAAe,CAAA;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,EAAE,eAAe,GAAG,gBAAgB,GAAG,0BAA0B,CAAA;CACvE;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;CACF;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,QAAQ,EAAE,MAAM,CAAA;QAChB,SAAS,CAAC,EAAE,OAAO,EAAE,CAAA;KACtB,CAAA;CACF;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;CACF;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowerforce/flowerbase",
3
- "version": "1.7.6-beta.8",
3
+ "version": "1.7.6-beta.9",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -5,7 +5,12 @@ import handleUserRegistration from '../../../shared/handleUserRegistration'
5
5
  import { PROVIDER } from '../../../shared/models/handleUserRegistration.model'
6
6
  import { StateManager } from '../../../state'
7
7
  import { GenerateContext } from '../../../utils/context'
8
- import { comparePassword, generateToken, hashPassword, hashToken } from '../../../utils/crypto'
8
+ import {
9
+ comparePassword,
10
+ generateToken,
11
+ hashPassword,
12
+ hashToken
13
+ } from '../../../utils/crypto'
9
14
  import {
10
15
  AUTH_ENDPOINTS,
11
16
  AUTH_ERRORS,
@@ -55,21 +60,23 @@ export async function localUserPassController(app: FastifyInstance) {
55
60
  const resetMaxAttempts = DEFAULT_CONFIG.AUTH_RESET_MAX_ATTEMPTS
56
61
  const refreshTokenTtlMs = DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000
57
62
  const resolveLocalUserpassProvider = () => AUTH_CONFIG.authProviders?.['local-userpass']
63
+ const invalidPasswordError = {
64
+ error: 'unauthorized',
65
+ error_code: 'InvalidPassword'
66
+ } as const
58
67
 
59
68
  try {
60
- await authDb.collection(resetPasswordCollection).createIndex(
61
- { createdAt: 1 },
62
- { expireAfterSeconds: resetPasswordTtlSeconds }
63
- )
69
+ await authDb
70
+ .collection(resetPasswordCollection)
71
+ .createIndex({ createdAt: 1 }, { expireAfterSeconds: resetPasswordTtlSeconds })
64
72
  } catch (error) {
65
73
  console.error('Failed to ensure reset password TTL index', error)
66
74
  }
67
75
 
68
76
  try {
69
- await authDb.collection(refreshTokensCollection).createIndex(
70
- { expiresAt: 1 },
71
- { expireAfterSeconds: 0 }
72
- )
77
+ await authDb
78
+ .collection(refreshTokensCollection)
79
+ .createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 })
73
80
  } catch (error) {
74
81
  console.error('Failed to ensure refresh token TTL index', error)
75
82
  }
@@ -107,8 +114,10 @@ export async function localUserPassController(app: FastifyInstance) {
107
114
  const services = StateManager.select('services')
108
115
  const currentFunction = functionsList[resetPasswordConfig.resetFunctionName]
109
116
  const baseArgs = { token, tokenId, email, password, username: email }
110
- const args = Array.isArray(extraArguments) ? [baseArgs, ...extraArguments] : [baseArgs]
111
- const response = await GenerateContext({
117
+ const args = Array.isArray(extraArguments)
118
+ ? [baseArgs, ...extraArguments]
119
+ : [baseArgs]
120
+ const response = (await GenerateContext({
112
121
  args,
113
122
  app,
114
123
  rules: {},
@@ -118,7 +127,7 @@ export async function localUserPassController(app: FastifyInstance) {
118
127
  functionsList,
119
128
  services,
120
129
  runAsSystem: true
121
- }) as ResetFunctionResult
130
+ })) as ResetFunctionResult
122
131
  const resetStatus = response?.status
123
132
 
124
133
  if (resetStatus === 'success') {
@@ -179,12 +188,18 @@ export async function localUserPassController(app: FastifyInstance) {
179
188
 
180
189
  let result
181
190
  try {
182
- result = await handleUserRegistration(app, { run_as_system: true, provider: PROVIDER.LOCAL_USERPASS })({
191
+ result = await handleUserRegistration(app, {
192
+ run_as_system: true,
193
+ provider: PROVIDER.LOCAL_USERPASS
194
+ })({
183
195
  email: req.body.email.toLowerCase(),
184
196
  password: req.body.password
185
197
  })
186
198
  } catch (error) {
187
- if (error instanceof Error && error.message === 'This email address is already used') {
199
+ if (
200
+ error instanceof Error &&
201
+ error.message === 'This email address is already used'
202
+ ) {
188
203
  res.status(409).send({
189
204
  error: 'name already in use',
190
205
  error_code: 'AccountNameInUse'
@@ -227,10 +242,10 @@ export async function localUserPassController(app: FastifyInstance) {
227
242
  return
228
243
  }
229
244
 
230
- const existing = await authDb.collection(authCollection!).findOne({
245
+ const existing = (await authDb.collection(authCollection!).findOne({
231
246
  confirmationToken: req.body.token,
232
247
  confirmationTokenId: req.body.tokenId
233
- }) as { _id: ObjectId; status?: string } | null
248
+ })) as { _id: ObjectId; status?: string } | null
234
249
 
235
250
  if (!existing) {
236
251
  res.status(500)
@@ -279,23 +294,22 @@ export async function localUserPassController(app: FastifyInstance) {
279
294
  })
280
295
 
281
296
  if (!authUser) {
282
- throw new Error(AUTH_ERRORS.INVALID_CREDENTIALS)
297
+ res.status(401)
298
+ return invalidPasswordError
283
299
  }
284
300
 
285
- const passwordMatches = await comparePassword(
286
- req.body.password,
287
- authUser.password
288
- )
301
+ const passwordMatches = await comparePassword(req.body.password, authUser.password)
289
302
 
290
303
  if (!passwordMatches) {
291
- throw new Error(AUTH_ERRORS.INVALID_CREDENTIALS)
304
+ res.status(401)
305
+ return invalidPasswordError
292
306
  }
293
307
 
294
308
  const user =
295
309
  user_id_field && userCollection
296
310
  ? await customUserDb
297
- .collection(userCollection)
298
- .findOne({ [user_id_field]: authUser._id.toString() })
311
+ .collection(userCollection)
312
+ .findOne({ [user_id_field]: authUser._id.toString() })
299
313
  : {}
300
314
  delete authUser?.password
301
315
 
@@ -325,10 +339,9 @@ export async function localUserPassController(app: FastifyInstance) {
325
339
  expiresAt: new Date(Date.now() + refreshTokenTtlMs),
326
340
  revokedAt: null
327
341
  })
328
- await authDb.collection(authCollection!).updateOne(
329
- { _id: authUser._id },
330
- { $set: { lastLoginAt: now } }
331
- )
342
+ await authDb
343
+ .collection(authCollection!)
344
+ .updateOne({ _id: authUser._id }, { $set: { lastLoginAt: now } })
332
345
 
333
346
  return {
334
347
  access_token: this.createAccessToken(userWithCustomData),
@@ -427,12 +440,15 @@ export async function localUserPassController(app: FastifyInstance) {
427
440
  }
428
441
 
429
442
  const createdAt = resetRequest.createdAt ? new Date(resetRequest.createdAt) : null
430
- const isExpired = !createdAt ||
443
+ const isExpired =
444
+ !createdAt ||
431
445
  Number.isNaN(createdAt.getTime()) ||
432
446
  Date.now() - createdAt.getTime() > resetPasswordTtlSeconds * 1000
433
447
 
434
448
  if (isExpired) {
435
- await authDb?.collection(resetPasswordCollection).deleteOne({ _id: resetRequest._id })
449
+ await authDb
450
+ ?.collection(resetPasswordCollection)
451
+ .deleteOne({ _id: resetRequest._id })
436
452
  throw new Error(AUTH_ERRORS.INVALID_RESET_PARAMS)
437
453
  }
438
454
  const hashedPassword = await hashPassword(password)
@@ -445,7 +461,9 @@ export async function localUserPassController(app: FastifyInstance) {
445
461
  }
446
462
  )
447
463
 
448
- await authDb?.collection(resetPasswordCollection).deleteOne({ _id: resetRequest._id })
464
+ await authDb
465
+ ?.collection(resetPasswordCollection)
466
+ .deleteOne({ _id: resetRequest._id })
449
467
  }
450
468
  )
451
469
  }
@@ -19,13 +19,18 @@ export type ErrorResponseDto = {
19
19
  message: string
20
20
  }
21
21
 
22
+ export type InvalidPasswordResponseDto = {
23
+ error: 'unauthorized'
24
+ error_code: 'InvalidPassword'
25
+ }
26
+
22
27
  export interface RegistrationDto {
23
28
  Body: RegisterUserDto
24
29
  }
25
30
 
26
31
  export interface LoginDto {
27
32
  Body: LoginUserDto
28
- Reply: LoginSuccessDto | ErrorResponseDto
33
+ Reply: LoginSuccessDto | ErrorResponseDto | InvalidPasswordResponseDto
29
34
  }
30
35
 
31
36
  export interface ResetPasswordSendDto {