vortez 5.0.0-dev.19 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/.gitignore +2 -0
  2. package/README.md +33 -9
  3. package/build/Template/Compiler.d.ts +70 -0
  4. package/build/Template/Compiler.js +135 -0
  5. package/build/Template/Compiler.js.map +1 -0
  6. package/build/Template/StreamCompiler.d.ts +16 -0
  7. package/build/Template/StreamCompiler.js +54 -0
  8. package/build/Template/StreamCompiler.js.map +1 -0
  9. package/build/Template/Template.d.ts +49 -0
  10. package/build/Template/Template.js +77 -0
  11. package/build/Template/Template.js.map +1 -0
  12. package/build/Vortez.d.ts +1 -1
  13. package/build/Vortez.js +1 -1
  14. package/build/Vortez.js.map +1 -1
  15. package/build/beta/JwtManager/JwtError.d.ts +8 -0
  16. package/build/beta/JwtManager/JwtError.js +10 -0
  17. package/build/beta/JwtManager/JwtError.js.map +1 -0
  18. package/build/beta/JwtManager/JwtManager.d.ts +4 -0
  19. package/build/beta/JwtManager/JwtManager.js +27 -7
  20. package/build/beta/JwtManager/JwtManager.js.map +1 -1
  21. package/build/server/BodyParser.d.ts +6 -0
  22. package/build/server/BodyParser.js +18 -3
  23. package/build/server/BodyParser.js.map +1 -1
  24. package/build/server/Request.d.ts +6 -4
  25. package/build/server/Request.js +15 -10
  26. package/build/server/Request.js.map +1 -1
  27. package/build/server/Response.d.ts +56 -10
  28. package/build/server/Response.js +204 -92
  29. package/build/server/Response.js.map +1 -1
  30. package/build/server/Server.js +29 -6
  31. package/build/server/Server.js.map +1 -1
  32. package/build/server/config/Config.d.ts +15 -13
  33. package/build/server/config/Config.js +8 -6
  34. package/build/server/config/Config.js.map +1 -1
  35. package/build/server/config/Loader.js +1 -1
  36. package/build/server/config/Loader.js.map +1 -1
  37. package/build/server/router/Router.d.ts +1 -1
  38. package/build/server/router/Router.js +4 -4
  39. package/build/server/router/Router.js.map +1 -1
  40. package/build/server/router/middleware/HttpMiddleware.js +5 -5
  41. package/build/server/router/middleware/HttpMiddleware.js.map +1 -1
  42. package/build/server/router/middleware/WsMiddleware.js +1 -1
  43. package/build/server/router/middleware/WsMiddleware.js.map +1 -1
  44. package/build/server/security/PathSecurity.d.ts +45 -0
  45. package/build/server/security/PathSecurity.js +108 -0
  46. package/build/server/security/PathSecurity.js.map +1 -0
  47. package/build/server/websocket/Websocket.js +4 -1
  48. package/build/server/websocket/Websocket.js.map +1 -1
  49. package/build/utilities/ConsoleUI.d.ts +2 -1
  50. package/build/utilities/ConsoleUI.js +2 -1
  51. package/build/utilities/ConsoleUI.js.map +1 -1
  52. package/build/utilities/DebugUI.d.ts +1 -1
  53. package/build/utilities/DebugUI.js +1 -1
  54. package/build/utilities/Encoding.d.ts +22 -0
  55. package/build/utilities/Encoding.js +26 -0
  56. package/build/utilities/Encoding.js.map +1 -0
  57. package/build/utilities/Env.js +7 -2
  58. package/build/utilities/Env.js.map +1 -1
  59. package/build/utilities/File.d.ts +10 -0
  60. package/build/utilities/File.js +19 -0
  61. package/build/utilities/File.js.map +1 -0
  62. package/build/utilities/Flatten.d.ts +18 -1
  63. package/build/utilities/Flatten.js +18 -1
  64. package/build/utilities/Flatten.js.map +1 -1
  65. package/build/utilities/Object.d.ts +16 -0
  66. package/build/utilities/Object.js +48 -0
  67. package/build/utilities/Object.js.map +1 -0
  68. package/build/utilities/Path.d.ts +31 -11
  69. package/build/utilities/Path.js +48 -15
  70. package/build/utilities/Path.js.map +1 -1
  71. package/build/utilities/Time.d.ts +21 -0
  72. package/build/utilities/Time.js +25 -0
  73. package/build/utilities/Time.js.map +1 -0
  74. package/build/utilities/Utilities.d.ts +43 -34
  75. package/build/utilities/Utilities.js +48 -38
  76. package/build/utilities/Utilities.js.map +1 -1
  77. package/changes.md +5 -0
  78. package/docs/ARCHITECTURE.md +142 -0
  79. package/global/style/template/error.css +29 -0
  80. package/global/style/template/folder.css +79 -0
  81. package/global/{Style/Template/Template.css → style/template/template.css} +60 -68
  82. package/global/template/error.vhtml +29 -0
  83. package/global/template/folder.vhtml +54 -0
  84. package/package.json +2 -2
  85. package/build/Template.d.ts +0 -46
  86. package/build/Template.js +0 -81
  87. package/build/Template.js.map +0 -1
  88. package/global/Style/Template/Error.css +0 -30
  89. package/global/Style/Template/Folder.css +0 -77
  90. package/global/Template/Error.vhtml +0 -29
  91. package/global/Template/Folder.vhtml +0 -41
  92. package/tests/Template/template.js +0 -18
  93. package/tests/Template/template.txt +0 -13
  94. package/tests/Template/template.vhtml +0 -23
  95. package/tests/config/config.js +0 -233
  96. package/tests/debug.js +0 -34
  97. package/tests/jwtManager/jwtManager.js +0 -342
  98. package/tests/router.js +0 -596
  99. package/tests/schema/schema.js +0 -368
  100. package/tests/test.env +0 -0
  101. package/tests/test.js +0 -131
  102. package/tests/test.vhtml +0 -14
  103. package/tests/utilities.js +0 -28
  104. package/tests/websocket.vhtml +0 -86
  105. /package/global/{Source/Logo_960.png → source/logo_960.png} +0 -0
  106. /package/global/{Source/Logo_SM_960.png → source/logo_SM_960.png} +0 -0
@@ -1,342 +0,0 @@
1
- // @ts-check
2
- import { strict as assert } from 'assert';
3
-
4
- import { Beta, Logger } from "../../build/Vortez.js";
5
-
6
- const JwtManager = Beta.JwtManager;
7
- const logger = new Logger({prefix: 'JWT'});
8
-
9
- /** @type { Beta.JwtManager.Algorithm.HashLength[] } */
10
- const MASKS = ['256', '384', '512'];
11
-
12
- const RSA_KEY = JwtManager.KeyGenerator.generate('rsa');
13
- const PSS_KEY = JwtManager.KeyGenerator.generate('rsa-pss');
14
- const EC_KEY = JwtManager.KeyGenerator.generate('ec');
15
- const SECRET = JwtManager.KeyGenerator.generate('secret');
16
-
17
- const payload = {
18
- uuid: '00000000-0000-0000-0000-000000000000',
19
- name: 'NetFeez',
20
- email: 'netfeez.dev@gmail.com'
21
- };
22
-
23
- const header = {
24
- exp: Math.floor((Date.now() + 10000) / 1000)
25
- };
26
-
27
- let testsPassed = 0;
28
- let testsFailed = 0;
29
-
30
- /**
31
- * Logs test results.
32
- * @param { string } testName The test name.
33
- * @param { boolean } passed Whether the test passed.
34
- * @param { unknown | null } error Optional error object for failures.
35
- */
36
- function logTestResult(testName, passed, error = null) {
37
- if (passed) {
38
- logger.log(`&C2✓ ${testName}`);
39
- testsPassed++;
40
- } else {
41
- const message = error instanceof Error ? error.message : String(error);
42
- logger.error(`&C1✗ ${testName}${error ? ': ' + message : ''}`);
43
- testsFailed++;
44
- }
45
- };
46
-
47
- /**
48
- * Verifies signing and parsing for a given algorithm and key.
49
- * @param { Beta.JwtManager.KeyEntry.AlgorithmName } algorithm The algorithm under test.
50
- * @param { Beta.JwtManager.KeyEntry.Signer } key The signing key.
51
- */
52
- function testValidSignVerify(algorithm, key) {
53
- try {
54
- const jwt = new JwtManager({
55
- alg: algorithm,
56
- key: key,
57
- kid: 'key-v1'
58
- });
59
- const token = jwt.sign(payload, header);
60
- const parsed = jwt.parse(token);
61
-
62
- assert.deepEqual(parsed.payload, payload);
63
- assert.equal(parsed.header.alg, algorithm);
64
- logTestResult(`${algorithm} - Valid token sign/verify`, true);
65
- } catch (error) {
66
- logTestResult(`${algorithm} - Valid token sign/verify`, false, error);
67
- }
68
- };
69
-
70
- /**
71
- * Ensures a tampered payload is rejected.
72
- * @param { Beta.JwtManager.KeyEntry.AlgorithmName } algorithm The algorithm under test.
73
- * @param { Beta.JwtManager.KeyEntry.Signer } key The signing key.
74
- */
75
- function testTamperedPayload(algorithm, key) {
76
- try {
77
- const jwt = new JwtManager({
78
- alg: algorithm,
79
- key: key,
80
- });
81
- const token = jwt.sign(payload, header);
82
-
83
- const parts = token.split('.');
84
- const encodedPayload = JwtManager.JwtUtils.objectToBase64Url({ ...payload, name: 'Hacker' });
85
- const tamperedToken = `${parts[0]}.${encodedPayload}.${parts[2]}`;
86
-
87
- try {
88
- jwt.parse(tamperedToken);
89
- logTestResult(`${algorithm} - Reject tampered payload`, false, new Error('Should have thrown'));
90
- } catch (error) {
91
- if (`${error}`.includes('Invalid signature')) {
92
- logTestResult(`${algorithm} - Reject tampered payload`, true);
93
- } else {
94
- logTestResult(`${algorithm} - Reject tampered payload`, false, error);
95
- }
96
- }
97
- } catch (error) {
98
- logTestResult(`${algorithm} - Reject tampered payload`, false, error);
99
- }
100
- };
101
-
102
- /**
103
- * Ensures an expired token is rejected.
104
- * @param { Beta.JwtManager.KeyEntry.AlgorithmName } algorithm The algorithm under test.
105
- * @param { Beta.JwtManager.KeyEntry.Signer } key The signing key.
106
- */
107
- function testExpiredToken(algorithm, key) {
108
- try {
109
- const jwt = new JwtManager({
110
- alg: algorithm,
111
- key: key,
112
- });
113
-
114
- const expiredPayload = { ...payload, exp: Math.floor(Date.now() / 1000) - 1 };
115
- const token = jwt.sign(expiredPayload, header);
116
-
117
- try {
118
- jwt.parse(token);
119
- logTestResult(`${algorithm} - Reject expired token`, false, new Error('Should have thrown'));
120
- } catch (error) {
121
- const message = `${error}`;
122
- if (message.includes('expired')) {
123
- logTestResult(`${algorithm} - Reject expired token`, true);
124
- } else {
125
- logTestResult(`${algorithm} - Reject expired token`, false, message);
126
- }
127
- }
128
- } catch (error) {
129
- logTestResult(`${algorithm} - Reject expired token`, false, error);
130
- }
131
- };
132
-
133
- /**
134
- * Ensures a token cannot be verified with an unrelated key set.
135
- * @param { Beta.JwtManager.KeyEntry.AlgorithmName } algorithm The algorithm under test.
136
- * @param { Beta.JwtManager.KeyEntry.Signer } key The signing key.
137
- */
138
- function testMissingKey(algorithm, key) {
139
- try {
140
- const jwt = new JwtManager({
141
- alg: algorithm,
142
- key: key,
143
- });
144
- const token = jwt.sign(payload, header);
145
-
146
- const replacementKey = algorithm.startsWith('HS')
147
- ? JwtManager.KeyGenerator.generate('secret')
148
- : algorithm.startsWith('RS')
149
- ? JwtManager.KeyGenerator.generate('rsa')
150
- : algorithm.startsWith('PS')
151
- ? JwtManager.KeyGenerator.generate('rsa-pss')
152
- : JwtManager.KeyGenerator.generate('ec');
153
-
154
- const newJwt = new JwtManager({
155
- alg: algorithm,
156
- key: replacementKey,
157
- kid: `${algorithm}-replacement`
158
- });
159
-
160
- try {
161
- newJwt.parse(token);
162
- logTestResult(`${algorithm} - Reject token with unknown KID`, false, new Error('Should have thrown'));
163
- } catch (error) {
164
- const message = `${error}`;
165
- if (message.includes('No key found')) {
166
- logTestResult(`${algorithm} - Reject token with unknown KID`, true);
167
- } else {
168
- logTestResult(`${algorithm} - Reject token with unknown KID`, false, error);
169
- }
170
- }
171
- } catch (error) {
172
- logTestResult(`${algorithm} - Reject token with unknown KID`, false, error);
173
- }
174
- };
175
-
176
- /**
177
- * Ensures key rotation works.
178
- * @param { Beta.JwtManager.KeyEntry.AlgorithmName } algorithm The algorithm under test.
179
- * @param { Beta.JwtManager.KeyEntry.Signer } key The signing key.
180
- */
181
- function testKeyRotation(algorithm, key) {
182
- try {
183
- const jwt = new JwtManager({
184
- alg: algorithm,
185
- key: key,
186
- kid: 'key-v1',
187
- });
188
-
189
- const newKeyObj = algorithm.startsWith('HS')
190
- ? JwtManager.KeyGenerator.generate('secret')
191
- : algorithm.startsWith('RS')
192
- ? JwtManager.KeyGenerator.generate('rsa')
193
- : algorithm.startsWith('PS')
194
- ? JwtManager.KeyGenerator.generate('rsa-pss')
195
- : JwtManager.KeyGenerator.generate('ec');
196
-
197
- jwt.addKey({
198
- alg: algorithm,
199
- key: newKeyObj,
200
- kid: 'key-v2'
201
- });
202
-
203
- const token = jwt.sign(payload, { ...header, kid: 'key-v2' });
204
-
205
- const parsed = jwt.parse(token);
206
- assert.deepEqual(parsed.payload, payload);
207
- assert.equal(parsed.header.kid, 'key-v2');
208
-
209
- logTestResult(`${algorithm} - Key rotation`, true);
210
- } catch (error) {
211
- logTestResult(`${algorithm} - Key rotation`, false, error);
212
- }
213
- };
214
-
215
- /**
216
- * Ensures a public-key-only manager can verify but cannot sign.
217
- * @param { Beta.JwtManager.KeyEntry.AlgorithmName } algorithm
218
- * @param { { pub: string } } keyObj Object containing the public key.
219
- */
220
- function testReadOnlyPublicKey(algorithm, keyObj) {
221
- if (algorithm.startsWith('HS')) return;
222
-
223
- try {
224
- const sharedKid = `${algorithm}-public-only`;
225
- const verifier = new JwtManager({
226
- alg: algorithm,
227
- key: { pub: keyObj.pub },
228
- kid: sharedKid
229
- });
230
-
231
- try {
232
- verifier.sign(payload);
233
- logTestResult(`${algorithm} - Public key only: Sign blocked`, false, new Error('Should not be able to sign'));
234
- } catch (error) {
235
- if (`${error}`.includes('No key provided')) {
236
- logTestResult(`${algorithm} - Public key only: Sign blocked`, true);
237
- } else {
238
- logTestResult(`${algorithm} - Public key only: Sign blocked`, false, error);
239
- }
240
- }
241
-
242
- const signer = new JwtManager({
243
- alg: algorithm,
244
- key: keyObj,
245
- kid: sharedKid
246
- });
247
- const token = signer.sign(payload, { ...header, kid: sharedKid });
248
-
249
- const parsed = verifier.parse(token);
250
- assert.deepEqual(parsed.payload, payload);
251
- logTestResult(`${algorithm} - Public key only: Verify works`, true);
252
-
253
- } catch (error) {
254
- logTestResult(`${algorithm} - Public key only`, false, error);
255
- }
256
- }
257
- /**
258
- * Prevents RS256 to HS256 downgrade attacks.
259
- */
260
- function testAlgorithmConfusionAttack() {
261
- const algRS = 'RS256';
262
- const algHS = 'HS256';
263
-
264
- try {
265
- const manager = new JwtManager({
266
- alg: algRS,
267
- key: RSA_KEY,
268
- kid: 'secure-key'
269
- });
270
-
271
- const attackerManager = new JwtManager({
272
- alg: algHS,
273
- key: RSA_KEY.pub,
274
- });
275
-
276
- const maliciousToken = attackerManager.sign({ ...payload, name: 'Attacker' });
277
-
278
- try {
279
- manager.parse(maliciousToken);
280
- logTestResult(`Security - RS256 to HS256 Attack`, false, new Error('VULNERABLE: Accepted HS256 signed with RSA Public Key'));
281
- } catch (error) {
282
- logTestResult(`Security - RS256 to HS256 Attack blocked`, true);
283
- }
284
- } catch (error) {
285
- logTestResult(`Security - RS256 to HS256 Attack error`, false, error);
286
- }
287
- }
288
-
289
- /**
290
- * Runs all tests for the JwtManager across different algorithms and key types.
291
- * Logs the results and exits with a non-zero code if any tests failed.
292
- */
293
- const runTests = () => {
294
- logger.log('\n&C6=== JWT Manager Test Suite ===\n');
295
-
296
- for (let index = 0; index < MASKS.length; index++) {
297
-
298
- /** @type {Beta.JwtManager.KeyEntry.AlgorithmName} */
299
- const algorithm = `HS${MASKS[index]}`;
300
- /** @type {Beta.JwtManager.KeyEntry.AlgorithmName} */
301
- const algorithmRS = `RS${MASKS[index]}`;
302
- /** @type {Beta.JwtManager.KeyEntry.AlgorithmName} */
303
- const algorithmPS = `PS${MASKS[index]}`;
304
- /** @type {Beta.JwtManager.KeyEntry.AlgorithmName} */
305
- const algorithmES = `ES${MASKS[index]}`;
306
-
307
- testValidSignVerify(algorithm, SECRET);
308
- testTamperedPayload(algorithm, SECRET);
309
- testExpiredToken(algorithm, SECRET);
310
- testMissingKey(algorithm, SECRET);
311
- testKeyRotation(algorithm, SECRET);
312
-
313
- testValidSignVerify(algorithmRS, RSA_KEY);
314
- testTamperedPayload(algorithmRS, RSA_KEY);
315
- testExpiredToken(algorithmRS, RSA_KEY);
316
- testMissingKey(algorithmRS, RSA_KEY);
317
- testReadOnlyPublicKey(algorithmRS, RSA_KEY);
318
-
319
-
320
- testValidSignVerify(algorithmPS, PSS_KEY);
321
- testTamperedPayload(algorithmPS, PSS_KEY);
322
- testExpiredToken(algorithmPS, PSS_KEY);
323
- testReadOnlyPublicKey(algorithmPS, PSS_KEY);
324
-
325
- testValidSignVerify(algorithmES, EC_KEY);
326
- testTamperedPayload(algorithmES, EC_KEY);
327
- testExpiredToken(algorithmES, EC_KEY);
328
- testReadOnlyPublicKey(algorithmES, EC_KEY);
329
-
330
- }
331
-
332
- testAlgorithmConfusionAttack();
333
-
334
- logger.log(`\n&C6=== Results ===`);
335
- logger.log(`&C2✓ Passed: ${testsPassed}`);
336
- logger.log(`&C1✗ Failed: ${testsFailed}`);
337
- logger.log(`&C3Total: ${testsPassed + testsFailed}\n`);
338
-
339
- process.exit(testsFailed > 0 ? 1 : 0);
340
- };
341
-
342
- runTests();