@lenne.tech/nest-server 11.6.1 → 11.7.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.
Files changed (120) hide show
  1. package/dist/config.env.js +132 -0
  2. package/dist/config.env.js.map +1 -1
  3. package/dist/core/common/decorators/graphql-populate.decorator.d.ts +2 -2
  4. package/dist/core/common/decorators/restricted.decorator.d.ts +1 -0
  5. package/dist/core/common/decorators/restricted.decorator.js +1 -1
  6. package/dist/core/common/decorators/restricted.decorator.js.map +1 -1
  7. package/dist/core/common/helpers/filter.helper.d.ts +9 -9
  8. package/dist/core/common/helpers/filter.helper.js +2 -4
  9. package/dist/core/common/helpers/filter.helper.js.map +1 -1
  10. package/dist/core/common/helpers/gridfs.helper.js +3 -3
  11. package/dist/core/common/helpers/gridfs.helper.js.map +1 -1
  12. package/dist/core/common/helpers/input.helper.d.ts +1 -0
  13. package/dist/core/common/helpers/input.helper.js +1 -1
  14. package/dist/core/common/helpers/input.helper.js.map +1 -1
  15. package/dist/core/common/interfaces/server-options.interface.d.ts +51 -0
  16. package/dist/core/common/services/crud.service.d.ts +16 -16
  17. package/dist/core/common/services/crud.service.js +1 -1
  18. package/dist/core/common/services/crud.service.js.map +1 -1
  19. package/dist/core/modules/auth/auth-guard-strategy.enum.d.ts +1 -0
  20. package/dist/core/modules/auth/auth-guard-strategy.enum.js +1 -0
  21. package/dist/core/modules/auth/auth-guard-strategy.enum.js.map +1 -1
  22. package/dist/core/modules/auth/guards/auth.guard.js +11 -5
  23. package/dist/core/modules/auth/guards/auth.guard.js.map +1 -1
  24. package/dist/core/modules/auth/tokens.decorator.d.ts +1 -1
  25. package/dist/core/modules/better-auth/better-auth-auth.model.d.ts +9 -0
  26. package/dist/core/modules/better-auth/better-auth-auth.model.js +63 -0
  27. package/dist/core/modules/better-auth/better-auth-auth.model.js.map +1 -0
  28. package/dist/core/modules/better-auth/better-auth-models.d.ts +43 -0
  29. package/dist/core/modules/better-auth/better-auth-models.js +181 -0
  30. package/dist/core/modules/better-auth/better-auth-models.js.map +1 -0
  31. package/dist/core/modules/better-auth/better-auth-rate-limit.middleware.d.ts +12 -0
  32. package/dist/core/modules/better-auth/better-auth-rate-limit.middleware.js +70 -0
  33. package/dist/core/modules/better-auth/better-auth-rate-limit.middleware.js.map +1 -0
  34. package/dist/core/modules/better-auth/better-auth-rate-limiter.service.d.ts +32 -0
  35. package/dist/core/modules/better-auth/better-auth-rate-limiter.service.js +173 -0
  36. package/dist/core/modules/better-auth/better-auth-rate-limiter.service.js.map +1 -0
  37. package/dist/core/modules/better-auth/better-auth-user.mapper.d.ts +43 -0
  38. package/dist/core/modules/better-auth/better-auth-user.mapper.js +159 -0
  39. package/dist/core/modules/better-auth/better-auth-user.mapper.js.map +1 -0
  40. package/dist/core/modules/better-auth/better-auth.config.d.ts +9 -0
  41. package/dist/core/modules/better-auth/better-auth.config.js +254 -0
  42. package/dist/core/modules/better-auth/better-auth.config.js.map +1 -0
  43. package/dist/core/modules/better-auth/better-auth.middleware.d.ts +20 -0
  44. package/dist/core/modules/better-auth/better-auth.middleware.js +79 -0
  45. package/dist/core/modules/better-auth/better-auth.middleware.js.map +1 -0
  46. package/dist/core/modules/better-auth/better-auth.module.d.ts +38 -0
  47. package/dist/core/modules/better-auth/better-auth.module.js +253 -0
  48. package/dist/core/modules/better-auth/better-auth.module.js.map +1 -0
  49. package/dist/core/modules/better-auth/better-auth.resolver.d.ts +45 -0
  50. package/dist/core/modules/better-auth/better-auth.resolver.js +221 -0
  51. package/dist/core/modules/better-auth/better-auth.resolver.js.map +1 -0
  52. package/dist/core/modules/better-auth/better-auth.service.d.ts +37 -0
  53. package/dist/core/modules/better-auth/better-auth.service.js +148 -0
  54. package/dist/core/modules/better-auth/better-auth.service.js.map +1 -0
  55. package/dist/core/modules/better-auth/better-auth.types.d.ts +39 -0
  56. package/dist/core/modules/better-auth/better-auth.types.js +26 -0
  57. package/dist/core/modules/better-auth/better-auth.types.js.map +1 -0
  58. package/dist/core/modules/better-auth/core-better-auth.controller.d.ts +66 -0
  59. package/dist/core/modules/better-auth/core-better-auth.controller.js +491 -0
  60. package/dist/core/modules/better-auth/core-better-auth.controller.js.map +1 -0
  61. package/dist/core/modules/better-auth/core-better-auth.resolver.d.ts +59 -0
  62. package/dist/core/modules/better-auth/core-better-auth.resolver.js +538 -0
  63. package/dist/core/modules/better-auth/core-better-auth.resolver.js.map +1 -0
  64. package/dist/core/modules/better-auth/index.d.ts +13 -0
  65. package/dist/core/modules/better-auth/index.js +30 -0
  66. package/dist/core/modules/better-auth/index.js.map +1 -0
  67. package/dist/core/modules/user/core-user.model.d.ts +2 -0
  68. package/dist/core/modules/user/core-user.model.js +21 -0
  69. package/dist/core/modules/user/core-user.model.js.map +1 -1
  70. package/dist/core.module.js +7 -0
  71. package/dist/core.module.js.map +1 -1
  72. package/dist/index.d.ts +1 -0
  73. package/dist/index.js +1 -0
  74. package/dist/index.js.map +1 -1
  75. package/dist/server/modules/better-auth/better-auth.controller.d.ts +10 -0
  76. package/dist/server/modules/better-auth/better-auth.controller.js +36 -0
  77. package/dist/server/modules/better-auth/better-auth.controller.js.map +1 -0
  78. package/dist/server/modules/better-auth/better-auth.module.d.ts +9 -0
  79. package/dist/server/modules/better-auth/better-auth.module.js +44 -0
  80. package/dist/server/modules/better-auth/better-auth.module.js.map +1 -0
  81. package/dist/server/modules/better-auth/better-auth.resolver.d.ts +45 -0
  82. package/dist/server/modules/better-auth/better-auth.resolver.js +221 -0
  83. package/dist/server/modules/better-auth/better-auth.resolver.js.map +1 -0
  84. package/dist/server/modules/file/file-info.model.d.ts +71 -3
  85. package/dist/server/modules/user/user.model.d.ts +169 -3
  86. package/dist/server/server.module.js +6 -1
  87. package/dist/server/server.module.js.map +1 -1
  88. package/dist/tsconfig.build.tsbuildinfo +1 -1
  89. package/package.json +21 -22
  90. package/src/config.env.ts +139 -1
  91. package/src/core/common/decorators/restricted.decorator.ts +2 -2
  92. package/src/core/common/helpers/filter.helper.ts +15 -17
  93. package/src/core/common/helpers/gridfs.helper.ts +5 -5
  94. package/src/core/common/helpers/input.helper.ts +2 -2
  95. package/src/core/common/interfaces/server-options.interface.ts +377 -20
  96. package/src/core/common/services/crud.service.ts +22 -22
  97. package/src/core/modules/auth/auth-guard-strategy.enum.ts +1 -0
  98. package/src/core/modules/auth/guards/auth.guard.ts +20 -6
  99. package/src/core/modules/better-auth/README.md +1422 -0
  100. package/src/core/modules/better-auth/better-auth-auth.model.ts +69 -0
  101. package/src/core/modules/better-auth/better-auth-models.ts +140 -0
  102. package/src/core/modules/better-auth/better-auth-rate-limit.middleware.ts +113 -0
  103. package/src/core/modules/better-auth/better-auth-rate-limiter.service.ts +326 -0
  104. package/src/core/modules/better-auth/better-auth-user.mapper.ts +269 -0
  105. package/src/core/modules/better-auth/better-auth.config.ts +488 -0
  106. package/src/core/modules/better-auth/better-auth.middleware.ts +111 -0
  107. package/src/core/modules/better-auth/better-auth.module.ts +474 -0
  108. package/src/core/modules/better-auth/better-auth.resolver.ts +213 -0
  109. package/src/core/modules/better-auth/better-auth.service.ts +314 -0
  110. package/src/core/modules/better-auth/better-auth.types.ts +90 -0
  111. package/src/core/modules/better-auth/core-better-auth.controller.ts +605 -0
  112. package/src/core/modules/better-auth/core-better-auth.resolver.ts +705 -0
  113. package/src/core/modules/better-auth/index.ts +32 -0
  114. package/src/core/modules/user/core-user.model.ts +29 -0
  115. package/src/core.module.ts +13 -0
  116. package/src/index.ts +6 -0
  117. package/src/server/modules/better-auth/better-auth.controller.ts +41 -0
  118. package/src/server/modules/better-auth/better-auth.module.ts +88 -0
  119. package/src/server/modules/better-auth/better-auth.resolver.ts +201 -0
  120. package/src/server/server.module.ts +10 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lenne.tech/nest-server",
3
- "version": "11.6.1",
3
+ "version": "11.7.0",
4
4
  "description": "Modern, fast, powerful Node.js web framework in TypeScript based on Nest with a GraphQL API and a connection to MongoDB (or other databases).",
5
5
  "keywords": [
6
6
  "node",
@@ -77,11 +77,14 @@
77
77
  "node": ">= 20"
78
78
  },
79
79
  "dependencies": {
80
+ "@apollo/server": "5.2.0",
81
+ "@as-integrations/express5": "1.1.2",
82
+ "@better-auth/passkey": "1.4.8-beta.4",
80
83
  "@getbrevo/brevo": "3.0.1",
81
- "@nestjs/apollo": "13.1.0",
84
+ "@nestjs/apollo": "13.2.3",
82
85
  "@nestjs/common": "11.1.9",
83
86
  "@nestjs/core": "11.1.9",
84
- "@nestjs/graphql": "13.2.0",
87
+ "@nestjs/graphql": "13.2.3",
85
88
  "@nestjs/jwt": "11.0.2",
86
89
  "@nestjs/mongoose": "11.0.4",
87
90
  "@nestjs/passport": "11.0.5",
@@ -89,14 +92,17 @@
89
92
  "@nestjs/schedule": "6.1.0",
90
93
  "@nestjs/swagger": "11.2.3",
91
94
  "@nestjs/terminus": "11.0.0",
95
+ "@nestjs/websockets": "11.1.9",
92
96
  "apollo-server-core": "3.13.0",
93
97
  "bcrypt": "6.0.0",
98
+ "better-auth": "1.4.8-beta.4",
94
99
  "class-transformer": "0.5.1",
95
100
  "class-validator": "0.14.3",
96
101
  "compression": "1.8.1",
97
102
  "cookie-parser": "1.4.7",
98
103
  "dotenv": "17.2.3",
99
104
  "ejs": "3.1.10",
105
+ "express": "5.1.0",
100
106
  "graphql": "16.12.0",
101
107
  "graphql-query-complexity": "1.1.0",
102
108
  "graphql-subscriptions": "3.0.0",
@@ -105,7 +111,7 @@
105
111
  "json-to-graphql-query": "2.3.0",
106
112
  "lodash": "4.17.21",
107
113
  "mongodb": "7.0.0",
108
- "mongoose": "8.19.3",
114
+ "mongoose": "9.0.2",
109
115
  "multer": "2.0.2",
110
116
  "node-mailjet": "6.0.11",
111
117
  "nodemailer": "7.0.11",
@@ -114,7 +120,6 @@
114
120
  "reflect-metadata": "0.2.2",
115
121
  "rfdc": "1.4.1",
116
122
  "rxjs": "7.8.2",
117
- "ts-jest": "29.4.6",
118
123
  "yuml-diagram": "1.2.0"
119
124
  },
120
125
  "devDependencies": {
@@ -124,23 +129,23 @@
124
129
  "@nestjs/schematics": "11.0.9",
125
130
  "@nestjs/testing": "11.1.9",
126
131
  "@swc/cli": "0.7.9",
127
- "@swc/core": "1.15.3",
132
+ "@swc/core": "1.15.7",
128
133
  "@types/compression": "1.8.1",
129
134
  "@types/cookie-parser": "1.4.10",
130
135
  "@types/ejs": "3.1.5",
131
136
  "@types/express": "4.17.21",
132
137
  "@types/lodash": "4.17.21",
133
138
  "@types/multer": "2.0.0",
134
- "@types/node": "25.0.1",
139
+ "@types/node": "25.0.3",
135
140
  "@types/nodemailer": "7.0.4",
136
141
  "@types/passport": "1.0.17",
137
142
  "@types/supertest": "6.0.3",
138
- "@typescript-eslint/eslint-plugin": "8.49.0",
139
- "@typescript-eslint/parser": "8.49.0",
140
- "@vitest/coverage-v8": "4.0.15",
141
- "@vitest/ui": "4.0.15",
143
+ "@typescript-eslint/eslint-plugin": "8.50.0",
144
+ "@typescript-eslint/parser": "8.50.0",
145
+ "@vitest/coverage-v8": "4.0.16",
146
+ "@vitest/ui": "4.0.16",
142
147
  "ansi-colors": "4.1.3",
143
- "eslint": "9.39.1",
148
+ "eslint": "9.39.2",
144
149
  "eslint-config-prettier": "10.1.8",
145
150
  "eslint-plugin-unused-imports": "4.3.0",
146
151
  "find-file-up": "2.0.1",
@@ -157,25 +162,19 @@
157
162
  "pretty-quick": "4.2.2",
158
163
  "rimraf": "6.1.2",
159
164
  "supertest": "7.1.4",
165
+ "ts-jest": "29.4.6",
160
166
  "ts-loader": "9.5.4",
161
167
  "ts-morph": "27.0.2",
162
168
  "ts-node": "10.9.2",
163
169
  "tsconfig-paths": "4.2.0",
164
170
  "typescript": "5.9.3",
165
171
  "unplugin-swc": "1.5.9",
166
- "vite": "7.2.7",
172
+ "vite": "7.3.0",
167
173
  "vite-plugin-node": "7.0.0",
168
- "vite-tsconfig-paths": "5.1.4",
169
- "vitest": "4.0.15",
174
+ "vite-tsconfig-paths": "6.0.3",
175
+ "vitest": "4.0.16",
170
176
  "yalc": "1.0.0-pre.53"
171
177
  },
172
- "overrides": {
173
- "@lykmapipo/common": {
174
- "flat": "5.0.2",
175
- "mime": "2.6.0"
176
- },
177
- "ts-morph": "27.0.2"
178
- },
179
178
  "jest": {
180
179
  "collectCoverage": true,
181
180
  "coverageDirectory": "../coverage",
package/src/config.env.ts CHANGED
@@ -15,6 +15,51 @@ const config: { [env: string]: IServerOptions } = {
15
15
  // ===========================================================================
16
16
  development: {
17
17
  automaticObjectIdFiltering: true,
18
+ betterAuth: {
19
+ basePath: '/iam',
20
+ baseUrl: 'http://localhost:3000',
21
+ // enabled: true by default - set false to explicitly disable
22
+ jwt: {
23
+ enabled: true,
24
+ expiresIn: '15m',
25
+ },
26
+ passkey: {
27
+ enabled: false,
28
+ origin: 'http://localhost:3000',
29
+ rpId: 'localhost',
30
+ rpName: 'Nest Server Development',
31
+ },
32
+ rateLimit: {
33
+ enabled: true,
34
+ max: 20,
35
+ message: 'Too many requests, please try again later.',
36
+ skipEndpoints: ['/session', '/callback'],
37
+ strictEndpoints: ['/sign-in', '/sign-up', '/forgot-password', '/reset-password'],
38
+ windowSeconds: 60,
39
+ },
40
+ secret: 'BETTER_AUTH_SECRET_DEV_32_CHARS_MIN',
41
+ socialProviders: {
42
+ apple: {
43
+ clientId: process.env.SOCIAL_APPLE_CLIENT_ID || '',
44
+ clientSecret: process.env.SOCIAL_APPLE_CLIENT_SECRET || '',
45
+ enabled: false,
46
+ },
47
+ github: {
48
+ clientId: process.env.SOCIAL_GITHUB_CLIENT_ID || '',
49
+ clientSecret: process.env.SOCIAL_GITHUB_CLIENT_SECRET || '',
50
+ enabled: false,
51
+ },
52
+ google: {
53
+ clientId: process.env.SOCIAL_GOOGLE_CLIENT_ID || '',
54
+ clientSecret: process.env.SOCIAL_GOOGLE_CLIENT_SECRET || '',
55
+ enabled: false,
56
+ },
57
+ },
58
+ twoFactor: {
59
+ appName: 'Nest Server Development',
60
+ enabled: false,
61
+ },
62
+ },
18
63
  compression: true,
19
64
  cookies: false,
20
65
  email: {
@@ -114,10 +159,55 @@ const config: { [env: string]: IServerOptions } = {
114
159
  },
115
160
 
116
161
  // ===========================================================================
117
- // Development environment
162
+ // Local environment
118
163
  // ===========================================================================
119
164
  local: {
120
165
  automaticObjectIdFiltering: true,
166
+ betterAuth: {
167
+ basePath: '/iam',
168
+ baseUrl: 'http://localhost:3000',
169
+ // enabled: true by default - set false to explicitly disable
170
+ jwt: {
171
+ enabled: true,
172
+ expiresIn: '15m',
173
+ },
174
+ passkey: {
175
+ enabled: true,
176
+ origin: 'http://localhost:3000',
177
+ rpId: 'localhost',
178
+ rpName: 'Nest Server Local',
179
+ },
180
+ rateLimit: {
181
+ enabled: true,
182
+ max: 20,
183
+ message: 'Too many requests, please try again later.',
184
+ skipEndpoints: ['/session', '/callback'],
185
+ strictEndpoints: ['/sign-in', '/sign-up', '/forgot-password', '/reset-password'],
186
+ windowSeconds: 60,
187
+ },
188
+ secret: 'BETTER_AUTH_SECRET_LOCAL_32_CHARS_M',
189
+ socialProviders: {
190
+ apple: {
191
+ clientId: process.env.SOCIAL_APPLE_CLIENT_ID || '',
192
+ clientSecret: process.env.SOCIAL_APPLE_CLIENT_SECRET || '',
193
+ enabled: false,
194
+ },
195
+ github: {
196
+ clientId: process.env.SOCIAL_GITHUB_CLIENT_ID || '',
197
+ clientSecret: process.env.SOCIAL_GITHUB_CLIENT_SECRET || '',
198
+ enabled: false,
199
+ },
200
+ google: {
201
+ clientId: process.env.SOCIAL_GOOGLE_CLIENT_ID || '',
202
+ clientSecret: process.env.SOCIAL_GOOGLE_CLIENT_SECRET || '',
203
+ enabled: false,
204
+ },
205
+ },
206
+ twoFactor: {
207
+ appName: 'Nest Server Local',
208
+ enabled: true,
209
+ },
210
+ },
121
211
  compression: true,
122
212
  cookies: false,
123
213
  cronJobs: {
@@ -232,6 +322,54 @@ const config: { [env: string]: IServerOptions } = {
232
322
  // ===========================================================================
233
323
  production: {
234
324
  automaticObjectIdFiltering: true,
325
+ betterAuth: {
326
+ basePath: '/iam',
327
+ baseUrl: process.env.BETTER_AUTH_URL || 'https://example.com',
328
+ // enabled: true by default - set false to explicitly disable
329
+ jwt: {
330
+ enabled: true,
331
+ expiresIn: '15m',
332
+ },
333
+ passkey: {
334
+ enabled: false,
335
+ origin: process.env.BETTER_AUTH_URL || 'https://example.com',
336
+ rpId: process.env.PASSKEY_RP_ID || 'example.com',
337
+ rpName: process.env.PASSKEY_RP_NAME || 'Nest Server Production',
338
+ },
339
+ rateLimit: {
340
+ enabled: process.env.RATE_LIMIT_ENABLED !== 'false',
341
+ max: parseInt(process.env.RATE_LIMIT_MAX || '10', 10),
342
+ message: process.env.RATE_LIMIT_MESSAGE || 'Too many requests, please try again later.',
343
+ skipEndpoints: ['/session', '/callback'],
344
+ strictEndpoints: ['/sign-in', '/sign-up', '/forgot-password', '/reset-password'],
345
+ windowSeconds: parseInt(process.env.RATE_LIMIT_WINDOW_SECONDS || '60', 10),
346
+ },
347
+ // IMPORTANT: Set BETTER_AUTH_SECRET in production!
348
+ // Without it, an insecure default is used which allows session forgery.
349
+ // Generate with: node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
350
+ secret: process.env.BETTER_AUTH_SECRET,
351
+ socialProviders: {
352
+ apple: {
353
+ clientId: process.env.SOCIAL_APPLE_CLIENT_ID || '',
354
+ clientSecret: process.env.SOCIAL_APPLE_CLIENT_SECRET || '',
355
+ enabled: !!process.env.SOCIAL_APPLE_CLIENT_ID,
356
+ },
357
+ github: {
358
+ clientId: process.env.SOCIAL_GITHUB_CLIENT_ID || '',
359
+ clientSecret: process.env.SOCIAL_GITHUB_CLIENT_SECRET || '',
360
+ enabled: !!process.env.SOCIAL_GITHUB_CLIENT_ID,
361
+ },
362
+ google: {
363
+ clientId: process.env.SOCIAL_GOOGLE_CLIENT_ID || '',
364
+ clientSecret: process.env.SOCIAL_GOOGLE_CLIENT_SECRET || '',
365
+ enabled: !!process.env.SOCIAL_GOOGLE_CLIENT_ID,
366
+ },
367
+ },
368
+ twoFactor: {
369
+ appName: process.env.TWO_FACTOR_APP_NAME || 'Nest Server',
370
+ enabled: process.env.TWO_FACTOR_ENABLED === 'true',
371
+ },
372
+ },
235
373
  compression: true,
236
374
  cookies: false,
237
375
  email: {
@@ -61,7 +61,7 @@ export const getRestricted = (object: unknown, propertyKey?: string): Restricted
61
61
  */
62
62
  export const checkRestricted = (
63
63
  data: any,
64
- user: { hasRole: (roles: string[]) => boolean; id: any; verified?: any; verifiedAt?: any },
64
+ user: { emailVerified?: any; hasRole: (roles: string[]) => boolean; id: any; verified?: any; verifiedAt?: any },
65
65
  options: {
66
66
  allowCreatorOfParent?: boolean;
67
67
  checkObjectItself?: boolean;
@@ -163,7 +163,7 @@ export const checkRestricted = (
163
163
  (roles.includes(RoleEnum.S_CREATOR) &&
164
164
  (('createdBy' in data && equalIds(data.createdBy, user)) ||
165
165
  (config.allowCreatorOfParent && !('createdBy' in data) && config.isCreatorOfParent))) ||
166
- (roles.includes(RoleEnum.S_VERIFIED) && (user?.verified || user?.verifiedAt))
166
+ (roles.includes(RoleEnum.S_VERIFIED) && (user?.verified || user?.verifiedAt || user?.emailVerified))
167
167
  ) {
168
168
  valid = true;
169
169
  }
@@ -1,4 +1,4 @@
1
- import { FilterQuery, QueryOptions } from 'mongoose';
1
+ import { QueryFilter, QueryOptions } from 'mongoose';
2
2
 
3
3
  import { FilterArgs } from '../args/filter.args';
4
4
  import { ComparisonOperatorEnum } from '../enums/comparison-operator.enum';
@@ -19,14 +19,14 @@ export class Filter {
19
19
  * Convert filter arguments to a query array
20
20
  * @param filterArgs
21
21
  */
22
- public static convertFilterArgsToQuery<T = any>(filterArgs: Partial<FilterArgs>): [FilterQuery<T>, QueryOptions] {
23
- return convertFilterArgsToQuery(filterArgs);
22
+ public static convertFilterArgsToQuery<T = Record<string, any>>(filterArgs: Partial<FilterArgs>): [T, QueryOptions] {
23
+ return convertFilterArgsToQuery<T>(filterArgs);
24
24
  }
25
25
 
26
26
  /**
27
27
  * Generate filter query
28
28
  */
29
- public static generateFilterQuery<T = any>(filter?: Partial<FilterInput>): any | FilterQuery<T> {
29
+ public static generateFilterQuery<T = any>(filter?: Partial<FilterInput>): any | QueryFilter<T> {
30
30
  return generateFilterQuery(filter);
31
31
  }
32
32
 
@@ -41,31 +41,29 @@ export class Filter {
41
41
  /**
42
42
  * Convert filter arguments to a query array
43
43
  */
44
- export function convertFilterArgsToQuery<T = any>(filterArgs: Partial<FilterArgs>): [FilterQuery<T>, QueryOptions] {
45
- return [generateFilterQuery(filterArgs?.filter), generateFindOptions(filterArgs)];
44
+ export function convertFilterArgsToQuery<T = Record<string, any>>(filterArgs: Partial<FilterArgs>): [T, QueryOptions] {
45
+ return [generateFilterQuery(filterArgs?.filter) as T, generateFindOptions(filterArgs)];
46
46
  }
47
47
 
48
48
  /**
49
49
  * Merge FilterArgs and FilterQueries
50
50
  */
51
- export function filterMerge<T = unknown>(
51
+ export function filterMerge<T = Record<string, any>>(
52
52
  filterArgs: Partial<FilterArgs>,
53
- filterQuery: Partial<FilterQuery<T>>,
53
+ filterQuery: Partial<T>,
54
54
  options?: {
55
55
  operator?: '$and' | '$nor' | '$or';
56
56
  queryOptions?: Partial<QueryOptions>;
57
57
  samples?: number;
58
58
  },
59
- ): { filterQuery: FilterQuery<T>; queryOptions?: QueryOptions; samples?: number } {
59
+ ): { filterQuery: T; queryOptions?: QueryOptions; samples?: number } {
60
60
  const config = {
61
61
  operator: '$and',
62
62
  ...options,
63
63
  };
64
64
  const converted = convertFilterArgsToQuery(filterArgs);
65
65
  return {
66
- filterQuery: (converted[0]
67
- ? { [config.operator]: [converted[0], filterQuery || {}] }
68
- : filterQuery) as FilterQuery<T>,
66
+ filterQuery: (converted[0] ? { [config.operator]: [converted[0], filterQuery || {}] } : filterQuery) as T,
69
67
  queryOptions: converted[1] || config.queryOptions ? { ...converted[1], ...config.queryOptions } : undefined,
70
68
  samples: config.samples,
71
69
  };
@@ -76,18 +74,18 @@ export function filterMerge<T = unknown>(
76
74
  */
77
75
  export function findFilter(options?: {
78
76
  conditions?: Record<string, any>[];
79
- filterOptions?: FilterQuery<any>;
77
+ filterOptions?: QueryFilter<any>;
80
78
  id?: any;
81
79
  ids?: any[];
82
80
  type?: '$and' | '$nor' | '$or';
83
- }): FilterQuery<any> {
81
+ }): QueryFilter<any> {
84
82
  const config = {
85
83
  type: '$and',
86
84
  ...options,
87
85
  };
88
86
 
89
87
  // Init filter Option
90
- let filterOptions: FilterQuery<any> = config?.filterOptions;
88
+ let filterOptions: QueryFilter<any> = config?.filterOptions;
91
89
 
92
90
  // Check where condition
93
91
  if (!filterOptions) {
@@ -120,7 +118,7 @@ export function findFilter(options?: {
120
118
  }
121
119
 
122
120
  // Filter falsy values
123
- filterOptions[config.type] = filterOptions[config.type].filter(value => value);
121
+ filterOptions[config.type] = filterOptions[config.type].filter((value) => value);
124
122
 
125
123
  // Optimizations
126
124
  if (!filterOptions[config.type].length) {
@@ -143,7 +141,7 @@ export function findFilter(options?: {
143
141
  export function generateFilterQuery<T = any>(
144
142
  filter?: Partial<FilterInput>,
145
143
  options?: { automaticObjectIdFiltering?: boolean },
146
- ): any | FilterQuery<T> {
144
+ ): any | QueryFilter<T> {
147
145
  // Check filter
148
146
  if (!filter) {
149
147
  return undefined;
@@ -166,7 +166,7 @@ export class GridFSHelper {
166
166
  */
167
167
  static async findFiles(bucket: GridFSBucket, filter: any = {}, options: any = {}): Promise<GridFSFileInfo[]> {
168
168
  const files = await bucket.find(filter, options).toArray();
169
- return files.map(file => GridFSHelper.normalizeFileInfo(file));
169
+ return files.map((file) => GridFSHelper.normalizeFileInfo(file));
170
170
  }
171
171
 
172
172
  /**
@@ -200,12 +200,12 @@ export class GridFSHelper {
200
200
  filename: string,
201
201
  options?: { contentType?: string },
202
202
  ): mongo.GridFSBucketWriteStream {
203
- // Store contentType in metadata to avoid deprecation warning
203
+ // Store contentType in metadata (mongodb 7.x no longer has contentType option)
204
204
  if (options?.contentType) {
205
205
  const metadata = { contentType: options.contentType };
206
206
  return bucket.openUploadStream(filename, { metadata });
207
207
  }
208
- return bucket.openUploadStream(filename, options);
208
+ return bucket.openUploadStream(filename);
209
209
  }
210
210
 
211
211
  /**
@@ -217,11 +217,11 @@ export class GridFSHelper {
217
217
  filename: string,
218
218
  options?: { contentType?: string },
219
219
  ): mongo.GridFSBucketWriteStream {
220
- // Store contentType in metadata to avoid deprecation warning
220
+ // Store contentType in metadata (mongodb 7.x no longer has contentType option)
221
221
  if (options?.contentType) {
222
222
  const metadata = { contentType: options.contentType };
223
223
  return bucket.openUploadStreamWithId(id, filename, { metadata });
224
224
  }
225
- return bucket.openUploadStreamWithId(id, filename, options);
225
+ return bucket.openUploadStreamWithId(id, filename);
226
226
  }
227
227
  }
@@ -209,7 +209,7 @@ export function assignPlain(target: Record<any, any>, ...args: Record<any, any>[
209
209
  */
210
210
  export async function check(
211
211
  value: any,
212
- user: { hasRole: (roles: string[]) => boolean; id: any; verified?: any; verifiedAt?: any },
212
+ user: { emailVerified?: any; hasRole: (roles: string[]) => boolean; id: any; verified?: any; verifiedAt?: any },
213
213
  options?: {
214
214
  allowCreatorOfParent?: boolean;
215
215
  dbObject?: any;
@@ -264,7 +264,7 @@ export async function check(
264
264
  !('createdBy' in config.dbObject) &&
265
265
  config.isCreatorOfParent))) ||
266
266
  // check if the is verified
267
- (roles.includes(RoleEnum.S_VERIFIED) && (user?.verified || user?.verifiedAt))
267
+ (roles.includes(RoleEnum.S_VERIFIED) && (user?.verified || user?.verifiedAt || user?.emailVerified))
268
268
  ) {
269
269
  valid = true;
270
270
  }