@splitin/verification-react 0.1.0-beta.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/LICENSE +21 -0
- package/NOTICE +32 -0
- package/README.md +14 -0
- package/dist/appeal.cjs +63 -0
- package/dist/appeal.cjs.map +1 -0
- package/dist/appeal.d.cts +21 -0
- package/dist/appeal.d.ts +21 -0
- package/dist/appeal.d.ts.map +1 -0
- package/dist/appeal.js +61 -0
- package/dist/appeal.js.map +1 -0
- package/dist/index.cjs +126 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +49 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +118 -0
- package/dist/index.js.map +1 -0
- package/dist/launcher.cjs +501 -0
- package/dist/launcher.cjs.map +1 -0
- package/dist/launcher.d.cts +39 -0
- package/dist/launcher.d.ts +39 -0
- package/dist/launcher.d.ts.map +1 -0
- package/dist/launcher.js +499 -0
- package/dist/launcher.js.map +1 -0
- package/dist/operations.cjs +225 -0
- package/dist/operations.cjs.map +1 -0
- package/dist/operations.d.cts +37 -0
- package/dist/operations.d.ts +37 -0
- package/dist/operations.d.ts.map +1 -0
- package/dist/operations.js +223 -0
- package/dist/operations.js.map +1 -0
- package/dist/retry.cjs +16 -0
- package/dist/retry.cjs.map +1 -0
- package/dist/retry.d.cts +9 -0
- package/dist/retry.d.ts +9 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +14 -0
- package/dist/retry.js.map +1 -0
- package/dist/status.cjs +27 -0
- package/dist/status.cjs.map +1 -0
- package/dist/status.d.cts +8 -0
- package/dist/status.d.ts +8 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +25 -0
- package/dist/status.js.map +1 -0
- package/dist/support.cjs +12 -0
- package/dist/support.cjs.map +1 -0
- package/dist/support.d.cts +8 -0
- package/dist/support.d.ts +8 -0
- package/dist/support.d.ts.map +1 -0
- package/dist/support.js +10 -0
- package/dist/support.js.map +1 -0
- package/package.json +92 -0
- package/src/styles.css +71 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { useState, useCallback, useEffect, useMemo } from 'react';
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
// src/operations/OperationsConsole.tsx
|
|
5
|
+
var TABS = ["health", "routes", "circuits", "attempts", "review", "reconciliation", "redaction", "audit"];
|
|
6
|
+
function OperationsConsole({ client }) {
|
|
7
|
+
const [snapshot, setSnapshot] = useState({ generatedAt: "" });
|
|
8
|
+
const [tab, setTab] = useState("health");
|
|
9
|
+
const [error, setError] = useState(null);
|
|
10
|
+
const [busy, setBusy] = useState(null);
|
|
11
|
+
const headers = useCallback((extra = {}) => {
|
|
12
|
+
const csrf = client.getCsrfToken?.();
|
|
13
|
+
return {
|
|
14
|
+
"Idempotency-Key": client.createIdempotencyKey?.() ?? (globalThis.crypto?.randomUUID?.() ?? `idem_${Date.now()}`),
|
|
15
|
+
...csrf ? { "X-CSRF-Token": csrf } : {},
|
|
16
|
+
...extra
|
|
17
|
+
};
|
|
18
|
+
}, [client]);
|
|
19
|
+
const refresh = useCallback(async () => {
|
|
20
|
+
const [health, routes, circuits, attempts, review, audit, reconciliation, redaction] = await Promise.all([
|
|
21
|
+
client.get("/v1/admin/health"),
|
|
22
|
+
client.get("/v1/admin/routes"),
|
|
23
|
+
client.get("/v1/admin/circuits"),
|
|
24
|
+
client.get("/v1/admin/attempts"),
|
|
25
|
+
client.get("/v1/admin/review"),
|
|
26
|
+
client.get("/v1/admin/audit"),
|
|
27
|
+
client.get("/v1/admin/reconciliation"),
|
|
28
|
+
client.get("/v1/admin/redaction")
|
|
29
|
+
]);
|
|
30
|
+
setSnapshot({
|
|
31
|
+
generatedAt: health.generatedAt,
|
|
32
|
+
runtime: health.runtime,
|
|
33
|
+
health: health.health,
|
|
34
|
+
alerts: health.alerts,
|
|
35
|
+
routes: routes.routes,
|
|
36
|
+
routeChanges: routes.routeChanges,
|
|
37
|
+
circuits: circuits.circuits,
|
|
38
|
+
attempts: attempts.attempts,
|
|
39
|
+
appeals: review.appeals,
|
|
40
|
+
manualExceptions: review.manualExceptions,
|
|
41
|
+
policyVersions: review.policyVersions,
|
|
42
|
+
audit: audit.audit,
|
|
43
|
+
reconciliationJobs: reconciliation.jobs,
|
|
44
|
+
queues: reconciliation.queues,
|
|
45
|
+
privacyRequests: redaction.privacyRequests,
|
|
46
|
+
redactionJobs: redaction.jobs
|
|
47
|
+
});
|
|
48
|
+
}, [client]);
|
|
49
|
+
const mutate = useCallback(async (path, body, key) => {
|
|
50
|
+
setBusy(key);
|
|
51
|
+
try {
|
|
52
|
+
await client.mutate(path, body, headers());
|
|
53
|
+
await refresh();
|
|
54
|
+
setError(null);
|
|
55
|
+
} catch (cause) {
|
|
56
|
+
setError(cause instanceof Error ? cause.message : "The operation could not be completed.");
|
|
57
|
+
} finally {
|
|
58
|
+
setBusy(null);
|
|
59
|
+
}
|
|
60
|
+
}, [client, headers, refresh]);
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
void refresh().catch((cause) => setError(cause instanceof Error ? cause.message : "Operations are unavailable."));
|
|
63
|
+
}, [refresh]);
|
|
64
|
+
const productionEnabled = useMemo(() => (snapshot.runtime ?? []).some((row) => row.provider_environment === "production" && row.enabled === true), [snapshot.runtime]);
|
|
65
|
+
return /* @__PURE__ */ jsxs("main", { className: "siv", children: [
|
|
66
|
+
/* @__PURE__ */ jsxs("header", { className: "siv-header", children: [
|
|
67
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
68
|
+
/* @__PURE__ */ jsx("h1", { className: "siv-title", children: "Identity operations" }),
|
|
69
|
+
/* @__PURE__ */ jsx("p", { className: "siv-copy", children: "Provider health, governed routes, reviews, appeals and privacy queues. Identity documents stay in provider dashboards. Routing policy is never shown to end users." })
|
|
70
|
+
] }),
|
|
71
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "siv-button", onClick: () => void refresh(), children: "Refresh" })
|
|
72
|
+
] }),
|
|
73
|
+
error ? /* @__PURE__ */ jsx("p", { role: "alert", children: error }) : null,
|
|
74
|
+
productionEnabled ? /* @__PURE__ */ jsx("p", { className: "siv-alert", role: "status", children: "Production routing is active. Review routes, approval expiry and provider health." }) : /* @__PURE__ */ jsx("p", { className: "siv-alert", role: "status", children: "Production is fail-closed until runtime enablement and a separately approved policy are both present." }),
|
|
75
|
+
/* @__PURE__ */ jsx("div", { className: "siv-tabs", role: "tablist", "aria-label": "Operations sections", children: TABS.map((item) => /* @__PURE__ */ jsx("button", { type: "button", role: "tab", className: "siv-button siv-tab", "aria-selected": tab === item, onClick: () => setTab(item), children: item }, item)) }),
|
|
76
|
+
tab === "health" ? /* @__PURE__ */ jsx(RecordList, { title: "Provider health", records: [...snapshot.runtime ?? [], ...snapshot.health ?? [], ...snapshot.alerts ?? []], empty: "No runtime, provider-health or alert records." }) : null,
|
|
77
|
+
tab === "routes" ? /* @__PURE__ */ jsxs("section", { children: [
|
|
78
|
+
/* @__PURE__ */ jsx(RouteChangeForm, { busy, currentActorId: client.currentActorId, changes: snapshot.routeChanges ?? [], onMutate: (body, key) => mutate("/v1/admin/routes", body, key) }),
|
|
79
|
+
/* @__PURE__ */ jsx(RecordList, { title: "Routes", records: snapshot.routes ?? [], empty: "No reviewed route policies." })
|
|
80
|
+
] }) : null,
|
|
81
|
+
tab === "circuits" ? /* @__PURE__ */ jsx(CircuitForm, { busy, onSubmit: (body) => mutate("/v1/admin/circuits", body, `circuit:${body.provider}`), records: snapshot.circuits ?? [] }) : null,
|
|
82
|
+
tab === "attempts" ? /* @__PURE__ */ jsx("div", { className: "siv-grid", children: (snapshot.attempts ?? []).map((row) => /* @__PURE__ */ jsxs("article", { className: "siv-record", children: [
|
|
83
|
+
/* @__PURE__ */ jsx("p", { children: String(row.package_code ?? "Verification attempt") }),
|
|
84
|
+
/* @__PURE__ */ jsxs("p", { className: "siv-copy", children: [
|
|
85
|
+
String(row.id),
|
|
86
|
+
" \xB7 ",
|
|
87
|
+
String(row.status)
|
|
88
|
+
] }),
|
|
89
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "siv-button", disabled: Boolean(busy), onClick: () => void mutate("/v1/admin/reconciliation", { attemptId: row.id }, `reconcile:${row.id}`), children: "Reconcile" })
|
|
90
|
+
] }, String(row.id))) }) : null,
|
|
91
|
+
tab === "review" ? /* @__PURE__ */ jsx(ReviewPanel, { snapshot, busy, currentActorId: client.currentActorId, onMutate: (body, key) => mutate("/v1/admin/review", body, key) }) : null,
|
|
92
|
+
tab === "reconciliation" ? /* @__PURE__ */ jsx(RecordList, { title: "Reconciliation", records: snapshot.reconciliationJobs ?? [], empty: "No reconciliation jobs." }) : null,
|
|
93
|
+
tab === "redaction" ? /* @__PURE__ */ jsx("div", { className: "siv-grid", children: (snapshot.privacyRequests ?? []).map((row) => /* @__PURE__ */ jsxs("article", { className: "siv-record", children: [
|
|
94
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
95
|
+
String(row.request_reference ?? "Privacy request"),
|
|
96
|
+
" \xB7 ",
|
|
97
|
+
String(row.status)
|
|
98
|
+
] }),
|
|
99
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "siv-button", disabled: Boolean(busy), onClick: () => void mutate("/v1/admin/redaction", { privacyRequestId: row.id }, `redact:${row.id}`), children: "Approve redaction" })
|
|
100
|
+
] }, String(row.id))) }) : null,
|
|
101
|
+
tab === "audit" ? /* @__PURE__ */ jsx(RecordList, { title: "Audit", records: snapshot.audit ?? [], empty: "No immutable operational audit events." }) : null,
|
|
102
|
+
/* @__PURE__ */ jsxs("p", { className: "siv-copy", children: [
|
|
103
|
+
"Last refreshed ",
|
|
104
|
+
snapshot.generatedAt || "not yet",
|
|
105
|
+
". Raw webhooks, launch secrets and identity documents are never displayed."
|
|
106
|
+
] })
|
|
107
|
+
] });
|
|
108
|
+
}
|
|
109
|
+
function RecordList({ title, records, empty }) {
|
|
110
|
+
if (!records.length) return /* @__PURE__ */ jsx("p", { className: "siv-copy", children: empty });
|
|
111
|
+
return /* @__PURE__ */ jsx("section", { "aria-label": title, className: "siv-grid", children: records.map((row, index) => /* @__PURE__ */ jsxs("article", { className: "siv-record", children: [
|
|
112
|
+
/* @__PURE__ */ jsx("p", { children: String(row.alert_code ?? row.provider ?? row.action ?? row.package_code ?? row.id ?? "Operational record") }),
|
|
113
|
+
/* @__PURE__ */ jsx("p", { className: "siv-copy", children: String(row.status ?? row.lifecycle ?? "") })
|
|
114
|
+
] }, `${row.id ?? index}`)) });
|
|
115
|
+
}
|
|
116
|
+
function RouteChangeForm({ busy, currentActorId, changes, onMutate }) {
|
|
117
|
+
const [targetRoutePolicyId, setTarget] = useState("");
|
|
118
|
+
const [action, setAction] = useState("drain");
|
|
119
|
+
const [reasonCode, setReason] = useState("operator_requested_drain");
|
|
120
|
+
return /* @__PURE__ */ jsxs("div", { className: "siv-grid", children: [
|
|
121
|
+
/* @__PURE__ */ jsxs("form", { className: "siv-record", onSubmit: (event) => {
|
|
122
|
+
event.preventDefault();
|
|
123
|
+
void onMutate({ operation: "propose", targetRoutePolicyId, action, reasonCode }, "propose");
|
|
124
|
+
}, children: [
|
|
125
|
+
/* @__PURE__ */ jsx("h2", { className: "siv-title", children: "Governed route change" }),
|
|
126
|
+
/* @__PURE__ */ jsx("p", { className: "siv-copy", children: "Proposal and approval must be performed by different authorized staff." }),
|
|
127
|
+
/* @__PURE__ */ jsxs("label", { className: "siv-field", children: [
|
|
128
|
+
"Route policy ID",
|
|
129
|
+
/* @__PURE__ */ jsx("input", { className: "siv-input", value: targetRoutePolicyId, onChange: (event) => setTarget(event.target.value) })
|
|
130
|
+
] }),
|
|
131
|
+
/* @__PURE__ */ jsxs("label", { className: "siv-field", children: [
|
|
132
|
+
"Action",
|
|
133
|
+
/* @__PURE__ */ jsxs("select", { className: "siv-select", value: action, onChange: (event) => setAction(event.target.value), children: [
|
|
134
|
+
/* @__PURE__ */ jsx("option", { value: "drain", children: "Drain" }),
|
|
135
|
+
/* @__PURE__ */ jsx("option", { value: "activate", children: "Activate" }),
|
|
136
|
+
/* @__PURE__ */ jsx("option", { value: "rollback", children: "Rollback" })
|
|
137
|
+
] })
|
|
138
|
+
] }),
|
|
139
|
+
/* @__PURE__ */ jsxs("label", { className: "siv-field", children: [
|
|
140
|
+
"Reason code",
|
|
141
|
+
/* @__PURE__ */ jsx("input", { className: "siv-input", value: reasonCode, onChange: (event) => setReason(event.target.value) })
|
|
142
|
+
] }),
|
|
143
|
+
/* @__PURE__ */ jsx("button", { type: "submit", className: "siv-button", disabled: Boolean(busy) || !targetRoutePolicyId, children: "Propose" })
|
|
144
|
+
] }),
|
|
145
|
+
changes.map((row) => {
|
|
146
|
+
const sameProposer = currentActorId && row.proposedBy === currentActorId;
|
|
147
|
+
return /* @__PURE__ */ jsxs("article", { className: "siv-record", children: [
|
|
148
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
149
|
+
String(row.action),
|
|
150
|
+
" \xB7 ",
|
|
151
|
+
String(row.status)
|
|
152
|
+
] }),
|
|
153
|
+
/* @__PURE__ */ jsxs("button", { type: "button", className: "siv-button", disabled: Boolean(busy), onClick: () => void onMutate({ operation: "approve", requestId: row.id }, `approve:${row.id}`), children: [
|
|
154
|
+
"Approve",
|
|
155
|
+
sameProposer ? " (server will enforce separation of duties)" : ""
|
|
156
|
+
] }),
|
|
157
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "siv-button", disabled: Boolean(busy), onClick: () => void onMutate({ operation: "apply", requestId: row.id }, `apply:${row.id}`), children: "Apply" })
|
|
158
|
+
] }, String(row.id));
|
|
159
|
+
})
|
|
160
|
+
] });
|
|
161
|
+
}
|
|
162
|
+
function CircuitForm({ busy, onSubmit, records }) {
|
|
163
|
+
const [provider, setProvider] = useState("test_fake");
|
|
164
|
+
const [providerEnvironment, setEnv] = useState("sandbox");
|
|
165
|
+
const [status, setStatus] = useState("healthy");
|
|
166
|
+
return /* @__PURE__ */ jsxs("section", { children: [
|
|
167
|
+
/* @__PURE__ */ jsxs("form", { className: "siv-record", onSubmit: (event) => {
|
|
168
|
+
event.preventDefault();
|
|
169
|
+
void onSubmit({ provider, providerEnvironment, status });
|
|
170
|
+
}, children: [
|
|
171
|
+
/* @__PURE__ */ jsx("h2", { className: "siv-title", children: "Provider circuit" }),
|
|
172
|
+
/* @__PURE__ */ jsxs("label", { className: "siv-field", children: [
|
|
173
|
+
"Provider",
|
|
174
|
+
/* @__PURE__ */ jsx("input", { className: "siv-input", value: provider, onChange: (event) => setProvider(event.target.value) })
|
|
175
|
+
] }),
|
|
176
|
+
/* @__PURE__ */ jsxs("label", { className: "siv-field", children: [
|
|
177
|
+
"Environment",
|
|
178
|
+
/* @__PURE__ */ jsxs("select", { className: "siv-select", value: providerEnvironment, onChange: (event) => setEnv(event.target.value), children: [
|
|
179
|
+
/* @__PURE__ */ jsx("option", { value: "sandbox", children: "Sandbox" }),
|
|
180
|
+
/* @__PURE__ */ jsx("option", { value: "production", children: "Production" })
|
|
181
|
+
] })
|
|
182
|
+
] }),
|
|
183
|
+
/* @__PURE__ */ jsxs("label", { className: "siv-field", children: [
|
|
184
|
+
"State",
|
|
185
|
+
/* @__PURE__ */ jsxs("select", { className: "siv-select", value: status, onChange: (event) => setStatus(event.target.value), children: [
|
|
186
|
+
/* @__PURE__ */ jsx("option", { value: "healthy", children: "Healthy" }),
|
|
187
|
+
/* @__PURE__ */ jsx("option", { value: "degraded", children: "Degraded" }),
|
|
188
|
+
/* @__PURE__ */ jsx("option", { value: "unavailable", children: "Unavailable" }),
|
|
189
|
+
/* @__PURE__ */ jsx("option", { value: "circuit_open", children: "Circuit open" })
|
|
190
|
+
] })
|
|
191
|
+
] }),
|
|
192
|
+
/* @__PURE__ */ jsx("button", { type: "submit", className: "siv-button", disabled: Boolean(busy), children: "Update circuit" })
|
|
193
|
+
] }),
|
|
194
|
+
/* @__PURE__ */ jsx(RecordList, { title: "Circuits", records, empty: "No circuit records." })
|
|
195
|
+
] });
|
|
196
|
+
}
|
|
197
|
+
function ReviewPanel({ snapshot, busy, currentActorId, onMutate }) {
|
|
198
|
+
return /* @__PURE__ */ jsxs("div", { className: "siv-grid", children: [
|
|
199
|
+
(snapshot.appeals ?? []).map((row) => /* @__PURE__ */ jsxs("article", { className: "siv-record", children: [
|
|
200
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
201
|
+
"Appeal \xB7 ",
|
|
202
|
+
String(row.reason_code ?? "review")
|
|
203
|
+
] }),
|
|
204
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "siv-button", disabled: Boolean(busy), onClick: () => void onMutate({ operation: "begin_appeal_review", appealId: row.id }, `review:${row.id}`), children: "Begin review" })
|
|
205
|
+
] }, `appeal:${row.id}`)),
|
|
206
|
+
(snapshot.manualExceptions ?? []).map((row) => /* @__PURE__ */ jsxs("article", { className: "siv-record", children: [
|
|
207
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
208
|
+
String(row.decision),
|
|
209
|
+
" \xB7 ",
|
|
210
|
+
String(row.status)
|
|
211
|
+
] }),
|
|
212
|
+
/* @__PURE__ */ jsxs("button", { type: "button", className: "siv-button", disabled: Boolean(busy), onClick: () => void onMutate({ operation: "approve_manual_exception", requestId: row.id }, `approve-exc:${row.id}`), children: [
|
|
213
|
+
"Approve",
|
|
214
|
+
currentActorId && row.proposedBy === currentActorId ? " (server will enforce separation of duties)" : ""
|
|
215
|
+
] }),
|
|
216
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "siv-button", disabled: Boolean(busy), onClick: () => void onMutate({ operation: "apply_manual_exception", requestId: row.id }, `apply-exc:${row.id}`), children: "Apply decision" })
|
|
217
|
+
] }, `exc:${row.id}`))
|
|
218
|
+
] });
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export { OperationsConsole };
|
|
222
|
+
//# sourceMappingURL=operations.js.map
|
|
223
|
+
//# sourceMappingURL=operations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/operations/OperationsConsole.tsx"],"names":[],"mappings":"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","file":"operations.js","sourcesContent":["import { useCallback, useEffect, useMemo, useState } from 'react';\n\nexport interface OperationsRecord {\n id?: string;\n [key: string]: string | number | boolean | null | undefined;\n}\n\nexport interface OperationsSnapshot {\n generatedAt: string;\n runtime?: OperationsRecord[];\n health?: OperationsRecord[];\n alerts?: OperationsRecord[];\n routes?: OperationsRecord[];\n routeChanges?: OperationsRecord[];\n circuits?: OperationsRecord[];\n attempts?: OperationsRecord[];\n appeals?: OperationsRecord[];\n manualExceptions?: OperationsRecord[];\n audit?: OperationsRecord[];\n reconciliationJobs?: OperationsRecord[];\n privacyRequests?: OperationsRecord[];\n redactionJobs?: OperationsRecord[];\n policyVersions?: OperationsRecord[];\n queues?: Record<string, number>;\n jobs?: OperationsRecord[];\n}\n\nexport interface OperationsClient {\n get(path: string): Promise<unknown>;\n mutate(path: string, body: unknown, headers: Record<string, string>): Promise<unknown>;\n createIdempotencyKey?: () => string;\n getCsrfToken?: () => string | null;\n currentActorId?: string;\n}\n\nconst TABS = ['health', 'routes', 'circuits', 'attempts', 'review', 'reconciliation', 'redaction', 'audit'] as const;\n\nexport function OperationsConsole({ client }: { client: OperationsClient }) {\n const [snapshot, setSnapshot] = useState<OperationsSnapshot>({ generatedAt: '' });\n const [tab, setTab] = useState<(typeof TABS)[number]>('health');\n const [error, setError] = useState<string | null>(null);\n const [busy, setBusy] = useState<string | null>(null);\n\n const headers = useCallback((extra: Record<string, string> = {}) => {\n const csrf = client.getCsrfToken?.();\n return {\n 'Idempotency-Key': client.createIdempotencyKey?.() ?? (globalThis.crypto?.randomUUID?.() ?? `idem_${Date.now()}`),\n ...(csrf ? { 'X-CSRF-Token': csrf } : {}),\n ...extra,\n };\n }, [client]);\n\n const refresh = useCallback(async () => {\n const [health, routes, circuits, attempts, review, audit, reconciliation, redaction] = await Promise.all([\n client.get('/v1/admin/health') as Promise<OperationsSnapshot>,\n client.get('/v1/admin/routes') as Promise<OperationsSnapshot>,\n client.get('/v1/admin/circuits') as Promise<OperationsSnapshot>,\n client.get('/v1/admin/attempts') as Promise<OperationsSnapshot>,\n client.get('/v1/admin/review') as Promise<OperationsSnapshot>,\n client.get('/v1/admin/audit') as Promise<OperationsSnapshot>,\n client.get('/v1/admin/reconciliation') as Promise<OperationsSnapshot>,\n client.get('/v1/admin/redaction') as Promise<OperationsSnapshot>,\n ]);\n setSnapshot({\n generatedAt: health.generatedAt,\n runtime: health.runtime,\n health: health.health,\n alerts: health.alerts,\n routes: routes.routes,\n routeChanges: routes.routeChanges,\n circuits: circuits.circuits,\n attempts: attempts.attempts,\n appeals: review.appeals,\n manualExceptions: review.manualExceptions,\n policyVersions: review.policyVersions,\n audit: audit.audit,\n reconciliationJobs: reconciliation.jobs as OperationsRecord[] | undefined,\n queues: reconciliation.queues,\n privacyRequests: redaction.privacyRequests,\n redactionJobs: redaction.jobs as OperationsRecord[] | undefined,\n });\n }, [client]);\n\n const mutate = useCallback(async (path: string, body: unknown, key: string) => {\n setBusy(key);\n try {\n await client.mutate(path, body, headers());\n await refresh();\n setError(null);\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : 'The operation could not be completed.');\n } finally {\n setBusy(null);\n }\n }, [client, headers, refresh]);\n\n useEffect(() => { void refresh().catch((cause) => setError(cause instanceof Error ? cause.message : 'Operations are unavailable.')); }, [refresh]);\n\n const productionEnabled = useMemo(() => (snapshot.runtime ?? []).some((row) => row.provider_environment === 'production' && row.enabled === true), [snapshot.runtime]);\n\n return (\n <main className=\"siv\">\n <header className=\"siv-header\">\n <div>\n <h1 className=\"siv-title\">Identity operations</h1>\n <p className=\"siv-copy\">Provider health, governed routes, reviews, appeals and privacy queues. Identity documents stay in provider dashboards. Routing policy is never shown to end users.</p>\n </div>\n <button type=\"button\" className=\"siv-button\" onClick={() => void refresh()}>Refresh</button>\n </header>\n {error ? <p role=\"alert\">{error}</p> : null}\n {productionEnabled\n ? <p className=\"siv-alert\" role=\"status\">Production routing is active. Review routes, approval expiry and provider health.</p>\n : <p className=\"siv-alert\" role=\"status\">Production is fail-closed until runtime enablement and a separately approved policy are both present.</p>}\n\n <div className=\"siv-tabs\" role=\"tablist\" aria-label=\"Operations sections\">\n {TABS.map((item) => (\n <button key={item} type=\"button\" role=\"tab\" className=\"siv-button siv-tab\" aria-selected={tab === item} onClick={() => setTab(item)}>{item}</button>\n ))}\n </div>\n\n {tab === 'health' ? <RecordList title=\"Provider health\" records={[...(snapshot.runtime ?? []), ...(snapshot.health ?? []), ...(snapshot.alerts ?? [])]} empty=\"No runtime, provider-health or alert records.\" /> : null}\n {tab === 'routes' ? (\n <section>\n <RouteChangeForm busy={busy} currentActorId={client.currentActorId} changes={snapshot.routeChanges ?? []} onMutate={(body, key) => mutate('/v1/admin/routes', body, key)} />\n <RecordList title=\"Routes\" records={snapshot.routes ?? []} empty=\"No reviewed route policies.\" />\n </section>\n ) : null}\n {tab === 'circuits' ? <CircuitForm busy={busy} onSubmit={(body) => mutate('/v1/admin/circuits', body, `circuit:${body.provider}`)} records={snapshot.circuits ?? []} /> : null}\n {tab === 'attempts' ? (\n <div className=\"siv-grid\">\n {(snapshot.attempts ?? []).map((row) => (\n <article key={String(row.id)} className=\"siv-record\">\n <p>{String(row.package_code ?? 'Verification attempt')}</p>\n <p className=\"siv-copy\">{String(row.id)} · {String(row.status)}</p>\n <button type=\"button\" className=\"siv-button\" disabled={Boolean(busy)} onClick={() => void mutate('/v1/admin/reconciliation', { attemptId: row.id }, `reconcile:${row.id}`)}>Reconcile</button>\n </article>\n ))}\n </div>\n ) : null}\n {tab === 'review' ? <ReviewPanel snapshot={snapshot} busy={busy} currentActorId={client.currentActorId} onMutate={(body, key) => mutate('/v1/admin/review', body, key)} /> : null}\n {tab === 'reconciliation' ? <RecordList title=\"Reconciliation\" records={snapshot.reconciliationJobs ?? []} empty=\"No reconciliation jobs.\" /> : null}\n {tab === 'redaction' ? (\n <div className=\"siv-grid\">\n {(snapshot.privacyRequests ?? []).map((row) => (\n <article key={String(row.id)} className=\"siv-record\">\n <p>{String(row.request_reference ?? 'Privacy request')} · {String(row.status)}</p>\n <button type=\"button\" className=\"siv-button\" disabled={Boolean(busy)} onClick={() => void mutate('/v1/admin/redaction', { privacyRequestId: row.id }, `redact:${row.id}`)}>Approve redaction</button>\n </article>\n ))}\n </div>\n ) : null}\n {tab === 'audit' ? <RecordList title=\"Audit\" records={snapshot.audit ?? []} empty=\"No immutable operational audit events.\" /> : null}\n <p className=\"siv-copy\">Last refreshed {snapshot.generatedAt || 'not yet'}. Raw webhooks, launch secrets and identity documents are never displayed.</p>\n </main>\n );\n}\n\nfunction RecordList({ title, records, empty }: { title: string; records: OperationsRecord[]; empty: string }) {\n if (!records.length) return <p className=\"siv-copy\">{empty}</p>;\n return (\n <section aria-label={title} className=\"siv-grid\">\n {records.map((row, index) => (\n <article key={`${row.id ?? index}`} className=\"siv-record\">\n <p>{String(row.alert_code ?? row.provider ?? row.action ?? row.package_code ?? row.id ?? 'Operational record')}</p>\n <p className=\"siv-copy\">{String(row.status ?? row.lifecycle ?? '')}</p>\n </article>\n ))}\n </section>\n );\n}\n\nfunction RouteChangeForm({ busy, currentActorId, changes, onMutate }: {\n busy: string | null;\n currentActorId?: string;\n changes: OperationsRecord[];\n onMutate: (body: unknown, key: string) => Promise<void>;\n}) {\n const [targetRoutePolicyId, setTarget] = useState('');\n const [action, setAction] = useState('drain');\n const [reasonCode, setReason] = useState('operator_requested_drain');\n return (\n <div className=\"siv-grid\">\n <form className=\"siv-record\" onSubmit={(event) => { event.preventDefault(); void onMutate({ operation: 'propose', targetRoutePolicyId, action, reasonCode }, 'propose'); }}>\n <h2 className=\"siv-title\">Governed route change</h2>\n <p className=\"siv-copy\">Proposal and approval must be performed by different authorized staff.</p>\n <label className=\"siv-field\">Route policy ID<input className=\"siv-input\" value={targetRoutePolicyId} onChange={(event) => setTarget(event.target.value)} /></label>\n <label className=\"siv-field\">Action\n <select className=\"siv-select\" value={action} onChange={(event) => setAction(event.target.value)}>\n <option value=\"drain\">Drain</option>\n <option value=\"activate\">Activate</option>\n <option value=\"rollback\">Rollback</option>\n </select>\n </label>\n <label className=\"siv-field\">Reason code<input className=\"siv-input\" value={reasonCode} onChange={(event) => setReason(event.target.value)} /></label>\n <button type=\"submit\" className=\"siv-button\" disabled={Boolean(busy) || !targetRoutePolicyId}>Propose</button>\n </form>\n {changes.map((row) => {\n const sameProposer = currentActorId && row.proposedBy === currentActorId;\n return (\n <article key={String(row.id)} className=\"siv-record\">\n <p>{String(row.action)} · {String(row.status)}</p>\n <button type=\"button\" className=\"siv-button\" disabled={Boolean(busy)} onClick={() => void onMutate({ operation: 'approve', requestId: row.id }, `approve:${row.id}`)}>\n Approve{sameProposer ? ' (server will enforce separation of duties)' : ''}\n </button>\n <button type=\"button\" className=\"siv-button\" disabled={Boolean(busy)} onClick={() => void onMutate({ operation: 'apply', requestId: row.id }, `apply:${row.id}`)}>Apply</button>\n </article>\n );\n })}\n </div>\n );\n}\n\nfunction CircuitForm({ busy, onSubmit, records }: {\n busy: string | null;\n records: OperationsRecord[];\n onSubmit: (body: { provider: string; providerEnvironment: string; status: string }) => Promise<void>;\n}) {\n const [provider, setProvider] = useState('test_fake');\n const [providerEnvironment, setEnv] = useState('sandbox');\n const [status, setStatus] = useState('healthy');\n return (\n <section>\n <form className=\"siv-record\" onSubmit={(event) => { event.preventDefault(); void onSubmit({ provider, providerEnvironment, status }); }}>\n <h2 className=\"siv-title\">Provider circuit</h2>\n <label className=\"siv-field\">Provider<input className=\"siv-input\" value={provider} onChange={(event) => setProvider(event.target.value)} /></label>\n <label className=\"siv-field\">Environment\n <select className=\"siv-select\" value={providerEnvironment} onChange={(event) => setEnv(event.target.value)}>\n <option value=\"sandbox\">Sandbox</option>\n <option value=\"production\">Production</option>\n </select>\n </label>\n <label className=\"siv-field\">State\n <select className=\"siv-select\" value={status} onChange={(event) => setStatus(event.target.value)}>\n <option value=\"healthy\">Healthy</option>\n <option value=\"degraded\">Degraded</option>\n <option value=\"unavailable\">Unavailable</option>\n <option value=\"circuit_open\">Circuit open</option>\n </select>\n </label>\n <button type=\"submit\" className=\"siv-button\" disabled={Boolean(busy)}>Update circuit</button>\n </form>\n <RecordList title=\"Circuits\" records={records} empty=\"No circuit records.\" />\n </section>\n );\n}\n\nfunction ReviewPanel({ snapshot, busy, currentActorId, onMutate }: {\n snapshot: OperationsSnapshot;\n busy: string | null;\n currentActorId?: string;\n onMutate: (body: unknown, key: string) => Promise<void>;\n}) {\n return (\n <div className=\"siv-grid\">\n {(snapshot.appeals ?? []).map((row) => (\n <article key={`appeal:${row.id}`} className=\"siv-record\">\n <p>Appeal · {String(row.reason_code ?? 'review')}</p>\n <button type=\"button\" className=\"siv-button\" disabled={Boolean(busy)} onClick={() => void onMutate({ operation: 'begin_appeal_review', appealId: row.id }, `review:${row.id}`)}>Begin review</button>\n </article>\n ))}\n {(snapshot.manualExceptions ?? []).map((row) => (\n <article key={`exc:${row.id}`} className=\"siv-record\">\n <p>{String(row.decision)} · {String(row.status)}</p>\n <button type=\"button\" className=\"siv-button\" disabled={Boolean(busy)} onClick={() => void onMutate({ operation: 'approve_manual_exception', requestId: row.id }, `approve-exc:${row.id}`)}>\n Approve{currentActorId && row.proposedBy === currentActorId ? ' (server will enforce separation of duties)' : ''}\n </button>\n <button type=\"button\" className=\"siv-button\" disabled={Boolean(busy)} onClick={() => void onMutate({ operation: 'apply_manual_exception', requestId: row.id }, `apply-exc:${row.id}`)}>Apply decision</button>\n </article>\n ))}\n </div>\n );\n}\n\nexport default OperationsConsole;\n"]}
|
package/dist/retry.cjs
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
|
|
5
|
+
// src/retry/RetryButton.tsx
|
|
6
|
+
function RetryButton({
|
|
7
|
+
disabled,
|
|
8
|
+
busy,
|
|
9
|
+
onClick
|
|
10
|
+
}) {
|
|
11
|
+
return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "siv-button", onClick, disabled: disabled || busy, "aria-busy": busy || void 0, children: busy ? "Retrying\u2026" : "Retry verification" });
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
exports.RetryButton = RetryButton;
|
|
15
|
+
//# sourceMappingURL=retry.cjs.map
|
|
16
|
+
//# sourceMappingURL=retry.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/retry/RetryButton.tsx"],"names":["jsx"],"mappings":";;;;;AAAO,SAAS,WAAA,CAAY;AAAA,EAC1B,QAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAA,EAIG;AACD,EAAA,uBACEA,cAAA,CAAC,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,WAAU,YAAA,EAAa,OAAA,EAAkB,QAAA,EAAU,QAAA,IAAY,MAAM,WAAA,EAAW,IAAA,IAAQ,MAAA,EAC3G,QAAA,EAAA,IAAA,GAAO,mBAAc,oBAAA,EACxB,CAAA;AAEJ","file":"retry.cjs","sourcesContent":["export function RetryButton({\n disabled,\n busy,\n onClick,\n}: {\n disabled?: boolean;\n busy?: boolean;\n onClick: () => void;\n}) {\n return (\n <button type=\"button\" className=\"siv-button\" onClick={onClick} disabled={disabled || busy} aria-busy={busy || undefined}>\n {busy ? 'Retrying…' : 'Retry verification'}\n </button>\n );\n}\n\nexport default RetryButton;\n"]}
|
package/dist/retry.d.cts
ADDED
package/dist/retry.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sources":["retry.d.ts"],"names":[],"mappings":"AAAA"}
|
package/dist/retry.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
// src/retry/RetryButton.tsx
|
|
4
|
+
function RetryButton({
|
|
5
|
+
disabled,
|
|
6
|
+
busy,
|
|
7
|
+
onClick
|
|
8
|
+
}) {
|
|
9
|
+
return /* @__PURE__ */ jsx("button", { type: "button", className: "siv-button", onClick, disabled: disabled || busy, "aria-busy": busy || void 0, children: busy ? "Retrying\u2026" : "Retry verification" });
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { RetryButton };
|
|
13
|
+
//# sourceMappingURL=retry.js.map
|
|
14
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/retry/RetryButton.tsx"],"names":[],"mappings":";;;AAAO,SAAS,WAAA,CAAY;AAAA,EAC1B,QAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAA,EAIG;AACD,EAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,WAAU,YAAA,EAAa,OAAA,EAAkB,QAAA,EAAU,QAAA,IAAY,MAAM,WAAA,EAAW,IAAA,IAAQ,MAAA,EAC3G,QAAA,EAAA,IAAA,GAAO,mBAAc,oBAAA,EACxB,CAAA;AAEJ","file":"retry.js","sourcesContent":["export function RetryButton({\n disabled,\n busy,\n onClick,\n}: {\n disabled?: boolean;\n busy?: boolean;\n onClick: () => void;\n}) {\n return (\n <button type=\"button\" className=\"siv-button\" onClick={onClick} disabled={disabled || busy} aria-busy={busy || undefined}>\n {busy ? 'Retrying…' : 'Retry verification'}\n </button>\n );\n}\n\nexport default RetryButton;\n"]}
|
package/dist/status.cjs
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
|
|
5
|
+
// src/hooks/status.ts
|
|
6
|
+
function useVerificationStatus(envelope) {
|
|
7
|
+
const blocked = envelope?.status === "processing" || envelope?.status === "manual_review_required";
|
|
8
|
+
const unavailable = envelope?.status === "provider_unavailable";
|
|
9
|
+
const terminal = envelope != null && ["verified", "declined", "failed", "expired", "canceled", "redacted"].includes(envelope.status);
|
|
10
|
+
return { blocked, unavailable, terminal, status: envelope?.status ?? "created", disclosure: envelope?.providerDisclosure ?? null };
|
|
11
|
+
}
|
|
12
|
+
function VerificationStatus({ envelope }) {
|
|
13
|
+
const state = useVerificationStatus(envelope);
|
|
14
|
+
if (!envelope) return /* @__PURE__ */ jsxRuntime.jsx("p", { className: "siv-copy", role: "status", children: "Verification has not started." });
|
|
15
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "siv siv-record", "aria-label": "Verification status", children: [
|
|
16
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { role: "status", "aria-live": "polite", children: [
|
|
17
|
+
"Status: ",
|
|
18
|
+
state.status.replace(/_/g, " ")
|
|
19
|
+
] }),
|
|
20
|
+
state.disclosure ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "siv-disclosure", children: state.disclosure }) : null,
|
|
21
|
+
state.blocked ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "siv-copy", children: "This protected action stays blocked until a server-side decision arrives." }) : null
|
|
22
|
+
] });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
exports.VerificationStatus = VerificationStatus;
|
|
26
|
+
//# sourceMappingURL=status.cjs.map
|
|
27
|
+
//# sourceMappingURL=status.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/status.ts","../src/status/VerificationStatus.tsx"],"names":["jsx","jsxs"],"mappings":";;;;;AAEO,SAAS,sBAAsB,QAAA,EAA6C;AACjF,EAAA,MAAM,OAAA,GAAU,QAAA,EAAU,MAAA,KAAW,YAAA,IAAgB,UAAU,MAAA,KAAW,wBAAA;AAC1E,EAAA,MAAM,WAAA,GAAc,UAAU,MAAA,KAAW,sBAAA;AACzC,EAAA,MAAM,QAAA,GAAW,QAAA,IAAY,IAAA,IAAQ,CAAC,UAAA,EAAY,UAAA,EAAY,QAAA,EAAU,SAAA,EAAW,UAAA,EAAY,UAAU,CAAA,CAAE,QAAA,CAAS,SAAS,MAAM,CAAA;AACnI,EAAA,OAAO,EAAE,OAAA,EAAS,WAAA,EAAa,QAAA,EAAU,MAAA,EAAQ,QAAA,EAAU,MAAA,IAAU,SAAA,EAAW,UAAA,EAAY,QAAA,EAAU,kBAAA,IAAsB,IAAA,EAAK;AACnI;ACHO,SAAS,kBAAA,CAAmB,EAAE,QAAA,EAAS,EAAoD;AAChG,EAAA,MAAM,KAAA,GAAQ,sBAAsB,QAAQ,CAAA;AAC5C,EAAA,IAAI,CAAC,UAAU,uBAAOA,cAAA,CAAC,OAAE,SAAA,EAAU,UAAA,EAAW,IAAA,EAAK,QAAA,EAAS,QAAA,EAAA,+BAAA,EAA6B,CAAA;AACzF,EAAA,uBACEC,eAAA,CAAC,SAAA,EAAA,EAAQ,SAAA,EAAU,gBAAA,EAAiB,cAAW,qBAAA,EAC7C,QAAA,EAAA;AAAA,oBAAAA,eAAA,CAAC,GAAA,EAAA,EAAE,IAAA,EAAK,QAAA,EAAS,WAAA,EAAU,QAAA,EAAS,QAAA,EAAA;AAAA,MAAA,UAAA;AAAA,MACzB,KAAA,CAAM,MAAA,CAAO,OAAA,CAAQ,IAAA,EAAM,GAAG;AAAA,KAAA,EACzC,CAAA;AAAA,IACC,KAAA,CAAM,6BAAaD,cAAA,CAAC,GAAA,EAAA,EAAE,WAAU,gBAAA,EAAkB,QAAA,EAAA,KAAA,CAAM,YAAW,CAAA,GAAO,IAAA;AAAA,IAC1E,MAAM,OAAA,mBAAUA,cAAA,CAAC,OAAE,SAAA,EAAU,UAAA,EAAW,uFAAyE,CAAA,GAAO;AAAA,GAAA,EAC3H,CAAA;AAEJ","file":"status.cjs","sourcesContent":["import type { VerificationStatusEnvelope } from '@splitin/verification-web';\n\nexport function useVerificationStatus(envelope: VerificationStatusEnvelope | null) {\n const blocked = envelope?.status === 'processing' || envelope?.status === 'manual_review_required';\n const unavailable = envelope?.status === 'provider_unavailable';\n const terminal = envelope != null && ['verified', 'declined', 'failed', 'expired', 'canceled', 'redacted'].includes(envelope.status);\n return { blocked, unavailable, terminal, status: envelope?.status ?? 'created', disclosure: envelope?.providerDisclosure ?? null };\n}\n","import type { VerificationStatusEnvelope } from '@splitin/verification-web';\n\nimport { useVerificationStatus } from '../hooks/status.ts';\n\nexport function VerificationStatus({ envelope }: { envelope: VerificationStatusEnvelope | null }) {\n const state = useVerificationStatus(envelope);\n if (!envelope) return <p className=\"siv-copy\" role=\"status\">Verification has not started.</p>;\n return (\n <section className=\"siv siv-record\" aria-label=\"Verification status\">\n <p role=\"status\" aria-live=\"polite\">\n Status: {state.status.replace(/_/g, ' ')}\n </p>\n {state.disclosure ? <p className=\"siv-disclosure\">{state.disclosure}</p> : null}\n {state.blocked ? <p className=\"siv-copy\">This protected action stays blocked until a server-side decision arrives.</p> : null}\n </section>\n );\n}\n\nexport default VerificationStatus;\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { VerificationStatusEnvelope } from '@splitin/verification-web';
|
|
3
|
+
|
|
4
|
+
declare function VerificationStatus({ envelope }: {
|
|
5
|
+
envelope: VerificationStatusEnvelope | null;
|
|
6
|
+
}): react.JSX.Element;
|
|
7
|
+
|
|
8
|
+
export { VerificationStatus };
|
package/dist/status.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { VerificationStatusEnvelope } from '@splitin/verification-web';
|
|
3
|
+
|
|
4
|
+
declare function VerificationStatus({ envelope }: {
|
|
5
|
+
envelope: VerificationStatusEnvelope | null;
|
|
6
|
+
}): react.JSX.Element;
|
|
7
|
+
|
|
8
|
+
export { VerificationStatus };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sources":["status.d.ts"],"names":[],"mappings":"AAAA"}
|
package/dist/status.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
// src/hooks/status.ts
|
|
4
|
+
function useVerificationStatus(envelope) {
|
|
5
|
+
const blocked = envelope?.status === "processing" || envelope?.status === "manual_review_required";
|
|
6
|
+
const unavailable = envelope?.status === "provider_unavailable";
|
|
7
|
+
const terminal = envelope != null && ["verified", "declined", "failed", "expired", "canceled", "redacted"].includes(envelope.status);
|
|
8
|
+
return { blocked, unavailable, terminal, status: envelope?.status ?? "created", disclosure: envelope?.providerDisclosure ?? null };
|
|
9
|
+
}
|
|
10
|
+
function VerificationStatus({ envelope }) {
|
|
11
|
+
const state = useVerificationStatus(envelope);
|
|
12
|
+
if (!envelope) return /* @__PURE__ */ jsx("p", { className: "siv-copy", role: "status", children: "Verification has not started." });
|
|
13
|
+
return /* @__PURE__ */ jsxs("section", { className: "siv siv-record", "aria-label": "Verification status", children: [
|
|
14
|
+
/* @__PURE__ */ jsxs("p", { role: "status", "aria-live": "polite", children: [
|
|
15
|
+
"Status: ",
|
|
16
|
+
state.status.replace(/_/g, " ")
|
|
17
|
+
] }),
|
|
18
|
+
state.disclosure ? /* @__PURE__ */ jsx("p", { className: "siv-disclosure", children: state.disclosure }) : null,
|
|
19
|
+
state.blocked ? /* @__PURE__ */ jsx("p", { className: "siv-copy", children: "This protected action stays blocked until a server-side decision arrives." }) : null
|
|
20
|
+
] });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { VerificationStatus };
|
|
24
|
+
//# sourceMappingURL=status.js.map
|
|
25
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/status.ts","../src/status/VerificationStatus.tsx"],"names":[],"mappings":";;;AAEO,SAAS,sBAAsB,QAAA,EAA6C;AACjF,EAAA,MAAM,OAAA,GAAU,QAAA,EAAU,MAAA,KAAW,YAAA,IAAgB,UAAU,MAAA,KAAW,wBAAA;AAC1E,EAAA,MAAM,WAAA,GAAc,UAAU,MAAA,KAAW,sBAAA;AACzC,EAAA,MAAM,QAAA,GAAW,QAAA,IAAY,IAAA,IAAQ,CAAC,UAAA,EAAY,UAAA,EAAY,QAAA,EAAU,SAAA,EAAW,UAAA,EAAY,UAAU,CAAA,CAAE,QAAA,CAAS,SAAS,MAAM,CAAA;AACnI,EAAA,OAAO,EAAE,OAAA,EAAS,WAAA,EAAa,QAAA,EAAU,MAAA,EAAQ,QAAA,EAAU,MAAA,IAAU,SAAA,EAAW,UAAA,EAAY,QAAA,EAAU,kBAAA,IAAsB,IAAA,EAAK;AACnI;ACHO,SAAS,kBAAA,CAAmB,EAAE,QAAA,EAAS,EAAoD;AAChG,EAAA,MAAM,KAAA,GAAQ,sBAAsB,QAAQ,CAAA;AAC5C,EAAA,IAAI,CAAC,UAAU,uBAAO,GAAA,CAAC,OAAE,SAAA,EAAU,UAAA,EAAW,IAAA,EAAK,QAAA,EAAS,QAAA,EAAA,+BAAA,EAA6B,CAAA;AACzF,EAAA,uBACE,IAAA,CAAC,SAAA,EAAA,EAAQ,SAAA,EAAU,gBAAA,EAAiB,cAAW,qBAAA,EAC7C,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,GAAA,EAAA,EAAE,IAAA,EAAK,QAAA,EAAS,WAAA,EAAU,QAAA,EAAS,QAAA,EAAA;AAAA,MAAA,UAAA;AAAA,MACzB,KAAA,CAAM,MAAA,CAAO,OAAA,CAAQ,IAAA,EAAM,GAAG;AAAA,KAAA,EACzC,CAAA;AAAA,IACC,KAAA,CAAM,6BAAa,GAAA,CAAC,GAAA,EAAA,EAAE,WAAU,gBAAA,EAAkB,QAAA,EAAA,KAAA,CAAM,YAAW,CAAA,GAAO,IAAA;AAAA,IAC1E,MAAM,OAAA,mBAAU,GAAA,CAAC,OAAE,SAAA,EAAU,UAAA,EAAW,uFAAyE,CAAA,GAAO;AAAA,GAAA,EAC3H,CAAA;AAEJ","file":"status.js","sourcesContent":["import type { VerificationStatusEnvelope } from '@splitin/verification-web';\n\nexport function useVerificationStatus(envelope: VerificationStatusEnvelope | null) {\n const blocked = envelope?.status === 'processing' || envelope?.status === 'manual_review_required';\n const unavailable = envelope?.status === 'provider_unavailable';\n const terminal = envelope != null && ['verified', 'declined', 'failed', 'expired', 'canceled', 'redacted'].includes(envelope.status);\n return { blocked, unavailable, terminal, status: envelope?.status ?? 'created', disclosure: envelope?.providerDisclosure ?? null };\n}\n","import type { VerificationStatusEnvelope } from '@splitin/verification-web';\n\nimport { useVerificationStatus } from '../hooks/status.ts';\n\nexport function VerificationStatus({ envelope }: { envelope: VerificationStatusEnvelope | null }) {\n const state = useVerificationStatus(envelope);\n if (!envelope) return <p className=\"siv-copy\" role=\"status\">Verification has not started.</p>;\n return (\n <section className=\"siv siv-record\" aria-label=\"Verification status\">\n <p role=\"status\" aria-live=\"polite\">\n Status: {state.status.replace(/_/g, ' ')}\n </p>\n {state.disclosure ? <p className=\"siv-disclosure\">{state.disclosure}</p> : null}\n {state.blocked ? <p className=\"siv-copy\">This protected action stays blocked until a server-side decision arrives.</p> : null}\n </section>\n );\n}\n\nexport default VerificationStatus;\n"]}
|
package/dist/support.cjs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
|
|
5
|
+
// src/support/SupportLink.tsx
|
|
6
|
+
function SupportLink({ href = "/support/verification", children = "Contact support" }) {
|
|
7
|
+
return /* @__PURE__ */ jsxRuntime.jsx("a", { className: "siv-link", href, rel: "noopener noreferrer", children });
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
exports.SupportLink = SupportLink;
|
|
11
|
+
//# sourceMappingURL=support.cjs.map
|
|
12
|
+
//# sourceMappingURL=support.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/support/SupportLink.tsx"],"names":[],"mappings":";;;;;AAAO,SAAS,YAAY,EAAE,IAAA,GAAO,uBAAA,EAAyB,QAAA,GAAW,mBAAkB,EAGxF;AACD,EAAA,sCACG,GAAA,EAAA,EAAE,SAAA,EAAU,YAAW,IAAA,EAAY,GAAA,EAAI,uBACrC,QAAA,EACH,CAAA;AAEJ","file":"support.cjs","sourcesContent":["export function SupportLink({ href = '/support/verification', children = 'Contact support' }: {\n href?: string;\n children?: string;\n}) {\n return (\n <a className=\"siv-link\" href={href} rel=\"noopener noreferrer\">\n {children}\n </a>\n );\n}\n\nexport default SupportLink;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"support.d.ts","sources":["support.d.ts"],"names":[],"mappings":"AAAA"}
|
package/dist/support.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
// src/support/SupportLink.tsx
|
|
4
|
+
function SupportLink({ href = "/support/verification", children = "Contact support" }) {
|
|
5
|
+
return /* @__PURE__ */ jsx("a", { className: "siv-link", href, rel: "noopener noreferrer", children });
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export { SupportLink };
|
|
9
|
+
//# sourceMappingURL=support.js.map
|
|
10
|
+
//# sourceMappingURL=support.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/support/SupportLink.tsx"],"names":[],"mappings":";;;AAAO,SAAS,YAAY,EAAE,IAAA,GAAO,uBAAA,EAAyB,QAAA,GAAW,mBAAkB,EAGxF;AACD,EAAA,2BACG,GAAA,EAAA,EAAE,SAAA,EAAU,YAAW,IAAA,EAAY,GAAA,EAAI,uBACrC,QAAA,EACH,CAAA;AAEJ","file":"support.js","sourcesContent":["export function SupportLink({ href = '/support/verification', children = 'Contact support' }: {\n href?: string;\n children?: string;\n}) {\n return (\n <a className=\"siv-link\" href={href} rel=\"noopener noreferrer\">\n {children}\n </a>\n );\n}\n\nexport default SupportLink;\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@splitin/verification-react",
|
|
3
|
+
"version": "0.1.0-beta.0",
|
|
4
|
+
"description": "Accessible React hooks and components for verification launch, status, appeals, and operations.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "SplitInTech, @ojchavan",
|
|
7
|
+
"homepage": "https://github.com/splitintech/open-internal-tools/tree/main/verification-adapter-sdk/packages/verification-react#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/splitintech/open-internal-tools.git",
|
|
11
|
+
"directory": "verification-adapter-sdk/packages/verification-react"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"sideEffects": ["./dist/styles.css", "./src/styles.css"],
|
|
15
|
+
"engines": { "node": ">=20" },
|
|
16
|
+
"main": "./dist/index.cjs",
|
|
17
|
+
"module": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js",
|
|
23
|
+
"require": "./dist/index.cjs"
|
|
24
|
+
},
|
|
25
|
+
"./launcher": {
|
|
26
|
+
"types": "./dist/launcher.d.ts",
|
|
27
|
+
"import": "./dist/launcher.js",
|
|
28
|
+
"require": "./dist/launcher.cjs"
|
|
29
|
+
},
|
|
30
|
+
"./status": {
|
|
31
|
+
"types": "./dist/status.d.ts",
|
|
32
|
+
"import": "./dist/status.js",
|
|
33
|
+
"require": "./dist/status.cjs"
|
|
34
|
+
},
|
|
35
|
+
"./retry": {
|
|
36
|
+
"types": "./dist/retry.d.ts",
|
|
37
|
+
"import": "./dist/retry.js",
|
|
38
|
+
"require": "./dist/retry.cjs"
|
|
39
|
+
},
|
|
40
|
+
"./appeal": {
|
|
41
|
+
"types": "./dist/appeal.d.ts",
|
|
42
|
+
"import": "./dist/appeal.js",
|
|
43
|
+
"require": "./dist/appeal.cjs"
|
|
44
|
+
},
|
|
45
|
+
"./support": {
|
|
46
|
+
"types": "./dist/support.d.ts",
|
|
47
|
+
"import": "./dist/support.js",
|
|
48
|
+
"require": "./dist/support.cjs"
|
|
49
|
+
},
|
|
50
|
+
"./operations": {
|
|
51
|
+
"types": "./dist/operations.d.ts",
|
|
52
|
+
"import": "./dist/operations.js",
|
|
53
|
+
"require": "./dist/operations.cjs"
|
|
54
|
+
},
|
|
55
|
+
"./styles.css": "./src/styles.css"
|
|
56
|
+
},
|
|
57
|
+
"files": ["dist", "src/styles.css", "LICENSE", "NOTICE", "README.md", "package.json"],
|
|
58
|
+
"publishConfig": { "access": "public" },
|
|
59
|
+
"scripts": {
|
|
60
|
+
"build": "tsup",
|
|
61
|
+
"test": "vitest run",
|
|
62
|
+
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
63
|
+
},
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"@splitin/verification-adapter-sdk": "0.1.0-beta.0",
|
|
66
|
+
"@splitin/verification-web": "0.1.0-beta.0"
|
|
67
|
+
},
|
|
68
|
+
"peerDependencies": {
|
|
69
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
70
|
+
"react-dom": "^18.0.0 || ^19.0.0",
|
|
71
|
+
"@stripe/stripe-js": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0",
|
|
72
|
+
"persona": ">=4.0.0",
|
|
73
|
+
"react-plaid-link": "^3.5.0 || ^4.0.0"
|
|
74
|
+
},
|
|
75
|
+
"peerDependenciesMeta": {
|
|
76
|
+
"@stripe/stripe-js": { "optional": true },
|
|
77
|
+
"persona": { "optional": true },
|
|
78
|
+
"react-plaid-link": { "optional": true }
|
|
79
|
+
},
|
|
80
|
+
"devDependencies": {
|
|
81
|
+
"@testing-library/jest-dom": "^6.6.3",
|
|
82
|
+
"@testing-library/react": "^16.3.0",
|
|
83
|
+
"@types/react": "^19.1.6",
|
|
84
|
+
"@types/react-dom": "^19.1.5",
|
|
85
|
+
"jsdom": "^26.1.0",
|
|
86
|
+
"react": "^19.1.0",
|
|
87
|
+
"react-dom": "^19.1.0",
|
|
88
|
+
"tsup": "^8.5.0",
|
|
89
|
+
"typescript": "^5.8.3",
|
|
90
|
+
"vitest": "^3.2.4"
|
|
91
|
+
}
|
|
92
|
+
}
|