@entity-access/server-pages 1.0.42 → 1.1.2

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 (65) hide show
  1. package/dist/Page.d.ts +6 -13
  2. package/dist/Page.d.ts.map +1 -1
  3. package/dist/Page.js +10 -41
  4. package/dist/Page.js.map +1 -1
  5. package/dist/ServerPages.d.ts.map +1 -1
  6. package/dist/ServerPages.js +14 -2
  7. package/dist/ServerPages.js.map +1 -1
  8. package/dist/core/CacheProperty.d.ts +5 -0
  9. package/dist/core/CacheProperty.d.ts.map +1 -0
  10. package/dist/core/CacheProperty.js +19 -0
  11. package/dist/core/CacheProperty.js.map +1 -0
  12. package/dist/core/Executor.d.ts +5 -0
  13. package/dist/core/Executor.d.ts.map +1 -0
  14. package/dist/core/Executor.js +13 -0
  15. package/dist/core/Executor.js.map +1 -0
  16. package/dist/core/RouteTree.d.ts.map +1 -1
  17. package/dist/core/RouteTree.js +15 -6
  18. package/dist/core/RouteTree.js.map +1 -1
  19. package/dist/core/SessionUser.d.ts +7 -5
  20. package/dist/core/SessionUser.d.ts.map +1 -1
  21. package/dist/core/SessionUser.js +36 -0
  22. package/dist/core/SessionUser.js.map +1 -1
  23. package/dist/core/Wrapped.d.ts +13 -16
  24. package/dist/core/Wrapped.d.ts.map +1 -1
  25. package/dist/core/Wrapped.js +151 -235
  26. package/dist/core/Wrapped.js.map +1 -1
  27. package/dist/decorators/Prepare.d.ts +14 -0
  28. package/dist/decorators/Prepare.d.ts.map +1 -0
  29. package/dist/decorators/Prepare.js +111 -0
  30. package/dist/decorators/Prepare.js.map +1 -0
  31. package/dist/routes/api/entity/index.d.ts.map +1 -1
  32. package/dist/routes/api/entity/index.js +9 -3
  33. package/dist/routes/api/entity/index.js.map +1 -1
  34. package/dist/routes/api/entity/model/get.d.ts.map +1 -1
  35. package/dist/routes/api/entity/model/get.js.map +1 -1
  36. package/dist/routes/api/entity/query/get.d.ts.map +1 -1
  37. package/dist/routes/api/entity/query/get.js +9 -3
  38. package/dist/routes/api/entity/query/get.js.map +1 -1
  39. package/dist/services/CookieService.d.ts.map +1 -1
  40. package/dist/services/CookieService.js +10 -2
  41. package/dist/services/CookieService.js.map +1 -1
  42. package/dist/socket/SocketService.d.ts.map +1 -1
  43. package/dist/socket/SocketService.js +1 -3
  44. package/dist/socket/SocketService.js.map +1 -1
  45. package/dist/tsconfig.tsbuildinfo +1 -1
  46. package/package.json +1 -1
  47. package/src/Page.tsx +11 -51
  48. package/src/ServerPages.ts +14 -2
  49. package/src/core/CacheProperty.ts +18 -0
  50. package/src/core/Executor.ts +16 -0
  51. package/src/core/RouteTree.ts +7 -3
  52. package/src/core/SessionUser.ts +21 -5
  53. package/src/core/Wrapped.ts +206 -270
  54. package/src/decorators/Prepare.ts +132 -0
  55. package/src/index.d.ts +10 -10
  56. package/src/routes/api/entity/index.tsx +4 -1
  57. package/src/routes/api/entity/model/get.tsx +1 -1
  58. package/src/routes/api/entity/query/get.ts +4 -1
  59. package/src/services/CookieService.ts +10 -2
  60. package/src/socket/SocketService.ts +1 -2
  61. package/dist/decorators/Authorize.d.ts +0 -2
  62. package/dist/decorators/Authorize.d.ts.map +0 -1
  63. package/dist/decorators/Authorize.js +0 -3
  64. package/dist/decorators/Authorize.js.map +0 -1
  65. package/src/decorators/Authorize.ts +0 -3
package/src/Page.tsx CHANGED
@@ -45,20 +45,20 @@ export default class Page {
45
45
 
46
46
  response: WrappedResponse;
47
47
 
48
- get query() {
48
+ get query(): any {
49
49
  return this.request?.query;
50
50
  }
51
51
 
52
- get asyncJsonBody() {
53
- return this.request?.asyncJsonBody;
52
+ get body(): any {
53
+ return this.request?.body;
54
54
  }
55
55
 
56
- get asyncForm() {
57
- return this.request?.asyncForm;
56
+ get form() {
57
+ return this.request?.form;
58
58
  }
59
59
 
60
- get asyncParams() {
61
- return this.request?.asyncParams;
60
+ get sessionUser() {
61
+ return this.request?.sessionUser;
62
62
  }
63
63
 
64
64
  get url() {
@@ -75,13 +75,6 @@ export default class Page {
75
75
 
76
76
  childPath: string[];
77
77
 
78
- /**
79
- * List of all paths that were tried before executing this page.
80
- */
81
- notFoundPath: string[];
82
-
83
- sessionUser: SessionUser;
84
-
85
78
  filePath: string;
86
79
 
87
80
  cacheControl: string;
@@ -94,47 +87,14 @@ export default class Page {
94
87
  this.cacheControl = "no-cache, no-store, max-age=0";
95
88
  }
96
89
 
97
- all(): IPageResult | Promise<IPageResult> {
98
- return this.notFound();
90
+ reportError(error) {
91
+ console.error(error);
99
92
  }
100
93
 
101
- readFormData(): Promise<IFormData> {
102
-
103
- return this.formDataPromise ??= (async () => {
104
- let tempFolder: TempFolder;
105
- const result: IFormData = {
106
- fields: {},
107
- files: []
108
- };
109
- const req = this.request;
110
- const bb = busboy({ headers: req.headers , defParamCharset: "utf8" });
111
- const tasks = [];
112
- await new Promise((resolve, reject) => {
113
-
114
- bb.on("field", (name, value) => {
115
- result.fields[name] = value;
116
- });
117
-
118
- bb.on("file", (name, file, info) => {
119
- if(!tempFolder) {
120
- tempFolder = new TempFolder();
121
- this.disposables.push(tempFolder);
122
- }
123
- const tf = tempFolder.get(info.filename, info.mimeType);
124
- tasks.push(tf.writeAll(file).then(() => {
125
- result.files.push(tf);
126
- }));
127
- });
128
- bb.on("error", reject);
129
- bb.on("close", resolve);
130
- req.pipe(bb);
131
- });
132
- await Promise.all(tasks);
133
- return result;
134
- })();
94
+ run(): IPageResult | Promise<IPageResult> {
95
+ return this.notFound();
135
96
  }
136
97
 
137
-
138
98
  protected content(body: string, status = 200, contentType = "text/html") {
139
99
  return Content.create({ body, status, contentType });
140
100
  }
@@ -13,6 +13,10 @@ import { Wrapped } from "./core/Wrapped.js";
13
13
  import { SecureContext } from "node:tls";
14
14
  import AcmeCertificateService, { IAcmeOptions } from "./ssl/AcmeCertificateService.js";
15
15
  import ChallengeServer from "./ssl/ChallengeServer.js";
16
+ import SessionUser from "./core/SessionUser.js";
17
+ import CookieService from "./services/CookieService.js";
18
+ import TokenService from "./services/TokenService.js";
19
+ import Executor from "./core/Executor.js";
16
20
 
17
21
  RegisterSingleton
18
22
  export default class ServerPages {
@@ -145,7 +149,15 @@ export default class ServerPages {
145
149
 
146
150
  using scope = ServiceProvider.createScope(this);
147
151
  let sent = false;
148
- const acceptJson = req.accepts().some((s) => /\/json$/i.test(s));
152
+ const user = scope.resolve(SessionUser);
153
+ user.resp = resp;
154
+ user.authorize = async () => {
155
+ const cookieService = scope.resolve(CookieService);
156
+ const tokenService = scope.resolve(TokenService);
157
+ await cookieService.createSessionUserFromCookie(tokenService.authCookieName, req.remoteIPAddress);
158
+ (user as any).isAuthorized = true;
159
+ };
160
+ const acceptJson = req.accepts("json");
149
161
 
150
162
 
151
163
  try {
@@ -165,7 +177,7 @@ export default class ServerPages {
165
177
  page.childPath = childPath;
166
178
  page.request = req;
167
179
  page.response = resp;
168
- const content = await page.all();
180
+ const content = await Executor.run(page);
169
181
  resp.setHeader("cache-control", page.cacheControl);
170
182
  resp.removeHeader("etag");
171
183
  sent = true;
@@ -0,0 +1,18 @@
1
+ export const CacheProperty = {
2
+ value: (target: any, name: string, value: any) => {
3
+ Object.defineProperty(target, name, {
4
+ value,
5
+ enumerable: true,
6
+ configurable: true
7
+ });
8
+ return value;
9
+ },
10
+ get: (target: any, name: string, get: Function) => {
11
+ Object.defineProperty(target, name, {
12
+ get: get as any,
13
+ enumerable: true,
14
+ configurable: true
15
+ });
16
+ return get.call(target);
17
+ }
18
+ };
@@ -0,0 +1,16 @@
1
+ import Page from "../Page.js";
2
+ import { prepareSymbol } from "../decorators/Prepare.js";
3
+
4
+ export default class Executor {
5
+
6
+ public static async run(c: Page) {
7
+ let ps = c.constructor[prepareSymbol];
8
+ if (ps) {
9
+ for (const iterator of ps) {
10
+ await iterator();
11
+ }
12
+ }
13
+ return c.run();
14
+ }
15
+
16
+ }
@@ -1,10 +1,10 @@
1
1
  import { readdirSync } from "fs";
2
2
  import { join } from "path";
3
3
  import Page from "../Page.js";
4
- import SessionUser from "./SessionUser.js";
5
4
  import { IRouteCheck, isPage } from "../Page.js";
6
5
  import { pathToFileURL } from "url";
7
6
  import Content, { IPageResult } from "../Content.js";
7
+ import { prepareSymbol } from "../decorators/Prepare.js";
8
8
 
9
9
  export interface IRouteHandler {
10
10
  get?: Promise<typeof Page>;
@@ -113,12 +113,16 @@ export default class RouteTree {
113
113
  if (pageClass[isPage]) {
114
114
  return pageClass as typeof Page;
115
115
  }
116
- return class extends Page {
117
- async all() {
116
+ const c = class extends Page {
117
+
118
+ [prepareSymbol] = pageClass[prepareSymbol];
119
+
120
+ async run() {
118
121
  const r = await pageClass.call(this);
119
122
  return Content.create(r);
120
123
  }
121
124
  }
125
+ return c;
122
126
  })();
123
127
 
124
128
  (this.handler ??= {})[name] = promise;
@@ -14,27 +14,37 @@ export default class SessionUser {
14
14
  /**
15
15
  * SessionID saved in database for current session.
16
16
  */
17
- sessionID: number;
17
+ get sessionID(): number | null {
18
+ throw new Error("Please call Authorize first");
19
+ }
18
20
 
19
21
  /**
20
22
  * UserID
21
23
  */
22
- userID?: number;
24
+ get userID(): number | null {
25
+ throw new Error("Please call Authorize first");
26
+ }
23
27
 
24
28
  /**
25
29
  * Logged in user name
26
30
  */
27
- userName?: string;
31
+ get userName(): string {
32
+ throw new Error("Please call Authorize first");
33
+ }
28
34
 
29
35
  /**
30
36
  * Application Roles, user is associated with.
31
37
  */
32
- roles?: string[];
38
+ get roles(): string[] {
39
+ throw new Error("Please call Authorize first");
40
+ }
33
41
 
34
42
  /**
35
43
  * Expiry date, after which this session is invalid
36
44
  */
37
- expiry?: Date;
45
+ get expiry(): Date {
46
+ throw new Error("Please call Authorize first");
47
+ }
38
48
 
39
49
  /**
40
50
  * If set to true, session is no longer valid.
@@ -49,9 +59,15 @@ export default class SessionUser {
49
59
 
50
60
  public resp: WrappedResponse;
51
61
 
62
+ private isAuthorized = false;
63
+
52
64
  @Inject
53
65
  protected tokenService: TokenService;
54
66
 
67
+ public async authorize() {
68
+ this.isAuthorized = true;
69
+ }
70
+
55
71
  isInRole(role: roles) {
56
72
  return this.roles?.includes(role) ?? false;
57
73
  }