@cat-factory/contracts 0.246.0 → 0.247.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/dist/auth.d.ts +1 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/execution.d.ts +8 -0
- package/dist/execution.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/judge.d.ts +31 -0
- package/dist/judge.d.ts.map +1 -1
- package/dist/judge.js +25 -0
- package/dist/judge.js.map +1 -1
- package/dist/pr-report.d.ts +27 -0
- package/dist/pr-report.d.ts.map +1 -1
- package/dist/pr-report.js +7 -1
- package/dist/pr-report.js.map +1 -1
- package/dist/routes/agent-runs.d.ts +8 -0
- package/dist/routes/agent-runs.d.ts.map +1 -1
- package/dist/routes/auth.d.ts +72 -0
- package/dist/routes/auth.d.ts.map +1 -1
- package/dist/routes/auth.js +28 -0
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/bug-hunt.d.ts +8 -0
- package/dist/routes/bug-hunt.d.ts.map +1 -1
- package/dist/routes/execution.d.ts +32 -0
- package/dist/routes/execution.d.ts.map +1 -1
- package/dist/routes/human-review.d.ts +4 -0
- package/dist/routes/human-review.d.ts.map +1 -1
- package/dist/routes/human-test.d.ts +20 -0
- package/dist/routes/human-test.d.ts.map +1 -1
- package/dist/routes/judge.d.ts +8 -0
- package/dist/routes/judge.d.ts.map +1 -1
- package/dist/routes/public-evidence.d.ts +4 -0
- package/dist/routes/public-evidence.d.ts.map +1 -1
- package/dist/routes/visual-confirm.d.ts +12 -0
- package/dist/routes/visual-confirm.d.ts.map +1 -1
- package/dist/routes/workspaces.d.ts +8 -0
- package/dist/routes/workspaces.d.ts.map +1 -1
- package/dist/snapshot.d.ts +4 -0
- package/dist/snapshot.d.ts.map +1 -1
- package/dist/sso.d.ts +70 -0
- package/dist/sso.d.ts.map +1 -0
- package/dist/sso.js +95 -0
- package/dist/sso.js.map +1 -0
- package/package.json +1 -1
package/dist/sso.d.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
/**
|
|
3
|
+
* The SSO protocols the adapter speaks.
|
|
4
|
+
*
|
|
5
|
+
* `oidc` covers every provider that exposes an OpenID Connect discovery document, which is all
|
|
6
|
+
* of the hosted directories and a Shibboleth IdP with the OIDC OP plugin installed. A classic
|
|
7
|
+
* SAML-2.0-only Shibboleth deployment is NOT served by it and is deliberately absent rather
|
|
8
|
+
* than approximated: see `docs/initiatives/enterprise-sso-oidc.md`. Adding `saml` here is what
|
|
9
|
+
* that slice extends, and every switch over this union fails to compile until it is handled.
|
|
10
|
+
*/
|
|
11
|
+
export declare const ssoProtocolSchema: v.PicklistSchema<["oidc"], undefined>;
|
|
12
|
+
export type SsoProtocol = v.InferOutput<typeof ssoProtocolSchema>;
|
|
13
|
+
/**
|
|
14
|
+
* What `GET /auth/config` reports about the configured provider, so the login screen can render
|
|
15
|
+
* the operator's own wording ("Sign in with Acme SSO") instead of a generic button. Present only
|
|
16
|
+
* when SSO is configured; `providers.sso` is the boolean the SPA gates on.
|
|
17
|
+
*/
|
|
18
|
+
export declare const ssoConfigViewSchema: v.ObjectSchema<{
|
|
19
|
+
/** Operator-supplied button label (`AUTH_SSO_LABEL`), never localized — it names their IdP. */
|
|
20
|
+
readonly label: v.StringSchema<undefined>;
|
|
21
|
+
readonly protocol: v.PicklistSchema<["oidc"], undefined>;
|
|
22
|
+
}, undefined>;
|
|
23
|
+
export type SsoConfigView = v.InferOutput<typeof ssoConfigViewSchema>;
|
|
24
|
+
/**
|
|
25
|
+
* Why an SSO sign-in did not produce a session. Each member is a DIFFERENT operator or user
|
|
26
|
+
* action, which is the whole reason the vocabulary is not one `sso_failed`:
|
|
27
|
+
*
|
|
28
|
+
* - `state_invalid` — the round-trip's signed state / browser-binding cookie didn't verify.
|
|
29
|
+
* A stale bookmark, a cookie-less browser, or a genuinely forged callback. Retrying works.
|
|
30
|
+
* - `provider_denied` — the IdP itself refused (`?error=access_denied` …): the user cancelled,
|
|
31
|
+
* or the app is not assigned to them. Nothing on this side to fix.
|
|
32
|
+
* - `exchange_failed` — the code-for-token call failed. A wrong client secret or a
|
|
33
|
+
* `redirect_uri` the IdP does not have registered: an OPERATOR fault, not the user's.
|
|
34
|
+
* - `token_invalid` — the ID token failed verification (signature, issuer, audience, nonce or
|
|
35
|
+
* expiry). A misconfigured client id, a clock skew, or an attack.
|
|
36
|
+
* - `subject_missing` — the token verified but carries no `sub`, so there is no stable identity
|
|
37
|
+
* to key a user on. A non-conforming provider.
|
|
38
|
+
* - `group_required` — the user authenticated but is in none of `AUTH_SSO_REQUIRED_GROUPS`.
|
|
39
|
+
* The user needs a directory group, and the message must say so rather than read as a bug.
|
|
40
|
+
* - `domain_not_allowed` — their verified email's domain is not on
|
|
41
|
+
* `AUTH_SSO_ALLOWED_EMAIL_DOMAINS`. Distinct from `group_required` because the remedy differs.
|
|
42
|
+
* - `email_required` — an email-domain allowlist is configured but the provider released no
|
|
43
|
+
* verified email to check it against, so admission cannot be decided. An operator must
|
|
44
|
+
* release the `email` claim (or drop the allowlist); admitting instead would silently void it.
|
|
45
|
+
* - `provider_unreachable` — the IdP (or the network to it) did not answer while the callback was
|
|
46
|
+
* being settled: its discovery document or key set could not be read. An OUTAGE, distinct from
|
|
47
|
+
* `exchange_failed` because the remedy is not the deployment's own client credentials, and
|
|
48
|
+
* distinct from `token_invalid` because nothing was wrong with the token. Retrying works once
|
|
49
|
+
* the provider does.
|
|
50
|
+
*/
|
|
51
|
+
export declare const ssoErrorReasonSchema: v.PicklistSchema<["state_invalid", "provider_denied", "exchange_failed", "token_invalid", "subject_missing", "group_required", "domain_not_allowed", "email_required", "provider_unreachable"], undefined>;
|
|
52
|
+
export type SsoErrorReason = v.InferOutput<typeof ssoErrorReasonSchema>;
|
|
53
|
+
/** Every reason, for the SPA's exhaustive copy `Record` and the coverage test over it. */
|
|
54
|
+
export declare const SSO_ERROR_REASONS: ["state_invalid", "provider_denied", "exchange_failed", "token_invalid", "subject_missing", "group_required", "domain_not_allowed", "email_required", "provider_unreachable"];
|
|
55
|
+
/**
|
|
56
|
+
* The URL-fragment key a failed SSO round-trip lands under, the sibling of the `token=` key a
|
|
57
|
+
* successful one uses. A FRAGMENT (not a query) for the same reason the token is: it never
|
|
58
|
+
* reaches a server log or a `Referer` header, and the reason names the deployment's admission
|
|
59
|
+
* rules. Shared so the redirect builder and the SPA reader cannot drift.
|
|
60
|
+
*/
|
|
61
|
+
export declare const SSO_ERROR_FRAGMENT_KEY = "sso_error";
|
|
62
|
+
/**
|
|
63
|
+
* Read a reason off an untrusted string, or null when it names none.
|
|
64
|
+
*
|
|
65
|
+
* Total by construction (derived from the picklist's own options), so a member added above is
|
|
66
|
+
* parseable with no edit here — and a value from a NEWER backend than the SPA reads as "unknown
|
|
67
|
+
* failure" rather than being rendered as the literal wire token.
|
|
68
|
+
*/
|
|
69
|
+
export declare function parseSsoErrorReason(value: string | null | undefined): SsoErrorReason | null;
|
|
70
|
+
//# sourceMappingURL=sso.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sso.d.ts","sourceRoot":"","sources":["../src/sso.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAiB5B;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,uCAAuB,CAAA;AACrD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAEjE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;IAC9B,+FAA+F;;;aAG/F,CAAA;AACF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAErE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,oBAAoB,4MAU/B,CAAA;AACF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAEvE,0FAA0F;AAC1F,eAAO,MAAM,iBAAiB,+KAA+B,CAAA;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,cAAc,CAAA;AAEjD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,cAAc,GAAG,IAAI,CAG3F"}
|
package/dist/sso.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Enterprise SSO: the wire vocabulary the backend and the SPA must agree about.
|
|
4
|
+
//
|
|
5
|
+
// Sign-in through a deployment's OWN identity provider (Okta, Entra ID, Auth0, Keycloak,
|
|
6
|
+
// PingFederate, OneLogin, JumpCloud, a Shibboleth IdP running the OIDC OP plugin) rather than
|
|
7
|
+
// through a consumer provider. One generic adapter serves all of them: a discovery document
|
|
8
|
+
// plus a client id/secret is the entire configuration, so there is nothing per-vendor to name
|
|
9
|
+
// here — only the PROTOCOL, which is what a second adapter would extend.
|
|
10
|
+
//
|
|
11
|
+
// A failed SSO round-trip lands the browser back on the SPA with a machine-readable reason in
|
|
12
|
+
// the URL fragment rather than a JSON envelope the user would have to read raw. The backend
|
|
13
|
+
// does not localize prose (CLAUDE.md's i18n rule), so the vocabulary is closed here and the SPA
|
|
14
|
+
// maps each member to translated copy through an exhaustive `Record`.
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
/**
|
|
17
|
+
* The SSO protocols the adapter speaks.
|
|
18
|
+
*
|
|
19
|
+
* `oidc` covers every provider that exposes an OpenID Connect discovery document, which is all
|
|
20
|
+
* of the hosted directories and a Shibboleth IdP with the OIDC OP plugin installed. A classic
|
|
21
|
+
* SAML-2.0-only Shibboleth deployment is NOT served by it and is deliberately absent rather
|
|
22
|
+
* than approximated: see `docs/initiatives/enterprise-sso-oidc.md`. Adding `saml` here is what
|
|
23
|
+
* that slice extends, and every switch over this union fails to compile until it is handled.
|
|
24
|
+
*/
|
|
25
|
+
export const ssoProtocolSchema = v.picklist(['oidc']);
|
|
26
|
+
/**
|
|
27
|
+
* What `GET /auth/config` reports about the configured provider, so the login screen can render
|
|
28
|
+
* the operator's own wording ("Sign in with Acme SSO") instead of a generic button. Present only
|
|
29
|
+
* when SSO is configured; `providers.sso` is the boolean the SPA gates on.
|
|
30
|
+
*/
|
|
31
|
+
export const ssoConfigViewSchema = v.object({
|
|
32
|
+
/** Operator-supplied button label (`AUTH_SSO_LABEL`), never localized — it names their IdP. */
|
|
33
|
+
label: v.string(),
|
|
34
|
+
protocol: ssoProtocolSchema,
|
|
35
|
+
});
|
|
36
|
+
/**
|
|
37
|
+
* Why an SSO sign-in did not produce a session. Each member is a DIFFERENT operator or user
|
|
38
|
+
* action, which is the whole reason the vocabulary is not one `sso_failed`:
|
|
39
|
+
*
|
|
40
|
+
* - `state_invalid` — the round-trip's signed state / browser-binding cookie didn't verify.
|
|
41
|
+
* A stale bookmark, a cookie-less browser, or a genuinely forged callback. Retrying works.
|
|
42
|
+
* - `provider_denied` — the IdP itself refused (`?error=access_denied` …): the user cancelled,
|
|
43
|
+
* or the app is not assigned to them. Nothing on this side to fix.
|
|
44
|
+
* - `exchange_failed` — the code-for-token call failed. A wrong client secret or a
|
|
45
|
+
* `redirect_uri` the IdP does not have registered: an OPERATOR fault, not the user's.
|
|
46
|
+
* - `token_invalid` — the ID token failed verification (signature, issuer, audience, nonce or
|
|
47
|
+
* expiry). A misconfigured client id, a clock skew, or an attack.
|
|
48
|
+
* - `subject_missing` — the token verified but carries no `sub`, so there is no stable identity
|
|
49
|
+
* to key a user on. A non-conforming provider.
|
|
50
|
+
* - `group_required` — the user authenticated but is in none of `AUTH_SSO_REQUIRED_GROUPS`.
|
|
51
|
+
* The user needs a directory group, and the message must say so rather than read as a bug.
|
|
52
|
+
* - `domain_not_allowed` — their verified email's domain is not on
|
|
53
|
+
* `AUTH_SSO_ALLOWED_EMAIL_DOMAINS`. Distinct from `group_required` because the remedy differs.
|
|
54
|
+
* - `email_required` — an email-domain allowlist is configured but the provider released no
|
|
55
|
+
* verified email to check it against, so admission cannot be decided. An operator must
|
|
56
|
+
* release the `email` claim (or drop the allowlist); admitting instead would silently void it.
|
|
57
|
+
* - `provider_unreachable` — the IdP (or the network to it) did not answer while the callback was
|
|
58
|
+
* being settled: its discovery document or key set could not be read. An OUTAGE, distinct from
|
|
59
|
+
* `exchange_failed` because the remedy is not the deployment's own client credentials, and
|
|
60
|
+
* distinct from `token_invalid` because nothing was wrong with the token. Retrying works once
|
|
61
|
+
* the provider does.
|
|
62
|
+
*/
|
|
63
|
+
export const ssoErrorReasonSchema = v.picklist([
|
|
64
|
+
'state_invalid',
|
|
65
|
+
'provider_denied',
|
|
66
|
+
'exchange_failed',
|
|
67
|
+
'token_invalid',
|
|
68
|
+
'subject_missing',
|
|
69
|
+
'group_required',
|
|
70
|
+
'domain_not_allowed',
|
|
71
|
+
'email_required',
|
|
72
|
+
'provider_unreachable',
|
|
73
|
+
]);
|
|
74
|
+
/** Every reason, for the SPA's exhaustive copy `Record` and the coverage test over it. */
|
|
75
|
+
export const SSO_ERROR_REASONS = ssoErrorReasonSchema.options;
|
|
76
|
+
/**
|
|
77
|
+
* The URL-fragment key a failed SSO round-trip lands under, the sibling of the `token=` key a
|
|
78
|
+
* successful one uses. A FRAGMENT (not a query) for the same reason the token is: it never
|
|
79
|
+
* reaches a server log or a `Referer` header, and the reason names the deployment's admission
|
|
80
|
+
* rules. Shared so the redirect builder and the SPA reader cannot drift.
|
|
81
|
+
*/
|
|
82
|
+
export const SSO_ERROR_FRAGMENT_KEY = 'sso_error';
|
|
83
|
+
/**
|
|
84
|
+
* Read a reason off an untrusted string, or null when it names none.
|
|
85
|
+
*
|
|
86
|
+
* Total by construction (derived from the picklist's own options), so a member added above is
|
|
87
|
+
* parseable with no edit here — and a value from a NEWER backend than the SPA reads as "unknown
|
|
88
|
+
* failure" rather than being rendered as the literal wire token.
|
|
89
|
+
*/
|
|
90
|
+
export function parseSsoErrorReason(value) {
|
|
91
|
+
if (!value)
|
|
92
|
+
return null;
|
|
93
|
+
return SSO_ERROR_REASONS.includes(value) ? value : null;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=sso.js.map
|
package/dist/sso.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sso.js","sourceRoot":"","sources":["../src/sso.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B,8EAA8E;AAC9E,gFAAgF;AAChF,EAAE;AACF,yFAAyF;AACzF,8FAA8F;AAC9F,4FAA4F;AAC5F,8FAA8F;AAC9F,yEAAyE;AACzE,EAAE;AACF,8FAA8F;AAC9F,4FAA4F;AAC5F,gGAAgG;AAChG,sEAAsE;AACtE,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;AAGrD;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,+FAA+F;IAC/F,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,QAAQ,EAAE,iBAAiB;CAC5B,CAAC,CAAA;AAGF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,QAAQ,CAAC;IAC7C,eAAe;IACf,iBAAiB;IACjB,iBAAiB;IACjB,eAAe;IACf,iBAAiB;IACjB,gBAAgB;IAChB,oBAAoB;IACpB,gBAAgB;IAChB,sBAAsB;CACvB,CAAC,CAAA;AAGF,0FAA0F;AAC1F,MAAM,CAAC,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,OAAO,CAAA;AAE7D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,WAAW,CAAA;AAEjD;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAgC;IAClE,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,OAAQ,iBAAuC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,KAAwB,CAAC,CAAC,CAAC,IAAI,CAAA;AACpG,CAAC"}
|