@entity-access/server-pages 1.1.548 → 1.1.552

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 (52) hide show
  1. package/dist/ServerPages.js +3 -3
  2. package/dist/ServerPages.js.map +1 -1
  3. package/dist/core/SessionUser.d.ts +2 -3
  4. package/dist/core/SessionUser.d.ts.map +1 -1
  5. package/dist/core/SessionUser.js +4 -12
  6. package/dist/core/SessionUser.js.map +1 -1
  7. package/dist/services/{AuthenticationService.d.ts → AuthorizationService.d.ts} +9 -3
  8. package/dist/services/AuthorizationService.d.ts.map +1 -0
  9. package/dist/services/AuthorizationService.js +65 -0
  10. package/dist/services/AuthorizationService.js.map +1 -0
  11. package/dist/services/CookieService.d.ts +1 -8
  12. package/dist/services/CookieService.d.ts.map +1 -1
  13. package/dist/services/CookieService.js +82 -154
  14. package/dist/services/CookieService.js.map +1 -1
  15. package/dist/services/IAuthKey.d.ts +7 -0
  16. package/dist/services/IAuthKey.d.ts.map +1 -0
  17. package/dist/services/IAuthKey.js +2 -0
  18. package/dist/services/IAuthKey.js.map +1 -0
  19. package/dist/services/IAuthorizationCookie.d.ts +2 -4
  20. package/dist/services/IAuthorizationCookie.d.ts.map +1 -1
  21. package/dist/services/KeyProvider.d.ts +1 -0
  22. package/dist/services/KeyProvider.d.ts.map +1 -1
  23. package/dist/services/KeyProvider.js +1 -0
  24. package/dist/services/KeyProvider.js.map +1 -1
  25. package/dist/socket/SocketService.d.ts +0 -1
  26. package/dist/socket/SocketService.d.ts.map +1 -1
  27. package/dist/socket/SocketService.js +4 -18
  28. package/dist/socket/SocketService.js.map +1 -1
  29. package/dist/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +1 -1
  31. package/src/ServerPages.ts +3 -3
  32. package/src/core/SessionUser.ts +5 -8
  33. package/src/services/AuthorizationService.ts +73 -0
  34. package/src/services/CookieService.ts +89 -157
  35. package/src/services/IAuthKey.ts +7 -0
  36. package/src/services/IAuthorizationCookie.ts +2 -4
  37. package/src/services/KeyProvider.ts +2 -0
  38. package/src/socket/SocketService.ts +4 -12
  39. package/dist/services/AuthenticationService.d.ts.map +0 -1
  40. package/dist/services/AuthenticationService.js +0 -40
  41. package/dist/services/AuthenticationService.js.map +0 -1
  42. package/dist/services/TokenService.d.ts +0 -31
  43. package/dist/services/TokenService.d.ts.map +0 -1
  44. package/dist/services/TokenService.js +0 -60
  45. package/dist/services/TokenService.js.map +0 -1
  46. package/dist/services/UserSessionProvider.d.ts +0 -6
  47. package/dist/services/UserSessionProvider.d.ts.map +0 -1
  48. package/dist/services/UserSessionProvider.js +0 -10
  49. package/dist/services/UserSessionProvider.js.map +0 -1
  50. package/src/services/AuthenticationService.ts +0 -44
  51. package/src/services/TokenService.ts +0 -81
  52. package/src/services/UserSessionProvider.ts +0 -16
@@ -0,0 +1,73 @@
1
+ import { RegisterSingleton, ServiceProvider } from "@entity-access/entity-access/dist/di/di.js";
2
+ import { SessionUser } from "../core/SessionUser.js";
3
+ import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
4
+ import type { IAuthorizationCookie } from "./IAuthorizationCookie.js";
5
+ import type { SerializeOptions } from "cookie";
6
+ import KeyProvider from "./KeyProvider.js";
7
+ import { privateDecrypt, publicEncrypt } from "node:crypto";
8
+
9
+ const secure = (process.env["SOCIAL_MAIL_AUTH_COOKIE_SECURE"] ?? "true") === "true";
10
+
11
+ export interface ICookie {
12
+ name: string,
13
+ value: string,
14
+ options?: SerializeOptions
15
+ }
16
+ @RegisterSingleton
17
+ export default class AuthorizationService {
18
+
19
+ authCookieName = "ec-1";
20
+ keyProvider: any;
21
+
22
+ async authorizeRequest(user: SessionUser, { ip, cookies }: { ip: string, cookies: Record<string, string>}) {
23
+ const cookie = cookies[this.authCookieName];
24
+ if (!cookie) {
25
+ return;
26
+ }
27
+ await this.loadUserSessionFromCookie(cookie, user);
28
+ }
29
+
30
+ async loadUserSessionFromCookie(cookie: string, user: SessionUser) {
31
+ const sessionID = await this.decode(cookie);
32
+ user.sessionID = sessionID;
33
+ // load session...
34
+ await this.loadSession(sessionID, user);
35
+ (user as any).isAuthorized = true;
36
+ }
37
+
38
+ async loadSession(sessionID, user: SessionUser): Promise<void> {
39
+ user.userID = sessionID;
40
+ }
41
+
42
+ async setAuthCookie(user: SessionUser, authCookie: IAuthorizationCookie): Promise<ICookie> {
43
+
44
+ const maxAge = ((authCookie?.expiry ? DateTime.from(authCookie.expiry) : null) ?? DateTime.now.addDays(30)).diff(DateTime.now).totalMilliseconds;
45
+ const name = this.authCookieName;
46
+ const value = await this.encode(authCookie?.sessionID ?? authCookie?.userID ?? "0");
47
+ const options = {
48
+ secure,
49
+ httpOnly: true,
50
+ maxAge
51
+ };
52
+ return { name, value, options };
53
+ }
54
+
55
+ async decode(cookie: string) {
56
+ this.keyProvider ??= ServiceProvider.resolve(this, KeyProvider, true) ?? new KeyProvider();
57
+ const keys = await this.keyProvider.getKeys();
58
+ const[id, value] = cookie.split(":")
59
+ for (const key of keys) {
60
+ if(key.id == id) {
61
+ return privateDecrypt(key.privateKey, value) as any as number;
62
+ }
63
+ }
64
+ throw new Error("no suitable key found");
65
+ }
66
+
67
+ async encode(sessionID) {
68
+ this.keyProvider ??= ServiceProvider.resolve(this, KeyProvider, true) ?? new KeyProvider();
69
+ const [key] = await this.keyProvider.getKeys();
70
+ return key.id + ":" + publicEncrypt(key.publicKey, sessionID.toString()).toString("base64url");
71
+ }
72
+
73
+ }
@@ -1,157 +1,89 @@
1
- import Inject, { RegisterScoped, RegisterSingleton, ServiceProvider } from "@entity-access/entity-access/dist/di/di.js";
2
- import TokenService, { IAuthCookie } from "./TokenService.js";
3
- import TimedCache from "@entity-access/entity-access/dist/common/cache/TimedCache.js";
4
- import { BaseDriver } from "@entity-access/entity-access/dist/drivers/base/BaseDriver.js";
5
- import cluster from "cluster";
6
- import { SessionUser } from "../core/SessionUser.js";
7
- import UserSessionProvider from "./UserSessionProvider.js";
8
- import { WrappedResponse } from "../core/Wrapped.js";
9
-
10
- /**
11
- * This will track userID,cookie pair so we can
12
- * clear the logged in user's file permissions
13
- */
14
- const userCookies = new Map<number,string>();
15
- const sessionCache = new TimedCache<string, Partial<SessionUser>>();
16
-
17
- let cookieName = null;
18
-
19
- const tagForCache = Symbol("tagForCache");
20
-
21
- const cacheFR = new FinalizationRegistry<number>((heldValue) => {
22
- userCookies.delete(heldValue);
23
- });
24
-
25
- const clearCache = (userID, broadcast = true) => {
26
- const cookie = userCookies.get(userID);
27
- if (cookie) {
28
- sessionCache.delete(cookie);
29
- }
30
- if (!broadcast) {
31
- return;
32
- }
33
- const clearMessage = {
34
- type: "cookie-service-clear-cache",
35
- userID
36
- };
37
- if (cluster.isWorker) {
38
- process.send(clearMessage);
39
- } else {
40
- if(cluster.workers) {
41
- for (const key in cluster.workers) {
42
- if (Object.prototype.hasOwnProperty.call(cluster.workers, key)) {
43
- const element = cluster.workers[key];
44
- element.send(clearMessage);
45
- }
46
- }
47
- }
48
- }
49
- };
50
-
51
- process.on("message", (msg: any) => {
52
- if (msg.type === "cookie-service-clear-cache") {
53
- clearCache(msg.userID, false);
54
- }
55
- });
56
-
57
- @RegisterScoped
58
- export default class CookieService {
59
-
60
- @Inject
61
- private tokenService: TokenService;
62
-
63
- public clearCache = clearCache;
64
-
65
- async createSessionUserFromCookie(cookie: string, ip: string) {
66
- const user = ServiceProvider.resolve(this, SessionUser);
67
- const ua = user as any;
68
- ua.isAuthorized = true;
69
- const value = null;
70
- const userID = { value, enumerable: true, writable: true};
71
- const sessionID = userID;
72
- const userName = userID;
73
- const expiry = userID;
74
- Object.defineProperties(ua, {
75
- authorize: {
76
- value: () => null
77
- },
78
- sessionID,
79
- userID,
80
- userName,
81
- expiry,
82
- roles: {
83
- value: [],
84
- enumerable: true,
85
- writable: true
86
- }
87
- });
88
- try {
89
- user.ipAddress = ip;
90
- if (cookie) {
91
- const userInfo = await this.getVerifiedUser(cookie);
92
- if (userInfo?.sessionID) {
93
- (user as any).sessionID = userInfo.sessionID;
94
- }
95
- if (userInfo?.userID) {
96
- user[tagForCache] = userInfo;
97
- for (const key in userInfo) {
98
- if (Object.prototype.hasOwnProperty.call(userInfo, key)) {
99
- const element = userInfo[key];
100
- user[key] = element;
101
- }
102
- }
103
- }
104
- }
105
- return user;
106
- } catch (error) {
107
- console.error(error);
108
- return user;
109
- }
110
- }
111
-
112
- private getVerifiedUser(cookie: string): Promise<Partial<SessionUser>> {
113
-
114
- return sessionCache.getOrCreateAsync(cookie, async (k) => {
115
-
116
- const parsedCookie = JSON.parse(cookie) as IAuthCookie;
117
- if (!parsedCookie.id) {
118
- return {};
119
- }
120
-
121
- if (typeof parsedCookie.expiry === "string") {
122
- parsedCookie.expiry = new Date(parsedCookie.expiry);
123
- }
124
-
125
- if(!await this.tokenService.verifyContent(parsedCookie, false)) {
126
- console.warn(`Cookie Verification failed for ${parsedCookie.id}: ${parsedCookie.userID}`);
127
- return {};
128
- }
129
-
130
- if (!parsedCookie.active) {
131
- return {
132
- sessionID: parsedCookie.id
133
- };
134
- }
135
-
136
- const r = await this.createUserInfo(cookie, parsedCookie);
137
- return r;
138
- });
139
- }
140
-
141
- private async createUserInfo(cookie: string, parsedCookie: IAuthCookie) {
142
- const usp = ServiceProvider.resolve(this, UserSessionProvider, true) ?? new UserSessionProvider();
143
- const r = await usp.getUserSession(parsedCookie);
144
- if (r === null) {
145
- console.warn(`Failed to get userSession for ${parsedCookie.id}: ${parsedCookie.userID}`);
146
- return {};
147
- }
148
- if (r.expiry.getTime() < Date.now() || r.invalid) {
149
- console.warn(`Session expired for ${parsedCookie.id}: ${parsedCookie.userID}`);
150
- return {};
151
- }
152
- cacheFR.register(r, r.userID);
153
- userCookies.set(r.userID, cookie);
154
- return r;
155
- }
156
-
157
- }
1
+ // import Inject, { RegisterScoped, RegisterSingleton, ServiceProvider } from "@entity-access/entity-access/dist/di/di.js";
2
+ // import TokenService, { IAuthCookie } from "./TokenService.js";
3
+ // import TimedCache from "@entity-access/entity-access/dist/common/cache/TimedCache.js";
4
+ // import { BaseDriver } from "@entity-access/entity-access/dist/drivers/base/BaseDriver.js";
5
+ // import cluster from "cluster";
6
+ // import { SessionUser } from "../core/SessionUser.js";
7
+ // import UserSessionProvider from "./UserSessionProvider.js";
8
+ // import { WrappedResponse } from "../core/Wrapped.js";
9
+
10
+ // let cookieName = null;
11
+
12
+ // @RegisterScoped
13
+ // export default class CookieService {
14
+
15
+ // @Inject
16
+ // private tokenService: TokenService;
17
+
18
+ // async createSessionUserFromCookie(cookie: string, ip: string) {
19
+ // const user = ServiceProvider.resolve(this, SessionUser);
20
+ // const ua = user as any;
21
+ // ua.isAuthorized = true;
22
+ // const value = null;
23
+ // const userID = { value, enumerable: true, writable: true};
24
+ // const sessionID = userID;
25
+ // const userName = userID;
26
+ // const expiry = userID;
27
+ // Object.defineProperties(ua, {
28
+ // authorize: {
29
+ // value: () => null
30
+ // },
31
+ // sessionID,
32
+ // userID,
33
+ // userName,
34
+ // expiry,
35
+ // roles: {
36
+ // value: [],
37
+ // enumerable: true,
38
+ // writable: true
39
+ // }
40
+ // });
41
+ // try {
42
+ // user.ipAddress = ip;
43
+ // if (cookie) {
44
+ // const userInfo = await this.getVerifiedUser(cookie);
45
+ // if (userInfo?.sessionID) {
46
+ // (user as any).sessionID = userInfo.sessionID;
47
+ // }
48
+ // if (userInfo?.userID) {
49
+ // for (const key in userInfo) {
50
+ // if (Object.prototype.hasOwnProperty.call(userInfo, key)) {
51
+ // const element = userInfo[key];
52
+ // user[key] = element;
53
+ // }
54
+ // }
55
+ // }
56
+ // }
57
+ // return user;
58
+ // } catch (error) {
59
+ // console.error(error);
60
+ // return user;
61
+ // }
62
+ // }
63
+
64
+ // private getVerifiedUser(cookie: string): Promise<Partial<SessionUser>> {
65
+
66
+ // return sessionCache.getOrCreateAsync(cookie, async (k) => {
67
+ // const parsedCookie = await this.tokenService.decryptContent(cookie);
68
+ // const r = await this.createUserInfo(cookie, parsedCookie);
69
+ // return r;
70
+ // });
71
+ // }
72
+
73
+ // private async createUserInfo(cookie: string, parsedCookie: IAuthCookie) {
74
+ // const usp = ServiceProvider.resolve(this, UserSessionProvider, true) ?? new UserSessionProvider();
75
+ // const r = await usp.getUserSession(parsedCookie);
76
+ // if (r === null) {
77
+ // console.warn(`Failed to get userSession for ${parsedCookie.id}: ${parsedCookie.userID}`);
78
+ // return {};
79
+ // }
80
+ // if (r.expiry.getTime() < Date.now() || r.invalid) {
81
+ // console.warn(`Session expired for ${parsedCookie.id}: ${parsedCookie.userID}`);
82
+ // return {};
83
+ // }
84
+ // cacheFR.register(r, r.userID);
85
+ // userCookies.set(r.userID, cookie);
86
+ // return r;
87
+ // }
88
+
89
+ // }
@@ -0,0 +1,7 @@
1
+ import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
2
+
3
+ export interface IAuthKey {
4
+ publicKey: string,
5
+ privateKey: string,
6
+ expires: DateTime
7
+ }
@@ -1,7 +1,5 @@
1
1
  export interface IAuthorizationCookie {
2
- id: number;
3
- userID: number;
2
+ sessionID: number;
3
+ userID: any;
4
4
  expiry: Date;
5
- version: string;
6
- active?: boolean;
7
5
  }
@@ -5,6 +5,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
5
  import { join } from "node:path";
6
6
 
7
7
  export interface IAuthKey {
8
+ id: number,
8
9
  publicKey: string,
9
10
  privateKey: string,
10
11
  expires: DateTime
@@ -51,6 +52,7 @@ export default class KeyProvider {
51
52
  },
52
53
  (error, publicKey, privateKey) => {
53
54
  resolve({
55
+ id: 1,
54
56
  publicKey,
55
57
  privateKey,
56
58
  expires
@@ -1,23 +1,15 @@
1
1
  /* eslint-disable no-console */
2
- import Inject, { RegisterSingleton, ServiceProvider, injectServiceKeysSymbol } from "@entity-access/entity-access/dist/di/di.js";
3
- import { Http2SecureServer } from "http2";
4
- import { Server as HttpServer } from "http";
5
- import { Server as HttpsServer } from "https";
2
+ import { ServiceProvider, injectServiceKeysSymbol } from "@entity-access/entity-access/dist/di/di.js";
6
3
  import { parse } from "cookie";
7
4
 
8
5
  import { Server, Socket } from "socket.io";
9
- import CookieService from "../services/CookieService.js";
10
- import TokenService from "../services/TokenService.js";
11
6
  import SocketNamespace, { SocketNamespaceClient } from "./SocketNamespace.js";
12
7
  import { camelToChain } from "../core/camelToChain.js";
13
- import AuthenticationService from "../services/AuthenticationService.js";
8
+ import AuthorizationService from "../services/AuthorizationService.js";
14
9
  import { SessionUser } from "../core/SessionUser.js";
15
10
 
16
11
  export default abstract class SocketService {
17
12
 
18
- @Inject
19
- private tokenService: TokenService;
20
-
21
13
  protected server: Server;
22
14
 
23
15
  constructor() {
@@ -70,11 +62,11 @@ export default abstract class SocketService {
70
62
  socket.onAny(async (methodName, ... args: any[]) => {
71
63
  const cookies = parse(socket.request.headers.cookie);
72
64
  const scope = ServiceProvider.createScope(this);
73
- const authService = ServiceProvider.resolve(this, AuthenticationService);
65
+ const authService = ServiceProvider.resolve(this, AuthorizationService);
74
66
  try {
75
67
  const user = scope.resolve(SessionUser);
76
68
  const ip = socket.conn.remoteAddress;
77
- await authService.authorize(user, { ip, cookies });
69
+ await authService.authorizeRequest(user, { ip, cookies });
78
70
  scope.add(Socket, socket);
79
71
  const clientClass = sns.clientClass ?? SocketNamespaceClient;
80
72
  let c = scope.resolve(clientClass, true);
@@ -1 +0,0 @@
1
- {"version":3,"file":"AuthenticationService.d.ts","sourceRoot":"","sources":["../../src/services/AuthenticationService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAIrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAI/C,MAAM,WAAW,OAAO;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,gBAAgB,CAAA;CAC7B;AAED,MAAM,CAAC,OAAO,OAAO,qBAAqB;IAEhC,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAC;IAS5F,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;CAgB7F"}
@@ -1,40 +0,0 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- import { RegisterSingleton, ServiceProvider } from "@entity-access/entity-access/dist/di/di.js";
8
- import CookieService from "./CookieService.js";
9
- import TokenService from "./TokenService.js";
10
- import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
11
- const secure = (process.env["SOCIAL_MAIL_AUTH_COOKIE_SECURE"] ?? "true") === "true";
12
- let AuthenticationService = class AuthenticationService {
13
- async authorize(user, { ip, cookies }) {
14
- const scope = ServiceProvider.from(user);
15
- const cookieService = scope.resolve(CookieService);
16
- const tokenService = scope.resolve(TokenService);
17
- const cookie = cookies[tokenService.authCookieName];
18
- await cookieService.createSessionUserFromCookie(cookie, ip);
19
- user.isAuthorized = true;
20
- }
21
- async setAuthCookie(user, authCookie) {
22
- const scope = ServiceProvider.from(user);
23
- const tokenService = scope.resolve(TokenService);
24
- const cookie = await tokenService.getAuthToken(authCookie);
25
- const maxAge = ((authCookie?.expiry ? DateTime.from(authCookie.expiry) : null) ?? DateTime.now.addDays(30)).diff(DateTime.now).totalMilliseconds;
26
- const name = cookie.cookieName;
27
- const value = cookie.cookie;
28
- const options = {
29
- secure,
30
- httpOnly: true,
31
- maxAge
32
- };
33
- return { name, value, options };
34
- }
35
- };
36
- AuthenticationService = __decorate([
37
- RegisterSingleton
38
- ], AuthenticationService);
39
- export default AuthenticationService;
40
- //# sourceMappingURL=AuthenticationService.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AuthenticationService.js","sourceRoot":"","sources":["../../src/services/AuthenticationService.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAEhG,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAC/C,OAAO,YAAY,MAAM,mBAAmB,CAAC;AAC7C,OAAO,QAAQ,MAAM,qDAAqD,CAAC;AAI3E,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,IAAI,MAAM,CAAC,KAAK,MAAM,CAAC;AAQrE,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IAEtC,KAAK,CAAC,SAAS,CAAC,IAAiB,EAAE,EAAE,EAAE,EAAE,OAAO,EAAkD;QAC9F,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QACnD,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;QACpD,MAAM,aAAa,CAAC,2BAA2B,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC3D,IAAY,CAAC,YAAY,GAAG,IAAI,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAiB,EAAE,UAAgC;QAEnE,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;QAC3D,MAAM,MAAM,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAE,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAC;QAClJ,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC;QAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,MAAM,OAAO,GAAG;YACZ,MAAM;YACN,QAAQ,EAAE,IAAI;YACd,MAAM;SACT,CAAC;QACF,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACpC,CAAC;CAEJ,CAAA;AA3BoB,qBAAqB;IADzC,iBAAiB;GACG,qBAAqB,CA2BzC;eA3BoB,qBAAqB"}
@@ -1,31 +0,0 @@
1
- import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
2
- export interface IAuthCookie {
3
- id: number;
4
- userID: number;
5
- expiry: Date;
6
- sign: string;
7
- version: string;
8
- active?: boolean;
9
- }
10
- export interface IAuthKey {
11
- publicKey: string;
12
- privateKey: string;
13
- expires: DateTime;
14
- }
15
- export type ISignedContent<T> = T & {
16
- sign: string;
17
- };
18
- export default class TokenService {
19
- authCookieName: string;
20
- shareCookieName: string;
21
- private keyProvider;
22
- getAuthToken(authCookie: Omit<IAuthCookie, "sign">): Promise<{
23
- cookieName: string;
24
- cookie: string;
25
- }>;
26
- signContent<T>(content: T): Promise<ISignedContent<T>>;
27
- verifyContent<T>(content: ISignedContent<T>, fail?: boolean): Promise<boolean>;
28
- verify(content: string | Buffer, signature: string, key: IAuthKey, fail?: boolean): boolean;
29
- private sign;
30
- }
31
- //# sourceMappingURL=TokenService.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TokenService.d.ts","sourceRoot":"","sources":["../../src/services/TokenService.ts"],"names":[],"mappings":"AACA,OAAO,QAAQ,MAAM,qDAAqD,CAAC;AAM3E,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,IAAI,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,QAAQ,CAAA;CACpB;AAED,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,CAAC,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;CAChB,CAAC;AAGF,MAAM,CAAC,OAAO,OAAO,YAAY;IAEtB,cAAc,SAAW;IAEzB,eAAe,SAAY;IAElC,OAAO,CAAC,WAAW,CAAc;IAEpB,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,CAAC;IAKnG,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAOtD,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,UAAO;IAc9D,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,UAAO;IAYrF,OAAO,CAAC,IAAI;CAOf"}
@@ -1,60 +0,0 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- import { RegisterSingleton, ServiceProvider } from "@entity-access/entity-access/dist/di/di.js";
8
- import { createSign, createVerify } from "node:crypto";
9
- import KeyProvider from "./KeyProvider.js";
10
- let TokenService = class TokenService {
11
- constructor() {
12
- this.authCookieName = "ea-c1";
13
- this.shareCookieName = "ea-ca1";
14
- }
15
- async getAuthToken(authCookie) {
16
- const cookie = await this.signContent(authCookie);
17
- return { cookieName: this.authCookieName, cookie: JSON.stringify(cookie) };
18
- }
19
- async signContent(content) {
20
- this.keyProvider ??= ServiceProvider.resolve(this, KeyProvider, true) ?? new KeyProvider();
21
- const [key] = await this.keyProvider.getKeys();
22
- const sign = this.sign(JSON.stringify(content), key);
23
- return { ...content, sign };
24
- }
25
- async verifyContent(content, fail = true) {
26
- this.keyProvider ??= ServiceProvider.resolve(this, KeyProvider, true) ?? new KeyProvider();
27
- const { sign, ...c } = content;
28
- const keys = await this.keyProvider.getKeys();
29
- for (const iterator of keys) {
30
- if (this.verify(JSON.stringify(c), sign, iterator, false)) {
31
- return true;
32
- }
33
- }
34
- if (fail) {
35
- throw new Error("Signature verification failed");
36
- }
37
- }
38
- verify(content, signature, key, fail = true) {
39
- const verify = createVerify("SHA256");
40
- verify.write(content);
41
- verify.end();
42
- if (verify.verify(key.publicKey, signature, "hex")) {
43
- return true;
44
- }
45
- if (fail) {
46
- throw new Error("Invalid signature");
47
- }
48
- }
49
- sign(content, key) {
50
- const sign = createSign("SHA256");
51
- sign.write(content);
52
- sign.end();
53
- return sign.sign(key.privateKey, "hex");
54
- }
55
- };
56
- TokenService = __decorate([
57
- RegisterSingleton
58
- ], TokenService);
59
- export default TokenService;
60
- //# sourceMappingURL=TokenService.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TokenService.js","sourceRoot":"","sources":["../../src/services/TokenService.ts"],"names":[],"mappings":"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"}
@@ -1,6 +0,0 @@
1
- import { SessionUser } from "../core/SessionUser.js";
2
- import { IAuthCookie } from "./TokenService.js";
3
- export default class UserSessionProvider {
4
- getUserSession({ userID, id: sessionID, expiry }: IAuthCookie): Promise<Partial<SessionUser>>;
5
- }
6
- //# sourceMappingURL=UserSessionProvider.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"UserSessionProvider.d.ts","sourceRoot":"","sources":["../../src/services/UserSessionProvider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,CAAC,OAAO,OAAO,mBAAmB;IAE9B,cAAc,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;CAQrG"}
@@ -1,10 +0,0 @@
1
- export default class UserSessionProvider {
2
- async getUserSession({ userID, id: sessionID, expiry }) {
3
- return {
4
- sessionID,
5
- userID,
6
- expiry
7
- };
8
- }
9
- }
10
- //# sourceMappingURL=UserSessionProvider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"UserSessionProvider.js","sourceRoot":"","sources":["../../src/services/UserSessionProvider.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,OAAO,OAAO,mBAAmB;IAEpC,KAAK,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAc;QAC9D,OAAO;YACH,SAAS;YACT,MAAM;YACN,MAAM;SACT,CAAA;IACL,CAAC;CAEJ"}
@@ -1,44 +0,0 @@
1
- import { RegisterSingleton, ServiceProvider } from "@entity-access/entity-access/dist/di/di.js";
2
- import { SessionUser } from "../core/SessionUser.js";
3
- import CookieService from "./CookieService.js";
4
- import TokenService from "./TokenService.js";
5
- import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
6
- import type { IAuthorizationCookie } from "./IAuthorizationCookie.js";
7
- import type { SerializeOptions } from "cookie";
8
-
9
- const secure = (process.env["SOCIAL_MAIL_AUTH_COOKIE_SECURE"] ?? "true") === "true";
10
-
11
- export interface ICookie {
12
- name: string,
13
- value: string,
14
- options?: SerializeOptions
15
- }
16
- @RegisterSingleton
17
- export default class AuthenticationService {
18
-
19
- async authorize(user: SessionUser, { ip, cookies }: { ip: string, cookies: Record<string, string>}) {
20
- const scope = ServiceProvider.from(user);
21
- const cookieService = scope.resolve(CookieService);
22
- const tokenService = scope.resolve(TokenService);
23
- const cookie = cookies[tokenService.authCookieName];
24
- await cookieService.createSessionUserFromCookie(cookie, ip);
25
- (user as any).isAuthorized = true;
26
- }
27
-
28
- async setAuthCookie(user: SessionUser, authCookie: IAuthorizationCookie): Promise<ICookie> {
29
-
30
- const scope = ServiceProvider.from(user);
31
- const tokenService = scope.resolve(TokenService);
32
- const cookie = await tokenService.getAuthToken(authCookie);
33
- const maxAge = ((authCookie?.expiry ? DateTime.from(authCookie.expiry) : null) ?? DateTime.now.addDays(30)).diff(DateTime.now).totalMilliseconds;
34
- const name = cookie.cookieName;
35
- const value = cookie.cookie;
36
- const options = {
37
- secure,
38
- httpOnly: true,
39
- maxAge
40
- };
41
- return { name, value, options };
42
- }
43
-
44
- }