@request-seal/core 0.1.0 → 0.2.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.
- package/CHANGELOG.md +15 -0
- package/README.md +341 -114
- package/dist/accept-signature.d.ts +11 -0
- package/dist/accept-signature.js +7 -0
- package/dist/adapters/fetch/index.d.ts +10 -0
- package/dist/adapters/fetch/index.js +21 -4
- package/dist/adapters/fetch/runtime.d.ts +1 -0
- package/dist/adapters/fetch/runtime.js +1 -0
- package/dist/adapters/node-http/index.d.ts +16 -0
- package/dist/adapters/node-http/index.js +8 -4
- package/dist/brand.d.ts +5 -0
- package/dist/brand.js +12 -0
- package/dist/bytes.d.ts +4 -0
- package/dist/bytes.js +5 -0
- package/dist/constants.d.ts +61 -1
- package/dist/constants.js +61 -1
- package/dist/context.d.ts +4 -0
- package/dist/context.js +3 -0
- package/dist/crypto/algorithm.d.ts +5 -0
- package/dist/crypto/index.d.ts +12 -2
- package/dist/crypto/index.js +34 -11
- package/dist/crypto/options.d.ts +3 -0
- package/dist/crypto/options.js +15 -0
- package/dist/crypto/primitive.d.ts +7 -3
- package/dist/crypto/primitive.js +36 -10
- package/dist/custody/content_key.d.ts +4 -0
- package/dist/custody/content_key.js +4 -2
- package/dist/custody/index.d.ts +2 -0
- package/dist/custody/index.js +5 -1
- package/dist/custody/local.d.ts +17 -1
- package/dist/custody/local.js +10 -5
- package/dist/custody/ssh-agent/index.d.ts +2 -0
- package/dist/custody/ssh-agent/index.js +11 -181
- package/dist/custody/ssh-agent/port.d.ts +19 -0
- package/dist/custody/ssh-agent/port.js +183 -0
- package/dist/digest.d.ts +22 -0
- package/dist/digest.js +15 -0
- package/dist/discovery/body.d.ts +7 -0
- package/dist/discovery/body.js +3 -0
- package/dist/discovery/cache.d.ts +9 -0
- package/dist/discovery/cache.js +2 -0
- package/dist/discovery/headers.d.ts +1 -0
- package/dist/discovery/index.d.ts +5 -0
- package/dist/discovery/index.js +10 -2
- package/dist/discovery/node-connection.d.ts +1 -1
- package/dist/discovery/node-connection.js +2 -2
- package/dist/discovery/node-trust.d.ts +2 -0
- package/dist/discovery/node-trust.js +9 -0
- package/dist/discovery/node.d.ts +4 -0
- package/dist/discovery/node.js +29 -11
- package/dist/discovery/source.d.ts +7 -0
- package/dist/discovery/source.js +5 -0
- package/dist/discovery/support.js +2 -3
- package/dist/errors/parity.d.ts +16 -1
- package/dist/errors/parity.js +14 -2
- package/dist/errors/types.d.ts +13 -1
- package/dist/errors/types.js +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/jose/header.d.ts +1 -0
- package/dist/jose/jwe.d.ts +9 -0
- package/dist/jose/jwe.js +17 -3
- package/dist/jose/jws.d.ts +11 -0
- package/dist/jose/jws.js +14 -2
- package/dist/jose/key-management.d.ts +11 -0
- package/dist/jose/key-management.js +13 -2
- package/dist/jose/nested.d.ts +6 -0
- package/dist/jose/nested.js +9 -1
- package/dist/json.d.ts +7 -0
- package/dist/key_handle.d.ts +12 -3
- package/dist/key_handle.js +32 -25
- package/dist/key_identity.d.ts +7 -0
- package/dist/key_identity.js +10 -2
- package/dist/message/index.d.ts +24 -0
- package/dist/message/index.js +20 -0
- package/dist/numbers.d.ts +6 -0
- package/dist/numbers.js +5 -0
- package/dist/policy.d.ts +15 -0
- package/dist/policy.js +30 -21
- package/dist/profile.d.ts +36 -0
- package/dist/profile.js +215 -0
- package/dist/public_key.d.ts +11 -2
- package/dist/public_key.js +31 -8
- package/dist/quorum/verification.d.ts +2 -0
- package/dist/quorum/verification.js +1 -0
- package/dist/quorum.d.ts +9 -0
- package/dist/quorum.js +7 -1
- package/dist/replay/claim.d.ts +5 -0
- package/dist/replay/claim.js +9 -1
- package/dist/replay/index.d.ts +6 -0
- package/dist/replay/index.js +13 -1
- package/dist/replay/postgres.d.ts +1 -0
- package/dist/replay/postgres.js +1 -0
- package/dist/replay/receipt.d.ts +1 -0
- package/dist/replay/receipt.js +1 -0
- package/dist/replay/store.d.ts +1 -0
- package/dist/replay/store.js +1 -0
- package/dist/replay-port.d.ts +6 -1
- package/dist/result.d.ts +3 -0
- package/dist/result.js +2 -0
- package/dist/sign.d.ts +5 -0
- package/dist/sign.js +1 -0
- package/dist/signature-base/index.d.ts +2 -0
- package/dist/signature-base/index.js +5 -1
- package/dist/structured-fields/index.d.ts +21 -0
- package/dist/structured-fields/index.js +14 -1
- package/dist/verification.d.ts +5 -1
- package/dist/verification.js +9 -6
- package/dist/verify-quorum.d.ts +1 -0
- package/dist/verify-quorum.js +1 -0
- package/dist/verify.d.ts +5 -0
- package/dist/verify.js +16 -11
- package/dist/web-bot-auth/index.d.ts +3 -0
- package/dist/web-bot-auth/index.js +3 -0
- package/dist/web-bot-auth/policy.d.ts +8 -0
- package/dist/web-bot-auth/policy.js +8 -4
- package/dist/web-bot-auth/verification.d.ts +8 -0
- package/dist/web-bot-auth/verification.js +4 -2
- package/package.json +17 -6
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { type Result } from "../result.ts";
|
|
2
2
|
import { fromSnapshot } from "./snapshot.ts";
|
|
3
3
|
import { type Resolution } from "./body.ts";
|
|
4
|
+
/** A discovery-backed signature key resolver. @inline */
|
|
4
5
|
export type KeyResolver = (request: unknown) => Promise<Result<Readonly<{
|
|
5
6
|
algorithm: Resolution["algorithm"];
|
|
6
7
|
key: Resolution["key"];
|
|
7
8
|
}>>>;
|
|
9
|
+
/** Create a resolver over a branded key set or caller-owned discovery cache. */
|
|
8
10
|
declare function resolver(input: unknown, opts: unknown): Result<KeyResolver>;
|
|
11
|
+
/** Snapshot resolution and explicit discovery operations. */
|
|
9
12
|
export declare const Discovery: Readonly<{
|
|
13
|
+
/** Create a resolver over a branded key set or caller-owned discovery cache. */
|
|
10
14
|
resolver: typeof resolver & {
|
|
15
|
+
/** Parse a caller-supplied discovery snapshot without fetching it. */
|
|
11
16
|
fromSnapshot: typeof fromSnapshot;
|
|
12
17
|
};
|
|
13
18
|
}>;
|
package/dist/discovery/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { isDiscoverySource } from "./source.js";
|
|
|
5
5
|
import { isDiscoveryCache } from "./cache.js";
|
|
6
6
|
import { fromSnapshot } from "./snapshot.js";
|
|
7
7
|
import { ensure, unwrap, failure } from "./support.js";
|
|
8
|
+
/** Create a resolver over a branded key set or caller-owned discovery cache. */
|
|
8
9
|
function resolver(input, opts) {
|
|
9
10
|
try {
|
|
10
11
|
const a = unwrap(snapshotOptions(opts, ["algorithms"]), "invalid_options");
|
|
@@ -44,8 +45,15 @@ function resolver(input, opts) {
|
|
|
44
45
|
return failure(e, "invalid_options");
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
|
-
const Resolver = Object.freeze(Object.assign(resolver, {
|
|
48
|
-
|
|
48
|
+
const Resolver = Object.freeze(Object.assign(resolver, {
|
|
49
|
+
/** Parse a caller-supplied discovery snapshot without fetching it. */
|
|
50
|
+
fromSnapshot
|
|
51
|
+
}));
|
|
52
|
+
/** Snapshot resolution and explicit discovery operations. */
|
|
53
|
+
export const Discovery = Object.freeze({
|
|
54
|
+
/** Create a resolver over a branded key set or caller-owned discovery cache. */
|
|
55
|
+
resolver: Resolver
|
|
56
|
+
});
|
|
49
57
|
export { DiscoverySource, isDiscoverySource, directoryId } from "./source.js";
|
|
50
58
|
export { isKeySet, isResolution, } from "./body.js";
|
|
51
59
|
export { createCache, isDiscoveryCache, } from "./cache.js";
|
|
@@ -3,5 +3,5 @@ export declare function checkPeer(observed: {
|
|
|
3
3
|
address: string | undefined;
|
|
4
4
|
port: number | undefined;
|
|
5
5
|
}, address: string, port: number, permittedAddresses: readonly string[]): void;
|
|
6
|
-
/**
|
|
6
|
+
/** Peer and trust-store denials terminate the address loop unchanged. */
|
|
7
7
|
export declare function allowConnectionRetry(error: unknown): void;
|
|
@@ -5,8 +5,8 @@ export function checkPeer(observed, address, port, permittedAddresses) {
|
|
|
5
5
|
ensure(sameAddress(observed.address, address) && observed.port === port &&
|
|
6
6
|
unwrap(addressAllowed(observed.address, permittedAddresses), "address_denied"), "address_denied");
|
|
7
7
|
}
|
|
8
|
-
/**
|
|
8
|
+
/** Peer and trust-store denials terminate the address loop unchanged. */
|
|
9
9
|
export function allowConnectionRetry(error) {
|
|
10
|
-
if (error && typeof error === "object" && "reason" in error && error.reason === "address_denied")
|
|
10
|
+
if (error && typeof error === "object" && "reason" in error && (error.reason === "address_denied" || error.reason === "transport_unavailable"))
|
|
11
11
|
throw error;
|
|
12
12
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { discoveryError } from '../errors/types.js';
|
|
2
|
+
/** Classify OS trust permission failures without changing other errors. */
|
|
3
|
+
export function systemCertificateError(error) {
|
|
4
|
+
const deno = globalThis.Deno;
|
|
5
|
+
const PermissionError = deno?.errors?.NotCapable;
|
|
6
|
+
if (PermissionError && error instanceof PermissionError)
|
|
7
|
+
throw discoveryError('transport_unavailable');
|
|
8
|
+
throw error;
|
|
9
|
+
}
|
package/dist/discovery/node.d.ts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { type Result } from "../result.ts";
|
|
2
2
|
import { type KeySet } from "./body.ts";
|
|
3
3
|
export type DiscoverySource = import("./source.ts").DiscoverySource;
|
|
4
|
+
/** Fetch a discovery key set with bounded HTTPS, address, and redirect policies. */
|
|
4
5
|
export declare function fetch(source: unknown, input?: unknown): Promise<Result<KeySet>>;
|
|
6
|
+
/** Discovery resolution with the explicit Node HTTPS transport. */
|
|
5
7
|
export declare const Discovery: Readonly<{
|
|
6
8
|
resolver: ((input: unknown, opts: unknown) => Result<import("./index.ts").KeyResolver>) & {
|
|
7
9
|
fromSnapshot: typeof import("./snapshot.ts").fromSnapshot;
|
|
8
10
|
};
|
|
11
|
+
/** Fetch a discovery key set through the bounded Node HTTPS transport. */
|
|
9
12
|
fetch: typeof fetch;
|
|
10
13
|
}>;
|
|
11
14
|
/** Node source creation fails closed when the OS trust store is unavailable or empty. */
|
|
12
15
|
export declare const DiscoverySource: Readonly<{
|
|
13
16
|
directoryId: typeof import("./source.ts").directoryId;
|
|
17
|
+
/** Create a discovery source after validating Node transport options. */
|
|
14
18
|
create(input: unknown): Result<import("./source.ts").DiscoverySource>;
|
|
15
19
|
}>;
|
package/dist/discovery/node.js
CHANGED
|
@@ -15,6 +15,7 @@ import { fields, header, expiry, mediaType } from "./headers.js";
|
|
|
15
15
|
import { bodyDocument } from "./body.js";
|
|
16
16
|
import { fromResource } from "./snapshot.js";
|
|
17
17
|
import { decodeBody } from "./gzip.js";
|
|
18
|
+
import { systemCertificateError } from "./node-trust.js";
|
|
18
19
|
import { checkPeer, allowConnectionRetry } from "./node-connection.js";
|
|
19
20
|
const lookup = dns.lookup.bind(dns);
|
|
20
21
|
function remaining(context) {
|
|
@@ -58,16 +59,23 @@ async function resolve(host, context, servers) {
|
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
remaining(context);
|
|
61
|
-
ensure(answers.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
ensure(answers.every((a) => isIP(a.address) === a.family), "resolution_failed");
|
|
63
|
+
// Match the reference resolver: IPv6 first, retaining order within each family,
|
|
64
|
+
// then remove duplicates before applying the address bound.
|
|
65
|
+
const addresses = [...new Set(answers.sort((a, b) => b.family - a.family).map((a) => a.address))];
|
|
66
|
+
ensure(addresses.length >= 1 && addresses.length <= 64, "resolution_failed");
|
|
67
|
+
return addresses;
|
|
65
68
|
}
|
|
66
69
|
function systemCertificates() {
|
|
67
70
|
if (typeof tls.getCACertificates !== "function")
|
|
68
71
|
return undefined;
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
try {
|
|
73
|
+
const certificates = tls.getCACertificates("system");
|
|
74
|
+
return certificates.length > 0 ? certificates : undefined;
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
systemCertificateError(error);
|
|
78
|
+
}
|
|
71
79
|
}
|
|
72
80
|
function tlsSocket(ip, url, source, context) {
|
|
73
81
|
remaining(context);
|
|
@@ -367,6 +375,7 @@ async function resource(url, source, context, servers, hops = 0) {
|
|
|
367
375
|
remaining(context);
|
|
368
376
|
return { fields: fs, encoded, decoded, location: url.href };
|
|
369
377
|
}
|
|
378
|
+
/** Fetch a discovery key set with bounded HTTPS, address, and redirect policies. */
|
|
370
379
|
export async function fetch(source, input = {}) {
|
|
371
380
|
try {
|
|
372
381
|
ensure(isDiscoverySource(source), "invalid_source");
|
|
@@ -446,14 +455,23 @@ export async function fetch(source, input = {}) {
|
|
|
446
455
|
return failure(error, "invalid_options");
|
|
447
456
|
}
|
|
448
457
|
}
|
|
449
|
-
|
|
458
|
+
/** Discovery resolution with the explicit Node HTTPS transport. */
|
|
459
|
+
export const Discovery = Object.freeze({ ...CoreDiscovery,
|
|
460
|
+
/** Fetch a discovery key set through the bounded Node HTTPS transport. */
|
|
461
|
+
fetch });
|
|
450
462
|
/** Node source creation fails closed when the OS trust store is unavailable or empty. */
|
|
451
463
|
export const DiscoverySource = Object.freeze({
|
|
452
464
|
...CoreSource,
|
|
465
|
+
/** Create a discovery source after validating Node transport options. */
|
|
453
466
|
create(input) {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
467
|
+
try {
|
|
468
|
+
const result = CoreSource.create(input);
|
|
469
|
+
if (result.ok && result.value.cacerts === "os" && !systemCertificates())
|
|
470
|
+
return err(custodyError("unsupported_format"));
|
|
471
|
+
return result;
|
|
472
|
+
}
|
|
473
|
+
catch (error) {
|
|
474
|
+
return failure(error, "invalid_source");
|
|
475
|
+
}
|
|
458
476
|
},
|
|
459
477
|
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type Result } from "../result.ts";
|
|
2
|
+
/** Supported discovery source kinds. @inline */
|
|
2
3
|
export type SourceType = "directory" | "jwks_uri" | "cimd";
|
|
4
|
+
/** A branded HTTPS discovery source with bounded transport and cache policies. */
|
|
3
5
|
export type DiscoverySource = Readonly<{
|
|
4
6
|
type: SourceType;
|
|
5
7
|
location: string;
|
|
@@ -18,9 +20,11 @@ export type DiscoverySource = Readonly<{
|
|
|
18
20
|
maxTtl: number;
|
|
19
21
|
negativeTtl: number;
|
|
20
22
|
}>;
|
|
23
|
+
/** Check the private brand of a discovery source. */
|
|
21
24
|
export declare function isDiscoverySource(s: unknown): s is DiscoverySource;
|
|
22
25
|
export declare function sourceIdentity(s: DiscoverySource): string;
|
|
23
26
|
export declare function thumbprintId(value: unknown): value is string;
|
|
27
|
+
/** Check whether a string is a valid directory key identifier. */
|
|
24
28
|
export declare function directoryId(value: unknown): Result<boolean>;
|
|
25
29
|
export declare function keyIdValid(s: DiscoverySource, v: unknown): v is string;
|
|
26
30
|
/** Validate raw spelling before WHATWG normalization can erase a dot segment. */
|
|
@@ -29,7 +33,10 @@ export declare function normalizedHost(url: URL): string;
|
|
|
29
33
|
export declare function sourceOrigin(url: URL): string;
|
|
30
34
|
export declare function sourceAuthority(url: URL): string;
|
|
31
35
|
export declare function createSource(input: unknown): Result<DiscoverySource>;
|
|
36
|
+
/** Discovery source construction and directory identifier validation. */
|
|
32
37
|
export declare const DiscoverySource: Readonly<{
|
|
38
|
+
/** Snapshot, validate, and brand an HTTPS discovery source. */
|
|
33
39
|
create: typeof createSource;
|
|
40
|
+
/** Check the directory key identifier syntax. */
|
|
34
41
|
directoryId: typeof directoryId;
|
|
35
42
|
}>;
|
package/dist/discovery/source.js
CHANGED
|
@@ -15,6 +15,7 @@ const limits = Object.freeze({
|
|
|
15
15
|
maxTtl: 86400,
|
|
16
16
|
negativeTtl: 30,
|
|
17
17
|
});
|
|
18
|
+
/** Check the private brand of a discovery source. */
|
|
18
19
|
export function isDiscoverySource(s) {
|
|
19
20
|
return !!s && typeof s === "object" && sources.has(s);
|
|
20
21
|
}
|
|
@@ -33,6 +34,7 @@ function validDirectoryId(v) {
|
|
|
33
34
|
v.length <= 256 &&
|
|
34
35
|
/^[\x20-\x7e]+$/.test(v));
|
|
35
36
|
}
|
|
37
|
+
/** Check whether a string is a valid directory key identifier. */
|
|
36
38
|
export function directoryId(value) {
|
|
37
39
|
return ok(validDirectoryId(value));
|
|
38
40
|
}
|
|
@@ -193,7 +195,10 @@ export function createSource(input) {
|
|
|
193
195
|
return failure(e, "invalid_source");
|
|
194
196
|
}
|
|
195
197
|
}
|
|
198
|
+
/** Discovery source construction and directory identifier validation. */
|
|
196
199
|
export const DiscoverySource = Object.freeze({
|
|
200
|
+
/** Snapshot, validate, and brand an HTTPS discovery source. */
|
|
197
201
|
create: createSource,
|
|
202
|
+
/** Check the directory key identifier syntax. */
|
|
198
203
|
directoryId,
|
|
199
204
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { snapshotOptions, deepFreeze } from "../brand.js";
|
|
1
|
+
import { snapshotOptions, deepFreeze, inspection } from "../brand.js";
|
|
2
2
|
import { discoveryError, isRequestSealError } from "../errors/types.js";
|
|
3
3
|
import { err } from "../result.js";
|
|
4
4
|
export function ensure(value, reason) {
|
|
@@ -49,8 +49,7 @@ export function inspectable(value, facts) {
|
|
|
49
49
|
const inspect = () => Object.freeze({ ...facts });
|
|
50
50
|
Object.defineProperties(value, {
|
|
51
51
|
toJSON: { value: inspect },
|
|
52
|
-
|
|
53
|
-
[Symbol.for("Deno.customInspect")]: { value: inspect },
|
|
52
|
+
...inspection(inspect),
|
|
54
53
|
});
|
|
55
54
|
return Object.freeze(value);
|
|
56
55
|
}
|
package/dist/errors/parity.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
/** The immutable reference release used for the error vocabulary. */
|
|
2
|
+
export declare const ELIXIR_ERROR_PIN = "0a6568aa246326617f760e94e21b359285c6ddfc";
|
|
2
3
|
declare const retryableRules: {
|
|
3
4
|
readonly core: {
|
|
4
5
|
readonly actor_unbound: {
|
|
@@ -511,6 +512,10 @@ declare const retryableRules: {
|
|
|
511
512
|
readonly kind: "constant";
|
|
512
513
|
readonly value: false;
|
|
513
514
|
};
|
|
515
|
+
readonly invalid_options: {
|
|
516
|
+
readonly kind: "constant";
|
|
517
|
+
readonly value: false;
|
|
518
|
+
};
|
|
514
519
|
readonly invalid_signature: {
|
|
515
520
|
readonly kind: "constant";
|
|
516
521
|
readonly value: false;
|
|
@@ -903,6 +908,7 @@ declare const retryableRules: {
|
|
|
903
908
|
};
|
|
904
909
|
};
|
|
905
910
|
export declare const ERROR_RETRYABLE: typeof retryableRules;
|
|
911
|
+
/** The pinned reason, layer, and retryability table. */
|
|
906
912
|
export declare const ERROR_PARITY: readonly Readonly<{
|
|
907
913
|
readonly kind: "core";
|
|
908
914
|
readonly layer: "binding";
|
|
@@ -1480,6 +1486,10 @@ export declare const ERROR_PARITY: readonly Readonly<{
|
|
|
1480
1486
|
readonly kind: "crypto";
|
|
1481
1487
|
readonly reason: "invalid_key";
|
|
1482
1488
|
readonly rule_id: "crypto/invalid_key";
|
|
1489
|
+
} | {
|
|
1490
|
+
readonly kind: "crypto";
|
|
1491
|
+
readonly reason: "invalid_options";
|
|
1492
|
+
readonly rule_id: "crypto/invalid_options";
|
|
1483
1493
|
} | {
|
|
1484
1494
|
readonly kind: "crypto";
|
|
1485
1495
|
readonly reason: "invalid_signature";
|
|
@@ -1882,13 +1892,18 @@ export declare const ERROR_PARITY: readonly Readonly<{
|
|
|
1882
1892
|
readonly reason: "untrusted_proxy";
|
|
1883
1893
|
readonly rule_id: "adapter/untrusted_proxy";
|
|
1884
1894
|
}>[];
|
|
1895
|
+
/** A pinned error reason and its layers and retryability metadata. */
|
|
1885
1896
|
export type ParityEntry = typeof ERROR_PARITY[number];
|
|
1897
|
+
/** An error family present in the pinned parity table. */
|
|
1886
1898
|
export type ErrorKind = ParityEntry["kind"];
|
|
1899
|
+
/** The allowed reason vocabulary for an error family. */
|
|
1887
1900
|
export type Reason<K extends ErrorKind> = Extract<ParityEntry, {
|
|
1888
1901
|
kind: K;
|
|
1889
1902
|
}>["reason"];
|
|
1903
|
+
/** The allowed layer vocabulary for an error family. */
|
|
1890
1904
|
export type Layer<K extends "core" | "jose"> = Extract<ParityEntry, {
|
|
1891
1905
|
kind: K;
|
|
1892
1906
|
}>["layer"];
|
|
1907
|
+
/** The complete set of rule IDs derived from the parity table. */
|
|
1893
1908
|
export declare const RULE_IDS: ReadonlySet<string>;
|
|
1894
1909
|
export {};
|
package/dist/errors/parity.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
// Derived from pinned Elixir constructors and call sites; regenerate with scripts/render-parity.ts --update-table.
|
|
2
|
-
|
|
1
|
+
// Derived from pinned Elixir constructors and call sites; regenerate with scripts/generate-parity.ts or scripts/render-parity.ts --update-table.
|
|
2
|
+
/** The immutable reference release used for the error vocabulary. */
|
|
3
|
+
export const ELIXIR_ERROR_PIN = '0a6568aa246326617f760e94e21b359285c6ddfc';
|
|
3
4
|
const entries = [
|
|
4
5
|
{
|
|
5
6
|
"kind": "core",
|
|
@@ -705,6 +706,11 @@ const entries = [
|
|
|
705
706
|
"reason": "invalid_key",
|
|
706
707
|
"rule_id": "crypto/invalid_key"
|
|
707
708
|
},
|
|
709
|
+
{
|
|
710
|
+
"kind": "crypto",
|
|
711
|
+
"reason": "invalid_options",
|
|
712
|
+
"rule_id": "crypto/invalid_options"
|
|
713
|
+
},
|
|
708
714
|
{
|
|
709
715
|
"kind": "crypto",
|
|
710
716
|
"reason": "invalid_signature",
|
|
@@ -1713,6 +1719,10 @@ const retryableRules = {
|
|
|
1713
1719
|
"kind": "constant",
|
|
1714
1720
|
"value": false
|
|
1715
1721
|
},
|
|
1722
|
+
"invalid_options": {
|
|
1723
|
+
"kind": "constant",
|
|
1724
|
+
"value": false
|
|
1725
|
+
},
|
|
1716
1726
|
"invalid_signature": {
|
|
1717
1727
|
"kind": "constant",
|
|
1718
1728
|
"value": false
|
|
@@ -2105,9 +2115,11 @@ const retryableRules = {
|
|
|
2105
2115
|
}
|
|
2106
2116
|
};
|
|
2107
2117
|
export const ERROR_RETRYABLE = Object.freeze(Object.fromEntries(Object.entries(retryableRules).map(([kind, rules]) => [kind, Object.freeze(Object.fromEntries(Object.entries(rules).map(([reason, rule]) => [reason, Object.freeze(rule)])))])));
|
|
2118
|
+
/** The pinned reason, layer, and retryability table. */
|
|
2108
2119
|
export const ERROR_PARITY = Object.freeze(entries.map(entry => Object.freeze(entry)));
|
|
2109
2120
|
const rules = new Set(ERROR_PARITY.map(e => e.rule_id));
|
|
2110
2121
|
// A frozen Set still exposes mutation methods; the facade keeps the backing Set private.
|
|
2122
|
+
/** The complete set of rule IDs derived from the parity table. */
|
|
2111
2123
|
export const RULE_IDS = Object.freeze({
|
|
2112
2124
|
get size() { return rules.size; },
|
|
2113
2125
|
has: (value) => rules.has(value),
|
package/dist/errors/types.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type Reason, type Layer } from './parity.ts';
|
|
2
|
+
/** The bounded detail vocabulary for core failures. */
|
|
2
3
|
export type CoreDetail = Reason<'core'> | Reason<'signature_base'> | 'legacy_string' | 'invalid_dictionary' | 'duplicate_member' | 'invalid_member' | 'missing_member' | 'unsupported_type' | 'not_an_origin' | 'untrusted_agent' | 'source_mismatch' | 'revoked_key' | 'source_unavailable' | 'timeout';
|
|
4
|
+
/** A core failure with layer, correlation, and optional bounded source. */
|
|
3
5
|
export type CoreError = Readonly<{
|
|
4
6
|
kind: 'core';
|
|
5
7
|
reason: Reason<'core'>;
|
|
@@ -10,21 +12,26 @@ export type CoreError = Readonly<{
|
|
|
10
12
|
message: string | null;
|
|
11
13
|
source: CustodyError | null;
|
|
12
14
|
}>;
|
|
15
|
+
/** Error families carrying only a reason. @inline */
|
|
13
16
|
type SimpleKind = 'message' | 'structured_fields' | 'signature_base' | 'digest' | 'crypto';
|
|
17
|
+
/** A reason-only error for message, field, digest, or crypto operations. */
|
|
14
18
|
export type SimpleError<K extends SimpleKind> = Readonly<{
|
|
15
19
|
kind: K;
|
|
16
20
|
reason: Reason<K>;
|
|
17
21
|
}>;
|
|
22
|
+
/** A custody failure with an explicit retryability flag. */
|
|
18
23
|
export type CustodyError = Readonly<{
|
|
19
24
|
kind: 'custody';
|
|
20
25
|
reason: Reason<'custody'>;
|
|
21
26
|
retryable: boolean;
|
|
22
27
|
}>;
|
|
28
|
+
/** A discovery failure with an explicit retryability flag. */
|
|
23
29
|
export type DiscoveryError = Readonly<{
|
|
24
30
|
kind: 'discovery';
|
|
25
31
|
reason: Reason<'discovery'>;
|
|
26
32
|
retryable: boolean;
|
|
27
33
|
}>;
|
|
34
|
+
/** A JOSE failure with layer and explicit retryability. */
|
|
28
35
|
export type JoseError = Readonly<{
|
|
29
36
|
kind: 'jose';
|
|
30
37
|
reason: Reason<'jose'>;
|
|
@@ -32,11 +39,13 @@ export type JoseError = Readonly<{
|
|
|
32
39
|
correlation: null;
|
|
33
40
|
retryable: boolean;
|
|
34
41
|
}>;
|
|
42
|
+
/** A nonretryable replay-store failure. */
|
|
35
43
|
export type ReplayError = Readonly<{
|
|
36
44
|
kind: 'replay';
|
|
37
45
|
reason: Reason<'replay'>;
|
|
38
46
|
retryable: false;
|
|
39
47
|
}>;
|
|
48
|
+
/** A bounded adapter failure with stage, attempt, and optional source. */
|
|
40
49
|
export type AdapterError = Readonly<{
|
|
41
50
|
kind: 'adapter';
|
|
42
51
|
reason: Reason<'adapter'>;
|
|
@@ -47,9 +56,11 @@ export type AdapterError = Readonly<{
|
|
|
47
56
|
correlation: string;
|
|
48
57
|
retryable: false;
|
|
49
58
|
}>;
|
|
59
|
+
/** The union of all branded, bounded public error families. */
|
|
50
60
|
export type RequestSealError = CoreError | {
|
|
51
61
|
[K in SimpleKind]: SimpleError<K>;
|
|
52
62
|
}[SimpleKind] | CustodyError | DiscoveryError | JoseError | ReplayError | AdapterError;
|
|
63
|
+
/** Check whether an error belongs to the private error brand. */
|
|
53
64
|
export declare function isRequestSealError(value: unknown): value is RequestSealError;
|
|
54
65
|
export declare function coreError(reason: Reason<'core'>, layer: Layer<'core'>, detail?: CoreDetail | null, source?: CustodyError | null): CoreError;
|
|
55
66
|
export declare const messageError: (reason: Reason<'message'>) => Readonly<{
|
|
@@ -70,12 +81,13 @@ export declare const digestError: (reason: Reason<'digest'>) => Readonly<{
|
|
|
70
81
|
}>;
|
|
71
82
|
export declare const cryptoError: (reason: Reason<'crypto'>) => Readonly<{
|
|
72
83
|
kind: "crypto";
|
|
73
|
-
reason: "invalid_data" | "invalid_key" | "invalid_signature" | "key_mismatch" | "unsupported_algorithm" | "unsupported_format";
|
|
84
|
+
reason: "invalid_data" | "invalid_key" | "invalid_options" | "invalid_signature" | "key_mismatch" | "unsupported_algorithm" | "unsupported_format";
|
|
74
85
|
}>;
|
|
75
86
|
export declare function custodyError(reason: Reason<'custody'>): CustodyError;
|
|
76
87
|
export declare function discoveryError(reason: Reason<'discovery'>, status?: number): DiscoveryError;
|
|
77
88
|
export declare function joseError(reason: Reason<'jose'>, layer: Layer<'jose'>): JoseError;
|
|
78
89
|
export declare function replayError(reason: Reason<'replay'>): ReplayError;
|
|
79
90
|
export declare function adapterError(reason: Reason<'adapter'>, adapter: AdapterError['adapter'], stage: AdapterError['stage'], attempt: number, source?: AdapterError['source']): AdapterError;
|
|
91
|
+
/** Format an error's family, layer when present, and reason as a rule ID. */
|
|
80
92
|
export declare function ruleId(error: RequestSealError): string;
|
|
81
93
|
export {};
|
package/dist/errors/types.js
CHANGED
|
@@ -4,6 +4,7 @@ const addError = errors.add.bind(errors), hasError = errors.has.bind(errors);
|
|
|
4
4
|
const random = globalThis.crypto.getRandomValues.bind(globalThis.crypto);
|
|
5
5
|
function correlation() { return Array.from(random(new Uint8Array(8)), b => b.toString(16).padStart(2, '0')).join(''); }
|
|
6
6
|
function freeze(error) { addError(error); return Object.freeze(error); }
|
|
7
|
+
/** Check whether an error belongs to the private error brand. */
|
|
7
8
|
export function isRequestSealError(value) { return typeof value === 'object' && value !== null && hasError(value); }
|
|
8
9
|
function reasonFor(kind, reason) {
|
|
9
10
|
if (!ERROR_PARITY.some(e => e.kind === kind && e.reason === reason))
|
|
@@ -58,4 +59,5 @@ export function adapterError(reason, adapter, stage, attempt, source = null) {
|
|
|
58
59
|
throw new TypeError('Invalid adapter source');
|
|
59
60
|
return freeze({ kind: 'adapter', reason, adapter, stage, attempt, source, correlation: correlation(), retryable: false });
|
|
60
61
|
}
|
|
62
|
+
/** Format an error's family, layer when present, and reason as a rule ID. */
|
|
61
63
|
export function ruleId(error) { return 'layer' in error ? `${error.kind}/${error.layer}.${error.reason}` : `${error.kind}/${error.reason}`; }
|
package/dist/index.d.ts
CHANGED
|
@@ -45,3 +45,4 @@ export { verifyQuorum } from './verify-quorum.ts';
|
|
|
45
45
|
export { isQuorumVerification } from './quorum/verification.ts';
|
|
46
46
|
export type { QuorumVerification } from './quorum/verification.ts';
|
|
47
47
|
export * from './web-bot-auth/index.ts';
|
|
48
|
+
export { Profile, type ProfileStamp, type ProfileMetadataValue, type SignatureDictionaries } from './profile.ts';
|
package/dist/index.js
CHANGED
|
@@ -33,3 +33,4 @@ export { AcceptSignature, parseAcceptSignature, serializeAcceptSignature, fulfil
|
|
|
33
33
|
export { verifyQuorum } from './verify-quorum.js';
|
|
34
34
|
export { isQuorumVerification } from './quorum/verification.js';
|
|
35
35
|
export * from './web-bot-auth/index.js';
|
|
36
|
+
export { Profile } from './profile.js';
|
package/dist/jose/header.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type JsonNode } from "../json.ts";
|
|
2
2
|
import { type JoseError } from "../errors/types.ts";
|
|
3
3
|
import { type Result } from "../result.ts";
|
|
4
|
+
/** An ordered JOSE protected-header sequence of JSON members. */
|
|
4
5
|
export type Header = readonly (readonly [string, JsonNode])[];
|
|
5
6
|
export declare function fail(reason: JoseError["reason"], layer?: JoseError["layer"]): never;
|
|
6
7
|
export declare function need(value: unknown, reason: JoseError["reason"], layer?: JoseError["layer"]): asserts value;
|
package/dist/jose/jwe.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Result } from "../result.ts";
|
|
2
2
|
import { type Header } from "./header.ts";
|
|
3
|
+
/** Check the private brand of an authenticated JWE result. */
|
|
3
4
|
export declare function isJweResult(value: unknown): value is JweResult;
|
|
5
|
+
/** A branded authenticated JWE result that confines plaintext bytes. */
|
|
4
6
|
export declare class JweResult {
|
|
5
7
|
#private;
|
|
6
8
|
readonly algorithm: string;
|
|
@@ -13,12 +15,19 @@ export declare class JweResult {
|
|
|
13
15
|
readonly authorization = "not_evaluated";
|
|
14
16
|
constructor(t: object, algorithm: string, encryption: string, header: Header, protectedPart: string, plaintext: Uint8Array);
|
|
15
17
|
get plaintext(): Uint8Array<ArrayBuffer>;
|
|
18
|
+
/** Return a bounded public inspection view without retained cryptographic bytes. */
|
|
16
19
|
toJSON(): unknown;
|
|
17
20
|
}
|
|
21
|
+
/** Encrypt content into compact JWE using explicit key-management and content algorithms. */
|
|
18
22
|
export declare function encrypt(protectedPairs: unknown, plaintext: unknown, recipient: unknown, options?: unknown): Promise<Result<string>>;
|
|
23
|
+
/** Authenticate and decrypt compact JWE under an explicit policy. */
|
|
19
24
|
export declare function decrypt(input: unknown, inputPolicy: unknown, options?: unknown): Promise<Result<JweResult>>;
|
|
25
|
+
/** Compact JWE encryption and authenticated decryption operations. */
|
|
20
26
|
export declare const JWE: Readonly<{
|
|
27
|
+
/** Encrypt content into compact JWE using explicit key-management and content algorithms. */
|
|
21
28
|
encrypt: typeof encrypt;
|
|
29
|
+
/** Authenticate and decrypt compact JWE under an explicit policy. */
|
|
22
30
|
decrypt: typeof decrypt;
|
|
31
|
+
/** Check the private brand of the operation result. */
|
|
23
32
|
isResult: typeof isJweResult;
|
|
24
33
|
}>;
|
package/dist/jose/jwe.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { denoInspection } from "../brand.js";
|
|
1
2
|
import { encodeJson } from "../json.js";
|
|
2
3
|
import { encodeUtf8 } from "../runtime.js";
|
|
3
4
|
import { encodeBase64Url, decodeBase64Url } from "../bytes.js";
|
|
@@ -11,9 +12,11 @@ import { bytes, serialize, parse, compact, headerValue, need, } from "./header.j
|
|
|
11
12
|
import { JWE_ALGORITHMS, ENCRYPTION, context, policy, resolve, selected, bounded, publicSafe, alive, take, ok, err, } from "./support.js";
|
|
12
13
|
import { random, wrapPublic } from "./key-management.js";
|
|
13
14
|
const branded = new WeakSet(), token = Object.freeze({});
|
|
15
|
+
/** Check the private brand of an authenticated JWE result. */
|
|
14
16
|
export function isJweResult(value) {
|
|
15
17
|
return typeof value === "object" && value !== null && branded.has(value);
|
|
16
18
|
}
|
|
19
|
+
/** A branded authenticated JWE result that confines plaintext bytes. */
|
|
17
20
|
export class JweResult {
|
|
18
21
|
algorithm;
|
|
19
22
|
encryption;
|
|
@@ -38,6 +41,7 @@ export class JweResult {
|
|
|
38
41
|
get plaintext() {
|
|
39
42
|
return new Uint8Array(this.#plaintext);
|
|
40
43
|
}
|
|
44
|
+
/** Return a bounded public inspection view without retained cryptographic bytes. */
|
|
41
45
|
toJSON() {
|
|
42
46
|
return Object.freeze({
|
|
43
47
|
algorithm: this.algorithm,
|
|
@@ -51,8 +55,8 @@ export class JweResult {
|
|
|
51
55
|
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
52
56
|
return this.toJSON();
|
|
53
57
|
}
|
|
54
|
-
[Symbol.for("Deno.customInspect")]() {
|
|
55
|
-
return this.toJSON();
|
|
58
|
+
[Symbol.for("Deno.customInspect")](render) {
|
|
59
|
+
return denoInspection(render, this.toJSON());
|
|
56
60
|
}
|
|
57
61
|
}
|
|
58
62
|
Object.freeze(JweResult.prototype);
|
|
@@ -71,6 +75,7 @@ function encryptedKey(alg, ek, h) {
|
|
|
71
75
|
else
|
|
72
76
|
need(ek.length >= 256 && ek.length <= 1024, "decryption_failed", "crypto");
|
|
73
77
|
}
|
|
78
|
+
/** Encrypt content into compact JWE using explicit key-management and content algorithms. */
|
|
74
79
|
export async function encrypt(protectedPairs, plaintext, recipient, options = {}) {
|
|
75
80
|
return publicSafe(async () => {
|
|
76
81
|
const c = context(options, 5000, true), data = bytes(plaintext), initial = take(serialize(protectedPairs)), alg = selected(initial.header, JWE_ALGORITHMS, ENCRYPTION), enc = headerValue(initial.header, "enc");
|
|
@@ -152,6 +157,7 @@ export async function encrypt(protectedPairs, plaintext, recipient, options = {}
|
|
|
152
157
|
}, "signer_failed");
|
|
153
158
|
});
|
|
154
159
|
}
|
|
160
|
+
/** Authenticate and decrypt compact JWE under an explicit policy. */
|
|
155
161
|
export async function decrypt(input, inputPolicy, options = {}) {
|
|
156
162
|
return publicSafe(async () => {
|
|
157
163
|
const p = policy(inputPolicy, "jwe"), c = context(options, p.timeout);
|
|
@@ -252,4 +258,12 @@ export async function decrypt(input, inputPolicy, options = {}) {
|
|
|
252
258
|
}, "decryption_failed");
|
|
253
259
|
});
|
|
254
260
|
}
|
|
255
|
-
|
|
261
|
+
/** Compact JWE encryption and authenticated decryption operations. */
|
|
262
|
+
export const JWE = Object.freeze({
|
|
263
|
+
/** Encrypt content into compact JWE using explicit key-management and content algorithms. */
|
|
264
|
+
encrypt,
|
|
265
|
+
/** Authenticate and decrypt compact JWE under an explicit policy. */
|
|
266
|
+
decrypt,
|
|
267
|
+
/** Check the private brand of the operation result. */
|
|
268
|
+
isResult: isJweResult
|
|
269
|
+
});
|
package/dist/jose/jws.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Result } from "../result.ts";
|
|
2
2
|
import { type Header } from "./header.ts";
|
|
3
|
+
/** Check the private brand of a verified JWS result. */
|
|
3
4
|
export declare function isJwsResult(value: unknown): value is JwsResult;
|
|
5
|
+
/** A branded verified JWS result that confines payload bytes. */
|
|
4
6
|
export declare class JwsResult {
|
|
5
7
|
#private;
|
|
6
8
|
readonly algorithm: string;
|
|
@@ -11,14 +13,23 @@ export declare class JwsResult {
|
|
|
11
13
|
readonly authorization = "not_evaluated";
|
|
12
14
|
constructor(t: object, algorithm: string, header: Header, protectedPart: string, payload: Uint8Array);
|
|
13
15
|
get payload(): Uint8Array<ArrayBuffer>;
|
|
16
|
+
/** Return a bounded public inspection view without retained cryptographic bytes. */
|
|
14
17
|
toJSON(): unknown;
|
|
15
18
|
}
|
|
19
|
+
/** Sign a compact JWS with an explicit algorithm and caller-owned signer. */
|
|
16
20
|
export declare function sign(protectedPairs: unknown, payload: unknown, handle: unknown, options?: unknown): Promise<Result<string>>;
|
|
21
|
+
/** Sign a compact JWS while preserving the supplied protected-header bytes. */
|
|
17
22
|
export declare function signProtected(protectedBytes: unknown, payload: unknown, handle: unknown, options?: unknown): Promise<Result<string>>;
|
|
23
|
+
/** Verify a compact JWS under an explicit algorithm and key policy. */
|
|
18
24
|
export declare function verify(input: unknown, inputPolicy: unknown, options?: unknown): Promise<Result<JwsResult>>;
|
|
25
|
+
/** Compact JWS signing and verification operations. */
|
|
19
26
|
export declare const JWS: Readonly<{
|
|
27
|
+
/** Sign a compact JWS with an explicit algorithm and caller-owned signer. */
|
|
20
28
|
sign: typeof sign;
|
|
29
|
+
/** Sign a compact JWS while preserving the supplied protected-header bytes. */
|
|
21
30
|
signProtected: typeof signProtected;
|
|
31
|
+
/** Verify a compact JWS under an explicit algorithm and key policy. */
|
|
22
32
|
verify: typeof verify;
|
|
33
|
+
/** Check the private brand of the operation result. */
|
|
23
34
|
isResult: typeof isJwsResult;
|
|
24
35
|
}>;
|