@asturiu/v0-sdk 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.
- package/CHANGELOG.md +42 -0
- package/LICENSE +202 -0
- package/NOTICE +5 -0
- package/README.md +82 -2
- package/contract/assertion-vectors.json +90 -0
- package/contract/schemas/branding.schema.json +46 -0
- package/contract/schemas/definitions.schema.json +376 -0
- package/contract/schemas/portal.schema.json +56 -0
- package/contract/tenant-api-routes.json +165 -0
- package/dist/branding.d.ts +131 -0
- package/dist/branding.d.ts.map +1 -0
- package/dist/branding.js +206 -0
- package/dist/branding.js.map +1 -0
- package/dist/changesets.d.ts +58 -0
- package/dist/changesets.d.ts.map +1 -0
- package/dist/changesets.js +18 -0
- package/dist/changesets.js.map +1 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +12 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/changesets.d.ts +14 -0
- package/dist/cli/changesets.d.ts.map +1 -0
- package/dist/cli/changesets.js +252 -0
- package/dist/cli/changesets.js.map +1 -0
- package/dist/cli/cli.d.ts +37 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/cli/cli.js +415 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/cli/context.d.ts +147 -0
- package/dist/cli/context.d.ts.map +1 -0
- package/dist/cli/context.js +258 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/engine.d.ts +59 -0
- package/dist/cli/engine.d.ts.map +1 -0
- package/dist/cli/engine.js +85 -0
- package/dist/cli/engine.js.map +1 -0
- package/dist/cli/feedback.d.ts +40 -0
- package/dist/cli/feedback.d.ts.map +1 -0
- package/dist/cli/feedback.js +420 -0
- package/dist/cli/feedback.js.map +1 -0
- package/dist/cli/files.d.ts +83 -0
- package/dist/cli/files.d.ts.map +1 -0
- package/dist/cli/files.js +389 -0
- package/dist/cli/files.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +8 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/overview.d.ts +6 -0
- package/dist/cli/overview.d.ts.map +1 -0
- package/dist/cli/overview.js +379 -0
- package/dist/cli/overview.js.map +1 -0
- package/dist/cli/parts.d.ts +5 -0
- package/dist/cli/parts.d.ts.map +1 -0
- package/dist/cli/parts.js +414 -0
- package/dist/cli/parts.js.map +1 -0
- package/dist/cli/sources.d.ts +37 -0
- package/dist/cli/sources.d.ts.map +1 -0
- package/dist/cli/sources.js +91 -0
- package/dist/cli/sources.js.map +1 -0
- package/dist/cli/terminal.d.ts +135 -0
- package/dist/cli/terminal.d.ts.map +1 -0
- package/dist/cli/terminal.js +353 -0
- package/dist/cli/terminal.js.map +1 -0
- package/dist/cli/ui-page.d.ts +8 -0
- package/dist/cli/ui-page.d.ts.map +1 -0
- package/dist/cli/ui-page.js +216 -0
- package/dist/cli/ui-page.js.map +1 -0
- package/dist/cli/ui.d.ts +54 -0
- package/dist/cli/ui.d.ts.map +1 -0
- package/dist/cli/ui.js +251 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/client.d.ts +88 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +165 -0
- package/dist/client.js.map +1 -0
- package/dist/contacts.d.ts +43 -0
- package/dist/contacts.d.ts.map +1 -0
- package/dist/contacts.js +46 -0
- package/dist/contacts.js.map +1 -0
- package/dist/definition-set.d.ts +731 -0
- package/dist/definition-set.d.ts.map +1 -0
- package/dist/definition-set.js +659 -0
- package/dist/definition-set.js.map +1 -0
- package/dist/definitions.d.ts +42 -0
- package/dist/definitions.d.ts.map +1 -0
- package/dist/definitions.js +154 -0
- package/dist/definitions.js.map +1 -0
- package/dist/enrolment.d.ts +9 -0
- package/dist/enrolment.d.ts.map +1 -0
- package/dist/enrolment.js +8 -0
- package/dist/enrolment.js.map +1 -0
- package/dist/fill.d.ts +73 -0
- package/dist/fill.d.ts.map +1 -0
- package/dist/fill.js +46 -0
- package/dist/fill.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/notifications.d.ts +33 -0
- package/dist/notifications.d.ts.map +1 -0
- package/dist/notifications.js +36 -0
- package/dist/notifications.js.map +1 -0
- package/dist/oidc.d.ts +122 -0
- package/dist/oidc.d.ts.map +1 -0
- package/dist/oidc.js +150 -0
- package/dist/oidc.js.map +1 -0
- package/dist/overlay.d.ts +109 -0
- package/dist/overlay.d.ts.map +1 -0
- package/dist/overlay.js +58 -0
- package/dist/overlay.js.map +1 -0
- package/dist/passes.d.ts +95 -0
- package/dist/passes.d.ts.map +1 -0
- package/dist/passes.js +140 -0
- package/dist/passes.js.map +1 -0
- package/dist/portal-options.d.ts +65 -0
- package/dist/portal-options.d.ts.map +1 -0
- package/dist/portal-options.js +120 -0
- package/dist/portal-options.js.map +1 -0
- package/dist/reads.d.ts +41 -0
- package/dist/reads.d.ts.map +1 -0
- package/dist/reads.js +44 -0
- package/dist/reads.js.map +1 -0
- package/dist/recovery-words.d.ts +8 -0
- package/dist/recovery-words.d.ts.map +1 -0
- package/dist/recovery-words.js +136 -0
- package/dist/recovery-words.js.map +1 -0
- package/dist/recovery.d.ts +198 -0
- package/dist/recovery.d.ts.map +1 -0
- package/dist/recovery.js +112 -0
- package/dist/recovery.js.map +1 -0
- package/dist/reveal.d.ts +35 -0
- package/dist/reveal.d.ts.map +1 -0
- package/dist/reveal.js +66 -0
- package/dist/reveal.js.map +1 -0
- package/dist/seal.d.ts +15 -0
- package/dist/seal.d.ts.map +1 -0
- package/dist/seal.js +0 -0
- package/dist/seal.js.map +1 -0
- package/dist/session.d.ts +66 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +61 -0
- package/dist/session.js.map +1 -0
- package/dist/signing-in-mark.d.ts +14 -0
- package/dist/signing-in-mark.d.ts.map +1 -0
- package/dist/signing-in-mark.js +24 -0
- package/dist/signing-in-mark.js.map +1 -0
- package/dist/signing-in.d.ts +22 -0
- package/dist/signing-in.d.ts.map +1 -0
- package/dist/signing-in.js +203 -0
- package/dist/signing-in.js.map +1 -0
- package/dist/tags.d.ts +96 -0
- package/dist/tags.d.ts.map +1 -0
- package/dist/tags.js +88 -0
- package/dist/tags.js.map +1 -0
- package/dist/tenant-subscription.d.ts +47 -0
- package/dist/tenant-subscription.d.ts.map +1 -0
- package/dist/tenant-subscription.js +7 -0
- package/dist/tenant-subscription.js.map +1 -0
- package/dist/testing/index.d.ts +125 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +320 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/theme.d.ts +237 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +504 -0
- package/dist/theme.js.map +1 -0
- package/dist/tickets.d.ts +152 -0
- package/dist/tickets.d.ts.map +1 -0
- package/dist/tickets.js +65 -0
- package/dist/tickets.js.map +1 -0
- package/dist/tiers.d.ts +168 -0
- package/dist/tiers.d.ts.map +1 -0
- package/dist/tiers.js +341 -0
- package/dist/tiers.js.map +1 -0
- package/dist/types.d.ts +885 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/dist/urlid.d.ts +50 -0
- package/dist/urlid.d.ts.map +1 -0
- package/dist/urlid.js +78 -0
- package/dist/urlid.js.map +1 -0
- package/dist/version.d.ts +15 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +15 -0
- package/dist/version.js.map +1 -0
- package/make/asturiu.mk +43 -0
- package/package.json +63 -4
- package/src/branding.ts +221 -0
- package/src/changesets.ts +61 -0
- package/src/cli/bin.ts +12 -0
- package/src/cli/changesets.ts +233 -0
- package/src/cli/cli.ts +425 -0
- package/src/cli/context.ts +299 -0
- package/src/cli/engine.ts +112 -0
- package/src/cli/feedback.ts +406 -0
- package/src/cli/files.ts +371 -0
- package/src/cli/index.ts +7 -0
- package/src/cli/overview.ts +343 -0
- package/src/cli/parts.ts +371 -0
- package/src/cli/sources.ts +111 -0
- package/src/cli/terminal.ts +384 -0
- package/src/cli/ui-page.ts +215 -0
- package/src/cli/ui.ts +266 -0
- package/src/client.ts +202 -0
- package/src/contacts.ts +61 -0
- package/src/definition-set.ts +965 -0
- package/src/definitions.ts +156 -0
- package/src/enrolment.ts +10 -0
- package/src/fill.ts +83 -0
- package/src/index.ts +38 -0
- package/src/notifications.ts +55 -0
- package/src/oidc.ts +199 -0
- package/src/overlay.ts +137 -0
- package/src/passes.ts +168 -0
- package/src/portal-options.ts +125 -0
- package/src/reads.ts +71 -0
- package/src/recovery-words.ts +137 -0
- package/src/recovery.ts +269 -0
- package/src/reveal.ts +72 -0
- package/src/seal.ts +0 -0
- package/src/session.ts +93 -0
- package/src/signing-in-mark.ts +23 -0
- package/src/signing-in.ts +213 -0
- package/src/tags.ts +146 -0
- package/src/tenant-subscription.ts +44 -0
- package/src/testing/index.ts +337 -0
- package/src/theme.ts +628 -0
- package/src/tickets.ts +195 -0
- package/src/tiers.ts +397 -0
- package/src/types.ts +847 -0
- package/src/urlid.ts +77 -0
- package/src/version.ts +15 -0
- package/templates/asturiu/branding.json +4 -0
- package/templates/asturiu/definitions.json +23 -0
- package/templates/asturiu/portal.json +16 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { RepositoryBranding, TenantSource } from "../branding.js";
|
|
2
|
+
import type { ChangesetStatus, FeedbackReport, TenantChangeset } from "../changesets.js";
|
|
3
|
+
import { type DefinitionStatus, type DefinitionSubmitResult, type EngineInfo, type TenantKeyRecord, type TenantKeyScope } from "../definition-set.js";
|
|
4
|
+
import type { PortalPage } from "../portal-options.js";
|
|
5
|
+
import type { TagView } from "../tags.js";
|
|
6
|
+
import type { AnnouncementItem, TicketView } from "../tickets.js";
|
|
7
|
+
export type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
|
|
8
|
+
export interface StandInOptions {
|
|
9
|
+
/** The Tenant key whose assertions it takes; without one, any well-formed assertion passes. */
|
|
10
|
+
key?: string;
|
|
11
|
+
/** What the key reaches (default: every scope). */
|
|
12
|
+
scopes?: TenantKeyScope[];
|
|
13
|
+
/** Routes it answers with 404, as an older Engine does: `"GET /tenant/v0/key"`. */
|
|
14
|
+
missing?: string[];
|
|
15
|
+
/** Answer every call with this status (`401`: the key was refused). */
|
|
16
|
+
refuse?: number;
|
|
17
|
+
/** Throw as `fetch` does when nothing answers (`ECONNREFUSED`), or another network code. */
|
|
18
|
+
down?: boolean | string;
|
|
19
|
+
engine?: Partial<EngineInfo>;
|
|
20
|
+
definitions?: Partial<DefinitionStatus> & {
|
|
21
|
+
/** How it answers a submitted set other than the live one: applied at once (default) or waiting for approval. */
|
|
22
|
+
submit?: "apply" | "wait" | ((set: Record<string, unknown>, hash: string) => DefinitionSubmitResult);
|
|
23
|
+
};
|
|
24
|
+
branding?: {
|
|
25
|
+
source?: TenantSource;
|
|
26
|
+
branding?: RepositoryBranding;
|
|
27
|
+
};
|
|
28
|
+
portal?: {
|
|
29
|
+
source?: TenantSource;
|
|
30
|
+
portal?: Record<string, unknown>;
|
|
31
|
+
redirected?: PortalPage[];
|
|
32
|
+
};
|
|
33
|
+
changesets?: TenantChangeset[];
|
|
34
|
+
/** Documents of the Engine site, by their whole address: what `changesets pull` fetches. */
|
|
35
|
+
documents?: Record<string, string>;
|
|
36
|
+
feedback?: TicketView[];
|
|
37
|
+
tickets?: TicketView[];
|
|
38
|
+
announcements?: {
|
|
39
|
+
items?: TicketView[];
|
|
40
|
+
platform?: AnnouncementItem[];
|
|
41
|
+
};
|
|
42
|
+
tags?: TagView[];
|
|
43
|
+
keyRecord?: Partial<TenantKeyRecord>;
|
|
44
|
+
now?: () => number;
|
|
45
|
+
}
|
|
46
|
+
export interface StandInCall {
|
|
47
|
+
method: string;
|
|
48
|
+
path: string;
|
|
49
|
+
query: string;
|
|
50
|
+
body: unknown;
|
|
51
|
+
status: number;
|
|
52
|
+
/** The SDK version the caller named in its User-Agent, as the Tenant API forwards it. */
|
|
53
|
+
sdk_version: string | null;
|
|
54
|
+
}
|
|
55
|
+
/** A Tenant key for tests: made here, registered with no Engine, so a real Tenant API refuses it. */
|
|
56
|
+
export declare function testTenantKey(slug?: string, kid?: string): Promise<string>;
|
|
57
|
+
/** The in-memory Tenant API. `fetch` is what the SDK's calls and `asturiu-v0-tenant` take as their `fetch`. */
|
|
58
|
+
export declare function createTenantApiStandIn(o?: StandInOptions): {
|
|
59
|
+
fetch: FetchLike;
|
|
60
|
+
handle: (request: Request) => Promise<Response>;
|
|
61
|
+
state: {
|
|
62
|
+
engine: EngineInfo;
|
|
63
|
+
definitions: DefinitionStatus;
|
|
64
|
+
branding: {
|
|
65
|
+
source: "admin_ui" | "repository";
|
|
66
|
+
branding: RepositoryBranding;
|
|
67
|
+
};
|
|
68
|
+
portal: {
|
|
69
|
+
source: "admin_ui" | "repository";
|
|
70
|
+
portal: Record<string, unknown>;
|
|
71
|
+
redirected: ("profile" | "security" | "plan" | "privacy" | "recovery" | "support")[];
|
|
72
|
+
};
|
|
73
|
+
changesets: {
|
|
74
|
+
url: string | null;
|
|
75
|
+
ticket: string | null;
|
|
76
|
+
status: ChangesetStatus | null;
|
|
77
|
+
number: number;
|
|
78
|
+
slug: string;
|
|
79
|
+
file: string;
|
|
80
|
+
date: string;
|
|
81
|
+
title: string;
|
|
82
|
+
applies_to: string;
|
|
83
|
+
decisions: string[];
|
|
84
|
+
action_required: boolean;
|
|
85
|
+
deadline: string | null;
|
|
86
|
+
sdk_version: string | null;
|
|
87
|
+
}[];
|
|
88
|
+
feedback: TicketView[];
|
|
89
|
+
tickets: TicketView[];
|
|
90
|
+
announcements: TicketView[];
|
|
91
|
+
platform: AnnouncementItem[];
|
|
92
|
+
tags: {
|
|
93
|
+
id: string;
|
|
94
|
+
name: string;
|
|
95
|
+
shown: string;
|
|
96
|
+
scope: "platform" | "tenant";
|
|
97
|
+
tenant?: string;
|
|
98
|
+
subject: import("../tags.js").TagSubject;
|
|
99
|
+
visibility: import("../tags.js").TagVisibility;
|
|
100
|
+
description: string;
|
|
101
|
+
colour: import("../tags.js").TagColour;
|
|
102
|
+
rules: import("../tags.js").TagRule[];
|
|
103
|
+
effects: import("../tags.js").TagEffect[];
|
|
104
|
+
system: boolean;
|
|
105
|
+
subjects: number;
|
|
106
|
+
created_at: string;
|
|
107
|
+
updated_at: string;
|
|
108
|
+
}[];
|
|
109
|
+
customerTags: Map<string, Set<string>>;
|
|
110
|
+
tiers: {
|
|
111
|
+
source: TenantSource;
|
|
112
|
+
tiers: {};
|
|
113
|
+
default_tier: string | null;
|
|
114
|
+
};
|
|
115
|
+
reports: FeedbackReport[];
|
|
116
|
+
};
|
|
117
|
+
calls: StandInCall[];
|
|
118
|
+
routes: readonly {
|
|
119
|
+
method: string;
|
|
120
|
+
path: string;
|
|
121
|
+
scope: TenantKeyScope | null;
|
|
122
|
+
}[];
|
|
123
|
+
};
|
|
124
|
+
export type TenantApiStandIn = ReturnType<typeof createTenantApiStandIn>;
|
|
125
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@asturiu/v0-sdk/testing` (ADR-074 §5): an in-memory stand-in for the Tenant API, so a Tenant's CI can run its
|
|
3
|
+
* start-up code and `asturiu-v0-tenant` without a key the Engine knows, a network or an Engine. Node only.
|
|
4
|
+
*
|
|
5
|
+
* It answers every route of `TENANT_API_ROUTES` the way the Tenant API does: a signed assertion on every call (checked
|
|
6
|
+
* against the stand-in's key when one is given), a `404` for a route the key's scopes do not reach, problem documents
|
|
7
|
+
* for refusals. It holds its state in memory and records each call. It is a stand-in, not the Engine: it plans no
|
|
8
|
+
* Definition change and checks no Definition rule.
|
|
9
|
+
*/
|
|
10
|
+
import { createHash, createPrivateKey, createPublicKey, verify } from "node:crypto";
|
|
11
|
+
import { TENANT_API_ROUTES, TENANT_ASSERTION_AUDIENCE, TENANT_ASSERTION_MAX_SECONDS, TENANT_KEY_SCOPES, definitionSetHash, formatTenantKey, fromB64url, generateTenantKeyPair, keyReachesRoute, matchTenantApiRoute, parseTenantKey } from "../definition-set.js";
|
|
12
|
+
import { SDK_VERSION } from "../version.js";
|
|
13
|
+
const ALL_PAGES = ["profile", "security", "plan", "privacy", "recovery", "support"];
|
|
14
|
+
const ALL_SWITCHES = ["account_link", "open_app", "back_link", "language_menu", "appearance"];
|
|
15
|
+
/** A Tenant key for tests: made here, registered with no Engine, so a real Tenant API refuses it. */
|
|
16
|
+
export async function testTenantKey(slug = "acme", kid = "0123456789abcdef") {
|
|
17
|
+
return formatTenantKey({ slug, kid, pkcs8: (await generateTenantKeyPair()).privatePkcs8 });
|
|
18
|
+
}
|
|
19
|
+
const problem = (status, type, detail) => new Response(JSON.stringify({ type, title: type.replace(/-/g, " "), status, detail }), { status, headers: { "content-type": "application/problem+json" } });
|
|
20
|
+
const ok = (body, status = 200, headers = {}) => new Response(body === undefined ? null : JSON.stringify(body), { status, headers: { "content-type": "application/json", ...headers } });
|
|
21
|
+
const b64 = (s) => JSON.parse(Buffer.from(s, "base64url").toString("utf8"));
|
|
22
|
+
function post(at, body, mine, label) {
|
|
23
|
+
return { id: `pst-${createHash("sha256").update(at + body).digest("hex").slice(0, 12)}`, at, side: mine ? "requester" : "handling", visibility: "all", author: { label, mine }, body, refs: [] };
|
|
24
|
+
}
|
|
25
|
+
function ticket(o) {
|
|
26
|
+
return {
|
|
27
|
+
arid: o.arid,
|
|
28
|
+
scope: "tenant",
|
|
29
|
+
direction: o.direction ?? "tenant_platform",
|
|
30
|
+
primary: o.primary ?? "request",
|
|
31
|
+
secondary: null,
|
|
32
|
+
type_label: o.primary === "announcement" ? "Announcement" : "Request",
|
|
33
|
+
subject: o.subject,
|
|
34
|
+
status: o.status ?? "new",
|
|
35
|
+
priority: "normal",
|
|
36
|
+
archived: false,
|
|
37
|
+
created_at: o.at,
|
|
38
|
+
updated_at: o.at,
|
|
39
|
+
side: "requester",
|
|
40
|
+
unread: false,
|
|
41
|
+
with_label: o.with_label ?? "Asturiu",
|
|
42
|
+
parties: [],
|
|
43
|
+
posts: o.body ? [post(o.at, o.body, true, "Your servers")] : [],
|
|
44
|
+
links: [],
|
|
45
|
+
refs: [],
|
|
46
|
+
audience: null,
|
|
47
|
+
hold_until: null,
|
|
48
|
+
closed_at: null,
|
|
49
|
+
can: { post: true, note: false, triage: false, statuses: ["canceled", "resolved"], reopen: false },
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** The in-memory Tenant API. `fetch` is what the SDK's calls and `asturiu-v0-tenant` take as their `fetch`. */
|
|
53
|
+
export function createTenantApiStandIn(o = {}) {
|
|
54
|
+
const now = o.now ?? (() => Date.now());
|
|
55
|
+
const iso = () => new Date(now()).toISOString();
|
|
56
|
+
const scopes = o.scopes ?? [...TENANT_KEY_SCOPES];
|
|
57
|
+
let counter = 0;
|
|
58
|
+
const id = (type) => `ARID:0:global:${type}:01STANDIN${String(++counter).padStart(17, "0")}`;
|
|
59
|
+
const seenJti = new Set();
|
|
60
|
+
const publicKey = o.key ? createPublicKey(createPrivateKey({ key: Buffer.from(fromB64url(parseTenantKey(o.key).pkcs8)), format: "der", type: "pkcs8" })) : null;
|
|
61
|
+
const state = {
|
|
62
|
+
engine: { version: "0.1.0", released_at: "2026-11-09", latest_changeset: 0, site: { docs: "https://engine.example/docs/tenants", changesets: "https://engine.example/changesets" }, sdk: { built_with: SDK_VERSION, minimum: SDK_VERSION }, ...o.engine },
|
|
63
|
+
definitions: { revision: 1, hash: null, source: "repository", auto_apply: "safe", waiting: [], ...o.definitions },
|
|
64
|
+
branding: { source: o.branding?.source ?? "repository", branding: o.branding?.branding ?? {} },
|
|
65
|
+
portal: { source: o.portal?.source ?? "repository", portal: { ...Object.fromEntries(ALL_SWITCHES.map((s) => [s, true])), pages: Object.fromEntries(ALL_PAGES.map((p) => [p, { mode: "portal" }])), ...o.portal?.portal }, redirected: o.portal?.redirected ?? [] },
|
|
66
|
+
changesets: (o.changesets ?? []).map((c) => ({ ...c })),
|
|
67
|
+
feedback: (o.feedback ?? []).map((t) => structuredClone(t)),
|
|
68
|
+
tickets: (o.tickets ?? []).map((t) => structuredClone(t)),
|
|
69
|
+
announcements: (o.announcements?.items ?? []).map((t) => structuredClone(t)),
|
|
70
|
+
platform: o.announcements?.platform ?? [],
|
|
71
|
+
tags: (o.tags ?? []).map((t) => ({ ...t })),
|
|
72
|
+
customerTags: new Map(),
|
|
73
|
+
tiers: { source: "repository", tiers: {}, default_tier: null },
|
|
74
|
+
reports: [],
|
|
75
|
+
};
|
|
76
|
+
const calls = [];
|
|
77
|
+
const submit = o.definitions?.submit ?? "apply";
|
|
78
|
+
/** The assertion, as the Tenant API and the Operations API check it; null when it passes. */
|
|
79
|
+
function refuseAssertion(headers, method, path, body) {
|
|
80
|
+
const m = /^Asturiu-Assertion ([A-Za-z0-9_-]+)\.([A-Za-z0-9_-]+)\.([A-Za-z0-9_-]+)$/.exec(headers.get("authorization") ?? "");
|
|
81
|
+
if (!m)
|
|
82
|
+
return problem(401, "unauthorized", "a signed assertion is required");
|
|
83
|
+
let header;
|
|
84
|
+
let claims;
|
|
85
|
+
try {
|
|
86
|
+
header = b64(m[1]);
|
|
87
|
+
claims = b64(m[2]);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return problem(401, "unauthorized", "a signed assertion is required");
|
|
91
|
+
}
|
|
92
|
+
if (header.alg !== "EdDSA" || typeof header.kid !== "string")
|
|
93
|
+
return problem(401, "unauthorized", "invalid assertion");
|
|
94
|
+
if (o.key) {
|
|
95
|
+
const k = parseTenantKey(o.key);
|
|
96
|
+
// An unknown key or Tenant is nothing to the Engine: 404, as the Operations API answers.
|
|
97
|
+
if (header.kid !== k.kid || claims.iss !== k.slug)
|
|
98
|
+
return problem(404, "not-found", "Not Found");
|
|
99
|
+
if (!verify(null, Buffer.from(`${m[1]}.${m[2]}`), publicKey, Buffer.from(m[3], "base64url")))
|
|
100
|
+
return problem(401, "unauthorized", "invalid signature");
|
|
101
|
+
}
|
|
102
|
+
const t = Math.floor(now() / 1000);
|
|
103
|
+
if (claims.aud !== TENANT_ASSERTION_AUDIENCE)
|
|
104
|
+
return problem(401, "unauthorized", "wrong audience");
|
|
105
|
+
if (claims.htm !== method || claims.htu !== path)
|
|
106
|
+
return problem(401, "unauthorized", "the assertion names another request");
|
|
107
|
+
if (typeof claims.exp !== "number" || typeof claims.iat !== "number" || claims.exp < t || claims.exp - claims.iat > TENANT_ASSERTION_MAX_SECONDS)
|
|
108
|
+
return problem(401, "unauthorized", "assertion expired");
|
|
109
|
+
if (claims.bdh !== createHash("sha256").update(body).digest("base64url"))
|
|
110
|
+
return problem(401, "unauthorized", "the body is not the one signed");
|
|
111
|
+
if (seenJti.has(claims.jti))
|
|
112
|
+
return problem(401, "unauthorized", "assertion already used");
|
|
113
|
+
seenJti.add(claims.jti);
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
async function route(method, path, query, body) {
|
|
117
|
+
const p = path.split("/").slice(3).map(decodeURIComponent); // after /tenant/v0
|
|
118
|
+
const [a, b, c, d] = p;
|
|
119
|
+
if (a === "engine")
|
|
120
|
+
return ok(state.engine);
|
|
121
|
+
if (a === "key") {
|
|
122
|
+
const k = o.key ? parseTenantKey(o.key) : { slug: "acme", kid: "0123456789abcdef" };
|
|
123
|
+
return ok({ id: k.kid, name: "Test key", tenant: k.slug, scopes, created_at: "2026-11-01T00:00:00.000Z", expires_at: new Date(now() + 120 * 86_400_000).toISOString(), ...o.keyRecord });
|
|
124
|
+
}
|
|
125
|
+
if (a === "definitions" && b === "status")
|
|
126
|
+
return ok(state.definitions);
|
|
127
|
+
if (a === "definitions" && method === "POST") {
|
|
128
|
+
if (state.definitions.source !== "repository")
|
|
129
|
+
return problem(409, "definitions-not-repository", "the Definitions are edited in the Admin UI");
|
|
130
|
+
const hash = await definitionSetHash(body ?? {});
|
|
131
|
+
if (hash === state.definitions.hash)
|
|
132
|
+
return ok({ status: "unchanged", hash, revision: state.definitions.revision });
|
|
133
|
+
if (typeof submit === "function")
|
|
134
|
+
return ok(submit(body, hash));
|
|
135
|
+
if (submit === "wait") {
|
|
136
|
+
const plan_id = `plan-${hash.slice(0, 8)}`;
|
|
137
|
+
if (!state.definitions.waiting.some((w) => w.hash === hash))
|
|
138
|
+
state.definitions.waiting.push({ plan_id, hash, created_at: iso() });
|
|
139
|
+
return ok({ status: "waiting", hash, revision: state.definitions.revision, plan_id, summary: { changes: 1, unsafe: 1 }, changes: [{ address: "wallet:example", kind: "wallet", change: "label", effect: "repins", safe: false }], approve_url: `https://admin.example/tenants/acme?tab=definitions&plan=${plan_id}` });
|
|
140
|
+
}
|
|
141
|
+
state.definitions = { ...state.definitions, revision: state.definitions.revision + 1, hash, waiting: [] };
|
|
142
|
+
return ok({ status: "applied", hash, revision: state.definitions.revision, summary: { changes: 1, unsafe: 0 }, changes: [{ address: "wallet:example", kind: "wallet", change: "registered", effect: "creates", safe: true }] });
|
|
143
|
+
}
|
|
144
|
+
for (const tab of ["branding", "portal"]) {
|
|
145
|
+
if (a !== tab)
|
|
146
|
+
continue;
|
|
147
|
+
if (method === "GET")
|
|
148
|
+
return ok(tab === "branding" ? state.branding : state.portal);
|
|
149
|
+
if (state[tab].source !== "repository")
|
|
150
|
+
return problem(409, `${tab}-not-repository`, `the ${tab === "branding" ? "Branding" : "Portal"} tab is edited in the Admin UI`);
|
|
151
|
+
if (tab === "branding") {
|
|
152
|
+
const same = JSON.stringify(state.branding.branding) === JSON.stringify(body);
|
|
153
|
+
state.branding.branding = body;
|
|
154
|
+
return ok({ status: same ? "unchanged" : "applied" });
|
|
155
|
+
}
|
|
156
|
+
const next = { ...Object.fromEntries(ALL_SWITCHES.map((s) => [s, body[s] ?? true])), pages: { ...state.portal.portal.pages, ...(body.pages ?? {}) } };
|
|
157
|
+
const same = JSON.stringify(next) === JSON.stringify(state.portal.portal);
|
|
158
|
+
state.portal.portal = next;
|
|
159
|
+
const kept = state.portal.redirected.filter((pg) => body.pages?.[pg]);
|
|
160
|
+
return ok({ status: same ? "unchanged" : "applied", ...(kept.length ? { kept } : {}) });
|
|
161
|
+
}
|
|
162
|
+
if (a === "tiers") {
|
|
163
|
+
if (method === "GET")
|
|
164
|
+
return ok(state.tiers);
|
|
165
|
+
state.tiers = { ...state.tiers, ...body };
|
|
166
|
+
return ok({ status: "applied" });
|
|
167
|
+
}
|
|
168
|
+
if (a === "subscription")
|
|
169
|
+
return ok({ arid: null, tier: "starter", label: "Starter", state: "active", frozen: false, renews: true, period_end: null, trial_end: null, allowance: { active_customers: 100, storage: 1_000_000_000 }, used: { active_customers: 3, storage: 0 }, overage: null, closing_at: null, features: null });
|
|
170
|
+
if (a === "customers" && c === "entitlement")
|
|
171
|
+
return ok({ customer: b, tier: body?.tier, billing: { status: body?.status ?? "active" } });
|
|
172
|
+
if (a === "customers" && c === "entitlements")
|
|
173
|
+
return ok({ customer: b, tier: null, features: {} });
|
|
174
|
+
if (a === "customers" && c === "tags") {
|
|
175
|
+
const tag = state.tags.find((t) => t.name === d);
|
|
176
|
+
if (!tag)
|
|
177
|
+
return problem(404, "not-found", "Not Found");
|
|
178
|
+
const set = state.customerTags.get(b) ?? new Set();
|
|
179
|
+
state.customerTags.set(b, set);
|
|
180
|
+
if (method === "PUT") {
|
|
181
|
+
const added = !set.has(d);
|
|
182
|
+
set.add(d);
|
|
183
|
+
return ok({ customer: b, tag: d, added });
|
|
184
|
+
}
|
|
185
|
+
const removed = set.delete(d);
|
|
186
|
+
return ok({ customer: b, tag: d, removed });
|
|
187
|
+
}
|
|
188
|
+
if (a === "tags" && !b)
|
|
189
|
+
return ok({ items: state.tags });
|
|
190
|
+
if (a === "tags" && b) {
|
|
191
|
+
const existing = state.tags.find((t) => t.name === b);
|
|
192
|
+
if (existing) {
|
|
193
|
+
Object.assign(existing, body, { updated_at: iso() });
|
|
194
|
+
return ok({ ...existing, created: false });
|
|
195
|
+
}
|
|
196
|
+
const made = { id: `tag-${b}`, name: b, shown: `acme:${b}`, scope: "tenant", subject: "customer", visibility: body?.visibility ?? "staff", description: body?.description ?? "", colour: body?.colour ?? "slate", rules: body?.rules ?? [], effects: body?.effects ?? [], system: false, subjects: 0, created_at: iso(), updated_at: iso() };
|
|
197
|
+
state.tags.push(made);
|
|
198
|
+
return ok({ ...made, created: true }, 201);
|
|
199
|
+
}
|
|
200
|
+
if (a === "changesets" && !b) {
|
|
201
|
+
const since = Number(query.get("since") ?? 0) || 0;
|
|
202
|
+
return ok({ latest: state.engine.latest_changeset || (state.changesets.at(-1)?.number ?? 0), changesets: state.changesets.filter((x) => x.number > since) });
|
|
203
|
+
}
|
|
204
|
+
if (a === "changesets" && c === "status") {
|
|
205
|
+
const cs = state.changesets.find((x) => x.number === Number(b));
|
|
206
|
+
if (!cs || !cs.ticket)
|
|
207
|
+
return problem(404, "not-found", "Not Found");
|
|
208
|
+
if (body?.status === "canceled" && !body.reason)
|
|
209
|
+
return problem(422, "unprocessable", "a canceled changeset needs a reason");
|
|
210
|
+
cs.status = body?.status;
|
|
211
|
+
return ok(cs);
|
|
212
|
+
}
|
|
213
|
+
if (a === "feedback" && !b && method === "POST") {
|
|
214
|
+
state.reports.push(body);
|
|
215
|
+
const arid = id("tkt");
|
|
216
|
+
state.feedback.push(ticket({ arid, subject: body.summary, body: body.detail, primary: "feedback", at: iso() }));
|
|
217
|
+
return ok({ id: arid, received_at: iso() }, 201);
|
|
218
|
+
}
|
|
219
|
+
if (a === "feedback" && !b)
|
|
220
|
+
return ok({ items: state.feedback, next: state.feedback.length ? iso() : null });
|
|
221
|
+
if (a === "feedback" && c === "posts") {
|
|
222
|
+
const t = state.feedback.find((x) => x.arid === b);
|
|
223
|
+
if (!t)
|
|
224
|
+
return problem(404, "not-found", "Not Found");
|
|
225
|
+
t.posts.push(post(iso(), body.body, true, "Your servers"));
|
|
226
|
+
return ok(t, 201);
|
|
227
|
+
}
|
|
228
|
+
if (a === "tickets" && !b && method === "GET") {
|
|
229
|
+
const status = query.get("status");
|
|
230
|
+
return ok({ items: state.tickets.filter((t) => !status || t.status === status).map(({ parties: _p, posts: _q, links: _l, refs: _r, audience: _a, hold_until: _h, closed_at: _c, can: _k, ...summary }) => summary) });
|
|
231
|
+
}
|
|
232
|
+
if (a === "tickets" && !b && method === "POST") {
|
|
233
|
+
if (body?.to !== "platform" && !/^ARID:0:[a-z0-9-]+:cst:/.test(body?.to ?? ""))
|
|
234
|
+
return problem(422, "unprocessable", "to is platform or a Customer of this Tenant");
|
|
235
|
+
const t = ticket({ arid: id("tkt"), subject: body.subject, body: body.body, direction: body.to === "platform" ? "tenant_platform" : "tenant_customer", at: iso(), with_label: body.to === "platform" ? "Asturiu" : (body.to_name ?? "A Customer") });
|
|
236
|
+
state.tickets.push(t);
|
|
237
|
+
return ok(t, 201);
|
|
238
|
+
}
|
|
239
|
+
for (const [family, list] of [["tickets", state.tickets], ["announcements", state.announcements]]) {
|
|
240
|
+
if (a !== family || !b)
|
|
241
|
+
continue;
|
|
242
|
+
const t = list.find((x) => x.arid === b);
|
|
243
|
+
if (!t)
|
|
244
|
+
return problem(404, "not-found", "Not Found");
|
|
245
|
+
if (method === "GET")
|
|
246
|
+
return ok(t);
|
|
247
|
+
if (method === "PATCH") {
|
|
248
|
+
if (body?.status)
|
|
249
|
+
t.status = body.status;
|
|
250
|
+
if (body?.priority)
|
|
251
|
+
t.priority = body.priority;
|
|
252
|
+
if (body?.archived !== undefined)
|
|
253
|
+
t.archived = body.archived;
|
|
254
|
+
t.updated_at = iso();
|
|
255
|
+
return ok(t);
|
|
256
|
+
}
|
|
257
|
+
if (method === "POST" && c === "posts") {
|
|
258
|
+
t.posts.push(post(iso(), body.body, true, "Your servers"));
|
|
259
|
+
return ok(t, 201);
|
|
260
|
+
}
|
|
261
|
+
if (method === "DELETE") {
|
|
262
|
+
if (t.status !== "draft")
|
|
263
|
+
return problem(409, "conflict", "only a draft is deleted; withdraw a published announcement");
|
|
264
|
+
state.announcements.splice(state.announcements.indexOf(t), 1);
|
|
265
|
+
return new Response(null, { status: 204 });
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (a === "announcements" && method === "GET")
|
|
269
|
+
return ok({ items: state.announcements, platform: state.platform });
|
|
270
|
+
if (a === "announcements" && method === "POST") {
|
|
271
|
+
const t = ticket({ arid: id("tkt"), subject: body.subject, body: body.body ?? "", status: "draft", primary: "announcement", direction: "tenant_customers", at: iso(), with_label: "Customers" });
|
|
272
|
+
state.announcements.push(t);
|
|
273
|
+
return ok(t, 201);
|
|
274
|
+
}
|
|
275
|
+
return problem(404, "not-found", "Not Found");
|
|
276
|
+
}
|
|
277
|
+
async function handle(request) {
|
|
278
|
+
const url = new URL(request.url);
|
|
279
|
+
const body = request.method === "GET" || request.method === "HEAD" ? "" : await request.text();
|
|
280
|
+
const record = (status) => calls.push({ method: request.method, path: url.pathname, query: url.search, body: body ? safeJson(body) : undefined, status, sdk_version: /(?:^|\s)asturiu-v0-sdk\/(\S+)/.exec(request.headers.get("user-agent") ?? "")?.[1] ?? null });
|
|
281
|
+
// The Engine site's documents.
|
|
282
|
+
if (!url.pathname.startsWith("/tenant/v0/")) {
|
|
283
|
+
const doc = o.documents?.[url.href];
|
|
284
|
+
record(doc === undefined ? 404 : 200);
|
|
285
|
+
return doc === undefined ? new Response("Not Found", { status: 404 }) : new Response(doc, { status: 200, headers: { "content-type": "text/markdown; charset=utf-8" } });
|
|
286
|
+
}
|
|
287
|
+
const respond = (r) => {
|
|
288
|
+
record(r.status);
|
|
289
|
+
return r;
|
|
290
|
+
};
|
|
291
|
+
if (o.refuse)
|
|
292
|
+
return respond(problem(o.refuse, o.refuse === 401 ? "unauthorized" : "refused", o.refuse === 401 ? "the key was refused" : "refused"));
|
|
293
|
+
const m = matchTenantApiRoute(request.method, url.pathname);
|
|
294
|
+
if (!m || o.missing?.includes(`${m.route.method} ${m.route.path}`))
|
|
295
|
+
return respond(problem(404, "not-found", "Not Found"));
|
|
296
|
+
const refused = refuseAssertion(request.headers, request.method, url.pathname, body);
|
|
297
|
+
if (refused)
|
|
298
|
+
return respond(refused);
|
|
299
|
+
if (!keyReachesRoute(scopes, m.route))
|
|
300
|
+
return respond(problem(404, "not-found", "Not Found"));
|
|
301
|
+
return respond(await route(request.method, url.pathname, url.searchParams, body ? safeJson(body) : undefined));
|
|
302
|
+
}
|
|
303
|
+
const fetch = async (input, init) => {
|
|
304
|
+
if (o.down) {
|
|
305
|
+
const code = typeof o.down === "string" ? o.down : "ECONNREFUSED";
|
|
306
|
+
throw Object.assign(new TypeError("fetch failed"), { cause: Object.assign(new Error(code), { code }) });
|
|
307
|
+
}
|
|
308
|
+
return handle(new Request(input, init));
|
|
309
|
+
};
|
|
310
|
+
return { fetch, handle, state, calls, routes: TENANT_API_ROUTES };
|
|
311
|
+
}
|
|
312
|
+
function safeJson(text) {
|
|
313
|
+
try {
|
|
314
|
+
return JSON.parse(text);
|
|
315
|
+
}
|
|
316
|
+
catch {
|
|
317
|
+
return text;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"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"}
|