@authup/server-kit 1.0.0-beta.5 → 1.0.0-beta.50

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 (197) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -1
  3. package/dist/cache/adapters/index.d.ts +3 -0
  4. package/dist/cache/adapters/index.d.ts.map +1 -0
  5. package/dist/cache/adapters/memory.d.ts +15 -0
  6. package/dist/cache/adapters/memory.d.ts.map +1 -0
  7. package/dist/cache/adapters/redis.d.ts +17 -0
  8. package/dist/cache/adapters/redis.d.ts.map +1 -0
  9. package/dist/cache/helper.d.ts +3 -0
  10. package/dist/cache/helper.d.ts.map +1 -0
  11. package/dist/cache/index.d.ts +4 -0
  12. package/dist/cache/index.d.ts.map +1 -0
  13. package/dist/cache/types.d.ts +25 -0
  14. package/dist/cache/types.d.ts.map +1 -0
  15. package/dist/core/actor/index.d.ts +2 -0
  16. package/dist/core/actor/index.d.ts.map +1 -0
  17. package/dist/core/actor/types.d.ts +7 -0
  18. package/dist/core/actor/types.d.ts.map +1 -0
  19. package/dist/core/index.d.ts +4 -0
  20. package/dist/core/index.d.ts.map +1 -0
  21. package/dist/core/service.d.ts +6 -0
  22. package/dist/core/service.d.ts.map +1 -0
  23. package/dist/core/types.d.ts +22 -0
  24. package/dist/core/types.d.ts.map +1 -0
  25. package/dist/crypto/hash/hash.d.ts +1 -1
  26. package/dist/crypto/hash/hash.d.ts.map +1 -1
  27. package/dist/crypto/index.d.ts +1 -1
  28. package/dist/crypto/index.d.ts.map +1 -1
  29. package/dist/crypto/json-web-token/extract.d.ts +16 -0
  30. package/dist/crypto/json-web-token/extract.d.ts.map +1 -0
  31. package/dist/crypto/json-web-token/index.d.ts +2 -2
  32. package/dist/crypto/json-web-token/index.d.ts.map +1 -1
  33. package/dist/crypto/json-web-token/sign/index.d.ts +3 -0
  34. package/dist/crypto/json-web-token/sign/index.d.ts.map +1 -0
  35. package/dist/crypto/json-web-token/sign/module.d.ts +4 -0
  36. package/dist/crypto/json-web-token/sign/module.d.ts.map +1 -0
  37. package/dist/crypto/json-web-token/sign/types.d.ts +28 -0
  38. package/dist/crypto/json-web-token/sign/types.d.ts.map +1 -0
  39. package/dist/crypto/json-web-token/types.d.ts +5 -0
  40. package/dist/crypto/json-web-token/types.d.ts.map +1 -0
  41. package/dist/crypto/json-web-token/utils.d.ts +5 -2
  42. package/dist/crypto/json-web-token/utils.d.ts.map +1 -1
  43. package/dist/crypto/json-web-token/verify/index.d.ts +3 -0
  44. package/dist/crypto/json-web-token/verify/index.d.ts.map +1 -0
  45. package/dist/crypto/json-web-token/verify/module.d.ts +12 -0
  46. package/dist/crypto/json-web-token/verify/module.d.ts.map +1 -0
  47. package/dist/crypto/json-web-token/verify/types.d.ts +25 -0
  48. package/dist/crypto/json-web-token/verify/types.d.ts.map +1 -0
  49. package/dist/crypto/key/asymmetric/check.d.ts +3 -0
  50. package/dist/crypto/key/asymmetric/check.d.ts.map +1 -0
  51. package/dist/crypto/key/asymmetric/constants.d.ts +8 -0
  52. package/dist/crypto/key/asymmetric/constants.d.ts.map +1 -0
  53. package/dist/crypto/key/asymmetric/create.d.ts +3 -0
  54. package/dist/crypto/key/asymmetric/create.d.ts.map +1 -0
  55. package/dist/crypto/key/asymmetric/helpers/index.d.ts +2 -0
  56. package/dist/crypto/key/asymmetric/helpers/index.d.ts.map +1 -0
  57. package/dist/crypto/key/asymmetric/helpers/wrap.d.ts +5 -0
  58. package/dist/crypto/key/asymmetric/helpers/wrap.d.ts.map +1 -0
  59. package/dist/crypto/key/asymmetric/index.d.ts +9 -0
  60. package/dist/crypto/key/asymmetric/index.d.ts.map +1 -0
  61. package/dist/crypto/key/asymmetric/key-usages.d.ts +5 -0
  62. package/dist/crypto/key/asymmetric/key-usages.d.ts.map +1 -0
  63. package/dist/crypto/key/asymmetric/module.d.ts +20 -0
  64. package/dist/crypto/key/asymmetric/module.d.ts.map +1 -0
  65. package/dist/crypto/key/asymmetric/normalize.d.ts +4 -0
  66. package/dist/crypto/key/asymmetric/normalize.d.ts.map +1 -0
  67. package/dist/crypto/key/asymmetric/types.d.ts +35 -0
  68. package/dist/crypto/key/asymmetric/types.d.ts.map +1 -0
  69. package/dist/crypto/key/base.d.ts +9 -0
  70. package/dist/crypto/key/base.d.ts.map +1 -0
  71. package/dist/crypto/key/index.d.ts +4 -0
  72. package/dist/crypto/key/index.d.ts.map +1 -0
  73. package/dist/crypto/key/symmetric/check.d.ts +3 -0
  74. package/dist/crypto/key/symmetric/check.d.ts.map +1 -0
  75. package/dist/crypto/key/symmetric/constants.d.ts +7 -0
  76. package/dist/crypto/key/symmetric/constants.d.ts.map +1 -0
  77. package/dist/crypto/key/symmetric/create.d.ts +3 -0
  78. package/dist/crypto/key/symmetric/create.d.ts.map +1 -0
  79. package/dist/crypto/key/symmetric/index.d.ts +7 -0
  80. package/dist/crypto/key/symmetric/index.d.ts.map +1 -0
  81. package/dist/crypto/key/symmetric/key-usages.d.ts +2 -0
  82. package/dist/crypto/key/symmetric/key-usages.d.ts.map +1 -0
  83. package/dist/crypto/key/symmetric/module.d.ts +13 -0
  84. package/dist/crypto/key/symmetric/module.d.ts.map +1 -0
  85. package/dist/crypto/key/symmetric/normalize.d.ts +4 -0
  86. package/dist/crypto/key/symmetric/normalize.d.ts.map +1 -0
  87. package/dist/crypto/key/symmetric/types.d.ts +32 -0
  88. package/dist/crypto/key/symmetric/types.d.ts.map +1 -0
  89. package/dist/domain-event/handlers/index.d.ts +3 -0
  90. package/dist/domain-event/handlers/index.d.ts.map +1 -0
  91. package/dist/domain-event/handlers/redis/index.d.ts +2 -0
  92. package/dist/domain-event/handlers/redis/index.d.ts.map +1 -0
  93. package/dist/domain-event/handlers/redis/module.d.ts +9 -0
  94. package/dist/domain-event/handlers/redis/module.d.ts.map +1 -0
  95. package/dist/domain-event/handlers/socket/index.d.ts +2 -0
  96. package/dist/domain-event/handlers/socket/index.d.ts.map +1 -0
  97. package/dist/domain-event/handlers/socket/module.d.ts +9 -0
  98. package/dist/domain-event/handlers/socket/module.d.ts.map +1 -0
  99. package/dist/domain-event/index.d.ts +3 -4
  100. package/dist/domain-event/index.d.ts.map +1 -1
  101. package/dist/domain-event/module.d.ts +16 -0
  102. package/dist/domain-event/module.d.ts.map +1 -0
  103. package/dist/domain-event/types.d.ts +20 -0
  104. package/dist/domain-event/types.d.ts.map +1 -0
  105. package/dist/domain-event/utils.d.ts +3 -2
  106. package/dist/domain-event/utils.d.ts.map +1 -1
  107. package/dist/index.d.mts +425 -0
  108. package/dist/index.d.mts.map +1 -0
  109. package/dist/index.d.ts +3 -1
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.mjs +713 -582
  112. package/dist/index.mjs.map +1 -1
  113. package/dist/logger/index.d.ts +1 -2
  114. package/dist/logger/index.d.ts.map +1 -1
  115. package/dist/logger/module.d.ts +3 -3
  116. package/dist/logger/module.d.ts.map +1 -1
  117. package/dist/logger/types.d.ts +17 -0
  118. package/dist/logger/types.d.ts.map +1 -0
  119. package/dist/redis/check.d.ts +3 -0
  120. package/dist/redis/check.d.ts.map +1 -0
  121. package/dist/redis/factory.d.ts +4 -0
  122. package/dist/redis/factory.d.ts.map +1 -0
  123. package/dist/redis/index.d.ts +4 -0
  124. package/dist/redis/index.d.ts.map +1 -0
  125. package/dist/redis/module.d.ts +5 -0
  126. package/dist/redis/module.d.ts.map +1 -0
  127. package/package.json +49 -34
  128. package/dist/crypto/json-web-token/decode.d.ts +0 -15
  129. package/dist/crypto/json-web-token/decode.d.ts.map +0 -1
  130. package/dist/crypto/json-web-token/sign.d.ts +0 -4
  131. package/dist/crypto/json-web-token/sign.d.ts.map +0 -1
  132. package/dist/crypto/json-web-token/type.d.ts +0 -34
  133. package/dist/crypto/json-web-token/type.d.ts.map +0 -1
  134. package/dist/crypto/json-web-token/verify.d.ts +0 -15
  135. package/dist/crypto/json-web-token/verify.d.ts.map +0 -1
  136. package/dist/crypto/key-pair/constants.d.ts +0 -5
  137. package/dist/crypto/key-pair/constants.d.ts.map +0 -1
  138. package/dist/crypto/key-pair/create.d.ts +0 -3
  139. package/dist/crypto/key-pair/create.d.ts.map +0 -1
  140. package/dist/crypto/key-pair/delete.d.ts +0 -3
  141. package/dist/crypto/key-pair/delete.d.ts.map +0 -1
  142. package/dist/crypto/key-pair/index.d.ts +0 -9
  143. package/dist/crypto/key-pair/index.d.ts.map +0 -1
  144. package/dist/crypto/key-pair/load.d.ts +0 -3
  145. package/dist/crypto/key-pair/load.d.ts.map +0 -1
  146. package/dist/crypto/key-pair/module.d.ts +0 -3
  147. package/dist/crypto/key-pair/module.d.ts.map +0 -1
  148. package/dist/crypto/key-pair/save.d.ts +0 -3
  149. package/dist/crypto/key-pair/save.d.ts.map +0 -1
  150. package/dist/crypto/key-pair/type.d.ts +0 -65
  151. package/dist/crypto/key-pair/type.d.ts.map +0 -1
  152. package/dist/crypto/key-pair/utils/check.d.ts +0 -4
  153. package/dist/crypto/key-pair/utils/check.d.ts.map +0 -1
  154. package/dist/crypto/key-pair/utils/file-name.d.ts +0 -4
  155. package/dist/crypto/key-pair/utils/file-name.d.ts.map +0 -1
  156. package/dist/crypto/key-pair/utils/index.d.ts +0 -5
  157. package/dist/crypto/key-pair/utils/index.d.ts.map +0 -1
  158. package/dist/crypto/key-pair/utils/options.d.ts +0 -3
  159. package/dist/crypto/key-pair/utils/options.d.ts.map +0 -1
  160. package/dist/crypto/key-pair/utils/private-key.d.ts +0 -4
  161. package/dist/crypto/key-pair/utils/private-key.d.ts.map +0 -1
  162. package/dist/domain-event/publish.d.ts +0 -4
  163. package/dist/domain-event/publish.d.ts.map +0 -1
  164. package/dist/domain-event/redis/index.d.ts +0 -2
  165. package/dist/domain-event/redis/index.d.ts.map +0 -1
  166. package/dist/domain-event/redis/publish.d.ts +0 -4
  167. package/dist/domain-event/redis/publish.d.ts.map +0 -1
  168. package/dist/domain-event/socket/index.d.ts +0 -3
  169. package/dist/domain-event/socket/index.d.ts.map +0 -1
  170. package/dist/domain-event/socket/publish.d.ts +0 -4
  171. package/dist/domain-event/socket/publish.d.ts.map +0 -1
  172. package/dist/domain-event/socket/singleton.d.ts +0 -4
  173. package/dist/domain-event/socket/singleton.d.ts.map +0 -1
  174. package/dist/domain-event/socket/type.d.ts +0 -5
  175. package/dist/domain-event/socket/type.d.ts.map +0 -1
  176. package/dist/domain-event/type.d.ts +0 -7
  177. package/dist/domain-event/type.d.ts.map +0 -1
  178. package/dist/index.cjs +0 -642
  179. package/dist/index.cjs.map +0 -1
  180. package/dist/logger/presets/index.d.ts +0 -2
  181. package/dist/logger/presets/index.d.ts.map +0 -1
  182. package/dist/logger/presets/void.d.ts +0 -16
  183. package/dist/logger/presets/void.d.ts.map +0 -1
  184. package/dist/logger/type.d.ts +0 -14
  185. package/dist/logger/type.d.ts.map +0 -1
  186. package/dist/smtp/config/index.d.ts +0 -2
  187. package/dist/smtp/config/index.d.ts.map +0 -1
  188. package/dist/smtp/config/singleton.d.ts +0 -5
  189. package/dist/smtp/config/singleton.d.ts.map +0 -1
  190. package/dist/smtp/index.d.ts +0 -5
  191. package/dist/smtp/index.d.ts.map +0 -1
  192. package/dist/smtp/module.d.ts +0 -4
  193. package/dist/smtp/module.d.ts.map +0 -1
  194. package/dist/smtp/singleton.d.ts +0 -3
  195. package/dist/smtp/singleton.d.ts.map +0 -1
  196. package/dist/smtp/type.d.ts +0 -14
  197. package/dist/smtp/type.d.ts.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,613 +1,744 @@
1
- import { compare as compare$1, hash as hash$1 } from 'bcrypt';
2
- import { createPrivateKey, generateKeyPair, createPublicKey } from 'node:crypto';
3
- import { isObject, TokenError, KeyType, DomainEventName, buildDomainEventFullName } from '@authup/core';
4
- import path from 'node:path';
5
- import fs from 'node:fs';
6
- import { decode, sign, verify } from 'jsonwebtoken';
7
- import { isObject as isObject$1 } from 'smob';
8
- import { hasClient, hasConfig, useClient } from 'redis-extension';
9
- import { Emitter } from '@socket.io/redis-emitter';
10
- import { createTransport, createTestAccount } from 'nodemailer';
11
-
1
+ import { TTLCache } from "@isaacs/ttlcache";
2
+ import { Client as RedisClient, JsonAdapter, JsonAdapter as RedisJsonAdapter, Watcher as RedisWatcher, buildKeyPath as buildRedisKeyPath, createClient, escapeKey as escapeRedisKey, parseKeyPath as parseRedisKeyPath } from "redis-extension";
3
+ import { isObject } from "smob";
4
+ import { REALM_MASTER_NAME } from "@authup/core-kit";
5
+ import { arrayBufferToBase64, base64ToArrayBuffer, isObject as isObject$1 } from "@authup/kit";
6
+ import { compare as compare$1, hash as hash$1 } from "@node-rs/bcrypt";
7
+ import { JWKType, JWTAlgorithm, JWTError } from "@authup/specs";
8
+ import { subtle } from "uncrypto";
9
+ import { Algorithm, sign, verify } from "@node-rs/jsonwebtoken";
10
+ import { buildEventFullName } from "@authup/core-realtime-kit";
11
+ import { Emitter } from "@socket.io/redis-emitter";
12
+ import path from "node:path";
13
+ import process from "node:process";
14
+ import { createLogger as createLogger$1, format, transports } from "winston";
15
+ //#region src/cache/adapters/memory.ts
16
+ var MemoryCache = class {
17
+ instance;
18
+ constructor(options = {}) {
19
+ this.instance = new TTLCache({
20
+ checkAgeOnGet: true,
21
+ ttl: Infinity,
22
+ ...options || {}
23
+ });
24
+ }
25
+ async pop(key) {
26
+ if (this.instance.has(key)) {
27
+ const output = this.instance.get(key);
28
+ this.instance.delete(key);
29
+ return output;
30
+ }
31
+ return null;
32
+ }
33
+ async has(key) {
34
+ return this.instance.has(key);
35
+ }
36
+ async get(key) {
37
+ const output = await this.instance.get(key);
38
+ if (output) return output;
39
+ return null;
40
+ }
41
+ async set(key, value, options) {
42
+ this.instance.set(key, value, { ttl: options.ttl });
43
+ }
44
+ async drop(key) {
45
+ this.instance.delete(key);
46
+ }
47
+ async dropMany(keys) {
48
+ for (const key of keys) this.instance.delete(key);
49
+ }
50
+ async clear(options = {}) {
51
+ if (options.prefix) {
52
+ const keys = this.instance.keys();
53
+ let iterator = keys.next();
54
+ while (!iterator.done) {
55
+ if (typeof iterator.value !== "string") continue;
56
+ if (iterator.value.startsWith(options.prefix)) this.instance.delete(iterator.value);
57
+ iterator = keys.next();
58
+ }
59
+ return;
60
+ }
61
+ this.instance.clear();
62
+ }
63
+ };
64
+ //#endregion
65
+ //#region src/redis/check.ts
66
+ function isRedisClient(data) {
67
+ return isObject(data) && typeof data.connect === "function" && typeof data.disconnect === "function";
68
+ }
69
+ //#endregion
70
+ //#region src/redis/factory.ts
71
+ function createRedisClient(input) {
72
+ if (typeof input === "boolean") return createClient({ connectionString: "redis://127.0.0.1" });
73
+ if (typeof input === "string") return createClient({ connectionString: input });
74
+ if (!isRedisClient(input)) return createClient({ options: input });
75
+ return input;
76
+ }
77
+ //#endregion
78
+ //#region src/cache/adapters/redis.ts
79
+ var RedisCache = class {
80
+ client;
81
+ jsonAdapter;
82
+ constructor(input) {
83
+ this.client = createRedisClient(input);
84
+ this.jsonAdapter = new JsonAdapter(this.client);
85
+ }
86
+ async get(key) {
87
+ const output = await this.jsonAdapter.get(key);
88
+ if (output) return output;
89
+ return null;
90
+ }
91
+ async pop(key) {
92
+ const raw = await this.client.getdel(key);
93
+ if (!raw) return null;
94
+ try {
95
+ return JSON.parse(raw);
96
+ } catch {
97
+ return null;
98
+ }
99
+ }
100
+ async has(key) {
101
+ return !!await this.get(key);
102
+ }
103
+ async set(key, value, options) {
104
+ await this.jsonAdapter.set(key, value, { milliseconds: options.ttl });
105
+ }
106
+ async drop(key) {
107
+ await this.jsonAdapter.drop(key);
108
+ }
109
+ async dropMany(keys) {
110
+ const pipeline = this.client.pipeline();
111
+ for (const key of keys) pipeline.del(key);
112
+ await pipeline.exec();
113
+ }
114
+ async clear(options = {}) {
115
+ if (options.prefix) {
116
+ const pipeline = this.client.pipeline();
117
+ const keys = await this.client.keys(`${options.prefix}*`);
118
+ for (const key of keys) pipeline.del(key);
119
+ await pipeline.exec();
120
+ return;
121
+ }
122
+ await this.client.flushdb();
123
+ }
124
+ };
125
+ //#endregion
126
+ //#region src/cache/helper.ts
127
+ function buildCacheKey(options) {
128
+ return buildRedisKeyPath(options);
129
+ }
130
+ //#endregion
131
+ //#region src/core/service.ts
132
+ var AbstractEntityService = class {
133
+ isActorMasterRealmMember(actor) {
134
+ if (!actor.identity) return false;
135
+ const { data } = actor.identity;
136
+ if ("realm" in data && data.realm && typeof data.realm === "object" && "name" in data.realm) return data.realm.name === REALM_MASTER_NAME;
137
+ return false;
138
+ }
139
+ getActorRealmId(actor) {
140
+ if (!actor.identity) return;
141
+ const { data } = actor.identity;
142
+ if (data.realm_id) return data.realm_id;
143
+ if (isObject$1(data.realm) && data.realm.id) return data.realm.id;
144
+ }
145
+ };
146
+ //#endregion
147
+ //#region src/crypto/hash/compare.ts
12
148
  async function compare(value, hashedValue) {
13
- return compare$1(value, hashedValue);
149
+ return compare$1(value, hashedValue);
14
150
  }
15
-
16
- async function hash(str, saltOrRounds = 10) {
17
- return hash$1(str, saltOrRounds);
151
+ //#endregion
152
+ //#region src/crypto/hash/hash.ts
153
+ async function hash(str, rounds = 10) {
154
+ return hash$1(str, rounds);
18
155
  }
19
-
20
- /*
21
- * Copyright (c) 2022.
22
- * Author Peter Placzek (tada5hi)
23
- * For the full copyright and license information,
24
- * view the LICENSE file that was distributed with this source code.
25
- */ var KeyPairKind;
26
- (function(KeyPairKind) {
27
- KeyPairKind["PRIVATE"] = "private";
28
- KeyPairKind["PUBLIC"] = "public";
29
- })(KeyPairKind || (KeyPairKind = {}));
30
-
31
- function isKeyPair(data) {
32
- return isObject(data) && typeof data.privateKey !== 'undefined' && typeof data.publicKey !== 'undefined';
156
+ //#endregion
157
+ //#region src/crypto/key/asymmetric/constants.ts
158
+ let CryptoAsymmetricAlgorithm = /* @__PURE__ */ function(CryptoAsymmetricAlgorithm) {
159
+ CryptoAsymmetricAlgorithm["RSA_PSS"] = "RSA-PSS";
160
+ CryptoAsymmetricAlgorithm["RSASSA_PKCS1_V1_5"] = "RSASSA-PKCS1-v1_5";
161
+ CryptoAsymmetricAlgorithm["RSA_OAEP"] = "RSA-OAEP";
162
+ CryptoAsymmetricAlgorithm["ECDSA"] = "ECDSA";
163
+ CryptoAsymmetricAlgorithm["ECDH"] = "ECDH";
164
+ return CryptoAsymmetricAlgorithm;
165
+ }({});
166
+ //#endregion
167
+ //#region src/crypto/key/base.ts
168
+ var BaseKey = class {
169
+ key;
170
+ constructor(cryptoKey) {
171
+ this.key = cryptoKey;
172
+ }
173
+ async toArrayBuffer() {
174
+ if (this.key.type === "private") return subtle.exportKey("pkcs8", this.key);
175
+ if (this.key.type === "public") return subtle.exportKey("spki", this.key);
176
+ return subtle.exportKey("raw", this.key);
177
+ }
178
+ async toUint8Array() {
179
+ const arrayBuffer = await this.toArrayBuffer();
180
+ return new Uint8Array(arrayBuffer);
181
+ }
182
+ async toBase64() {
183
+ return arrayBufferToBase64(await this.toArrayBuffer());
184
+ }
185
+ async toJWK() {
186
+ return subtle.exportKey("jwk", this.key);
187
+ }
188
+ };
189
+ //#endregion
190
+ //#region src/crypto/key/asymmetric/helpers/wrap.ts
191
+ function enc(type, input) {
192
+ return `-----BEGIN ${type}-----\n${input}\n-----END ${type}-----`;
33
193
  }
34
- function isKeyPairWithPublicKey(data) {
35
- return isObject(data) && typeof data.publicKey !== 'undefined';
194
+ function encodePKCS8ToPEM(base64) {
195
+ return enc("PRIVATE KEY", base64);
36
196
  }
37
-
38
- function extendKeyPairOptions(options) {
39
- var _options;
40
- options = options ?? {};
41
- options.directory = options.directory || process.cwd();
42
- options.directory = path.isAbsolute(options.directory) ? options.directory : path.resolve(process.cwd(), options.directory);
43
- (_options = options).type ?? (_options.type = 'rsa');
44
- if (options.type === 'rsa' || options.type === 'rsa-pss' || options.type === 'dsa') {
45
- options.modulusLength = 2048;
46
- }
47
- if (!options.privateKeyEncoding) {
48
- options.privateKeyEncoding = {
49
- type: 'pkcs8',
50
- format: 'pem'
51
- };
52
- }
53
- if (!options.publicKeyEncoding) {
54
- options.publicKeyEncoding = {
55
- type: 'spki',
56
- format: 'pem'
57
- };
58
- }
59
- if (options.privateKeyEncoding.passphrase && !options.privateKeyEncoding.cipher) {
60
- options.privateKeyEncoding.cipher = 'aes-256-cbc';
61
- }
62
- return options;
197
+ function encodeSPKIToPem(input) {
198
+ return enc("PUBLIC KEY", input);
63
199
  }
64
-
65
- function buildKeyFileName(type, context) {
66
- const options = extendKeyPairOptions(context);
67
- const parts = [];
68
- switch(type){
69
- case KeyPairKind.PRIVATE:
70
- {
71
- if (options.privateName) {
72
- parts.push(options.privateName);
73
- } else {
74
- parts.push(type);
75
- }
76
- if (options.privateExtension) {
77
- if (options.privateExtension.startsWith('.')) {
78
- options.privateExtension = options.privateExtension.slice(1);
79
- }
80
- parts.push(options.privateExtension);
81
- } else {
82
- parts.push('pem');
83
- }
84
- break;
85
- }
86
- case KeyPairKind.PUBLIC:
87
- {
88
- if (options.publicName) {
89
- parts.push(options.publicName);
90
- } else {
91
- parts.push(type);
92
- }
93
- if (options.publicExtension) {
94
- if (options.publicExtension.startsWith('.')) {
95
- options.publicExtension = options.publicExtension.slice(1);
96
- }
97
- parts.push(options.publicExtension);
98
- } else {
99
- parts.push('pem');
100
- }
101
- break;
102
- }
103
- }
104
- return parts.join('.');
200
+ function dec(type, input) {
201
+ input = input.replace(`-----BEGIN ${type}-----\n`, "");
202
+ input = input.replace(`\n-----END ${type}-----\n`, "");
203
+ input = input.replace(`-----END ${type}-----\n`, "");
204
+ input = input.replace(`\n-----END ${type}-----`, "");
205
+ return input;
105
206
  }
106
-
107
- function decryptRSAPrivateKey(context, key) {
108
- const privateKey = createPrivateKey({
109
- type: context.privateKeyEncoding.type,
110
- format: context.privateKeyEncoding.format,
111
- key,
112
- passphrase: context.privateKeyEncoding.passphrase || context.passphrase
113
- });
114
- let content = privateKey.export({
115
- type: context.privateKeyEncoding.type,
116
- format: context.privateKeyEncoding.format
117
- });
118
- if (typeof content !== 'string') {
119
- content = Buffer.from(content).toString('utf-8');
120
- }
121
- return content;
207
+ function decodePemToPKCS8(input) {
208
+ return dec("PRIVATE KEY", input);
122
209
  }
123
-
124
- async function saveKeyPair(keyPair, context) {
125
- context = extendKeyPairOptions(context);
126
- await fs.promises.mkdir(context.directory, {
127
- recursive: true
128
- });
129
- await Promise.all([
130
- {
131
- path: path.resolve(context.directory, buildKeyFileName(KeyPairKind.PRIVATE, context)),
132
- content: keyPair.privateKey
133
- },
134
- {
135
- path: path.resolve(context.directory, buildKeyFileName(KeyPairKind.PUBLIC, context)),
136
- content: keyPair.publicKey
137
- }
138
- ].map((file)=>fs.promises.writeFile(file.path, file.content)));
139
- return keyPair;
210
+ function decodePemToSpki(input) {
211
+ return dec("PUBLIC KEY", input);
140
212
  }
141
-
142
- async function createKeyPair(context) {
143
- const options = extendKeyPairOptions(context);
144
- const keyPair = await new Promise((resolve, reject)=>{
145
- const callback = (err, publicKey, privateKey)=>{
146
- if (err) reject(err);
147
- resolve({
148
- privateKey,
149
- publicKey
150
- });
151
- };
152
- switch(options.type){
153
- case 'dsa':
154
- generateKeyPair(options.type, options, callback);
155
- break;
156
- case 'ec':
157
- generateKeyPair(options.type, options, callback);
158
- break;
159
- case 'rsa':
160
- generateKeyPair(options.type, options, callback);
161
- break;
162
- case 'rsa-pss':
163
- generateKeyPair(options.type, options, callback);
164
- break;
165
- }
166
- });
167
- if (options.save) {
168
- await saveKeyPair(keyPair, options);
169
- }
170
- if (options.passphrase || options.privateKeyEncoding.passphrase) {
171
- keyPair.privateKey = decryptRSAPrivateKey(options, keyPair.privateKey);
172
- }
173
- return keyPair;
213
+ //#endregion
214
+ //#region src/crypto/key/asymmetric/key-usages.ts
215
+ /**
216
+ * @see https://nodejs.org/api/webcrypto.html#cryptokeyusages
217
+ */
218
+ function getKeyUsagesForAsymmetricAlgorithm(name, format) {
219
+ if (name === "RSA-PSS" || name === "ECDSA" || name === "RSASSA-PKCS1-v1_5") {
220
+ if (format === "spki") return ["verify"];
221
+ if (format === "pkcs8") return ["sign"];
222
+ return ["sign", "verify"];
223
+ }
224
+ if (name === "ECDH") {
225
+ if (format === "spki") return [];
226
+ return ["deriveKey", "deriveBits"];
227
+ }
228
+ if (name === "RSA-OAEP") {
229
+ if (format === "spki") return ["encrypt"];
230
+ if (format === "pkcs8") return ["decrypt"];
231
+ return ["encrypt", "decrypt"];
232
+ }
233
+ throw new SyntaxError(`Key usages can not be determined for asymmetric algorithm: ${name}`);
174
234
  }
175
-
176
- async function deleteKeyPair(context) {
177
- const options = extendKeyPairOptions(context);
178
- const privateKeyPath = path.resolve(options.directory, buildKeyFileName(KeyPairKind.PRIVATE, options));
179
- const publicKeyPath = path.resolve(options.directory, buildKeyFileName(KeyPairKind.PUBLIC, options));
180
- try {
181
- await Promise.all([
182
- privateKeyPath,
183
- publicKeyPath
184
- ].map((filePath)=>fs.promises.stat(filePath)));
185
- } catch (e) {
186
- return;
187
- }
188
- await Promise.all([
189
- privateKeyPath,
190
- publicKeyPath
191
- ].map((filePath)=>fs.promises.rm(filePath)));
235
+ //#endregion
236
+ //#region src/crypto/key/asymmetric/normalize.ts
237
+ function normalizeAsymmetricKeyPairCreateOptions(options) {
238
+ let optionsNormalized;
239
+ switch (options.name) {
240
+ case "RSASSA-PKCS1-v1_5":
241
+ case "RSA-PSS":
242
+ case "RSA-OAEP":
243
+ optionsNormalized = {
244
+ modulusLength: 2048,
245
+ publicExponent: new Uint8Array([
246
+ 1,
247
+ 0,
248
+ 1
249
+ ]),
250
+ hash: "SHA-256",
251
+ ...options
252
+ };
253
+ break;
254
+ case "ECDSA":
255
+ case "ECDH": optionsNormalized = {
256
+ namedCurve: "P-256",
257
+ ...options
258
+ };
259
+ }
260
+ return optionsNormalized;
192
261
  }
193
-
194
- async function loadKeyPair(context) {
195
- const options = extendKeyPairOptions(context);
196
- const privateKeyPath = path.resolve(options.directory, buildKeyFileName(KeyPairKind.PRIVATE, options));
197
- try {
198
- await fs.promises.stat(privateKeyPath);
199
- } catch (e) {
200
- return undefined;
201
- }
202
- const privateKeyBuffer = await fs.promises.readFile(privateKeyPath);
203
- let privateKey = privateKeyBuffer.toString();
204
- if (options.passphrase || options.privateKeyEncoding.passphrase) {
205
- privateKey = decryptRSAPrivateKey(options, privateKey);
206
- }
207
- const publicKeyPath = path.resolve(options.directory, buildKeyFileName(KeyPairKind.PUBLIC, options));
208
- let publicKey;
209
- try {
210
- await fs.promises.stat(publicKeyPath);
211
- const publicKeyBuffer = await fs.promises.readFile(publicKeyPath);
212
- publicKey = publicKeyBuffer.toString();
213
- } catch (e) {
214
- const publicKeyObject = createPublicKey({
215
- key: privateKey,
216
- format: options.privateKeyEncoding.format,
217
- type: options.publicKeyEncoding.type
218
- });
219
- const stringOrBuffer = publicKeyObject.export({
220
- format: options.publicKeyEncoding.format,
221
- type: options.publicKeyEncoding.type
222
- });
223
- if (typeof stringOrBuffer !== 'string') {
224
- publicKey = stringOrBuffer.toString();
225
- } else {
226
- publicKey = stringOrBuffer;
227
- }
228
- if (options.save) {
229
- await saveKeyPair({
230
- privateKey,
231
- publicKey
232
- }, options);
233
- }
234
- }
235
- return {
236
- privateKey,
237
- publicKey
238
- };
262
+ function normalizeAsymmetricKeyImportOptions(options) {
263
+ let optionsNormalized;
264
+ switch (options.name) {
265
+ case "RSASSA-PKCS1-v1_5":
266
+ case "RSA-PSS":
267
+ case "RSA-OAEP":
268
+ optionsNormalized = {
269
+ hash: "SHA-256",
270
+ ...options
271
+ };
272
+ break;
273
+ case "ECDSA":
274
+ case "ECDH": optionsNormalized = {
275
+ namedCurve: "P-256",
276
+ ...options
277
+ };
278
+ }
279
+ return optionsNormalized;
239
280
  }
240
-
241
- const keyPairCache = {};
242
- async function useKeyPair(value) {
243
- let options;
244
- if (typeof value === 'string') {
245
- options = extendKeyPairOptions({
246
- privateName: value
247
- });
248
- } else {
249
- options = extendKeyPairOptions(value || {});
250
- }
251
- if (Object.prototype.hasOwnProperty.call(keyPairCache, options.privateName)) {
252
- return keyPairCache[options.privateName];
253
- }
254
- let keyPair = await loadKeyPair(options);
255
- if (typeof keyPair === 'undefined') {
256
- keyPair = await createKeyPair(options);
257
- }
258
- keyPairCache[options.privateName] = keyPair;
259
- return keyPair;
281
+ //#endregion
282
+ //#region src/crypto/key/asymmetric/module.ts
283
+ var AsymmetricKey = class AsymmetricKey extends BaseKey {
284
+ async toPem() {
285
+ const base64 = await this.toBase64();
286
+ if (this.key.type === "public") return encodeSPKIToPem(base64);
287
+ if (this.key.type === "private") return encodePKCS8ToPEM(base64);
288
+ throw new Error(`${this.key.type} can not be converted to pem.`);
289
+ }
290
+ static async fromPem(ctx) {
291
+ if (ctx.format === "pkcs8") return AsymmetricKey.fromBase64({
292
+ ...ctx,
293
+ key: decodePemToPKCS8(ctx.key)
294
+ });
295
+ return AsymmetricKey.fromBase64({
296
+ ...ctx,
297
+ key: decodePemToSpki(ctx.key)
298
+ });
299
+ }
300
+ static async fromBase64(ctx) {
301
+ const arrayBuffer = base64ToArrayBuffer(ctx.key);
302
+ return AsymmetricKey.fromArrayBuffer({
303
+ ...ctx,
304
+ key: arrayBuffer
305
+ });
306
+ }
307
+ static async fromArrayBuffer(ctx) {
308
+ const normalizedOptions = normalizeAsymmetricKeyImportOptions(ctx.options);
309
+ return new AsymmetricKey(await subtle.importKey(ctx.format, ctx.key, normalizedOptions, true, getKeyUsagesForAsymmetricAlgorithm(normalizedOptions.name, ctx.format)));
310
+ }
311
+ static buildImportOptionsForJWTAlgorithm(alg) {
312
+ if (alg === JWTAlgorithm.RS256) return {
313
+ name: "RSASSA-PKCS1-v1_5",
314
+ hash: "SHA-256"
315
+ };
316
+ if (alg === JWTAlgorithm.RS384) return {
317
+ name: "RSASSA-PKCS1-v1_5",
318
+ hash: "SHA-384"
319
+ };
320
+ if (alg === JWTAlgorithm.RS512) return {
321
+ name: "RSASSA-PKCS1-v1_5",
322
+ hash: "SHA-512"
323
+ };
324
+ if (alg === JWTAlgorithm.ES256) return {
325
+ name: "ECDSA",
326
+ namedCurve: "P-256"
327
+ };
328
+ if (alg === JWTAlgorithm.ES384) return {
329
+ name: "ECDSA",
330
+ namedCurve: "P-384"
331
+ };
332
+ if (alg === JWTAlgorithm.ES512) return {
333
+ name: "ECDSA",
334
+ namedCurve: "P-521"
335
+ };
336
+ throw new Error(`Signature algorithm ${alg} is not supported.`);
337
+ }
338
+ };
339
+ //#endregion
340
+ //#region src/crypto/key/asymmetric/check.ts
341
+ function isAsymmetricAlgorithm(input) {
342
+ return Object.values(CryptoAsymmetricAlgorithm).includes(input);
260
343
  }
261
-
262
- function createErrorForJWTError(e) {
263
- if (isObject$1(e) && typeof e.name === 'string') {
264
- switch(e.name){
265
- case 'TokenExpiredError':
266
- {
267
- return TokenError.expired();
268
- }
269
- case 'NotBeforeError':
270
- {
271
- if (typeof e.date === 'string' || e.date instanceof Date) {
272
- return TokenError.notActiveBefore(e.date);
273
- }
274
- break;
275
- }
276
- case 'JsonWebTokenError':
277
- {
278
- if (typeof e.message === 'string') {
279
- return TokenError.payloadInvalid(e.message);
280
- }
281
- break;
282
- }
283
- }
284
- }
285
- return new TokenError({
286
- cause: e,
287
- logMessage: true,
288
- message: 'The JWT error could not be determined.'
289
- });
344
+ //#endregion
345
+ //#region src/crypto/key/asymmetric/create.ts
346
+ async function createAsymmetricKeyPair(options) {
347
+ const optionsNormalized = normalizeAsymmetricKeyPairCreateOptions(options);
348
+ return subtle.generateKey(optionsNormalized, true, getKeyUsagesForAsymmetricAlgorithm(optionsNormalized.name));
290
349
  }
291
-
292
- function decodeToken(token, options) {
293
- options ?? (options = {});
294
- let output;
295
- try {
296
- output = decode(token, {
297
- ...options
298
- });
299
- } catch (e) {
300
- throw createErrorForJWTError(e);
301
- }
302
- if (output === null) {
303
- throw TokenError.payloadInvalid('The token could not be decoded.');
304
- }
305
- return output;
350
+ //#endregion
351
+ //#region src/crypto/key/symmetric/constants.ts
352
+ let SymmetricAlgorithm = /* @__PURE__ */ function(SymmetricAlgorithm) {
353
+ SymmetricAlgorithm["HMAC"] = "HMAC";
354
+ SymmetricAlgorithm["AES_CTR"] = "AES-CTR";
355
+ SymmetricAlgorithm["AES_CBC"] = "AES-CBC";
356
+ SymmetricAlgorithm["AES_GCM"] = "AES-GCM";
357
+ return SymmetricAlgorithm;
358
+ }({});
359
+ //#endregion
360
+ //#region src/crypto/key/symmetric/check.ts
361
+ function isSymmetricAlgorithm(input) {
362
+ return Object.values(SymmetricAlgorithm).includes(input);
306
363
  }
307
-
308
- async function signToken(payload, context) {
309
- context.expiresIn = context.expiresIn || 3600;
310
- switch(context.type){
311
- case KeyType.RSA:
312
- case KeyType.EC:
313
- {
314
- const { type, keyPair, ...options } = context;
315
- const { privateKey } = isKeyPair(keyPair) ? keyPair : await useKeyPair(keyPair);
316
- if (type === KeyType.RSA) {
317
- options.algorithm = options.algorithm || 'RS256';
318
- } else {
319
- options.algorithm = options.algorithm || 'ES256';
320
- }
321
- return sign(payload, privateKey, options);
322
- }
323
- case KeyType.OCT:
324
- {
325
- const { type, secret, ...options } = context;
326
- options.algorithm = options.algorithm || 'HS256';
327
- return sign(payload, secret, options);
328
- }
329
- }
330
- throw new TokenError();
364
+ //#endregion
365
+ //#region src/crypto/key/symmetric/key-usages.ts
366
+ function getKeyUsagesForSymmetricAlgorithm(name) {
367
+ /**
368
+ * @see https://nodejs.org/api/webcrypto.html#cryptokeyusages
369
+ */
370
+ if (name === "HMAC") return ["sign", "verify"];
371
+ if (name === "AES-CBC" || name === "AES-GCM" || name === "AES-CTR") return ["encrypt", "decrypt"];
372
+ throw new SyntaxError(`Key usages can not be determined for symmetric algorithm: ${name}`);
331
373
  }
332
-
333
- async function verifyToken(token, context) {
334
- let promise;
335
- let output;
336
- try {
337
- switch(context.type){
338
- case KeyType.RSA:
339
- case KeyType.EC:
340
- {
341
- const { type, keyPair, ...options } = context;
342
- const { publicKey } = isKeyPairWithPublicKey(keyPair) ? keyPair : await useKeyPair(keyPair);
343
- if (type === KeyType.RSA) {
344
- options.algorithms = options.algorithms || [
345
- 'RS256',
346
- 'RS384',
347
- 'RS512',
348
- 'PS256',
349
- 'PS384',
350
- 'PS512'
351
- ];
352
- } else {
353
- options.algorithms = options.algorithms || [
354
- 'ES256',
355
- 'ES384',
356
- 'ES512'
357
- ];
358
- }
359
- promise = new Promise((resolve, reject)=>{
360
- verify(token, publicKey, options, (err, decoded)=>{
361
- if (err) {
362
- reject(err);
363
- return;
364
- }
365
- resolve(decoded);
366
- });
367
- });
368
- break;
369
- }
370
- case KeyType.OCT:
371
- {
372
- const { type, secret, ...options } = context;
373
- options.algorithms = options.algorithms || [
374
- 'HS256',
375
- 'HS384',
376
- 'HS512'
377
- ];
378
- promise = new Promise((resolve, reject)=>{
379
- verify(token, secret, options, (err, decoded)=>{
380
- if (err) {
381
- reject(err);
382
- return;
383
- }
384
- resolve(decoded);
385
- });
386
- });
387
- }
388
- }
389
- output = await promise;
390
- } catch (e) {
391
- throw createErrorForJWTError(e);
392
- }
393
- if (typeof output === 'undefined') {
394
- throw new TokenError({
395
- message: 'Invalid type.'
396
- });
397
- }
398
- return output;
374
+ //#endregion
375
+ //#region src/crypto/key/symmetric/normalize.ts
376
+ function normalizeSymmetricKeyCreateOptions(input) {
377
+ if (input.name === "HMAC") return {
378
+ hash: "SHA-256",
379
+ ...input
380
+ };
381
+ return {
382
+ length: 256,
383
+ name: input.name
384
+ };
399
385
  }
400
-
401
- function transformDomainEventData(input) {
402
- if (isObject(input)) {
403
- const keys = Object.keys(input);
404
- for(let i = 0; i < keys.length; i++){
405
- const value = input[keys[i]];
406
- if (value instanceof Date) {
407
- input[keys[i]] = value.toISOString();
408
- }
409
- }
410
- }
411
- return input;
386
+ function normalizeSymmetricKeyImportOptions(input) {
387
+ if (input.name === "HMAC") return {
388
+ hash: "SHA-256",
389
+ ...input
390
+ };
391
+ return input;
412
392
  }
413
- function buildDomainEventChannelName(input, id) {
414
- if (typeof input === 'string') {
415
- return input;
416
- }
417
- return input(id);
393
+ //#endregion
394
+ //#region src/crypto/key/symmetric/module.ts
395
+ var SymmetricKey = class SymmetricKey extends BaseKey {
396
+ static async fromBase64(ctx) {
397
+ const arrayBuffer = base64ToArrayBuffer(ctx.key);
398
+ return SymmetricKey.fromArrayBuffer({
399
+ ...ctx,
400
+ key: arrayBuffer
401
+ });
402
+ }
403
+ static async fromArrayBuffer(ctx) {
404
+ const normalizedOptions = normalizeSymmetricKeyImportOptions(ctx.options);
405
+ return new SymmetricKey(await subtle.importKey(ctx.format, ctx.key, normalizedOptions, true, getKeyUsagesForSymmetricAlgorithm(normalizedOptions.name)));
406
+ }
407
+ static buildImportOptionsForJWTAlgorithm(alg) {
408
+ if (alg === JWTAlgorithm.HS256) return {
409
+ name: "HMAC",
410
+ hash: "SHA-256"
411
+ };
412
+ if (alg === JWTAlgorithm.HS384) return {
413
+ name: "HMAC",
414
+ hash: "SHA-384"
415
+ };
416
+ if (alg === JWTAlgorithm.HS512) return {
417
+ name: "HMAC",
418
+ hash: "SHA-512"
419
+ };
420
+ throw new Error(`Signature algorithm ${alg} is not supported.`);
421
+ }
422
+ };
423
+ //#endregion
424
+ //#region src/crypto/key/symmetric/create.ts
425
+ async function createSymmetricKey(input) {
426
+ const optionsNormalized = normalizeSymmetricKeyCreateOptions(input);
427
+ return subtle.generateKey(optionsNormalized, true, getKeyUsagesForSymmetricAlgorithm(optionsNormalized.name));
418
428
  }
419
-
420
- async function publishDomainRedisEvent(context, destinations) {
421
- if (!hasClient() && !hasConfig()) {
422
- return Promise.resolve();
423
- }
424
- context = transformDomainEventData(context);
425
- const json = JSON.stringify(context);
426
- const client = useClient();
427
- const pipeline = client.pipeline();
428
- for(let i = 0; i < destinations.length; i++){
429
- const { namespace } = destinations[i];
430
- const keyPrefix = namespace ? `${namespace}:` : '';
431
- let key = keyPrefix + buildDomainEventChannelName(destinations[i].channel);
432
- pipeline.publish(key, json);
433
- if (context.event !== DomainEventName.CREATED && typeof destinations[i].channel === 'function') {
434
- key = keyPrefix + buildDomainEventChannelName(destinations[i].channel, context.data.id);
435
- pipeline.publish(key, json);
436
- }
437
- }
438
- return pipeline.exec();
429
+ //#endregion
430
+ //#region src/crypto/json-web-token/extract.ts
431
+ /**
432
+ * Decode a JWT token with no verification.
433
+ *
434
+ * @param token
435
+ *
436
+ * @throws JWTError
437
+ */
438
+ function extractTokenHeader(token) {
439
+ const parts = token.split(".");
440
+ if (parts.length !== 3) throw JWTError.invalid();
441
+ const [headerBase64] = parts;
442
+ try {
443
+ const payload = atob(headerBase64);
444
+ return JSON.parse(payload);
445
+ } catch {
446
+ throw JWTError.headerInvalid("The token header could not be extracted.");
447
+ }
439
448
  }
440
-
441
- let instance$3;
442
- function useSocketEmitter() {
443
- if (typeof instance$3 !== 'undefined') {
444
- return instance$3;
445
- }
446
- instance$3 = new Emitter(useClient());
447
- return instance$3;
449
+ /**
450
+ * @param token
451
+ *
452
+ * @throws JWTError
453
+ */
454
+ function extractTokenPayload(token) {
455
+ const parts = token.split(".");
456
+ if (parts.length !== 3) throw JWTError.invalid();
457
+ const [, payloadBase64] = parts;
458
+ try {
459
+ const payload = atob(payloadBase64);
460
+ return JSON.parse(payload);
461
+ } catch {
462
+ throw JWTError.payloadInvalid("The token payload could not be extracted.");
463
+ }
448
464
  }
449
-
450
- function publishDomainSocketEvent(context, destinations) {
451
- if (!hasClient() && !hasConfig()) {
452
- return;
453
- }
454
- context = transformDomainEventData(context);
455
- for(let i = 0; i < destinations.length; i++){
456
- let emitter = useSocketEmitter();
457
- if (destinations[i].namespace) {
458
- emitter = emitter.of(destinations[i].namespace);
459
- }
460
- let roomName = buildDomainEventChannelName(destinations[i].channel);
461
- const fullEventName = buildDomainEventFullName(context.type, context.event);
462
- emitter.in(roomName)// eslint-disable-next-line @typescript-eslint/ban-ts-comment
463
- // @ts-ignore
464
- .emit(fullEventName, {
465
- ...context,
466
- meta: {
467
- roomName
468
- }
469
- });
470
- if (context.event !== DomainEventName.CREATED && typeof destinations[i].channel === 'function') {
471
- roomName = buildDomainEventChannelName(destinations[i].channel, context.data.id);
472
- emitter.in(roomName)// eslint-disable-next-line @typescript-eslint/ban-ts-comment
473
- // @ts-ignore
474
- .emit(fullEventName, {
475
- ...context,
476
- meta: {
477
- roomName,
478
- roomId: context.data.id
479
- }
480
- });
481
- }
482
- }
465
+ //#endregion
466
+ //#region src/crypto/json-web-token/utils.ts
467
+ function createErrorForJWTError(e) {
468
+ if (isObject(e)) {
469
+ if (typeof e.name === "string") switch (e.name) {
470
+ case "TokenExpiredError": return JWTError.expired();
471
+ case "NotBeforeError":
472
+ if (typeof e.date === "string" || e.date instanceof Date) return JWTError.notActiveBefore(e.date);
473
+ break;
474
+ case "JsonWebTokenError":
475
+ if (typeof e.message === "string") return JWTError.payloadInvalid(e.message);
476
+ break;
477
+ }
478
+ switch (e.message) {
479
+ case "ExpiredSignature": return JWTError.expired();
480
+ case "ImmatureSignature": return JWTError.notActiveBefore();
481
+ case "InvalidToken":
482
+ case "InvalidSignature": return JWTError.payloadInvalid();
483
+ }
484
+ }
485
+ return new JWTError({
486
+ cause: e,
487
+ message: "The JWT error could not be determined."
488
+ });
483
489
  }
484
-
485
- async function publishDomainEvent(context, destinations) {
486
- await publishDomainRedisEvent(context, destinations);
487
- publishDomainSocketEvent(context, destinations);
490
+ function transformJWTAlgorithmToInternal(algorithm) {
491
+ switch (algorithm) {
492
+ case JWTAlgorithm.HS256: return Algorithm.HS256;
493
+ case JWTAlgorithm.HS384: return Algorithm.HS384;
494
+ case JWTAlgorithm.HS512: return Algorithm.HS512;
495
+ case JWTAlgorithm.RS256: return Algorithm.RS256;
496
+ case JWTAlgorithm.RS384: return Algorithm.RS384;
497
+ case JWTAlgorithm.RS512: return Algorithm.RS512;
498
+ case JWTAlgorithm.ES256: return Algorithm.ES256;
499
+ case JWTAlgorithm.ES384: return Algorithm.ES384;
500
+ case JWTAlgorithm.PS256: return Algorithm.PS256;
501
+ case JWTAlgorithm.PS384: return Algorithm.PS384;
502
+ case JWTAlgorithm.PS512: return Algorithm.PS512;
503
+ }
504
+ throw new Error(`The algorithm ${algorithm} is not supported.`);
488
505
  }
489
-
490
- /*
491
- * Copyright (c) 2022.
492
- * Author Peter Placzek (tada5hi)
493
- * For the full copyright and license information,
494
- * view the LICENSE file that was distributed with this source code.
495
- */ class VoidLogger {
496
- error() {
497
- return this;
498
- }
499
- warn() {
500
- return this;
501
- }
502
- info() {
503
- return this;
504
- }
505
- http() {
506
- return this;
507
- }
508
- verbose() {
509
- return this;
510
- }
511
- debug() {
512
- return this;
513
- }
506
+ //#endregion
507
+ //#region src/crypto/json-web-token/sign/module.ts
508
+ const getUtcTimestamp = () => Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3);
509
+ async function signToken(claims, context) {
510
+ if (typeof claims.exp !== "number") claims.exp = getUtcTimestamp() + 3600;
511
+ if (typeof claims.iat !== "number") claims.iat = getUtcTimestamp();
512
+ switch (context.type) {
513
+ case JWKType.RSA:
514
+ case JWKType.EC: {
515
+ let algorithm;
516
+ let key;
517
+ if (typeof context.key === "string") key = encodePKCS8ToPEM(context.key);
518
+ else key = await new AsymmetricKey(context.key).toPem();
519
+ if (context.type === JWKType.RSA) algorithm = context.algorithm ? transformJWTAlgorithmToInternal(context.algorithm) : Algorithm.RS256;
520
+ else algorithm = context.algorithm ? transformJWTAlgorithmToInternal(context.algorithm) : Algorithm.ES256;
521
+ return sign(claims, key, {
522
+ algorithm,
523
+ keyId: context.keyId
524
+ });
525
+ }
526
+ case JWKType.OCT: {
527
+ const algorithm = context.algorithm ? transformJWTAlgorithmToInternal(context.algorithm) : Algorithm.HS256;
528
+ let key;
529
+ if (typeof context.key === "string") key = context.key;
530
+ else key = await new SymmetricKey(context.key).toUint8Array();
531
+ return sign(claims, key, {
532
+ algorithm,
533
+ keyId: context.keyId
534
+ });
535
+ }
536
+ }
537
+ throw new JWTError();
514
538
  }
515
-
516
- let instance$2;
517
- function useLogger() {
518
- if (typeof instance$2 !== 'undefined') {
519
- return instance$2;
520
- }
521
- instance$2 = new VoidLogger();
522
- return instance$2;
539
+ //#endregion
540
+ //#region src/crypto/json-web-token/verify/module.ts
541
+ /**
542
+ * Verify JWT.
543
+ *
544
+ * @param token
545
+ * @param context
546
+ *
547
+ * @throws OAuth2Error
548
+ */
549
+ async function verifyToken(token, context) {
550
+ let promise;
551
+ let output;
552
+ try {
553
+ switch (context.type) {
554
+ case JWKType.RSA:
555
+ case JWKType.EC: {
556
+ let algorithms;
557
+ if (context.type === JWKType.RSA) algorithms = context.algorithms ? context.algorithms.map((algorithm) => transformJWTAlgorithmToInternal(algorithm)) : [
558
+ Algorithm.RS256,
559
+ Algorithm.RS384,
560
+ Algorithm.RS512,
561
+ Algorithm.PS256,
562
+ Algorithm.PS384,
563
+ Algorithm.PS512
564
+ ];
565
+ else algorithms = context.algorithms ? context.algorithms.map((algorithm) => transformJWTAlgorithmToInternal(algorithm)) : [Algorithm.ES256, Algorithm.ES384];
566
+ let key;
567
+ if (typeof context.key === "string") key = encodeSPKIToPem(context.key);
568
+ else key = await new AsymmetricKey(context.key).toPem();
569
+ promise = verify(token, key, {
570
+ algorithms,
571
+ validateNbf: true
572
+ });
573
+ break;
574
+ }
575
+ case JWKType.OCT: {
576
+ const algorithms = context.algorithms ? context.algorithms.map((algorithm) => transformJWTAlgorithmToInternal(algorithm)) : [
577
+ Algorithm.HS256,
578
+ Algorithm.HS384,
579
+ Algorithm.HS512
580
+ ];
581
+ let key;
582
+ if (typeof context.key === "string") key = context.key;
583
+ else key = await new SymmetricKey(context.key).toUint8Array();
584
+ promise = verify(token, key, {
585
+ algorithms,
586
+ validateNbf: true
587
+ });
588
+ }
589
+ }
590
+ if (promise) output = await promise;
591
+ } catch (e) {
592
+ throw createErrorForJWTError(e);
593
+ }
594
+ if (!output) throw new JWTError();
595
+ return output;
523
596
  }
524
- function setLogger(logger) {
525
- instance$2 = logger;
597
+ //#endregion
598
+ //#region src/domain-event/utils.ts
599
+ function transformDomainEventData(input) {
600
+ const keys = Object.keys(input);
601
+ for (const key_ of keys) {
602
+ const key = key_;
603
+ const value = input[key];
604
+ if (!isObject$1(value)) continue;
605
+ if (value instanceof Date) input[key] = value.toISOString();
606
+ }
607
+ return input;
526
608
  }
527
-
528
- /*
529
- * Copyright (c) 2022.
530
- * Author Peter Placzek (tada5hi)
531
- * For the full copyright and license information,
532
- * view the LICENSE file that was distributed with this source code.
533
- */ let instance$1;
534
- function hasSmtpConfig() {
535
- return !!instance$1;
536
- }
537
- function setSmtpConfig(value) {
538
- instance$1 = value;
539
- }
540
- function useSmtpConfig() {
541
- if (typeof instance$1 !== 'undefined') {
542
- return instance$1;
543
- }
544
- instance$1 = {};
545
- return instance$1;
609
+ function buildDomainEventChannelName(input, id) {
610
+ if (typeof input === "string") return input;
611
+ return input(id);
546
612
  }
547
-
548
- function createSmtpClient(options) {
549
- let transport;
550
- options = options || {};
551
- if (typeof options === 'string') {
552
- transport = createTransport(options);
553
- } else if (options.connectionString) {
554
- transport = createTransport(options.connectionString);
555
- } else {
556
- let auth;
557
- if (options.user && options.password) {
558
- auth = {
559
- type: 'login',
560
- user: options.user,
561
- pass: options.password
562
- };
563
- }
564
- transport = createTransport({
565
- host: options.host,
566
- port: options.port,
567
- auth,
568
- secure: options.ssl,
569
- opportunisticTLS: options.starttls,
570
- tls: {
571
- rejectUnauthorized: false
572
- }
573
- });
574
- }
575
- transport.on('error', (e)=>{
576
- useLogger().error(e.message);
577
- });
578
- return transport;
613
+ //#endregion
614
+ //#region src/domain-event/handlers/redis/module.ts
615
+ var DomainEventRedisHandler = class {
616
+ driver;
617
+ constructor(input) {
618
+ this.driver = createRedisClient(input);
619
+ }
620
+ async handle(ctx) {
621
+ const data = JSON.stringify(transformDomainEventData(ctx.content));
622
+ const pipeline = this.driver.pipeline();
623
+ for (let i = 0; i < ctx.destinations.length; i++) {
624
+ const { namespace } = ctx.destinations[i];
625
+ const keyPrefix = namespace ? `${namespace}:` : "";
626
+ let key = keyPrefix + buildDomainEventChannelName(ctx.destinations[i].channel);
627
+ pipeline.publish(key, data);
628
+ if (typeof ctx.destinations[i].channel === "function") {
629
+ key = keyPrefix + buildDomainEventChannelName(ctx.destinations[i].channel, ctx.content.data.id);
630
+ pipeline.publish(key, data);
631
+ }
632
+ }
633
+ await pipeline.exec();
634
+ }
635
+ };
636
+ //#endregion
637
+ //#region src/domain-event/handlers/socket/module.ts
638
+ var DomainEventSocketHandler = class {
639
+ driver;
640
+ constructor(input) {
641
+ const client = createRedisClient(input);
642
+ this.driver = new Emitter(client);
643
+ }
644
+ async handle(ctx) {
645
+ ctx.content = transformDomainEventData(ctx.content);
646
+ for (let i = 0; i < ctx.destinations.length; i++) {
647
+ const destination = ctx.destinations[i];
648
+ let emitter;
649
+ if (destination.namespace) emitter = this.driver.of(destination.namespace);
650
+ else emitter = this.driver;
651
+ let roomName = buildDomainEventChannelName(destination.channel);
652
+ const fullEventName = buildEventFullName(ctx.content.type, ctx.content.event);
653
+ emitter.in(roomName).emit(fullEventName, {
654
+ ...ctx.content,
655
+ meta: { roomName }
656
+ });
657
+ if (typeof destination.channel === "function") {
658
+ roomName = buildDomainEventChannelName(destination.channel, ctx.content.data.id);
659
+ emitter.in(roomName).emit(fullEventName, {
660
+ ...ctx.content,
661
+ meta: {
662
+ roomName,
663
+ roomId: ctx.content.data.id
664
+ }
665
+ });
666
+ }
667
+ }
668
+ }
669
+ };
670
+ //#endregion
671
+ //#region src/domain-event/module.ts
672
+ var DomainEventPublisher = class {
673
+ handlers;
674
+ logger;
675
+ constructor(ctx = {}) {
676
+ this.handlers = /* @__PURE__ */ new Set();
677
+ this.logger = ctx.logger;
678
+ }
679
+ register(handler) {
680
+ this.handlers.add(handler);
681
+ }
682
+ async dispose() {
683
+ for (const handler of this.handlers) if (handler.dispose) await handler.dispose();
684
+ this.handlers.clear();
685
+ }
686
+ async safePublish(ctx) {
687
+ try {
688
+ await this.publish(ctx);
689
+ } catch (e) {
690
+ if (this.logger) {
691
+ this.logger.error(`Publishing event ${buildEventFullName(ctx.content.type, ctx.content.event)} failed.`);
692
+ this.logger.error(e);
693
+ }
694
+ }
695
+ }
696
+ async publish(ctx) {
697
+ if (this.handlers.size === 0) return;
698
+ if (this.logger) this.logger.debug(`Publishing event ${buildEventFullName(ctx.content.type, ctx.content.event)}...`);
699
+ const handlers = this.handlers.values();
700
+ while (true) {
701
+ const it = handlers.next();
702
+ if (it.done) return;
703
+ await it.value.handle(ctx);
704
+ }
705
+ }
706
+ };
707
+ //#endregion
708
+ //#region src/logger/module.ts
709
+ function createNoopLogger() {
710
+ return createLogger$1({ silent: true });
579
711
  }
580
-
581
- let instance;
582
- async function useSMTPClient() {
583
- if (typeof instance !== 'undefined') {
584
- return instance;
585
- }
586
- let options;
587
- if (process.env.NODE_ENV === 'test') {
588
- const testAccount = await createTestAccount();
589
- options = {
590
- host: 'smtp.ethereal.email',
591
- port: 587,
592
- ssl: false,
593
- user: testAccount.user,
594
- password: testAccount.pass
595
- };
596
- } else {
597
- options = useSmtpConfig();
598
- }
599
- instance = createSmtpClient(options);
600
- return instance;
712
+ function createLogger(context) {
713
+ let items;
714
+ const cwd = context.directory || process.cwd();
715
+ if (context.env === "production") items = [
716
+ new transports.Console({ level: "info" }),
717
+ new transports.File({
718
+ filename: path.join(cwd, "http.log"),
719
+ level: "http",
720
+ maxsize: 10 * 1024 * 1024,
721
+ maxFiles: 5
722
+ }),
723
+ new transports.File({
724
+ filename: path.join(cwd, "error.log"),
725
+ level: "warn",
726
+ maxsize: 10 * 1024 * 1024,
727
+ maxFiles: 5
728
+ })
729
+ ];
730
+ else items = [new transports.Console({ level: "debug" })];
731
+ return createLogger$1({
732
+ format: format.combine(format.errors({ stack: true }), format.timestamp(), format.colorize(), format.simple()),
733
+ transports: items
734
+ });
601
735
  }
602
-
603
- /*
604
- * Copyright (c) 2022.
605
- * Author Peter Placzek (tada5hi)
606
- * For the full copyright and license information,
607
- * view the LICENSE file that was distributed with this source code.
608
- */ function hasOwnProperty(obj, prop) {
609
- return Object.prototype.hasOwnProperty.call(obj, prop);
736
+ //#endregion
737
+ //#region src/utils/has-property.ts
738
+ function hasOwnProperty(obj, prop) {
739
+ return Object.prototype.hasOwnProperty.call(obj, prop);
610
740
  }
741
+ //#endregion
742
+ export { AbstractEntityService, AsymmetricKey, BaseKey, CryptoAsymmetricAlgorithm, DomainEventPublisher, DomainEventRedisHandler, DomainEventSocketHandler, MemoryCache, RedisCache, RedisClient, RedisJsonAdapter, RedisWatcher, SymmetricAlgorithm, SymmetricKey, buildCacheKey, buildRedisKeyPath, compare, createAsymmetricKeyPair, createLogger, createNoopLogger, createRedisClient, createSymmetricKey, decodePemToPKCS8, decodePemToSpki, encodePKCS8ToPEM, encodeSPKIToPem, escapeRedisKey, extractTokenHeader, extractTokenPayload, getKeyUsagesForAsymmetricAlgorithm, getKeyUsagesForSymmetricAlgorithm, hasOwnProperty, hash, isAsymmetricAlgorithm, isRedisClient, isSymmetricAlgorithm, normalizeAsymmetricKeyImportOptions, normalizeAsymmetricKeyPairCreateOptions, parseRedisKeyPath, signToken, verifyToken };
611
743
 
612
- export { KeyPairKind, VoidLogger, buildKeyFileName, compare, createKeyPair, createSmtpClient, decodeToken, decryptRSAPrivateKey, deleteKeyPair, extendKeyPairOptions, hasOwnProperty, hasSmtpConfig, hash, isKeyPair, isKeyPairWithPublicKey, loadKeyPair, publishDomainEvent, publishDomainRedisEvent, publishDomainSocketEvent, saveKeyPair, setLogger, setSmtpConfig, signToken, useKeyPair, useLogger, useSMTPClient, useSmtpConfig, useSocketEmitter, verifyToken };
613
- //# sourceMappingURL=index.mjs.map
744
+ //# sourceMappingURL=index.mjs.map