@sequenceholdings/managed-functions 0.4.5 → 0.5.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.
- package/README.md +147 -12
- package/dist/abrigo-contract.d.ts +2 -92
- package/dist/abrigo-contract.js +12 -53
- package/dist/abrigo-response.d.ts +1 -6
- package/dist/abrigo-response.js +3 -25
- package/dist/abrigo.d.ts +5 -5
- package/dist/abrigo.js +66 -92
- package/dist/agent-evidence.d.ts +5 -5
- package/dist/agent-evidence.js +58 -48
- package/dist/agent-source-evidence-contract.d.ts +2 -1197
- package/dist/agent-source-evidence-contract.js +24 -94
- package/dist/agents-contract.d.ts +2 -99
- package/dist/agents-contract.js +13 -67
- package/dist/agents.d.ts +5 -5
- package/dist/agents.js +79 -44
- package/dist/capabilities.d.ts +1 -1
- package/dist/capabilities.js +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.js +4 -1
- package/dist/directory-config.d.ts +1 -23
- package/dist/directory-config.js +8 -20
- package/dist/directory-contract.d.ts +2 -68
- package/dist/directory-contract.js +13 -55
- package/dist/directory-roster-contract.d.ts +2 -22
- package/dist/directory-roster-contract.js +7 -22
- package/dist/directory.d.ts +4 -8
- package/dist/directory.js +15 -33
- package/dist/group-roster-access.d.ts +7 -0
- package/dist/group-roster-access.js +8 -0
- package/dist/index.d.ts +49 -46
- package/dist/index.js +8 -1
- package/dist/invocation-client.d.ts +4 -4
- package/dist/invocation-client.js +32 -60
- package/dist/invocation-contract.d.ts +2 -59
- package/dist/invocation-contract.js +10 -61
- package/dist/invocation.d.ts +4 -4
- package/dist/invocation.js +42 -63
- package/dist/lattice-provenance-contract.d.ts +2 -607
- package/dist/lattice-provenance-contract.js +14 -154
- package/dist/lattice-provenance.d.ts +3 -3
- package/dist/lattice-provenance.js +46 -97
- package/dist/monitoring-annotations.d.ts +2 -53
- package/dist/monitoring-annotations.js +2 -51
- package/dist/monitoring-contract.d.ts +5 -460
- package/dist/monitoring-contract.js +37 -77
- package/dist/monitoring-events.d.ts +2 -252
- package/dist/monitoring-events.js +15 -125
- package/dist/monitoring.d.ts +3 -3
- package/dist/monitoring.js +41 -41
- package/dist/orm.d.ts +10 -1
- package/dist/orm.js +27 -7
- package/dist/platform-client.d.ts +27 -0
- package/dist/platform-client.js +79 -0
- package/dist/platform-domains.d.ts +1671 -0
- package/dist/platform-domains.js +77 -0
- package/dist/processes-contract.d.ts +2 -149
- package/dist/processes-contract.js +17 -100
- package/dist/processes.d.ts +3 -3
- package/dist/processes.js +64 -49
- package/dist/runtime.cjs +4251 -1666
- package/dist/service-directory-roster.d.ts +12 -3
- package/dist/service-directory-roster.js +11 -17
- package/dist/service-directory.d.ts +4 -8
- package/dist/service-directory.js +16 -67
- package/dist/storage.d.ts +36 -35
- package/dist/storage.js +12 -5
- package/dist/workflow-source-contract.d.ts +2 -524
- package/dist/workflow-source-contract.js +16 -56
- package/dist/workflow-source.d.ts +3 -3
- package/dist/workflow-source.js +106 -43
- package/package.json +4 -3
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.readInvocationCredential = readInvocationCredential;
|
|
4
4
|
exports.createInvocationReadTransport = createInvocationReadTransport;
|
|
5
|
-
const
|
|
5
|
+
const adapters_1 = require("@sequenceholdings/platform/adapters");
|
|
6
6
|
function readInvocationCredential({ request, header, maxBytes, claimsSchema, invalidContext, }) {
|
|
7
7
|
const { headers } = request;
|
|
8
|
-
const matches = typeof headers.get ===
|
|
8
|
+
const matches = typeof headers.get === "function"
|
|
9
9
|
? [headers.get(header)]
|
|
10
10
|
: Object.entries(headers)
|
|
11
11
|
.filter(([name]) => name.toLowerCase() === header)
|
|
12
12
|
.map(([, value]) => value);
|
|
13
13
|
const token = matches[0];
|
|
14
14
|
if (matches.length !== 1 ||
|
|
15
|
-
typeof token !==
|
|
15
|
+
typeof token !== "string" ||
|
|
16
16
|
token.length > maxBytes)
|
|
17
17
|
throw invalidContext();
|
|
18
18
|
const envelope = /^([A-Za-z0-9_-]+)\.([A-Za-z0-9_-]{43})$/.exec(token);
|
|
@@ -20,7 +20,7 @@ function readInvocationCredential({ request, header, maxBytes, claimsSchema, inv
|
|
|
20
20
|
throw invalidContext();
|
|
21
21
|
let value;
|
|
22
22
|
try {
|
|
23
|
-
value = JSON.parse(Buffer.from(envelope[1],
|
|
23
|
+
value = JSON.parse(Buffer.from(envelope[1], "base64url").toString("utf8"));
|
|
24
24
|
}
|
|
25
25
|
catch {
|
|
26
26
|
throw invalidContext();
|
|
@@ -30,61 +30,33 @@ function readInvocationCredential({ request, header, maxBytes, claimsSchema, inv
|
|
|
30
30
|
throw invalidContext();
|
|
31
31
|
return { token, expiresAt: parsed.data.exp };
|
|
32
32
|
}
|
|
33
|
-
function
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (new Set(names).size !== names.length || names.includes('content-type')) {
|
|
62
|
-
throw error(400, 'invalid_configuration', 'Credential headers must be distinct');
|
|
63
|
-
}
|
|
64
|
-
return async function read({ body, schema, }) {
|
|
65
|
-
if (credentials.some((value) => value.credential.expiresAt <= Date.now() / 1000)) {
|
|
66
|
-
throw error(401, 'expired_context', 'The invocation credential expired; start a new invocation');
|
|
67
|
-
}
|
|
68
|
-
const response = await fetchImpl(url, {
|
|
69
|
-
method: 'POST',
|
|
70
|
-
headers: {
|
|
71
|
-
'content-type': 'application/json',
|
|
72
|
-
...Object.fromEntries(credentials.map((value) => [value.header, value.credential.token])),
|
|
73
|
-
},
|
|
74
|
-
body: JSON.stringify(body),
|
|
75
|
-
redirect: 'error',
|
|
76
|
-
signal: AbortSignal.timeout(timeoutMs),
|
|
77
|
-
});
|
|
78
|
-
const result = await response.json().catch(() => null);
|
|
79
|
-
if (!response.ok) {
|
|
80
|
-
const parsed = errorResponseSchema.safeParse(result);
|
|
81
|
-
throw error(response.status, parsed.success ? (parsed.data.code ?? failure.code) : failure.code, parsed.success
|
|
82
|
-
? (parsed.data.detail ?? failure.message)
|
|
83
|
-
: failure.message);
|
|
84
|
-
}
|
|
85
|
-
const validated = schema.safeParse(result);
|
|
86
|
-
if (!validated.success)
|
|
87
|
-
throw error(502, 'malformed_response', 'Atlas returned an invalid capability response');
|
|
88
|
-
return validated.data;
|
|
33
|
+
function createInvocationReadTransport({ baseUrl, fetchImpl, path, header, credential, additionalCredentials = [], timeoutMs, error, failure, }) {
|
|
34
|
+
const domain = path === "/api/managed-functions/directory/members"
|
|
35
|
+
? "caller-directory"
|
|
36
|
+
: path === "/api/managed-functions/processes/read"
|
|
37
|
+
? "process-reference"
|
|
38
|
+
: null;
|
|
39
|
+
if (domain === null)
|
|
40
|
+
throw error(400, "invalid_configuration", "Unsupported invocation read domain");
|
|
41
|
+
const send = (0, adapters_1.createInvocationDomainTransport)({
|
|
42
|
+
baseUrl,
|
|
43
|
+
fetchImpl,
|
|
44
|
+
domain,
|
|
45
|
+
credentials: [
|
|
46
|
+
{ header, ...credential },
|
|
47
|
+
...additionalCredentials.map((value) => ({
|
|
48
|
+
header: value.header,
|
|
49
|
+
...value.credential,
|
|
50
|
+
})),
|
|
51
|
+
],
|
|
52
|
+
timeoutMs,
|
|
53
|
+
error,
|
|
54
|
+
failure,
|
|
55
|
+
});
|
|
56
|
+
return async ({ body, schema, }) => {
|
|
57
|
+
const parsed = schema.safeParse(await send(body));
|
|
58
|
+
if (!parsed.success)
|
|
59
|
+
throw error(502, "malformed_response", "Atlas returned an invalid capability response");
|
|
60
|
+
return parsed.data;
|
|
89
61
|
};
|
|
90
62
|
}
|
|
@@ -1,59 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
export declare const FUNCTION_INVOCATION_CONTEXT_PATH = "/api/managed-functions/invocation/context";
|
|
4
|
-
export declare const functionInvocationIdentityCapabilitySchema: z.ZodObject<{
|
|
5
|
-
identity: z.ZodLiteral<true>;
|
|
6
|
-
caller_capabilities: z.ZodOptional<z.ZodLiteral<true>>;
|
|
7
|
-
}, z.core.$strict>;
|
|
8
|
-
export declare function readFunctionInvocationIdentityCapability(manifest: unknown): boolean;
|
|
9
|
-
export declare const functionInvocationContextRequestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
10
|
-
operation: z.ZodLiteral<"getInvocationContext">;
|
|
11
|
-
}, z.core.$strict>, z.ZodObject<{
|
|
12
|
-
operation: z.ZodLiteral<"getCallerCapabilities">;
|
|
13
|
-
}, z.core.$strict>], "operation">;
|
|
14
|
-
export type FunctionInvocationContextRequest = z.infer<typeof functionInvocationContextRequestSchema>;
|
|
15
|
-
export declare const functionInvocationContextSchema: z.ZodObject<{
|
|
16
|
-
receiver: z.ZodObject<{
|
|
17
|
-
functionId: z.ZodString;
|
|
18
|
-
versionId: z.ZodString;
|
|
19
|
-
invocationId: z.ZodString;
|
|
20
|
-
orgId: z.ZodString;
|
|
21
|
-
serviceAccountId: z.ZodString;
|
|
22
|
-
serviceAccountSub: z.ZodString;
|
|
23
|
-
}, z.core.$strict>;
|
|
24
|
-
caller: z.ZodObject<{
|
|
25
|
-
kind: z.ZodEnum<{
|
|
26
|
-
human: "human";
|
|
27
|
-
service_account: "service_account";
|
|
28
|
-
system: "system";
|
|
29
|
-
}>;
|
|
30
|
-
sub: z.ZodString;
|
|
31
|
-
}, z.core.$strict>;
|
|
32
|
-
}, z.core.$strict>;
|
|
33
|
-
export type FunctionInvocationContext = z.infer<typeof functionInvocationContextSchema>;
|
|
34
|
-
export declare class FunctionInvocationContextError extends Error {
|
|
35
|
-
readonly status: number;
|
|
36
|
-
readonly code: string;
|
|
37
|
-
readonly name = "FunctionInvocationContextError";
|
|
38
|
-
constructor(status: number, code: string, message: string);
|
|
39
|
-
}
|
|
40
|
-
export declare const functionInvocationCapabilitiesSchema: z.ZodObject<{
|
|
41
|
-
receiver: z.ZodObject<{
|
|
42
|
-
functionId: z.ZodString;
|
|
43
|
-
versionId: z.ZodString;
|
|
44
|
-
invocationId: z.ZodString;
|
|
45
|
-
orgId: z.ZodString;
|
|
46
|
-
serviceAccountId: z.ZodString;
|
|
47
|
-
serviceAccountSub: z.ZodString;
|
|
48
|
-
}, z.core.$strict>;
|
|
49
|
-
caller: z.ZodObject<{
|
|
50
|
-
kind: z.ZodEnum<{
|
|
51
|
-
human: "human";
|
|
52
|
-
service_account: "service_account";
|
|
53
|
-
system: "system";
|
|
54
|
-
}>;
|
|
55
|
-
sub: z.ZodString;
|
|
56
|
-
}, z.core.$strict>;
|
|
57
|
-
capabilities: z.ZodArray<z.ZodString>;
|
|
58
|
-
}, z.core.$strict>;
|
|
59
|
-
export type FunctionInvocationCapabilities = z.infer<typeof functionInvocationCapabilitiesSchema>;
|
|
1
|
+
export { FUNCTION_INVOCATION_IDENTITY_TOKEN_HEADER, FUNCTION_INVOCATION_CONTEXT_PATH, functionInvocationIdentityCapabilitySchema, readFunctionInvocationIdentityCapability, functionInvocationContextRequestSchema, functionInvocationContextSchema, FunctionInvocationContextError, functionInvocationCapabilitiesSchema, } from "@sequenceholdings/platform/contracts";
|
|
2
|
+
export type { FunctionInvocationContextRequest, FunctionInvocationContext, FunctionInvocationCapabilities, } from "@sequenceholdings/platform/contracts";
|
|
@@ -1,63 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.functionInvocationCapabilitiesSchema = exports.FunctionInvocationContextError = exports.functionInvocationContextSchema = exports.functionInvocationContextRequestSchema = exports.functionInvocationIdentityCapabilitySchema = exports.FUNCTION_INVOCATION_CONTEXT_PATH = exports.FUNCTION_INVOCATION_IDENTITY_TOKEN_HEADER = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
exports.
|
|
7
|
-
exports.
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
exports
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
});
|
|
14
|
-
function readFunctionInvocationIdentityCapability(manifest) {
|
|
15
|
-
if (typeof manifest !== 'object' || manifest === null)
|
|
16
|
-
return false;
|
|
17
|
-
const capabilities = Reflect.get(manifest, 'capabilities');
|
|
18
|
-
if (typeof capabilities !== 'object' || capabilities === null)
|
|
19
|
-
return false;
|
|
20
|
-
return exports.functionInvocationIdentityCapabilitySchema.safeParse(Reflect.get(capabilities, 'invocation')).success;
|
|
21
|
-
}
|
|
22
|
-
exports.functionInvocationContextRequestSchema = zod_1.z.discriminatedUnion('operation', [
|
|
23
|
-
zod_1.z.strictObject({ operation: zod_1.z.literal('getInvocationContext') }),
|
|
24
|
-
zod_1.z.strictObject({ operation: zod_1.z.literal('getCallerCapabilities') }),
|
|
25
|
-
]);
|
|
26
|
-
exports.functionInvocationContextSchema = zod_1.z.strictObject({
|
|
27
|
-
receiver: zod_1.z
|
|
28
|
-
.strictObject({
|
|
29
|
-
functionId: identifier,
|
|
30
|
-
versionId: identifier,
|
|
31
|
-
invocationId: identifier,
|
|
32
|
-
orgId: identifier,
|
|
33
|
-
serviceAccountId: identifier,
|
|
34
|
-
serviceAccountSub: principal,
|
|
35
|
-
})
|
|
36
|
-
.refine((value) => value.serviceAccountSub === `service-account|${value.serviceAccountId}`, 'The receiver subject must identify the attached service account'),
|
|
37
|
-
caller: zod_1.z.strictObject({
|
|
38
|
-
kind: zod_1.z.enum(['human', 'service_account', 'system']),
|
|
39
|
-
sub: principal,
|
|
40
|
-
}),
|
|
41
|
-
});
|
|
42
|
-
class FunctionInvocationContextError extends Error {
|
|
43
|
-
status;
|
|
44
|
-
code;
|
|
45
|
-
name = 'FunctionInvocationContextError';
|
|
46
|
-
constructor(status, code, message) {
|
|
47
|
-
super(message);
|
|
48
|
-
this.status = status;
|
|
49
|
-
this.code = code;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
exports.FunctionInvocationContextError = FunctionInvocationContextError;
|
|
53
|
-
exports.functionInvocationCapabilitiesSchema = exports.functionInvocationContextSchema
|
|
54
|
-
.extend({
|
|
55
|
-
capabilities: zod_1.z
|
|
56
|
-
.array(zod_1.z
|
|
57
|
-
.string()
|
|
58
|
-
.min(1)
|
|
59
|
-
.max(140)
|
|
60
|
-
.regex(/^[a-z0-9][a-z0-9/_.:-]*$/))
|
|
61
|
-
.max(256),
|
|
62
|
-
})
|
|
63
|
-
.refine((value) => new Set(value.capabilities).size === value.capabilities.length, 'Capabilities must be unique');
|
|
3
|
+
exports.functionInvocationCapabilitiesSchema = exports.FunctionInvocationContextError = exports.functionInvocationContextSchema = exports.functionInvocationContextRequestSchema = exports.readFunctionInvocationIdentityCapability = exports.functionInvocationIdentityCapabilitySchema = exports.FUNCTION_INVOCATION_CONTEXT_PATH = exports.FUNCTION_INVOCATION_IDENTITY_TOKEN_HEADER = void 0;
|
|
4
|
+
var contracts_1 = require("@sequenceholdings/platform/contracts");
|
|
5
|
+
Object.defineProperty(exports, "FUNCTION_INVOCATION_IDENTITY_TOKEN_HEADER", { enumerable: true, get: function () { return contracts_1.FUNCTION_INVOCATION_IDENTITY_TOKEN_HEADER; } });
|
|
6
|
+
Object.defineProperty(exports, "FUNCTION_INVOCATION_CONTEXT_PATH", { enumerable: true, get: function () { return contracts_1.FUNCTION_INVOCATION_CONTEXT_PATH; } });
|
|
7
|
+
Object.defineProperty(exports, "functionInvocationIdentityCapabilitySchema", { enumerable: true, get: function () { return contracts_1.functionInvocationIdentityCapabilitySchema; } });
|
|
8
|
+
Object.defineProperty(exports, "readFunctionInvocationIdentityCapability", { enumerable: true, get: function () { return contracts_1.readFunctionInvocationIdentityCapability; } });
|
|
9
|
+
Object.defineProperty(exports, "functionInvocationContextRequestSchema", { enumerable: true, get: function () { return contracts_1.functionInvocationContextRequestSchema; } });
|
|
10
|
+
Object.defineProperty(exports, "functionInvocationContextSchema", { enumerable: true, get: function () { return contracts_1.functionInvocationContextSchema; } });
|
|
11
|
+
Object.defineProperty(exports, "FunctionInvocationContextError", { enumerable: true, get: function () { return contracts_1.FunctionInvocationContextError; } });
|
|
12
|
+
Object.defineProperty(exports, "functionInvocationCapabilitiesSchema", { enumerable: true, get: function () { return contracts_1.functionInvocationCapabilitiesSchema; } });
|
package/dist/invocation.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type FunctionInvocationCapabilities, type FunctionInvocationContext } from
|
|
2
|
-
export * from
|
|
3
|
-
import type { FunctionInvocationClientOptions } from
|
|
4
|
-
export type { FunctionInvocationClientOptions } from
|
|
1
|
+
import { type FunctionInvocationCapabilities, type FunctionInvocationContext } from "./invocation-contract";
|
|
2
|
+
export * from "./invocation-contract";
|
|
3
|
+
import type { FunctionInvocationClientOptions } from "./invocation-client";
|
|
4
|
+
export type { FunctionInvocationClientOptions } from "./invocation-client";
|
|
5
5
|
export interface FunctionInvocationClient {
|
|
6
6
|
getInvocationContext(): Promise<FunctionInvocationContext>;
|
|
7
7
|
getCallerCapabilities(): Promise<FunctionInvocationCapabilities>;
|
package/dist/invocation.js
CHANGED
|
@@ -15,20 +15,21 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
exports.createFunctionInvocationClient = createFunctionInvocationClient;
|
|
18
|
+
const adapters_1 = require("@sequenceholdings/platform/adapters");
|
|
18
19
|
const zod_1 = require("zod");
|
|
19
20
|
const invocation_contract_1 = require("./invocation-contract");
|
|
20
21
|
__exportStar(require("./invocation-contract"), exports);
|
|
21
22
|
const identifier = zod_1.z.string().min(1).max(255);
|
|
22
23
|
const principal = zod_1.z.string().min(1).max(512);
|
|
23
24
|
const tokenClaimsSchema = zod_1.z.strictObject({
|
|
24
|
-
audience: zod_1.z.literal(
|
|
25
|
+
audience: zod_1.z.literal("atlas-managed-function-invocation-identity"),
|
|
25
26
|
environment: zod_1.z.string().min(1).max(4096),
|
|
26
27
|
functionId: identifier,
|
|
27
28
|
versionId: identifier,
|
|
28
29
|
invocationId: identifier,
|
|
29
30
|
serviceAccountId: identifier,
|
|
30
31
|
org: identifier,
|
|
31
|
-
callerKind: zod_1.z.enum([
|
|
32
|
+
callerKind: zod_1.z.enum(["human", "service_account", "system"]),
|
|
32
33
|
callerSub: principal,
|
|
33
34
|
callerAuthenticationMethod: identifier,
|
|
34
35
|
exp: zod_1.z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
|
|
@@ -41,26 +42,28 @@ const errorSchema = zod_1.z.strictObject({
|
|
|
41
42
|
.regex(/^[a-z][a-z0-9_]*$/),
|
|
42
43
|
detail: zod_1.z.string().min(1).max(2000),
|
|
43
44
|
});
|
|
44
|
-
const invalidContext = () => new invocation_contract_1.FunctionInvocationContextError(401,
|
|
45
|
-
function readCredential({ request }) {
|
|
45
|
+
const invalidContext = () => new invocation_contract_1.FunctionInvocationContextError(401, "invalid_context", "This invocation has no valid identity credential");
|
|
46
|
+
function readCredential({ request, }) {
|
|
46
47
|
const { headers } = request;
|
|
47
|
-
const matches = typeof headers.get ===
|
|
48
|
+
const matches = typeof headers.get === "function"
|
|
48
49
|
? [headers.get(invocation_contract_1.FUNCTION_INVOCATION_IDENTITY_TOKEN_HEADER)]
|
|
49
50
|
: Object.entries(headers)
|
|
50
51
|
.filter(([name]) => name.toLowerCase() === invocation_contract_1.FUNCTION_INVOCATION_IDENTITY_TOKEN_HEADER)
|
|
51
52
|
.map(([, value]) => value);
|
|
52
53
|
const token = matches[0];
|
|
53
|
-
if (matches.length !== 1 ||
|
|
54
|
+
if (matches.length !== 1 ||
|
|
55
|
+
typeof token !== "string" ||
|
|
56
|
+
token.length > 16_384)
|
|
54
57
|
throw invalidContext();
|
|
55
58
|
const envelope = /^([A-Za-z0-9_-]+)\.([A-Za-z0-9_-]{43})$/.exec(token);
|
|
56
59
|
if (!envelope?.[1])
|
|
57
60
|
throw invalidContext();
|
|
58
61
|
let value;
|
|
59
62
|
try {
|
|
60
|
-
const decoded = Buffer.from(envelope[1],
|
|
61
|
-
if (decoded.toString(
|
|
63
|
+
const decoded = Buffer.from(envelope[1], "base64url");
|
|
64
|
+
if (decoded.toString("base64url") !== envelope[1])
|
|
62
65
|
throw invalidContext();
|
|
63
|
-
value = JSON.parse(new TextDecoder(
|
|
66
|
+
value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(decoded));
|
|
64
67
|
}
|
|
65
68
|
catch {
|
|
66
69
|
throw invalidContext();
|
|
@@ -71,7 +74,7 @@ function readCredential({ request }) {
|
|
|
71
74
|
return { token, claims: parsed.data };
|
|
72
75
|
}
|
|
73
76
|
function trustedOrigin(baseUrl) {
|
|
74
|
-
const invalid = () => new invocation_contract_1.FunctionInvocationContextError(400,
|
|
77
|
+
const invalid = () => new invocation_contract_1.FunctionInvocationContextError(400, "invalid_configuration", "Configure a trusted HTTPS Atlas origin without credentials, path, query or fragment");
|
|
75
78
|
let url;
|
|
76
79
|
try {
|
|
77
80
|
url = new URL(baseUrl);
|
|
@@ -79,66 +82,42 @@ function trustedOrigin(baseUrl) {
|
|
|
79
82
|
catch {
|
|
80
83
|
throw invalid();
|
|
81
84
|
}
|
|
82
|
-
const loopback = url.protocol ===
|
|
83
|
-
|
|
85
|
+
const loopback = url.protocol === "http:" &&
|
|
86
|
+
["localhost", "127.0.0.1", "[::1]"].includes(url.hostname);
|
|
87
|
+
if ((!loopback && url.protocol !== "https:") ||
|
|
84
88
|
url.username ||
|
|
85
89
|
url.password ||
|
|
86
|
-
url.pathname !==
|
|
90
|
+
url.pathname !== "/" ||
|
|
87
91
|
url.search ||
|
|
88
92
|
url.hash)
|
|
89
93
|
throw invalid();
|
|
90
94
|
return url.origin;
|
|
91
95
|
}
|
|
92
|
-
function requireFresh(claims) {
|
|
93
|
-
if (claims.exp <= Date.now() / 1000)
|
|
94
|
-
throw new invocation_contract_1.FunctionInvocationContextError(401, 'expired_context', 'The identity credential expired; start a new invocation');
|
|
95
|
-
}
|
|
96
|
-
function matchesInvocation({ context, claims, }) {
|
|
97
|
-
const { receiver, caller } = context;
|
|
98
|
-
return (receiver.functionId === claims.functionId &&
|
|
99
|
-
receiver.versionId === claims.versionId &&
|
|
100
|
-
receiver.invocationId === claims.invocationId &&
|
|
101
|
-
receiver.orgId === claims.org &&
|
|
102
|
-
receiver.serviceAccountId === claims.serviceAccountId &&
|
|
103
|
-
caller.kind === claims.callerKind &&
|
|
104
|
-
caller.sub === claims.callerSub);
|
|
105
|
-
}
|
|
106
96
|
function createFunctionInvocationClient({ request, baseUrl, fetchImpl = globalThis.fetch, }) {
|
|
107
|
-
|
|
97
|
+
trustedOrigin(baseUrl);
|
|
108
98
|
const { token, claims } = readCredential({ request });
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
requireFresh(claims);
|
|
135
|
-
const parsed = schema.safeParse(result);
|
|
136
|
-
if (!parsed.success || !matchesInvocation({ context: parsed.data, claims }))
|
|
137
|
-
throw new invocation_contract_1.FunctionInvocationContextError(502, 'malformed_response', 'Atlas returned an invalid invocation context response');
|
|
138
|
-
return parsed.data;
|
|
139
|
-
}
|
|
140
|
-
return {
|
|
141
|
-
getInvocationContext: () => read('getInvocationContext', invocation_contract_1.functionInvocationContextSchema),
|
|
142
|
-
getCallerCapabilities: () => read('getCallerCapabilities', invocation_contract_1.functionInvocationCapabilitiesSchema),
|
|
143
|
-
};
|
|
99
|
+
const send = (0, adapters_1.createInvocationDomainTransport)({
|
|
100
|
+
baseUrl,
|
|
101
|
+
fetchImpl,
|
|
102
|
+
domain: "invocation",
|
|
103
|
+
credentials: [
|
|
104
|
+
{
|
|
105
|
+
header: invocation_contract_1.FUNCTION_INVOCATION_IDENTITY_TOKEN_HEADER,
|
|
106
|
+
token,
|
|
107
|
+
expiresAt: claims.exp,
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
error: (status, code, message) => new invocation_contract_1.FunctionInvocationContextError(["transport_failed", "timeout", "redirect_refused"].includes(code)
|
|
111
|
+
? 502
|
|
112
|
+
: status, ["transport_failed", "timeout"].includes(code)
|
|
113
|
+
? "context_request_failed"
|
|
114
|
+
: code, ["transport_failed", "timeout"].includes(code)
|
|
115
|
+
? "The invocation context request failed"
|
|
116
|
+
: message),
|
|
117
|
+
failure: {
|
|
118
|
+
code: "context_read_failed",
|
|
119
|
+
message: "Invocation context read failed",
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
return (0, adapters_1.createInvocationContextClient)({ claims, send });
|
|
144
123
|
}
|