@axorum/client 0.0.0-stage → 1.0.0

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 (79) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +530 -2
  3. package/dist/agent-uri.d.ts +30 -0
  4. package/dist/agent-uri.d.ts.map +1 -0
  5. package/dist/agent-uri.js +218 -0
  6. package/dist/agent-uri.js.map +1 -0
  7. package/dist/authorize.d.ts +671 -0
  8. package/dist/authorize.d.ts.map +1 -0
  9. package/dist/authorize.js +947 -0
  10. package/dist/authorize.js.map +1 -0
  11. package/dist/capabilities.d.ts +30 -0
  12. package/dist/capabilities.d.ts.map +1 -0
  13. package/dist/capabilities.js +40 -0
  14. package/dist/capabilities.js.map +1 -0
  15. package/dist/chart.d.ts +74 -0
  16. package/dist/chart.d.ts.map +1 -0
  17. package/dist/chart.js +107 -0
  18. package/dist/chart.js.map +1 -0
  19. package/dist/client.d.ts +644 -0
  20. package/dist/client.d.ts.map +1 -0
  21. package/dist/client.js +1302 -0
  22. package/dist/client.js.map +1 -0
  23. package/dist/errors.d.ts +646 -0
  24. package/dist/errors.d.ts.map +1 -0
  25. package/dist/errors.js +928 -0
  26. package/dist/errors.js.map +1 -0
  27. package/dist/failover.d.ts +197 -0
  28. package/dist/failover.d.ts.map +1 -0
  29. package/dist/failover.js +289 -0
  30. package/dist/failover.js.map +1 -0
  31. package/dist/freshness.d.ts +65 -0
  32. package/dist/freshness.d.ts.map +1 -0
  33. package/dist/freshness.js +148 -0
  34. package/dist/freshness.js.map +1 -0
  35. package/dist/generated/agent-plane.d.ts +1863 -0
  36. package/dist/generated/agent-plane.d.ts.map +1 -0
  37. package/dist/generated/agent-plane.js +19 -0
  38. package/dist/generated/agent-plane.js.map +1 -0
  39. package/dist/idempotency.d.ts +160 -0
  40. package/dist/idempotency.d.ts.map +1 -0
  41. package/dist/idempotency.js +208 -0
  42. package/dist/idempotency.js.map +1 -0
  43. package/dist/index.d.ts +89 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +87 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/intent.d.ts +163 -0
  48. package/dist/intent.d.ts.map +1 -0
  49. package/dist/intent.js +82 -0
  50. package/dist/intent.js.map +1 -0
  51. package/dist/json.d.ts +49 -0
  52. package/dist/json.d.ts.map +1 -0
  53. package/dist/json.js +259 -0
  54. package/dist/json.js.map +1 -0
  55. package/dist/key.d.ts +64 -0
  56. package/dist/key.d.ts.map +1 -0
  57. package/dist/key.js +71 -0
  58. package/dist/key.js.map +1 -0
  59. package/dist/payment.d.ts +172 -0
  60. package/dist/payment.d.ts.map +1 -0
  61. package/dist/payment.js +178 -0
  62. package/dist/payment.js.map +1 -0
  63. package/dist/refusal.d.ts +121 -0
  64. package/dist/refusal.d.ts.map +1 -0
  65. package/dist/refusal.js +176 -0
  66. package/dist/refusal.js.map +1 -0
  67. package/dist/retry.d.ts +215 -0
  68. package/dist/retry.d.ts.map +1 -0
  69. package/dist/retry.js +297 -0
  70. package/dist/retry.js.map +1 -0
  71. package/dist/typeid.d.ts +64 -0
  72. package/dist/typeid.d.ts.map +1 -0
  73. package/dist/typeid.js +119 -0
  74. package/dist/typeid.js.map +1 -0
  75. package/dist/types.d.ts +245 -0
  76. package/dist/types.d.ts.map +1 -0
  77. package/dist/types.js +14 -0
  78. package/dist/types.js.map +1 -0
  79. package/package.json +58 -3
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Whether an attestation will still be valid for as long as a submission may take.
3
+ *
4
+ * The service checks one thing about time: `now < exp`, with no leeway. A token that
5
+ * expires while a submission is being re-sent is refused on the late attempt, possibly
6
+ * after an earlier one committed. So `authorize` bounds each submission, every send and
7
+ * every wait between sends, by a deadline {@link ATTESTATION_CLOCK_ALLOWANCE_MS} before
8
+ * the token's `exp` ({@link submissionDeadline}); a wait that would reach it ends the
9
+ * re-sends. The call's own budget ({@link AUTHORIZE_DEADLINE_MS}) bounds the submission
10
+ * too: it ends at whichever of the two comes first. Before it sends, it checks that at
11
+ * least {@link ATTESTATION_MIN_REMAINING_MS} is left, and asks for a fresh token when less
12
+ * is.
13
+ *
14
+ * The payload is read, never verified: the signature is the service's to check.
15
+ *
16
+ * @packageDocumentation
17
+ */
18
+ import { AUTHORIZE_DEADLINE_MS } from "./retry.js";
19
+ /**
20
+ * How long before a token's `exp` a submission stops sending: room for the clocks of
21
+ * the issuer, this process and the service to disagree, since the service allows none.
22
+ */
23
+ export const ATTESTATION_CLOCK_ALLOWANCE_MS = 30_000;
24
+ /**
25
+ * How long a token must still be valid when a submission starts (45 s): the whole
26
+ * {@link AUTHORIZE_DEADLINE_MS} plus the {@link ATTESTATION_CLOCK_ALLOWANCE_MS}. The
27
+ * submission's deadline is the earlier of the call's and the token's `exp` less the
28
+ * allowance ({@link submissionDeadline}), so a token that passes this check never cuts a
29
+ * submission shorter than the call's own budget does.
30
+ */
31
+ export const ATTESTATION_MIN_REMAINING_MS = AUTHORIZE_DEADLINE_MS + ATTESTATION_CLOCK_ALLOWANCE_MS;
32
+ /**
33
+ * The deadline of a submission whose attestation expires at `expMs` (epoch
34
+ * milliseconds): `expMs` less {@link ATTESTATION_CLOCK_ALLOWANCE_MS}, read against the
35
+ * wall clock once (`wallNowMs`) and returned on the monotonic clock `monoNowMs` is read
36
+ * from, so a wall-clock step does not move it. `undefined` when that point has passed,
37
+ * and nothing may be sent. Pure.
38
+ */
39
+ export function submissionDeadline(expMs, wallNowMs, monoNowMs) {
40
+ const left = expMs - ATTESTATION_CLOCK_ALLOWANCE_MS - wallNowMs;
41
+ return left > 0 ? monoNowMs + left : undefined;
42
+ }
43
+ /**
44
+ * Why a token without a readable `exp` is refused here rather than sent: the service
45
+ * refuses it too. Its `agent-uri-attestation` declares `AttestationClaims.exp` a required
46
+ * date-time, so such a token fails to decode in `verify_for_uri` and is answered `403
47
+ * attestation` before its expiry is ever checked.
48
+ */
49
+ const SERVICE_EXP_RULE = ", and the service refuses such a token: it reads exp as a required date-time " +
50
+ "(agent-uri-attestation's AttestationClaims.exp), so the token fails to decode before its " +
51
+ "expiry is ever checked. Its issuer must set one";
52
+ /**
53
+ * The token's `exp` in epoch milliseconds, or why its claims cannot be read. Pure; never
54
+ * verifies the signature.
55
+ */
56
+ export function attestationExpiryMs(token) {
57
+ const claims = readClaims(token);
58
+ if (typeof claims === "string") {
59
+ return claims;
60
+ }
61
+ const exp = claims["exp"];
62
+ if (typeof exp !== "string") {
63
+ return `the attestation's claims carry no exp date-time${SERVICE_EXP_RULE}`;
64
+ }
65
+ return parseRfc3339Ms(exp) ?? `the attestation's exp is not an RFC 3339 date-time (${exp})${SERVICE_EXP_RULE}`;
66
+ }
67
+ /** The length of an Ed25519 signature, which ends every v4.public payload. */
68
+ const SIGNATURE_BYTES = 64;
69
+ /**
70
+ * Whether `token` is valid for at least `minRemainingMs` after `nowMs`, compared in whole
71
+ * milliseconds (digits of `exp` below a millisecond truncate). Pure; the same rule as the
72
+ * Rust SDK, pinned by `spec/fixtures/attestation-freshness-v1.json`.
73
+ */
74
+ export function attestationFreshness(token, nowMs, minRemainingMs) {
75
+ const expMs = attestationExpiryMs(token);
76
+ if (typeof expMs === "string") {
77
+ return { state: "unreadable", problem: expMs };
78
+ }
79
+ const expiresAt = formatUtcMs(expMs);
80
+ return expMs - nowMs >= minRemainingMs ? { state: "fresh", expiresAt } : { state: "expiring", expiresAt };
81
+ }
82
+ /** The token's claims object, or why it cannot be read. Pure. */
83
+ function readClaims(token) {
84
+ const parts = token.split(".");
85
+ if (parts.length < 3 || parts.length > 4 || parts[0] !== "v4" || parts[1] !== "public") {
86
+ return "the attestation is not a PASETO v4.public token";
87
+ }
88
+ const payload = decodeBase64Url(parts[2]);
89
+ if (payload === undefined) {
90
+ return "the attestation's payload is not base64url";
91
+ }
92
+ if (payload.length <= SIGNATURE_BYTES) {
93
+ return "the attestation's payload is too short to carry claims and a signature";
94
+ }
95
+ let claims;
96
+ try {
97
+ claims = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(payload.subarray(0, payload.length - SIGNATURE_BYTES)));
98
+ }
99
+ catch {
100
+ return "the attestation's claims are not JSON";
101
+ }
102
+ if (typeof claims !== "object" || claims === null || Array.isArray(claims)) {
103
+ return "the attestation's claims are not a JSON object";
104
+ }
105
+ return claims;
106
+ }
107
+ /** Unpadded base64url, strictly: the alphabet only, no padding, canonical length. Pure. */
108
+ function decodeBase64Url(text) {
109
+ if (text.length === 0 || text.length % 4 === 1 || !/^[A-Za-z0-9_-]+$/.test(text)) {
110
+ return undefined;
111
+ }
112
+ const standard = text.replaceAll("-", "+").replaceAll("_", "/");
113
+ const binary = atob(standard + "=".repeat((4 - (standard.length % 4)) % 4));
114
+ return Uint8Array.from(binary, (char) => char.charCodeAt(0));
115
+ }
116
+ const RFC3339 = /^(\d{4})-(\d{2})-(\d{2})[Tt ](\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(?:([Zz])|([+-])(\d{2}):(\d{2}))$/;
117
+ /** Milliseconds since the epoch for an RFC 3339 date-time, or `undefined`. Pure. */
118
+ export function parseRfc3339Ms(text) {
119
+ const match = RFC3339.exec(text);
120
+ if (match === null) {
121
+ return undefined;
122
+ }
123
+ const [year, month, day, hour, minute, second] = match.slice(1, 7).map(Number);
124
+ const leap = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
125
+ const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month - 1];
126
+ if (days === undefined || day < 1 || day > days || hour > 23 || minute > 59 || second > 59) {
127
+ return undefined;
128
+ }
129
+ let offsetMinutes = 0;
130
+ if (match[9] !== undefined) {
131
+ const offsetHours = Number(match[10]);
132
+ const offsetMins = Number(match[11]);
133
+ if (offsetHours > 23 || offsetMins > 59) {
134
+ return undefined;
135
+ }
136
+ offsetMinutes = (match[9] === "-" ? -1 : 1) * (offsetHours * 60 + offsetMins);
137
+ }
138
+ const millis = Number((match[7] ?? "").padEnd(3, "0").slice(0, 3));
139
+ const date = new Date(0);
140
+ date.setUTCFullYear(year, month - 1, day);
141
+ date.setUTCHours(hour, minute, second, millis);
142
+ return date.getTime() - offsetMinutes * 60_000;
143
+ }
144
+ /** `YYYY-MM-DDTHH:MM:SS[.mmm]Z`, the milliseconds only when not zero. Pure. */
145
+ export function formatUtcMs(ms) {
146
+ return new Date(ms).toISOString().replace(".000Z", "Z");
147
+ }
148
+ //# sourceMappingURL=freshness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freshness.js","sourceRoot":"","sources":["../src/freshness.ts"],"names":[],"mappings":"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"}