proteum 1.0.2 → 2.0.0-1

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 (185) hide show
  1. package/AGENTS.md +101 -0
  2. package/agents/codex/AGENTS.md +95 -0
  3. package/agents/codex/CODING_STYLE.md +71 -0
  4. package/agents/codex/agents.md.zip +0 -0
  5. package/agents/codex/client/AGENTS.md +102 -0
  6. package/agents/codex/client/pages/AGENTS.md +35 -0
  7. package/agents/codex/server/routes/AGENTS.md +12 -0
  8. package/agents/codex/server/services/AGENTS.md +137 -0
  9. package/agents/codex/tests/AGENTS.md +8 -0
  10. package/cli/app/config.ts +13 -11
  11. package/cli/app/index.ts +74 -82
  12. package/cli/bin.js +1 -1
  13. package/cli/commands/build.ts +51 -14
  14. package/cli/commands/check.ts +19 -0
  15. package/cli/commands/deploy/app.ts +4 -8
  16. package/cli/commands/deploy/web.ts +16 -20
  17. package/cli/commands/dev.ts +189 -64
  18. package/cli/commands/devEvents.ts +106 -0
  19. package/cli/commands/init.ts +63 -57
  20. package/cli/commands/lint.ts +21 -0
  21. package/cli/commands/refresh.ts +18 -0
  22. package/cli/commands/typecheck.ts +18 -0
  23. package/cli/compiler/client/identite.ts +80 -53
  24. package/cli/compiler/client/index.ts +139 -213
  25. package/cli/compiler/common/bundleAnalysis.ts +94 -0
  26. package/cli/compiler/common/clientManifest.ts +67 -0
  27. package/cli/compiler/common/controllers.ts +288 -0
  28. package/cli/compiler/common/files/autres.ts +7 -18
  29. package/cli/compiler/common/files/images.ts +40 -37
  30. package/cli/compiler/common/files/style.ts +11 -22
  31. package/cli/compiler/common/generatedRouteModules.ts +368 -0
  32. package/cli/compiler/common/index.ts +31 -65
  33. package/cli/compiler/common/loaders/forbid-ssr-import.js +13 -0
  34. package/cli/compiler/common/rspackAliases.ts +13 -0
  35. package/cli/compiler/common/scripts.ts +37 -0
  36. package/cli/compiler/index.ts +781 -230
  37. package/cli/compiler/server/index.ts +59 -75
  38. package/cli/compiler/writeIfChanged.ts +21 -0
  39. package/cli/index.ts +71 -72
  40. package/cli/paths.ts +51 -57
  41. package/cli/print.ts +17 -11
  42. package/cli/tsconfig.json +5 -4
  43. package/cli/utils/agents.ts +100 -0
  44. package/cli/utils/check.ts +71 -0
  45. package/cli/utils/index.ts +1 -3
  46. package/cli/utils/keyboard.ts +8 -25
  47. package/cli/utils/runProcess.ts +30 -0
  48. package/client/app/component.tsx +29 -29
  49. package/client/app/index.ts +36 -57
  50. package/client/app/service.ts +7 -12
  51. package/client/app.tsconfig.json +2 -2
  52. package/client/components/Dialog/Manager.ssr.tsx +40 -0
  53. package/client/components/Dialog/Manager.tsx +119 -150
  54. package/client/components/Dialog/status.tsx +3 -3
  55. package/client/components/index.ts +1 -1
  56. package/client/components/types.d.ts +1 -3
  57. package/client/dev/hmr.ts +65 -0
  58. package/client/global.d.ts +2 -2
  59. package/client/hooks.ts +6 -9
  60. package/client/index.ts +2 -1
  61. package/client/islands/index.ts +7 -0
  62. package/client/islands/useDeferredModule.ts +199 -0
  63. package/client/pages/_layout/index.tsx +4 -12
  64. package/client/pages/useHeader.tsx +14 -21
  65. package/client/router.ts +27 -0
  66. package/client/services/router/components/Link.tsx +34 -27
  67. package/client/services/router/components/Page.tsx +6 -14
  68. package/client/services/router/components/router.ssr.tsx +36 -0
  69. package/client/services/router/components/router.tsx +63 -83
  70. package/client/services/router/index.tsx +185 -220
  71. package/client/services/router/request/api.ts +97 -119
  72. package/client/services/router/request/history.ts +2 -2
  73. package/client/services/router/request/index.ts +13 -12
  74. package/client/services/router/request/multipart.ts +72 -62
  75. package/client/services/router/response/index.tsx +68 -61
  76. package/client/services/router/response/page.ts +28 -32
  77. package/client/utils/dom.ts +17 -33
  78. package/common/app/index.ts +3 -3
  79. package/common/data/chaines/index.ts +22 -23
  80. package/common/data/dates.ts +35 -70
  81. package/common/data/markdown.ts +42 -39
  82. package/common/dev/serverHotReload.ts +26 -0
  83. package/common/errors/index.tsx +110 -142
  84. package/common/router/contracts.ts +29 -0
  85. package/common/router/index.ts +89 -108
  86. package/common/router/layouts.ts +34 -47
  87. package/common/router/pageSetup.ts +50 -0
  88. package/common/router/register.ts +53 -24
  89. package/common/router/request/api.ts +30 -36
  90. package/common/router/request/index.ts +2 -8
  91. package/common/router/response/index.ts +8 -15
  92. package/common/router/response/page.ts +70 -58
  93. package/common/utils.ts +1 -1
  94. package/doc/TODO.md +1 -1
  95. package/eslint.js +62 -0
  96. package/package.json +14 -49
  97. package/prettier.config.cjs +9 -0
  98. package/scripts/cleanup-generated-controllers.ts +62 -0
  99. package/scripts/fix-reference-app-typing.ts +490 -0
  100. package/scripts/refactor-client-app-imports.ts +244 -0
  101. package/scripts/refactor-client-pages.ts +587 -0
  102. package/scripts/refactor-server-controllers.ts +470 -0
  103. package/scripts/refactor-server-runtime-aliases.ts +360 -0
  104. package/scripts/restore-client-app-import-files.ts +41 -0
  105. package/scripts/restore-files-from-git-head.ts +20 -0
  106. package/scripts/update-codex-agents.ts +35 -0
  107. package/server/app/commands.ts +35 -64
  108. package/server/app/container/config.ts +48 -59
  109. package/server/app/container/console/index.ts +202 -248
  110. package/server/app/container/index.ts +33 -71
  111. package/server/app/controller/index.ts +61 -0
  112. package/server/app/index.ts +39 -105
  113. package/server/app/service/container.ts +41 -42
  114. package/server/app/service/index.ts +120 -147
  115. package/server/context.ts +1 -1
  116. package/server/index.ts +25 -1
  117. package/server/services/auth/index.ts +75 -115
  118. package/server/services/auth/router/index.ts +31 -32
  119. package/server/services/auth/router/request.ts +14 -16
  120. package/server/services/cron/CronTask.ts +13 -26
  121. package/server/services/cron/index.ts +14 -36
  122. package/server/services/disks/driver.ts +40 -58
  123. package/server/services/disks/drivers/local/index.ts +79 -90
  124. package/server/services/disks/drivers/s3/index.ts +116 -163
  125. package/server/services/disks/index.ts +23 -38
  126. package/server/services/email/index.ts +45 -104
  127. package/server/services/email/utils.ts +14 -27
  128. package/server/services/fetch/index.ts +53 -85
  129. package/server/services/prisma/Facet.ts +39 -91
  130. package/server/services/prisma/index.ts +74 -110
  131. package/server/services/router/generatedRuntime.ts +29 -0
  132. package/server/services/router/http/index.ts +78 -73
  133. package/server/services/router/http/multipart.ts +19 -42
  134. package/server/services/router/index.ts +378 -365
  135. package/server/services/router/request/api.ts +26 -25
  136. package/server/services/router/request/index.ts +44 -51
  137. package/server/services/router/request/service.ts +7 -11
  138. package/server/services/router/request/validation/zod.ts +111 -148
  139. package/server/services/router/response/index.ts +110 -125
  140. package/server/services/router/response/mask/Filter.ts +31 -72
  141. package/server/services/router/response/mask/index.ts +8 -15
  142. package/server/services/router/response/mask/selecteurs.ts +11 -25
  143. package/server/services/router/response/page/clientManifest.ts +25 -0
  144. package/server/services/router/response/page/document.tsx +199 -127
  145. package/server/services/router/response/page/index.tsx +89 -94
  146. package/server/services/router/service.ts +13 -15
  147. package/server/services/schema/index.ts +17 -26
  148. package/server/services/schema/request.ts +19 -33
  149. package/server/services/schema/router/index.ts +8 -11
  150. package/server/services/security/encrypt/aes/index.ts +15 -35
  151. package/server/utils/slug.ts +29 -35
  152. package/skills/clean-project-code/SKILL.md +63 -0
  153. package/skills/clean-project-code/agents/openai.yaml +4 -0
  154. package/tsconfig.common.json +4 -3
  155. package/tsconfig.json +4 -1
  156. package/types/aliases.d.ts +17 -21
  157. package/types/controller-input.test.ts +48 -0
  158. package/types/express-extra.d.ts +6 -0
  159. package/types/global/constants.d.ts +13 -0
  160. package/types/global/express-extra.d.ts +6 -0
  161. package/types/global/modules.d.ts +13 -16
  162. package/types/global/utils.d.ts +17 -49
  163. package/types/global/vendors.d.ts +62 -0
  164. package/types/icons.d.ts +65 -1
  165. package/types/uuid.d.ts +3 -0
  166. package/types/vendors.d.ts +62 -0
  167. package/cli/compiler/common/babel/index.ts +0 -170
  168. package/cli/compiler/common/babel/plugins/index.ts +0 -0
  169. package/cli/compiler/common/babel/plugins/services.ts +0 -586
  170. package/cli/compiler/common/babel/routes/imports.ts +0 -127
  171. package/cli/compiler/common/babel/routes/routes.ts +0 -1130
  172. package/client/services/captcha/index.ts +0 -67
  173. package/client/services/socket/index.ts +0 -147
  174. package/common/data/rte/nodes.ts +0 -83
  175. package/common/data/stats.ts +0 -90
  176. package/common/utils/rte.ts +0 -183
  177. package/server/services/auth/old.ts +0 -277
  178. package/server/services/cache/commands.ts +0 -41
  179. package/server/services/cache/index.ts +0 -297
  180. package/server/services/cache/service.json +0 -6
  181. package/server/services/socket/index.ts +0 -162
  182. package/server/services/socket/scope.ts +0 -226
  183. package/server/services/socket/service.json +0 -6
  184. package/server/services_old/SocketClient.ts +0 -92
  185. package/server/services_old/Token.old.ts +0 -97
@@ -8,12 +8,9 @@ import type express from 'express';
8
8
  import type http from 'http';
9
9
 
10
10
  // Core
11
- import { Application } from '@server/app';
11
+ import type { Application } from '@server/app/index';
12
12
  import Service from '@server/app/service';
13
- import type { TAnyRouter } from '@server/services/router';
14
- import {
15
- default as Router, Request as ServerRequest,
16
- } from '@server/services/router';
13
+ import { type TAnyRouter, Request as ServerRequest } from '@server/services/router';
17
14
  import { InputError, AuthRequired, Forbidden } from '@common/errors';
18
15
 
19
16
  /*----------------------------------
@@ -44,18 +41,12 @@ declare global {
44
41
  * - If the app does not define a feature catalog, this defaults to `string`.
45
42
  * - Otherwise it becomes the string keys of `ProteumAuthFeatureCatalog`.
46
43
  */
47
- type FeatureKeys = (
48
- keyof ProteumAuthFeatureCatalog extends never
49
- ? string
50
- : Extract<keyof ProteumAuthFeatureCatalog, string>
51
- );
44
+ type FeatureKeys = keyof ProteumAuthFeatureCatalog extends never
45
+ ? string
46
+ : Extract<keyof ProteumAuthFeatureCatalog, string>;
52
47
  }
53
48
 
54
- export type TUserRole = (
55
- typeof UserRoles[number]
56
- |
57
- Extract<keyof ProteumAuthRoleCatalog, string>
58
- );
49
+ export type TUserRole = (typeof UserRoles)[number] | Extract<keyof ProteumAuthRoleCatalog, string>;
59
50
 
60
51
  export type THttpRequest = express.Request | http.IncomingMessage;
61
52
 
@@ -65,40 +56,37 @@ export type TFeatureKey = FeatureKeys;
65
56
  - CONFIG
66
57
  ----------------------------------*/
67
58
 
68
- const LogPrefix = '[auth]'
59
+ const LogPrefix = '[auth]';
69
60
 
70
- export const UserRoles = ['USER', 'ADMIN', 'TEST', 'DEV'] as const
61
+ export const UserRoles = ['USER', 'ADMIN', 'TEST', 'DEV'] as const;
71
62
 
72
63
  /*----------------------------------
73
64
  - SERVICE CONVIG
74
65
  ----------------------------------*/
75
66
 
76
67
  export type TConfig = {
77
- debug: boolean,
78
- logoutUrl: string,
68
+ debug: boolean;
69
+ logoutUrl: string;
79
70
  jwt: {
80
71
  // 2048 bits
81
- key: string,
82
- expiration: number,
83
- },
84
- }
72
+ key: string;
73
+ expiration: number;
74
+ };
75
+ };
85
76
 
86
- export type THooks = {
87
-
88
- }
77
+ export type THooks = {};
89
78
 
90
79
  export type TBasicUser = {
91
- type: string,
92
- name: string | null,
93
- email: string,
94
- roles: string[]
95
- }
80
+ type: string;
81
+ name: string | null;
82
+ email: string;
83
+ roles: string[];
84
+ locale?: string | null;
85
+ };
86
+
87
+ export type TBasicJwtSession = { apiKey: string } | { email: string };
96
88
 
97
- export type TBasicJwtSession = (
98
- { apiKey: string }
99
- |
100
- { email: string }
101
- )
89
+ type TApiKeySession = { apiKey: string; accountType?: string };
102
90
 
103
91
  /*----------------------------------
104
92
  - SERVICE
@@ -109,27 +97,24 @@ export default abstract class AuthService<
109
97
  TJwtSession extends TBasicJwtSession = TBasicJwtSession,
110
98
  TRequest extends ServerRequest<TAnyRouter> = ServerRequest<TAnyRouter>,
111
99
  > extends Service<TConfig, THooks, TApplication, TApplication> {
112
-
113
- //public abstract login( ...args: any[] ): Promise<{ user: TUser, token: string }>;
114
- public abstract decodeSession( jwt: TJwtSession, req: THttpRequest ): Promise<TUser | null>;
100
+ public login?(request: TRequest, email: string): Promise<unknown>;
101
+ public abstract decodeSession(jwt: TJwtSession, req: THttpRequest): Promise<TUser | null>;
115
102
 
116
103
  // https://beeceptor.com/docs/concepts/authorization-header/#examples
117
- public async decode( req: THttpRequest, withData: true ): Promise<TUser | null>;
118
- public async decode( req: THttpRequest, withData?: false ): Promise<TJwtSession | null>;
119
- public async decode( req: THttpRequest, withData: boolean = false ): Promise<TJwtSession | TUser | null> {
104
+ public async decode(req: THttpRequest, withData: true): Promise<TUser | null>;
105
+ public async decode(req: THttpRequest, withData?: false): Promise<TJwtSession | null>;
106
+ public async decode(req: THttpRequest, withData: boolean = false): Promise<TJwtSession | TUser | null> {
107
+ const requestCookies = 'cookies' in req ? req.cookies : undefined;
108
+ this.config.debug && console.log(LogPrefix, 'Decode:', { cookie: requestCookies?.['authorization'] });
120
109
 
121
- this.config.debug && console.log(LogPrefix, 'Decode:', { cookie: req.cookies['authorization'] });
122
-
123
110
  // Get auth token
124
111
  const authMethod = this.getAuthMethod(req);
125
- if (authMethod === null)
126
- return null;
112
+ if (authMethod === null) return null;
127
113
  const { tokenType, token } = authMethod;
128
114
 
129
115
  // Get auth session
130
116
  const session = this.getAuthSession(tokenType, token);
131
- if (session === null)
132
- return null;
117
+ if (session === null) return null;
133
118
 
134
119
  // Return email only
135
120
  if (!withData) {
@@ -140,87 +125,70 @@ export default abstract class AuthService<
140
125
  // Deserialize full user data
141
126
  this.config.debug && console.log(LogPrefix, `Deserialize user`, session);
142
127
  const user = await this.decodeSession(session, req);
143
- if (user === null)
144
- return null;
128
+ if (user === null) return null;
145
129
 
146
130
  this.config.debug && console.log(LogPrefix, `Deserialized user:`, user.name);
147
131
 
148
- return {
149
- ...user,
150
- _token: token
151
- };
132
+ return { ...user, _token: token };
152
133
  }
153
134
 
154
- private getAuthMethod( req: THttpRequest ): null | { token: string, tokenType?: string } {
155
-
135
+ private getAuthMethod(req: THttpRequest): null | { token: string; tokenType?: string } {
156
136
  let token: string | undefined;
157
137
  let tokenType: string | undefined;
158
138
  if (typeof req.headers['authorization'] === 'string') {
159
-
160
- ([ tokenType, token ] = req.headers['authorization'].split(' '));
161
-
162
- } else if (('cookies' in req) && typeof req.cookies['authorization'] === 'string') {
163
-
139
+ [tokenType, token] = req.headers['authorization'].split(' ');
140
+ } else if ('cookies' in req && typeof req.cookies['authorization'] === 'string') {
164
141
  token = req.cookies['authorization'];
165
142
  tokenType = 'Bearer';
143
+ } else return null;
166
144
 
167
- } else
168
- return null;
169
-
170
- if (token === undefined)
171
- return null;
145
+ if (token === undefined) return null;
172
146
 
173
147
  return { tokenType, token };
174
148
  }
175
149
 
176
- private getAuthSession( tokenType: string | undefined, token: string ): TJwtSession | null {
177
-
150
+ private getAuthSession(tokenType: string | undefined, token: string): TJwtSession | null {
178
151
  let session: TJwtSession;
179
152
 
180
153
  // API Key
181
154
  if (tokenType === 'Apikey') {
182
-
183
155
  const [accountType] = token.split('-');
156
+ const apiKeySession = { accountType, apiKey: token } satisfies TApiKeySession;
184
157
 
185
158
  this.config.debug && console.log(LogPrefix, `Auth via API Key`, token);
186
- session = { accountType, apiKey: token } as TJwtSession;
159
+ session = apiKeySession as TJwtSession & TApiKeySession;
187
160
 
188
- // JWT
161
+ // JWT
189
162
  } else if (tokenType === 'Bearer') {
190
163
  this.config.debug && console.log(LogPrefix, `Auth via JWT token`, token);
191
164
  try {
192
- session = jwt.verify(token, this.config.jwt.key, {
193
- maxAge: this.config.jwt.expiration
194
- });
165
+ session = jwt.verify(token, this.config.jwt.key, {
166
+ maxAge: this.config.jwt.expiration,
167
+ }) as TJwtSession;
195
168
  } catch (error) {
196
- console.warn(LogPrefix, "Failed to decode jwt token:", token);
169
+ console.warn(LogPrefix, 'Failed to decode jwt token:', token);
197
170
  return null;
198
171
  //throw new Forbidden(`The JWT token provided in the Authorization header is invalid`);
199
172
  }
200
- } else
201
- return null;
202
- //throw new InputError(`The authorization scheme provided in the Authorization header is unsupported.`);
173
+ } else return null;
174
+ //throw new InputError(`The authorization scheme provided in the Authorization header is unsupported.`);
203
175
 
204
176
  return session;
205
177
  }
206
178
 
207
- public createSession( session: TJwtSession, request2: TRequest ): string {
208
-
179
+ public createSession(session: TJwtSession, request2: TRequest): string {
209
180
  this.config.debug && console.info(LogPrefix, `Creating new session:`, session);
210
181
 
211
182
  const token = jwt.sign(session, this.config.jwt.key);
212
183
 
213
184
  this.config.debug && console.info(LogPrefix, `Generated JWT token for session:` + token);
214
185
 
215
- request2.res.cookie('authorization', token, {
216
- maxAge: this.config.jwt.expiration,
217
- });
186
+ request2.res.cookie('authorization', token, { maxAge: this.config.jwt.expiration });
218
187
 
219
188
  return token;
220
189
  }
221
190
 
222
- public logout( request: TRequest ) {
223
-
191
+ public logout(request: TRequest) {
224
192
  const user = request.user;
225
193
  if (!user) return;
226
194
 
@@ -228,58 +196,50 @@ export default abstract class AuthService<
228
196
  request.res.clearCookie('authorization');
229
197
  }
230
198
 
231
- public check(
232
- request: TRequest,
233
- role?: TUserRole | false,
234
- ): TUser | null;
199
+ public check(request: TRequest, role?: TUserRole | boolean): TUser | null;
235
200
 
236
- public check(
237
- request: TRequest,
238
- role: TUserRole | false,
239
- feature: FeatureKeys,
240
- action?: string,
241
- ): TUser | null;
201
+ public check(request: TRequest, role: TUserRole | boolean, feature: FeatureKeys, action?: string): TUser | null;
242
202
 
243
203
  public check(
244
204
  request: TRequest,
245
- role: TUserRole | false = 'USER',
205
+ role: TUserRole | boolean = 'USER',
246
206
  feature?: FeatureKeys,
247
207
  action?: string,
248
208
  ): TUser | null {
249
-
209
+ const normalizedRole = role === true ? 'USER' : role;
250
210
  const user = request.user;
251
211
 
252
- this.config.debug && console.warn(LogPrefix, `Check auth, role = ${role}. Current user =`, user?.name, feature);
212
+ this.config.debug &&
213
+ console.warn(LogPrefix, `Check auth, role = ${normalizedRole}. Current user =`, user?.name, feature);
253
214
 
254
215
  if (user === undefined) {
255
-
256
216
  throw new Error(`request.user has not been decoded.`);
257
217
 
258
- // Shoudln't be logged
259
- } else if (role === false) {
260
-
218
+ // Shoudln't be logged
219
+ } else if (normalizedRole === false) {
261
220
  return user as TUser;
262
221
 
263
- // Not connected
222
+ // Not connected
264
223
  } else if (user === null) {
265
-
266
- console.warn(LogPrefix, "Refusé pour anonyme (" + request.ip + ")");
224
+ console.warn(LogPrefix, 'Refusé pour anonyme (' + request.ip + ')');
267
225
  throw new AuthRequired('Please login to continue', feature as any, action as any);
268
-
269
- // Insufficient permissions
270
- } else if (!user.roles.includes(role)) {
271
-
272
- console.warn(LogPrefix, "Refusé: " + role + " pour " + user.name + " (" + (user.roles || 'role inconnu') + ")");
273
226
 
274
- throw new Forbidden("You do not have sufficient permissions to access this resource.");
227
+ // Insufficient permissions
228
+ } else if (!user.roles.includes(normalizedRole)) {
229
+ console.warn(
230
+ LogPrefix,
231
+ 'Refusé: ' + normalizedRole + ' pour ' + user.name + ' (' + (user.roles || 'role inconnu') + ')',
232
+ );
275
233
 
234
+ throw new Forbidden('You do not have sufficient permissions to access this resource.');
276
235
  } else {
277
-
278
- this.config.debug && console.warn(LogPrefix, "Autorisé " + role + " pour " + user.name + " (" + user.roles + ")");
279
-
236
+ this.config.debug &&
237
+ console.warn(
238
+ LogPrefix,
239
+ 'Autorisé ' + normalizedRole + ' pour ' + user.name + ' (' + user.roles + ')',
240
+ );
280
241
  }
281
242
 
282
243
  return user as TUser;
283
244
  }
284
-
285
245
  }
@@ -5,12 +5,15 @@
5
5
  // Npm
6
6
 
7
7
  // Core
8
- import {
9
- default as Router, Request as ServerRequest, Response as ServerResponse, TAnyRoute,
10
- RouterService, TAnyRouter
8
+ import {
9
+ Request as ServerRequest,
10
+ Response as ServerResponse,
11
+ TAnyRoute,
12
+ RouterService,
13
+ TAnyRouter,
11
14
  } from '@server/services/router';
12
15
 
13
- import type { Application } from '@server/app';
16
+ import type { Application } from '@server/app/index';
14
17
 
15
18
  import type { TRouterServiceArgs } from '@server/services/router/service';
16
19
 
@@ -22,7 +25,6 @@ import UsersRequestService from './request';
22
25
  - TYPES
23
26
  ----------------------------------*/
24
27
 
25
-
26
28
  /*----------------------------------
27
29
  - CONFIG
28
30
  ----------------------------------*/
@@ -34,62 +36,59 @@ const LogPrefix = '[router][auth]';
34
36
  ----------------------------------*/
35
37
  export default class AuthenticationRouterService<
36
38
  TApplication extends Application = Application,
37
- TUser extends TBasicUser = TApplication["app"]["userType"],
39
+ TUser extends TBasicUser = TApplication['app']['userType'],
38
40
  TRouter extends TAnyRouter = TAnyRouter,
39
41
  TRequest extends ServerRequest<TRouter> = ServerRequest<TRouter>,
40
- > extends RouterService<{}, TRouter> {
41
-
42
+ > extends RouterService<
43
+ { users: UsersService<TUser, TApplication> },
44
+ TRouter,
45
+ UsersRequestService<TRouter, TUser, TRequest>
46
+ > {
42
47
  /*----------------------------------
43
48
  - LIFECYCLE
44
49
  ----------------------------------*/
45
50
 
46
- public users: UsersService<TUser, Application>;
51
+ public users: UsersService<TUser, TApplication>;
47
52
 
48
- public constructor( getConfig: TRouterServiceArgs[0], app: TApplication ) {
49
- super( getConfig, app );
53
+ public constructor(
54
+ getConfig: TRouterServiceArgs<{ users: UsersService<TUser, TApplication> }, TRouter>[0],
55
+ app: TApplication,
56
+ ) {
57
+ super(getConfig, app);
50
58
 
51
59
  this.users = this.config.users;
52
60
  }
53
61
 
54
- protected async ready() {
55
-
62
+ public async ready() {
56
63
  // Decode current user
57
64
  this.parent.on('request', async (request: TRequest) => {
58
-
59
65
  // TODO: Typings. (context.user ?)
60
- const decoded = await this.users.decode( request.req, true);
66
+ const decoded = await this.users.decode(request.req, true);
61
67
 
62
68
  request.user = decoded || null;
63
- })
69
+ });
64
70
 
65
71
  // Check route permissions
66
- this.parent.on('resolved', async (
67
- route: TAnyRoute,
68
- request: TRequest,
69
- response: ServerResponse<TRouter>
70
- ) => {
71
-
72
+ this.parent.on('resolved', async (route: TAnyRoute, request: TRequest, response: ServerResponse<TRouter>) => {
72
73
  if (route.options.auth !== undefined) {
73
-
74
74
  // Basic auth check
75
- this.users.check(request, route.options.auth);
75
+ const requiredRole = route.options.auth === true ? 'USER' : route.options.auth;
76
+ this.users.check(request, requiredRole as TUserRole | false);
76
77
 
77
78
  // Redirect to logged page
78
79
  if (route.options.auth === false && request.user && route.options.redirectLogged)
79
80
  response.redirect(route.options.redirectLogged);
80
81
  }
81
- })
82
+ });
82
83
  }
83
84
 
84
- protected async shutdown() {
85
-
86
- }
85
+ public async shutdown() {}
87
86
 
88
87
  /*----------------------------------
89
88
  - ROUTER SERVICE LIFECYCLE
90
89
  ----------------------------------*/
91
90
 
92
- public requestService( request: TRequest ): UsersRequestService<TRouter, TUser> {
93
- return new UsersRequestService( request, this );
94
- }
95
- }
91
+ public requestService(request: TRequest): UsersRequestService<TRouter, TUser, TRequest> {
92
+ return new UsersRequestService(request, this);
93
+ }
94
+ }
@@ -6,7 +6,7 @@
6
6
  import jwt from 'jsonwebtoken';
7
7
 
8
8
  // Core
9
- import type { default as Router, Request as ServerRequest, TAnyRouter } from '@server/services/router';
9
+ import type { Request as ServerRequest, TAnyRouter } from '@server/services/router';
10
10
  import RequestService from '@server/services/router/request/service';
11
11
 
12
12
  // Specific
@@ -25,23 +25,24 @@ import type { TBasicUser } from '@server/services/auth';
25
25
  ----------------------------------*/
26
26
  export default class UsersRequestService<
27
27
  TRouter extends TAnyRouter,
28
- TUser extends TBasicUser
29
- > extends RequestService {
30
-
31
- public constructor(
32
- request: ServerRequest<TRouter>,
33
- public auth: AuthenticationRouterService,
28
+ TUser extends TBasicUser,
29
+ TRequest extends ServerRequest<TRouter> = ServerRequest<TRouter>,
30
+ > extends RequestService<TRequest> {
31
+ public constructor(
32
+ request: TRequest,
33
+ public auth: AuthenticationRouterService<TRouter['app'], TUser, TRouter, TRequest>,
34
34
  public users = auth.users,
35
35
  ) {
36
36
  super(request);
37
37
  }
38
38
 
39
- public login( email: string ) {
40
- return this.users.login( this.request, email );
39
+ public login(email: string) {
40
+ if (!this.users.login) throw new Error('The current auth service does not implement login().');
41
+ return this.users.login(this.request, email);
41
42
  }
42
43
 
43
44
  public logout() {
44
- return this.users.logout( this.request );
45
+ return this.users.logout(this.request);
45
46
  }
46
47
 
47
48
  public check(): TUser;
@@ -55,11 +56,8 @@ export default class UsersRequestService<
55
56
 
56
57
  public check(role: false, feature: FeatureKeys, action?: string): null;
57
58
 
58
- public check(
59
- role: TUserRole | false = 'USER',
60
- feature?: FeatureKeys | null,
61
- action?: string
62
- ) {
63
- return this.users.check( this.request, role, feature, action ) as any;
59
+ public check(role: TUserRole | false = 'USER', feature?: FeatureKeys | null, action?: string) {
60
+ if (feature === null || feature === undefined) return this.users.check(this.request, role);
61
+ return this.users.check(this.request, role, feature, action);
64
62
  }
65
63
  }
@@ -12,14 +12,13 @@ import cronParser, { CronExpression } from 'cron-parser';
12
12
  import type CronManager from '.';
13
13
 
14
14
  export type TFrequence = string | Date;
15
- export type TRunner = () => Promise<any>
15
+ export type TRunner = () => Promise<any>;
16
16
 
17
17
  /*----------------------------------
18
18
  - CLASS
19
19
  ----------------------------------*/
20
20
  export default class CronTask {
21
-
22
- public cron?: CronExpression
21
+ public cron?: CronExpression;
23
22
  public nextInvocation?: Date;
24
23
 
25
24
  public constructor(
@@ -27,60 +26,48 @@ export default class CronTask {
27
26
  public nom: string,
28
27
  next: TFrequence,
29
28
  public runner: TRunner,
30
- public autoexec?: boolean
29
+ public autoexec?: boolean,
31
30
  ) {
32
-
33
31
  this.manager.config.debug && console.info(`[cron][${this.nom}] Enregistrement de la tâche`);
34
32
 
35
33
  this.schedule(next);
36
-
37
34
  }
38
35
 
39
36
  public schedule(next: TFrequence) {
40
-
41
37
  this.cron = undefined;
42
38
 
43
39
  // Cron expression
44
40
  if (typeof next === 'string') {
45
-
46
41
  this.cron = cronParser.parseExpression(next);
47
42
  this.nextInvocation = this.cron.next().toDate();
48
43
 
49
- this.manager.config.debug &&
44
+ this.manager.config.debug &&
50
45
  console.info(`[cron][${this.nom}] Planifié pour ${this.nextInvocation.toISOString()} via cron ${next}`);
51
46
 
52
47
  // Date
53
48
  } else {
54
-
55
49
  this.nextInvocation = next;
56
- this.manager.config.debug &&
50
+ this.manager.config.debug &&
57
51
  console.info(`[cron][${this.nom}] Planifié pour ${this.nextInvocation.toISOString()} via date`);
58
-
59
52
  }
60
53
  }
61
54
 
62
55
  public scheduleNext() {
63
-
64
56
  // Prochaine invocation
65
- if (this.cron !== undefined)
66
- this.nextInvocation = this.cron.next().toDate();
67
- else
68
- this.nextInvocation = undefined;
57
+ if (this.cron !== undefined) this.nextInvocation = this.cron.next().toDate();
58
+ else this.nextInvocation = undefined;
69
59
  }
70
60
 
71
61
  public run(now: boolean = false) {
72
-
73
62
  // Update invocation date
74
- const maintenant = new Date
75
- const runnable = this.nextInvocation !== undefined && this.nextInvocation.valueOf() <= maintenant.valueOf()
76
- if (runnable)
77
- this.scheduleNext();
78
- else if (now === false)
79
- return;
63
+ const maintenant = new Date();
64
+ const runnable = this.nextInvocation !== undefined && this.nextInvocation.valueOf() <= maintenant.valueOf();
65
+ if (runnable) this.scheduleNext();
66
+ else if (now === false) return;
80
67
 
81
68
  // Execution
82
69
  this.runner().then(() => {
83
70
  this.manager.config.debug && console.info(`Task runned.`);
84
- })
71
+ });
85
72
  }
86
- }
73
+ }