@toa.io/extensions.exposition 1.0.0-alpha.302 → 1.0.0-alpha.304

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/components/identity.basic/types/toa.d.ts +1 -1
  2. package/components/identity.clients/types/toa.d.ts +1 -1
  3. package/components/identity.federation/types/toa.d.ts +1 -1
  4. package/components/identity.grants/manifest.toa.yaml +3 -1
  5. package/components/identity.grants/types/toa.d.ts +1 -1
  6. package/components/identity.otp/types/toa.d.ts +1 -1
  7. package/components/identity.passkeys/types/toa.d.ts +1 -1
  8. package/components/identity.tokens/operations/decrypt.js +106 -60
  9. package/components/identity.tokens/operations/lib/jose.js +5 -2
  10. package/components/identity.tokens/source/decrypt.ts +136 -65
  11. package/components/identity.tokens/source/lib/jose.js +5 -1
  12. package/components/identity.tokens/types/index.d.ts +1 -0
  13. package/components/identity.tokens/types/toa.d.ts +1 -1
  14. package/package.json +7 -7
  15. package/transpiled/Directive.d.ts +11 -4
  16. package/transpiled/Directive.js +50 -14
  17. package/transpiled/Directive.js.map +1 -1
  18. package/transpiled/Endpoint.js +13 -11
  19. package/transpiled/Endpoint.js.map +1 -1
  20. package/transpiled/Gateway.js +4 -0
  21. package/transpiled/Gateway.js.map +1 -1
  22. package/transpiled/HTTP/Context.d.ts +17 -0
  23. package/transpiled/HTTP/Context.js +17 -0
  24. package/transpiled/HTTP/Context.js.map +1 -1
  25. package/transpiled/HTTP/Server.js +12 -6
  26. package/transpiled/HTTP/Server.js.map +1 -1
  27. package/transpiled/HTTP/messages.d.ts +9 -7
  28. package/transpiled/HTTP/messages.js +15 -2
  29. package/transpiled/HTTP/messages.js.map +1 -1
  30. package/transpiled/HTTP/types.d.ts +1 -0
  31. package/transpiled/MCP/tools.js +66 -31
  32. package/transpiled/MCP/tools.js.map +1 -1
  33. package/transpiled/Query.js +2 -0
  34. package/transpiled/Query.js.map +1 -1
  35. package/transpiled/RTD/Directives.d.ts +26 -8
  36. package/transpiled/RTD/Match.d.ts +6 -0
  37. package/transpiled/RTD/Method.d.ts +12 -0
  38. package/transpiled/RTD/Method.js +21 -1
  39. package/transpiled/RTD/Method.js.map +1 -1
  40. package/transpiled/RTD/Node.d.ts +3 -1
  41. package/transpiled/RTD/Node.js +5 -3
  42. package/transpiled/RTD/Node.js.map +1 -1
  43. package/transpiled/RTD/Route.d.ts +1 -1
  44. package/transpiled/RTD/Route.js +8 -5
  45. package/transpiled/RTD/Route.js.map +1 -1
  46. package/transpiled/RTD/Tree.d.ts +12 -0
  47. package/transpiled/RTD/Tree.js +19 -1
  48. package/transpiled/RTD/Tree.js.map +1 -1
  49. package/transpiled/RTD/segment.d.ts +2 -0
  50. package/transpiled/RTD/segment.js +15 -0
  51. package/transpiled/RTD/segment.js.map +1 -1
  52. package/transpiled/directives/auth/Authorization.d.ts +9 -7
  53. package/transpiled/directives/auth/Authorization.js +17 -16
  54. package/transpiled/directives/auth/Authorization.js.map +1 -1
  55. package/transpiled/directives/cache/Cache.d.ts +11 -0
  56. package/transpiled/directives/cache/Cache.js +23 -24
  57. package/transpiled/directives/cache/Cache.js.map +1 -1
  58. package/transpiled/directives/cache/etag.d.ts +10 -7
  59. package/transpiled/directives/cache/etag.js +13 -10
  60. package/transpiled/directives/cache/etag.js.map +1 -1
  61. package/transpiled/directives/cors/CORS.js +1 -1
  62. package/transpiled/directives/cors/CORS.js.map +1 -1
  63. package/transpiled/directives/flow/Compose.js +2 -0
  64. package/transpiled/directives/flow/Compose.js.map +1 -1
  65. package/transpiled/directives/help/Family.d.ts +1 -2
  66. package/transpiled/directives/help/Family.js +1 -1
  67. package/transpiled/directives/help/Family.js.map +1 -1
  68. package/transpiled/directives/io/IO.d.ts +1 -1
  69. package/transpiled/directives/io/IO.js +1 -1
  70. package/transpiled/directives/io/IO.js.map +1 -1
  71. package/transpiled/directives/io/Output.d.ts +5 -3
  72. package/transpiled/directives/io/Output.js +11 -35
  73. package/transpiled/directives/io/Output.js.map +1 -1
  74. package/transpiled/directives/io/Status.d.ts +1 -1
  75. package/transpiled/directives/io/Status.js +4 -2
  76. package/transpiled/directives/io/Status.js.map +1 -1
  77. package/transpiled/directives/map/Map.d.ts +1 -1
  78. package/transpiled/directives/map/Map.js +1 -1
  79. package/transpiled/directives/map/Map.js.map +1 -1
  80. package/transpiled/directives/mcp/MCP.d.ts +1 -2
  81. package/transpiled/directives/mcp/MCP.js +1 -1
  82. package/transpiled/directives/mcp/MCP.js.map +1 -1
  83. package/transpiled/directives/octets/Octets.d.ts +1 -1
  84. package/transpiled/directives/octets/Octets.js +1 -1
  85. package/transpiled/directives/octets/Octets.js.map +1 -1
  86. package/transpiled/measurements.d.ts +22 -0
  87. package/transpiled/measurements.js +37 -0
  88. package/transpiled/measurements.js.map +1 -0
  89. package/transpiled/service.js +22 -2
  90. package/transpiled/service.js.map +1 -1
  91. package/ui/dist/_app/immutable/chunks/{Wl536IQX.js → BI21DxGX.js} +1 -1
  92. package/ui/dist/_app/immutable/chunks/{CyQvDdUS.js → B_XBOx9b.js} +1 -1
  93. package/ui/dist/_app/immutable/chunks/{BNmwbB_m.js → D9-CL3SX.js} +2 -2
  94. package/ui/dist/_app/immutable/chunks/{D8WVrjO4.js → DfeVAkjY.js} +1 -1
  95. package/ui/dist/_app/immutable/entry/{app.BnIDHdVY.js → app.BG2uapp5.js} +2 -2
  96. package/ui/dist/_app/immutable/entry/start.Bnttjc6A.js +1 -0
  97. package/ui/dist/_app/immutable/nodes/{0.DV2orh1u.js → 0.CAhVptPP.js} +1 -1
  98. package/ui/dist/_app/immutable/nodes/{1.Bgonurdo.js → 1.CymYf6vY.js} +1 -1
  99. package/ui/dist/_app/immutable/nodes/{2.C0ZHj2rR.js → 2.DtwEKRzb.js} +1 -1
  100. package/ui/dist/_app/immutable/nodes/{3.DOixCoug.js → 3.BgfGYNeS.js} +1 -1
  101. package/ui/dist/_app/immutable/nodes/{4.fXuZ_LUX.js → 4.B7W24tJ1.js} +1 -1
  102. package/ui/dist/_app/immutable/nodes/{5.BN65yDZR.js → 5.FCfJU5jO.js} +1 -1
  103. package/ui/dist/_app/immutable/nodes/{6.gez_DiIA.js → 6.B9oqMcPQ.js} +1 -1
  104. package/ui/dist/_app/version.json +1 -1
  105. package/ui/dist/index.html +10 -10
  106. package/ui/dist/_app/immutable/entry/start.BhKXzsOH.js +0 -1
@@ -4,7 +4,7 @@
4
4
  import type { Options, Query, RemoteError } from '@toa.io/core/types'
5
5
  import type { Secret } from '@toa.io/extensions.configuration'
6
6
  import type { FetchInit } from '@toa.io/extensions.fetch'
7
- import type { Logs, Span } from '@toa.io/extensions.telemetry'
7
+ import type { Logs, Metrics, Span } from '@toa.io/extensions.telemetry'
8
8
  import type { Readable } from 'node:stream'
9
9
 
10
10
  export interface Entity {
@@ -4,7 +4,7 @@
4
4
  import type { Options, Query, RemoteError } from '@toa.io/core/types'
5
5
  import type { FetchInit } from '@toa.io/extensions.fetch'
6
6
  import type { Stash } from '@toa.io/extensions.stash'
7
- import type { Logs, Span } from '@toa.io/extensions.telemetry'
7
+ import type { Logs, Metrics, Span } from '@toa.io/extensions.telemetry'
8
8
  import type { Readable } from 'node:stream'
9
9
 
10
10
  export interface Entity {
@@ -4,7 +4,7 @@
4
4
  import type { Options, Query, RemoteError } from '@toa.io/core/types'
5
5
  import type { Secret } from '@toa.io/extensions.configuration'
6
6
  import type { FetchInit } from '@toa.io/extensions.fetch'
7
- import type { Logs, Span } from '@toa.io/extensions.telemetry'
7
+ import type { Logs, Metrics, Span } from '@toa.io/extensions.telemetry'
8
8
  import type { Readable } from 'node:stream'
9
9
 
10
10
  export interface Entity {
@@ -231,7 +231,9 @@ exposition:
231
231
  endpoint: list
232
232
  POST:
233
233
  io:input: [client, redirect, challenge, method, scope, resource]
234
- io:output: [code, expires_in, error, error_description]
234
+ # `status` is read by `io:status` out of what the operation answers, and taken out of the
235
+ # body before it is sent
236
+ io:output: [code, expires_in, error, error_description, status]
235
237
  io:status: status
236
238
  cache:exact: no-store
237
239
  endpoint: authorize
@@ -4,7 +4,7 @@
4
4
  import type { Options, Query, RemoteError } from '@toa.io/core/types'
5
5
  import type { FetchInit } from '@toa.io/extensions.fetch'
6
6
  import type { Stash } from '@toa.io/extensions.stash'
7
- import type { Logs, Span } from '@toa.io/extensions.telemetry'
7
+ import type { Logs, Metrics, Span } from '@toa.io/extensions.telemetry'
8
8
  import type { Readable } from 'node:stream'
9
9
 
10
10
  export interface Entity {
@@ -4,7 +4,7 @@
4
4
  import type { Options, Query, RemoteError } from '@toa.io/core/types'
5
5
  import type { FetchInit } from '@toa.io/extensions.fetch'
6
6
  import type { Stash } from '@toa.io/extensions.stash'
7
- import type { Logs, Span } from '@toa.io/extensions.telemetry'
7
+ import type { Logs, Metrics, Span } from '@toa.io/extensions.telemetry'
8
8
  import type { Readable } from 'node:stream'
9
9
 
10
10
  export interface Entity {
@@ -4,7 +4,7 @@
4
4
  import type { Options, Query, RemoteError } from '@toa.io/core/types'
5
5
  import type { FetchInit } from '@toa.io/extensions.fetch'
6
6
  import type { Stash } from '@toa.io/extensions.stash'
7
- import type { Logs, Span } from '@toa.io/extensions.telemetry'
7
+ import type { Logs, Metrics, Span } from '@toa.io/extensions.telemetry'
8
8
  import type { Readable } from 'node:stream'
9
9
 
10
10
  export interface Entity {
@@ -1,7 +1,7 @@
1
+ import { createDecipheriv } from 'node:crypto';
1
2
  import { DecryptFactory, ImportKeyFactory } from 'paseto/v3/local';
2
3
  import { LRUCache } from 'lru-cache';
3
4
  import { form, jweKey } from './lib/index.js';
4
- import { load } from './lib/jose.js';
5
5
  export class Computation {
6
6
  keys = {};
7
7
  legacy = {};
@@ -23,32 +23,29 @@ export class Computation {
23
23
  }
24
24
  }
25
25
  async execute(token) {
26
- const legacy = form(token) === 'paseto';
27
- const kid = legacy ? this.pasetoKid(token) : await this.jweKid(token);
28
- if (kid instanceof Error)
29
- return kid;
30
- const key = await this.key(kid, legacy);
26
+ if (form(token) === 'paseto') {
27
+ const kid = this.pasetoKid(token);
28
+ if (kid instanceof Error)
29
+ return kid;
30
+ const key = await this.key(kid, true);
31
+ if (key instanceof Error)
32
+ return key;
33
+ const claims = await decryptPaseto(token, key.key);
34
+ if (claims instanceof Error)
35
+ return claims;
36
+ // a token of the form this component leaves behind is answered with a re-issue
37
+ return this.answer(claims, key, true);
38
+ }
39
+ const jwe = parse(token);
40
+ if (jwe instanceof Error)
41
+ return jwe;
42
+ const key = await this.key(jwe.kid, false);
31
43
  if (key instanceof Error)
32
44
  return key;
33
- const claims = legacy
34
- ? await decryptPaseto(token, key.key)
35
- : await decryptJWE(token, key.key);
45
+ const claims = open(jwe, key.key);
36
46
  if (claims instanceof Error)
37
47
  return claims;
38
- this.logs.debug('Token claims', claims);
39
- if (key.identity !== undefined && claims.identity.id !== key.identity)
40
- return ERR_FORGED_KEY;
41
- if (key.revokedAt !== undefined)
42
- return ERR_REVOKED_KEY;
43
- return {
44
- iss: claims.iss,
45
- iat: claims.iat,
46
- exp: claims.exp,
47
- identity: claims.identity,
48
- ...(claims.aud === undefined ? {} : { aud: claims.aud }),
49
- refresh: legacy || (kid !== this.latest && key.identity === undefined),
50
- custom: key.identity !== undefined
51
- };
48
+ return this.answer(claims, key, jwe.kid !== this.latest && key.identity === undefined);
52
49
  }
53
50
  pasetoKid(token) {
54
51
  const [, , , footer] = token.split('.');
@@ -65,20 +62,22 @@ export class Computation {
65
62
  return ERR_INVALID_TOKEN;
66
63
  }
67
64
  }
68
- async jweKid(token) {
69
- try {
70
- const { decodeProtectedHeader } = await load();
71
- const header = decodeProtectedHeader(token);
72
- if (header.alg !== 'dir' ||
73
- header.enc !== 'A256GCM' ||
74
- header.typ !== 'JWT' ||
75
- typeof header.kid !== 'string')
76
- return ERR_INVALID_TOKEN;
77
- return header.kid;
78
- }
79
- catch {
80
- return ERR_INVALID_TOKEN;
81
- }
65
+ /** What both forms answer once their claims are open. */
66
+ answer(claims, key, refresh) {
67
+ this.logs.debug('Token claims', claims);
68
+ if (key.identity !== undefined && claims.identity.id !== key.identity)
69
+ return ERR_FORGED_KEY;
70
+ if (key.revokedAt !== undefined)
71
+ return ERR_REVOKED_KEY;
72
+ return {
73
+ iss: claims.iss,
74
+ iat: claims.iat,
75
+ exp: claims.exp,
76
+ identity: claims.identity,
77
+ ...(claims.aud === undefined ? {} : { aud: claims.aud }),
78
+ refresh,
79
+ custom: key.identity !== undefined
80
+ };
82
81
  }
83
82
  async key(kid, legacy) {
84
83
  const configured = legacy ? this.legacy : this.keys;
@@ -103,34 +102,81 @@ async function decryptPaseto(token, key) {
103
102
  return ERR_INVALID_TOKEN;
104
103
  }
105
104
  }
106
- async function decryptJWE(token, key) {
105
+ /**
106
+ * The five parts of a compact JWE (RFC 7516), of the one form this component issues: `dir`, so
107
+ * the encrypted key is empty, `A256GCM`, and a `kid` naming the key. A header that asks for
108
+ * anything else — another algorithm, a critical extension, compression — is refused, as jose
109
+ * refuses it.
110
+ */
111
+ function parse(token) {
112
+ const parts = token.split('.');
113
+ if (parts.length !== PARTS || parts[1] !== '')
114
+ return ERR_INVALID_TOKEN;
115
+ const [header, , iv, ciphertext, tag] = parts;
116
+ let declared;
107
117
  try {
108
- const { jwtDecrypt } = await load();
109
- const { payload } = await jwtDecrypt(token, jweKey(key), {
110
- keyManagementAlgorithms: ['dir'],
111
- contentEncryptionAlgorithms: ['A256GCM']
112
- });
113
- if (typeof payload.iss !== 'string' ||
114
- typeof payload.iat !== 'number' ||
115
- typeof payload.identity !== 'object' ||
116
- payload.identity === null)
117
- return ERR_INVALID_TOKEN;
118
- if (payload.exp !== undefined && payload.exp * 1000 <= Date.now())
119
- return ERR_INVALID_TOKEN;
120
- return {
121
- iss: payload.iss,
122
- iat: new Date(payload.iat * 1000).toISOString(),
123
- ...(payload.exp === undefined
124
- ? {}
125
- : { exp: new Date(payload.exp * 1000).toISOString() }),
126
- identity: payload.identity,
127
- ...(payload.aud === undefined ? {} : { aud: payload.aud })
128
- };
118
+ declared = JSON.parse(Buffer.from(header, 'base64url').toString('utf-8'));
119
+ }
120
+ catch {
121
+ return ERR_INVALID_TOKEN;
122
+ }
123
+ if (declared === null ||
124
+ typeof declared !== 'object' ||
125
+ declared.alg !== 'dir' ||
126
+ declared.enc !== 'A256GCM' ||
127
+ declared.typ !== 'JWT' ||
128
+ typeof declared.kid !== 'string' ||
129
+ declared.crit !== undefined ||
130
+ declared.zip !== undefined)
131
+ return ERR_INVALID_TOKEN;
132
+ return {
133
+ kid: declared.kid,
134
+ // the header as it was written, which is what it was encrypted against
135
+ aad: Buffer.from(header, 'ascii'),
136
+ iv: Buffer.from(iv, 'base64url'),
137
+ ciphertext: Buffer.from(ciphertext, 'base64url'),
138
+ tag: Buffer.from(tag, 'base64url')
139
+ };
140
+ }
141
+ /** The claims a token carries, where its tag holds and its times admit it. */
142
+ function open(jwe, key) {
143
+ if (jwe.iv.length !== IV || jwe.tag.length !== TAG)
144
+ return ERR_INVALID_TOKEN;
145
+ let payload;
146
+ try {
147
+ const decipher = createDecipheriv('aes-256-gcm', jweKey(key), jwe.iv);
148
+ decipher.setAAD(jwe.aad);
149
+ decipher.setAuthTag(jwe.tag);
150
+ payload = JSON.parse(Buffer.concat([decipher.update(jwe.ciphertext), decipher.final()]).toString('utf-8'));
129
151
  }
130
152
  catch {
131
153
  return ERR_INVALID_TOKEN;
132
154
  }
155
+ if (payload === null ||
156
+ typeof payload !== 'object' ||
157
+ typeof payload.iss !== 'string' ||
158
+ typeof payload.iat !== 'number' ||
159
+ typeof payload.identity !== 'object' ||
160
+ payload.identity === null)
161
+ return ERR_INVALID_TOKEN;
162
+ const now = Date.now();
163
+ if (payload.exp !== undefined && payload.exp * 1000 <= now)
164
+ return ERR_INVALID_TOKEN;
165
+ if (payload.nbf !== undefined && payload.nbf * 1000 > now)
166
+ return ERR_INVALID_TOKEN;
167
+ return {
168
+ iss: payload.iss,
169
+ iat: new Date(payload.iat * 1000).toISOString(),
170
+ ...(payload.exp === undefined
171
+ ? {}
172
+ : { exp: new Date(payload.exp * 1000).toISOString() }),
173
+ identity: payload.identity,
174
+ ...(payload.aud === undefined ? {} : { aud: payload.aud })
175
+ };
133
176
  }
177
+ const PARTS = 5;
178
+ const IV = 12;
179
+ const TAG = 16;
134
180
  const importKey = ImportKeyFactory().run;
135
181
  const decryptLocal = DecryptFactory().run;
136
182
  const ERR_INVALID_TOKEN = new (class InvalidTokenError extends Error {
@@ -145,4 +191,4 @@ const ERR_FORGED_KEY = new (class ForgedKeyError extends Error {
145
191
  const ERR_REVOKED_KEY = new (class RevokedKeyError extends Error {
146
192
  code = 'REVOKED_KEY';
147
193
  })();
148
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVjcnlwdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NvdXJjZS9kZWNyeXB0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUNsRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQ3BDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFDN0MsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUtwQyxNQUFNLE9BQU8sV0FBVztJQUNMLElBQUksR0FBd0IsRUFBRSxDQUFBO0lBQzlCLE1BQU0sR0FBd0IsRUFBRSxDQUFBO0lBQ3pDLEtBQUssQ0FBNkI7SUFDbEMsTUFBTSxDQUFTO0lBQ2YsTUFBTSxDQUF3QztJQUM5QyxJQUFJLENBQWtCO0lBRXZCLEtBQUssQ0FBQyxPQUFnQjtRQUMzQixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsQ0FBQyxNQUFNLEtBQUssUUFBUSxDQUFDLENBQUE7UUFFbkYsSUFBSSxNQUFNLEtBQUssU0FBUztZQUN0QixNQUFNLElBQUksU0FBUyxDQUFDLHlDQUF5QyxDQUFDLENBQUE7UUFFaEUsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFBO1FBQ3ZCLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFBO1FBQzFDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxRQUFRLENBQW1CLE9BQU8sQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDeEUsSUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFBO1FBRXhCLEtBQUssTUFBTSxF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
194
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVjcnlwdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NvdXJjZS9kZWNyeXB0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFDbEUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUNwQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBSzdDLE1BQU0sT0FBTyxXQUFXO0lBQ0wsSUFBSSxHQUF3QixFQUFFLENBQUE7SUFDOUIsTUFBTSxHQUF3QixFQUFFLENBQUE7SUFDekMsS0FBSyxDQUE2QjtJQUNsQyxNQUFNLENBQVM7SUFDZixNQUFNLENBQXdDO0lBQzlDLElBQUksQ0FBa0I7SUFFdkIsS0FBSyxDQUFDLE9BQWdCO1FBQzNCLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxDQUFDLE1BQU0sS0FBSyxRQUFRLENBQUMsQ0FBQTtRQUVuRixJQUFJLE1BQU0sS0FBSyxTQUFTO1lBQ3RCLE1BQU0sSUFBSSxTQUFTLENBQUMseUNBQXlDLENBQUMsQ0FBQTtRQUVoRSxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUE7UUFDdkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUE7UUFDMUMsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLFFBQVEsQ0FBbUIsT0FBTyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUN4RSxJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUE7UUFFeEIsS0FBSyxNQUFN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
@@ -1,2 +1,5 @@
1
- export const load = async () => await import('jose');
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiam9zZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NvdXJjZS9saWIvam9zZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQUMsTUFBTSxJQUFJLEdBQUcsS0FBSyxJQUFJLEVBQUUsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQSJ9
1
+ /** @type {Promise<typeof import('jose')> | undefined} */
2
+ let loading;
3
+ // resolved once: an import per call resolves the module again on every token
4
+ export const load = () => (loading ??= import('jose'));
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiam9zZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NvdXJjZS9saWIvam9zZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx5REFBeUQ7QUFDekQsSUFBSSxPQUFPLENBQUE7QUFFWCw2RUFBNkU7QUFDN0UsTUFBTSxDQUFDLE1BQU0sSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsT0FBTyxLQUFLLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFBIn0=
@@ -1,7 +1,7 @@
1
+ import { createDecipheriv } from 'node:crypto'
1
2
  import { DecryptFactory, ImportKeyFactory } from 'paseto/v3/local'
2
3
  import { LRUCache } from 'lru-cache'
3
4
  import { form, jweKey } from './lib/index.ts'
4
- import { load } from './lib/jose.js'
5
5
  import type { Maybe } from '@toa.io/core/types'
6
6
  import type { Operation } from '@toa.io/bridges.node'
7
7
  import type { Context, Claims, DecryptOutput, JWEClaims } from './lib/index.ts'
@@ -33,37 +33,40 @@ export class Computation implements Operation {
33
33
  }
34
34
 
35
35
  public async execute(token: string): Promise<Maybe<DecryptOutput>> {
36
- const legacy = form(token) === 'paseto'
37
- const kid = legacy ? this.pasetoKid(token) : await this.jweKid(token)
36
+ if (form(token) === 'paseto') {
37
+ const kid = this.pasetoKid(token)
38
38
 
39
- if (kid instanceof Error) return kid
39
+ if (kid instanceof Error) return kid
40
40
 
41
- const key = await this.key(kid, legacy)
41
+ const key = await this.key(kid, true)
42
42
 
43
- if (key instanceof Error) return key
43
+ if (key instanceof Error) return key
44
44
 
45
- const claims = legacy
46
- ? await decryptPaseto(token, key.key)
47
- : await decryptJWE(token, key.key)
45
+ const claims = await decryptPaseto(token, key.key)
48
46
 
49
- if (claims instanceof Error) return claims
47
+ if (claims instanceof Error) return claims
50
48
 
51
- this.logs.debug('Token claims', claims)
49
+ // a token of the form this component leaves behind is answered with a re-issue
50
+ return this.answer(claims, key, true)
51
+ }
52
52
 
53
- if (key.identity !== undefined && claims.identity.id !== key.identity)
54
- return ERR_FORGED_KEY
53
+ const jwe = parse(token)
55
54
 
56
- if (key.revokedAt !== undefined) return ERR_REVOKED_KEY
55
+ if (jwe instanceof Error) return jwe
57
56
 
58
- return {
59
- iss: claims.iss,
60
- iat: claims.iat,
61
- exp: claims.exp,
62
- identity: claims.identity,
63
- ...(claims.aud === undefined ? {} : { aud: claims.aud }),
64
- refresh: legacy || (kid !== this.latest && key.identity === undefined),
65
- custom: key.identity !== undefined
66
- }
57
+ const key = await this.key(jwe.kid, false)
58
+
59
+ if (key instanceof Error) return key
60
+
61
+ const claims = open(jwe, key.key)
62
+
63
+ if (claims instanceof Error) return claims
64
+
65
+ return this.answer(
66
+ claims,
67
+ key,
68
+ jwe.kid !== this.latest && key.identity === undefined
69
+ )
67
70
  }
68
71
 
69
72
  private pasetoKid(token: string): Maybe<string> {
@@ -83,22 +86,23 @@ export class Computation implements Operation {
83
86
  }
84
87
  }
85
88
 
86
- private async jweKid(token: string): Promise<Maybe<string>> {
87
- try {
88
- const { decodeProtectedHeader } = await load()
89
- const header = decodeProtectedHeader(token)
90
-
91
- if (
92
- header.alg !== 'dir' ||
93
- header.enc !== 'A256GCM' ||
94
- header.typ !== 'JWT' ||
95
- typeof header.kid !== 'string'
96
- )
97
- return ERR_INVALID_TOKEN
98
-
99
- return header.kid
100
- } catch {
101
- return ERR_INVALID_TOKEN
89
+ /** What both forms answer once their claims are open. */
90
+ private answer(claims: Claims, key: Key, refresh: boolean): Maybe<DecryptOutput> {
91
+ this.logs.debug('Token claims', claims)
92
+
93
+ if (key.identity !== undefined && claims.identity.id !== key.identity)
94
+ return ERR_FORGED_KEY
95
+
96
+ if (key.revokedAt !== undefined) return ERR_REVOKED_KEY
97
+
98
+ return {
99
+ iss: claims.iss,
100
+ iat: claims.iat,
101
+ exp: claims.exp,
102
+ identity: claims.identity,
103
+ ...(claims.aud === undefined ? {} : { aud: claims.aud }),
104
+ refresh,
105
+ custom: key.identity !== undefined
102
106
  }
103
107
  }
104
108
 
@@ -131,40 +135,107 @@ async function decryptPaseto(token: string, key: string): Promise<Maybe<Claims>>
131
135
  }
132
136
  }
133
137
 
134
- async function decryptJWE(token: string, key: string): Promise<Maybe<Claims>> {
138
+ /**
139
+ * The five parts of a compact JWE (RFC 7516), of the one form this component issues: `dir`, so
140
+ * the encrypted key is empty, `A256GCM`, and a `kid` naming the key. A header that asks for
141
+ * anything else — another algorithm, a critical extension, compression — is refused, as jose
142
+ * refuses it.
143
+ */
144
+ function parse(token: string): Maybe<JWE> {
145
+ const parts = token.split('.')
146
+
147
+ if (parts.length !== PARTS || parts[1] !== '') return ERR_INVALID_TOKEN
148
+
149
+ const [header, , iv, ciphertext, tag] = parts
150
+
151
+ let declared: Record<string, unknown>
152
+
135
153
  try {
136
- const { jwtDecrypt } = await load()
137
-
138
- const { payload } = await jwtDecrypt<JWEClaims>(token, jweKey(key), {
139
- keyManagementAlgorithms: ['dir'],
140
- contentEncryptionAlgorithms: ['A256GCM']
141
- })
142
-
143
- if (
144
- typeof payload.iss !== 'string' ||
145
- typeof payload.iat !== 'number' ||
146
- typeof payload.identity !== 'object' ||
147
- payload.identity === null
148
- )
149
- return ERR_INVALID_TOKEN
154
+ declared = JSON.parse(Buffer.from(header, 'base64url').toString('utf-8'))
155
+ } catch {
156
+ return ERR_INVALID_TOKEN
157
+ }
150
158
 
151
- if (payload.exp !== undefined && payload.exp * 1000 <= Date.now())
152
- return ERR_INVALID_TOKEN
159
+ if (
160
+ declared === null ||
161
+ typeof declared !== 'object' ||
162
+ declared.alg !== 'dir' ||
163
+ declared.enc !== 'A256GCM' ||
164
+ declared.typ !== 'JWT' ||
165
+ typeof declared.kid !== 'string' ||
166
+ declared.crit !== undefined ||
167
+ declared.zip !== undefined
168
+ )
169
+ return ERR_INVALID_TOKEN
153
170
 
154
- return {
155
- iss: payload.iss,
156
- iat: new Date(payload.iat * 1000).toISOString(),
157
- ...(payload.exp === undefined
158
- ? {}
159
- : { exp: new Date(payload.exp * 1000).toISOString() }),
160
- identity: payload.identity,
161
- ...(payload.aud === undefined ? {} : { aud: payload.aud })
162
- }
171
+ return {
172
+ kid: declared.kid,
173
+ // the header as it was written, which is what it was encrypted against
174
+ aad: Buffer.from(header, 'ascii'),
175
+ iv: Buffer.from(iv, 'base64url'),
176
+ ciphertext: Buffer.from(ciphertext, 'base64url'),
177
+ tag: Buffer.from(tag, 'base64url')
178
+ }
179
+ }
180
+
181
+ /** The claims a token carries, where its tag holds and its times admit it. */
182
+ function open(jwe: JWE, key: string): Maybe<Claims> {
183
+ if (jwe.iv.length !== IV || jwe.tag.length !== TAG) return ERR_INVALID_TOKEN
184
+
185
+ let payload: JWEClaims
186
+
187
+ try {
188
+ const decipher = createDecipheriv('aes-256-gcm', jweKey(key), jwe.iv)
189
+
190
+ decipher.setAAD(jwe.aad)
191
+ decipher.setAuthTag(jwe.tag)
192
+
193
+ payload = JSON.parse(
194
+ Buffer.concat([decipher.update(jwe.ciphertext), decipher.final()]).toString('utf-8')
195
+ )
163
196
  } catch {
164
197
  return ERR_INVALID_TOKEN
165
198
  }
199
+
200
+ if (
201
+ payload === null ||
202
+ typeof payload !== 'object' ||
203
+ typeof payload.iss !== 'string' ||
204
+ typeof payload.iat !== 'number' ||
205
+ typeof payload.identity !== 'object' ||
206
+ payload.identity === null
207
+ )
208
+ return ERR_INVALID_TOKEN
209
+
210
+ const now = Date.now()
211
+
212
+ if (payload.exp !== undefined && payload.exp * 1000 <= now) return ERR_INVALID_TOKEN
213
+
214
+ if (payload.nbf !== undefined && payload.nbf * 1000 > now) return ERR_INVALID_TOKEN
215
+
216
+ return {
217
+ iss: payload.iss,
218
+ iat: new Date(payload.iat * 1000).toISOString(),
219
+ ...(payload.exp === undefined
220
+ ? {}
221
+ : { exp: new Date(payload.exp * 1000).toISOString() }),
222
+ identity: payload.identity,
223
+ ...(payload.aud === undefined ? {} : { aud: payload.aud })
224
+ }
225
+ }
226
+
227
+ interface JWE {
228
+ kid: string
229
+ aad: Buffer
230
+ iv: Buffer
231
+ ciphertext: Buffer
232
+ tag: Buffer
166
233
  }
167
234
 
235
+ const PARTS = 5
236
+ const IV = 12
237
+ const TAG = 16
238
+
168
239
  const importKey = ImportKeyFactory().run
169
240
  const decryptLocal = DecryptFactory().run
170
241
 
@@ -1 +1,5 @@
1
- export const load = async () => await import('jose')
1
+ /** @type {Promise<typeof import('jose')> | undefined} */
2
+ let loading
3
+
4
+ // resolved once: an import per call resolves the module again on every token
5
+ export const load = () => (loading ??= import('jose'))
@@ -38,6 +38,7 @@ export interface Claims {
38
38
  export interface JWEClaims extends Omit<Claims, 'iat' | 'exp'> {
39
39
  iat: number
40
40
  exp?: number
41
+ nbf?: number
41
42
  }
42
43
 
43
44
  /** What this component is given: its own operations, and the two it reads keys and roles from. */
@@ -4,7 +4,7 @@
4
4
  import type { Options, Query, RemoteError } from '@toa.io/core/types'
5
5
  import type { Secret } from '@toa.io/extensions.configuration'
6
6
  import type { FetchInit } from '@toa.io/extensions.fetch'
7
- import type { Logs, Span } from '@toa.io/extensions.telemetry'
7
+ import type { Logs, Metrics, Span } from '@toa.io/extensions.telemetry'
8
8
  import type { Readable } from 'node:stream'
9
9
 
10
10
  export interface Entity {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toa.io/extensions.exposition",
3
- "version": "1.0.0-alpha.302",
3
+ "version": "1.0.0-alpha.304",
4
4
  "type": "module",
5
5
  "description": "Toa Exposition",
6
6
  "author": "temich <tema.gurtovoy@gmail.com>",
@@ -28,16 +28,16 @@
28
28
  "!**/.env*"
29
29
  ],
30
30
  "dependencies": {
31
- "@toa.io/core": "1.0.0-alpha.302",
32
- "@toa.io/definitions": "1.0.0-alpha.302",
33
- "@toa.io/generic": "1.0.0-alpha.301",
34
- "@toa.io/schemas": "1.0.0-alpha.301",
31
+ "@toa.io/core": "1.0.0-alpha.304",
32
+ "@toa.io/definitions": "1.0.0-alpha.304",
33
+ "@toa.io/generic": "1.0.0-alpha.304",
34
+ "@toa.io/schemas": "1.0.0-alpha.304",
35
35
  "content-type": "3.0.0",
36
36
  "matchacho": "0.6.1",
37
37
  "minimatch": "10.2.6",
38
38
  "msgpackr": "2.1.0",
39
39
  "negotiator": "1.1.0",
40
- "openspan": "1.0.0-alpha.301"
40
+ "openspan": "1.0.0-alpha.304"
41
41
  },
42
42
  "scripts": {
43
43
  "test": "echo \"Error: run tests from root\" && exit 1",
@@ -72,5 +72,5 @@
72
72
  "lru-cache": "11.5.2",
73
73
  "paseto": "4.0.1"
74
74
  },
75
- "gitHead": "3cbbca55a61711db78f98b13e50cf4d1afaf5c08"
75
+ "gitHead": "a95a5a5a64922b11b23142d4acbcee1331ed31aa"
76
76
  }