@k9o/gate 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 +41 -0
- package/LICENSE +201 -0
- package/NOTICE +4 -0
- package/README.md +110 -2
- package/dist/chunk-LZQ7MBXS.js +41 -0
- package/dist/chunk-LZQ7MBXS.js.map +1 -0
- package/dist/chunk-PEW6HZFB.js +51 -0
- package/dist/chunk-PEW6HZFB.js.map +1 -0
- package/dist/chunk-ZNFI2CQA.js +125 -0
- package/dist/chunk-ZNFI2CQA.js.map +1 -0
- package/dist/errors.d.ts +55 -0
- package/dist/errors.js +9 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +717 -0
- package/dist/index.js +614 -0
- package/dist/index.js.map +1 -0
- package/dist/jwt.d.ts +84 -0
- package/dist/jwt.js +12 -0
- package/dist/jwt.js.map +1 -0
- package/dist/mode.d.ts +82 -0
- package/dist/mode.js +13 -0
- package/dist/mode.js.map +1 -0
- package/dist/types.d.ts +250 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/package.json +59 -4
- package/src/client-factory.ts +39 -0
- package/src/client.ts +175 -0
- package/src/errors.ts +117 -0
- package/src/gate.ts +385 -0
- package/src/idp-providers/identity-providers.ts +244 -0
- package/src/index.ts +62 -0
- package/src/jwt.ts +229 -0
- package/src/magic-link-redirects.ts +103 -0
- package/src/mode.ts +115 -0
- package/src/paths.ts +21 -0
- package/src/region.ts +85 -0
- package/src/types.ts +264 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,717 @@
|
|
|
1
|
+
import { GateConfig } from './mode.js';
|
|
2
|
+
export { GateMode, configureGate, getGateConfig, resetGateConfig } from './mode.js';
|
|
3
|
+
import { Envelope, SignUpInput, AuthResult, SignInInput, SignOutInput, WhoamiResult, RefreshTokenInput, VerifySessionResult, HostedGateInfo, SignInCallbackResult, RequestOtpInput, VerifyOtpInput, RequestMagicLinkInput, VerifyMagicLinkInput, MagicLinkCallbackResult } from './types.js';
|
|
4
|
+
export { EndUser, GateJwtClaims, OtpPurpose, Session, VerifyJwtFailure, VerifyJwtResult } from './types.js';
|
|
5
|
+
export { VerifyJwtOptions, extractClaims, requireScope, verifyJwt } from './jwt.js';
|
|
6
|
+
export { GateError, GateErrorCode, KErrorWire, gateErrorFromWire } from './errors.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* `gate.magicLinkRedirects` sub-namespace — the per-project magic-link
|
|
10
|
+
* redirect-URL allowlist, PROJECT_ADMIN+ managed. Blessed shape (
|
|
11
|
+
* 2026-07-16): `list()`/`add()`/`remove()`, mirroring the
|
|
12
|
+
* `gate.idpProviders.*` sub-namespace convention (gate-admin surface,
|
|
13
|
+
* not the end-user-facing `passwordless.*` send/verify flow).
|
|
14
|
+
*
|
|
15
|
+
* Wraps the live gateway routes (`services/gateway/src/routes/
|
|
16
|
+
* gate-magic-link-redirects.ts`):
|
|
17
|
+
*
|
|
18
|
+
* GET /@<projectSlug>/gate/magic-link-redirects
|
|
19
|
+
* POST /@<projectSlug>/gate/magic-link-redirects { redirectUrl, isDefault? }
|
|
20
|
+
* DELETE /@<projectSlug>/gate/magic-link-redirects/:id
|
|
21
|
+
*
|
|
22
|
+
* One deliberate deviation from the shorthand in the original blessing
|
|
23
|
+
* relay ("remove(redirectUrl)"): the shipped route deletes by the
|
|
24
|
+
* redirect row's `id`, not by re-presenting its `redirectUrl` value —
|
|
25
|
+
* verified directly against the route, not assumed from the relay's
|
|
26
|
+
* informal shape sketch. `remove(id)` matches what the gateway actually
|
|
27
|
+
* does; a `redirectUrl`-keyed removal would need an extra `list()`
|
|
28
|
+
* round-trip to resolve the id first, which the SDK should not do
|
|
29
|
+
* silently on the caller's behalf.
|
|
30
|
+
*
|
|
31
|
+
* Auth: operator JWT with PROJECT_ADMIN+ (or ORG_ADMIN/ORG_OWNER) role —
|
|
32
|
+
* the gateway rejects end-user JWTs and lower-role operators alike
|
|
33
|
+
* (K9O_RBAC_DENY). The allowlist is a security control: registering a
|
|
34
|
+
* redirect target is an admin act, same posture as `idpProviders.*`.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/** A single allowlisted magic-link redirect target. */
|
|
38
|
+
type MagicLinkRedirect = {
|
|
39
|
+
id: string;
|
|
40
|
+
redirectUrl: string;
|
|
41
|
+
isDefault: boolean;
|
|
42
|
+
createdAt: string;
|
|
43
|
+
};
|
|
44
|
+
type AddMagicLinkRedirectInput = {
|
|
45
|
+
redirectUrl: string;
|
|
46
|
+
/**
|
|
47
|
+
* When true, this target becomes the default the gateway falls back to
|
|
48
|
+
* when a `requestMagicLink` call doesn't specify one. The gateway
|
|
49
|
+
* atomically demotes any previously-default entry — never two
|
|
50
|
+
* simultaneous defaults.
|
|
51
|
+
*/
|
|
52
|
+
isDefault?: boolean;
|
|
53
|
+
};
|
|
54
|
+
type RemoveMagicLinkRedirectResult = {
|
|
55
|
+
removed: true;
|
|
56
|
+
id: string;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* `gate.identityProviders` namespace — project-scoped end-user IdP
|
|
61
|
+
* provider-config management (ch04 §1.6).
|
|
62
|
+
*
|
|
63
|
+
* Wraps the live gateway route family shipped in
|
|
64
|
+
* `services/gateway/src/routes/project-identity-providers.ts`, mounted on
|
|
65
|
+
* the project plane (`<orgSlug>.api.k9o.io/@<projectSlug>/identity-providers`):
|
|
66
|
+
*
|
|
67
|
+
* POST /@<projectSlug>/identity-providers — create (PROJECT_ADMIN)
|
|
68
|
+
* GET /@<projectSlug>/identity-providers — list (READ_ROLES)
|
|
69
|
+
* PATCH /@<projectSlug>/identity-providers/:epcId — update (PROJECT_ADMIN)
|
|
70
|
+
* POST /@<projectSlug>/identity-providers/:epcId/test — testProvider (PROJECT_ADMIN)
|
|
71
|
+
*
|
|
72
|
+
* `create()` + `list()` back the Gate Studio `FederationPresetsPanel`; `update()` backs its
|
|
73
|
+
* `DirectorySyncPanel` (directory-sync settings are read off `list()` and written via `update()`, replacing
|
|
74
|
+
* the unanswered `federation.getDirectorySync`/`updateDirectorySync` bridge messages). Read-one/delete stay
|
|
75
|
+
* unbound until a caller needs them (the SDK does not speculatively surface routes).
|
|
76
|
+
*
|
|
77
|
+
* Auth: operator JWT with PROJECT_ADMIN+ role, server-enforced by the
|
|
78
|
+
* gateway RBAC layer (`requireProjectAdmin`); end-user JWTs (`eu_`-prefixed
|
|
79
|
+
* subjects) are rejected at the route. The bearer is taken from
|
|
80
|
+
* `partnerToken` in config, or per-call via the client's bearer plumbing.
|
|
81
|
+
*
|
|
82
|
+
* 🔴 `clientSecretRef` is a RAW SECRET on the way in, not a reference.
|
|
83
|
+
* Post-v105 the gateway encrypts the submitted value (AES-256-GCM under
|
|
84
|
+
* `K9O_SECRET_STORAGE_MASTER_KEY`) into the opaque `client_secret_enc`
|
|
85
|
+
* handle and persists only that; the field name is retained for wire
|
|
86
|
+
* compatibility but the create handler comment
|
|
87
|
+
* (`project-identity-providers.ts`, the v105 INSERT) is authoritative —
|
|
88
|
+
* there is NO Kibo custody on this path. Reads NEVER carry the secret or its
|
|
89
|
+
* handle: they carry only `clientSecretSet` (a presence boolean,
|
|
90
|
+
* the write-only fix). `serviceAccountKey` (directory sync) follows the same write-only rule.
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
/** Closed end-user-class provider enum per ch04 §1.6 — 11 values since v221 (the project-plane substrate
|
|
94
|
+
* `_sys.end_user_idp_provider_configs`); the org plane carries the same 11 since v222/v223. */
|
|
95
|
+
type IdpProviderKind = "google" | "github" | "microsoft" | "oidc" | "saml" | "scim" | "ldap" | "active_directory" | "apple" | "facebook" | "twitter";
|
|
96
|
+
/**
|
|
97
|
+
* The result of a provider connectivity test (`testProvider`). `ok` is the reachability + metadata-validity
|
|
98
|
+
* verdict; `reason` (present only when `!ok`) is a CLOSED-enum machine code, NEVER the upstream response body
|
|
99
|
+
* or any credential material. v1 is a NO-SECRET probe: it validates the issuer/metadata
|
|
100
|
+
* endpoint is reachable + structurally valid; it never transmits the stored client secret. `credentials_rejected`
|
|
101
|
+
* is deliberately NOT a v1 reason — the secret is never used, so it cannot be validated (a v2 concern).
|
|
102
|
+
*/
|
|
103
|
+
type FederationTestProviderResult = {
|
|
104
|
+
ok: boolean;
|
|
105
|
+
reason?: "endpoint_unreachable" | "endpoint_forbidden" | "metadata_invalid" | "secret_not_provisioned" | "kind_unsupported";
|
|
106
|
+
};
|
|
107
|
+
/** Per ch04 §1.6 the provider→tier pairing is structurally fixed:
|
|
108
|
+
* `free_tier_ok ∈ {google, github, microsoft, apple, facebook, twitter}`,
|
|
109
|
+
* `ridge_plus ∈ {oidc, saml, scim, ldap, active_directory}`. The gateway rejects a mismatched
|
|
110
|
+
* pairing (`K9O_INVALID_FIELD_VALUE`); the SDK forwards the caller value
|
|
111
|
+
* verbatim rather than second-guessing it. */
|
|
112
|
+
type IdpTierGating = "free_tier_ok" | "ridge_plus";
|
|
113
|
+
/**
|
|
114
|
+
* The provider-config metadata shape returned by every read surface and
|
|
115
|
+
* mutation response (`shapeIdpConfig`). Mirrors the gateway wire shape
|
|
116
|
+
* one-to-one.
|
|
117
|
+
*
|
|
118
|
+
* Reads carry `clientSecretSet` (presence only), never the secret or a handle (see the module header).
|
|
119
|
+
* `metadataUrl`/`updatedAt` are `null` until set; `attributeMap` defaults to `{}`; `allowedRedirectUris`
|
|
120
|
+
* defaults to `[]`. The `directory*` fields are GS-F7 scheduled directory sync (Google only, ch03 §5.11):
|
|
121
|
+
* settings plus the scheduler's last-run status; the service-account key itself is never returned.
|
|
122
|
+
*/
|
|
123
|
+
type IdpConfig = {
|
|
124
|
+
id: string;
|
|
125
|
+
projectId: string;
|
|
126
|
+
idpProvider: IdpProviderKind;
|
|
127
|
+
displayName: string;
|
|
128
|
+
clientId: string;
|
|
129
|
+
/** Whether a client secret is stored. The secret (and any handle to it) is write-only. */
|
|
130
|
+
clientSecretSet: boolean;
|
|
131
|
+
redirectUri: string;
|
|
132
|
+
metadataUrl: string | null;
|
|
133
|
+
attributeMap: Record<string, unknown>;
|
|
134
|
+
tierGating: IdpTierGating;
|
|
135
|
+
enabled: boolean;
|
|
136
|
+
allowedRedirectUris: string[];
|
|
137
|
+
directoryPullEnabled: boolean;
|
|
138
|
+
directorySyncSubject: string | null;
|
|
139
|
+
directorySyncIntervalMins: number | null;
|
|
140
|
+
directorySyncLastRunAt: string | null;
|
|
141
|
+
directorySyncLastStatus: string | null;
|
|
142
|
+
createdAt: string;
|
|
143
|
+
updatedAt: string | null;
|
|
144
|
+
};
|
|
145
|
+
/** GS-F7 directory-sync write fields — accepted on create AND update (one PROJECT_ADMIN surface). */
|
|
146
|
+
type DirectorySyncInput = {
|
|
147
|
+
/** Enabling requires `idpProvider: "google"`, a `serviceAccountKey` (now or already stored) and an interval. */
|
|
148
|
+
directoryPullEnabled?: boolean;
|
|
149
|
+
directorySyncIntervalMins?: number;
|
|
150
|
+
/** The raw Google service-account key JSON. Write-only: encrypted at rest server-side, never returned. */
|
|
151
|
+
serviceAccountKey?: string;
|
|
152
|
+
/** The Workspace admin user the service account impersonates (domain-wide delegation subject). */
|
|
153
|
+
directorySyncSubject?: string;
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Create-request body — mirrors the gateway `CreateIdpBody` (t.Object)
|
|
157
|
+
* exactly, including which fields are optional.
|
|
158
|
+
*/
|
|
159
|
+
type CreateIdpInput = {
|
|
160
|
+
idpProvider: IdpProviderKind;
|
|
161
|
+
displayName: string;
|
|
162
|
+
clientId: string;
|
|
163
|
+
/**
|
|
164
|
+
* The OAuth2 client secret. Sent over TLS; encrypted-at-rest server-side
|
|
165
|
+
* (AES-256-GCM) and never returned. Named `clientSecretRef` for wire
|
|
166
|
+
* compatibility — it is NOT a reference on the way in (see module header).
|
|
167
|
+
*/
|
|
168
|
+
clientSecretRef: string;
|
|
169
|
+
redirectUri: string;
|
|
170
|
+
/** Optional; `null`/omitted for providers that don't use discovery metadata. */
|
|
171
|
+
metadataUrl?: string | null;
|
|
172
|
+
/** Optional claim→attribute mapping; defaults to `{}` server-side. */
|
|
173
|
+
attributeMap?: Record<string, string>;
|
|
174
|
+
tierGating: IdpTierGating;
|
|
175
|
+
/** Defaults to `false` server-side — a provider is created disabled. */
|
|
176
|
+
enabled?: boolean;
|
|
177
|
+
/**
|
|
178
|
+
* Customer SPA origins the SDK gate flow (`gate.signInWithProvider`) may
|
|
179
|
+
* hand session tokens back to. Origin-matched + fail-closed at authorize,
|
|
180
|
+
* so an empty/omitted list means SDK sign-in is disabled for this provider
|
|
181
|
+
* until an origin is registered. Defaults to `[]` server-side.
|
|
182
|
+
*/
|
|
183
|
+
allowedRedirectUris?: string[] | null;
|
|
184
|
+
} & DirectorySyncInput;
|
|
185
|
+
/**
|
|
186
|
+
* Update-request body — mirrors the gateway `PatchIdpBody` exactly: every field optional; `idpProvider` and
|
|
187
|
+
* `tierGating` are immutable after create. An empty patch returns the current config unchanged.
|
|
188
|
+
*
|
|
189
|
+
* 🔴 For `oidc`/`microsoft`, changing `metadataUrl` WITHOUT `clientSecretRef` in the same patch CLEARS the
|
|
190
|
+
* stored client secret (the gateway's secret-invalidate-on-host-change control, ch04 §1.6): re-supply the
|
|
191
|
+
* secret whenever the metadata URL changes.
|
|
192
|
+
*/
|
|
193
|
+
type PatchIdpInput = {
|
|
194
|
+
displayName?: string;
|
|
195
|
+
clientId?: string;
|
|
196
|
+
/** The raw client secret (write-only; see the module header). */
|
|
197
|
+
clientSecretRef?: string;
|
|
198
|
+
redirectUri?: string;
|
|
199
|
+
metadataUrl?: string | null;
|
|
200
|
+
attributeMap?: Record<string, string>;
|
|
201
|
+
enabled?: boolean;
|
|
202
|
+
allowedRedirectUris?: string[] | null;
|
|
203
|
+
} & DirectorySyncInput;
|
|
204
|
+
/** Factory — produces an `identityProviders` namespace bound to the supplied
|
|
205
|
+
* config getter. Used by both the `gate` singleton + `createGateClient`. */
|
|
206
|
+
declare function makeIdentityProviders(getConfig: () => GateConfig): {
|
|
207
|
+
/**
|
|
208
|
+
* Register a new end-user IdP provider config for the configured
|
|
209
|
+
* project. PROJECT_ADMIN+ required (server-enforced). The plaintext
|
|
210
|
+
* client secret is encrypted-at-rest server-side; the returned config
|
|
211
|
+
* carries only the opaque secret handle.
|
|
212
|
+
*
|
|
213
|
+
* The gateway validates the `idpProvider`→`tierGating` pairing per ch04
|
|
214
|
+
* §1.6 and rejects a mismatch with `K9O_INVALID_FIELD_VALUE`.
|
|
215
|
+
*/
|
|
216
|
+
create(input: CreateIdpInput): Promise<Envelope<IdpConfig>>;
|
|
217
|
+
/**
|
|
218
|
+
* List the configured end-user IdP provider configs for the project.
|
|
219
|
+
* READ_ROLES-gated server-side (PROJECT_ADMIN/EDITOR/MEMBER/VIEWER/AUTHOR/
|
|
220
|
+
* ANALYST) — the SAME shape + roles as the existing GET route
|
|
221
|
+
* (`listProviders` returns the existing route's shape, no
|
|
222
|
+
* confidentiality-narrower endpoint). Each `IdpConfig` carries the opaque
|
|
223
|
+
* secret handle, never the secret. Callers that only need the summary
|
|
224
|
+
* (`id`/`idpProvider`/`displayName`/`enabled`/`tierGating`) pick fields off
|
|
225
|
+
* the result — no server change needed for that shaping.
|
|
226
|
+
*/
|
|
227
|
+
list(): Promise<Envelope<IdpConfig[]>>;
|
|
228
|
+
/**
|
|
229
|
+
* Test connectivity to a configured provider by id — a NO-SECRET reachability + metadata-validity probe
|
|
230
|
+
* (no-secret): the gateway resolve-and-pins the issuer/metadata endpoint (SSRF-fenced) and
|
|
231
|
+
* validates it structurally, WITHOUT decrypting or transmitting the stored client secret. Returns
|
|
232
|
+
* `{ok, reason?}`; the `reason` is a closed machine code, never the upstream body or any credential.
|
|
233
|
+
* PROJECT_ADMIN required (server-enforced) — it triggers live external egress on the platform's behalf.
|
|
234
|
+
*/
|
|
235
|
+
/**
|
|
236
|
+
* Update a provider config by id (PATCH; PROJECT_ADMIN, server-enforced). Partial: only supplied fields
|
|
237
|
+
* change; `idpProvider`/`tierGating` are immutable. Returns the updated config (secrets never included).
|
|
238
|
+
* GS-F7: write directory-sync settings here and read their status back off `list()`. See `PatchIdpInput`
|
|
239
|
+
* for the metadataUrl-change-clears-secret rule.
|
|
240
|
+
*/
|
|
241
|
+
update(configId: string, patch: PatchIdpInput): Promise<Envelope<IdpConfig>>;
|
|
242
|
+
testProvider(configId: string): Promise<Envelope<FederationTestProviderResult>>;
|
|
243
|
+
};
|
|
244
|
+
type IdentityProvidersNamespace = ReturnType<typeof makeIdentityProviders>;
|
|
245
|
+
|
|
246
|
+
/** Factory — produces a `gate.*` namespace bound to the supplied config getter.
|
|
247
|
+
* Used by both the module-level `gate` singleton (config from `configureGate`)
|
|
248
|
+
* and `createGateClient(config)` (config supplied at construction time). */
|
|
249
|
+
declare function makeGateNamespace(getConfig: () => GateConfig): {
|
|
250
|
+
/**
|
|
251
|
+
* Create a new end-user identity for the configured project. Returns
|
|
252
|
+
* the new user record + an initial session per ch01 §12.2. Emits a
|
|
253
|
+
* `data.write.auth.signup` audit event per ch01 §12.5.
|
|
254
|
+
*
|
|
255
|
+
* Errors (closed taxonomy per ch01 §2):
|
|
256
|
+
* - `EMAIL_ALREADY_REGISTERED` (409) when the email collides
|
|
257
|
+
* - `INVALID_FIELD_VALUE` (400) on schema violation (password policy, malformed email)
|
|
258
|
+
* - `TIER_FEATURE_GATED` (403) when the project's tier blocks email/password
|
|
259
|
+
*/
|
|
260
|
+
signUp(input: SignUpInput): Promise<Envelope<AuthResult>>;
|
|
261
|
+
/**
|
|
262
|
+
* Sign in an existing end-user with email + password. Returns the
|
|
263
|
+
* user record + a fresh session. Emits a `data.write.auth.signin`
|
|
264
|
+
* audit event.
|
|
265
|
+
*
|
|
266
|
+
* Errors:
|
|
267
|
+
* - `INVALID_CREDENTIALS` (401) on bad email/password (ambiguous on
|
|
268
|
+
* purpose — does not distinguish "user not found" vs "password
|
|
269
|
+
* wrong" to avoid enumeration)
|
|
270
|
+
*/
|
|
271
|
+
signIn(input: SignInInput): Promise<Envelope<AuthResult>>;
|
|
272
|
+
/**
|
|
273
|
+
* Sign out — revoke the bound refresh token (or an explicit one, if
|
|
274
|
+
* supplied). Emits a `data.write.auth.signout` audit event.
|
|
275
|
+
*
|
|
276
|
+
* Errors:
|
|
277
|
+
* - `UNAUTHENTICATED` (401) when no session is present
|
|
278
|
+
* - `REFRESH_TOKEN_INVALID` (400) when the supplied refresh token
|
|
279
|
+
* doesn't match the bearer's session
|
|
280
|
+
*/
|
|
281
|
+
signOut(input?: SignOutInput): Promise<Envelope<{
|
|
282
|
+
revoked: boolean;
|
|
283
|
+
}>>;
|
|
284
|
+
/**
|
|
285
|
+
* Return the caller's identity claims from the bearer JWT. Useful in
|
|
286
|
+
* Standalone mode where the SDK consumer wants to surface the user's
|
|
287
|
+
* roles / groups without parsing the JWT itself.
|
|
288
|
+
*
|
|
289
|
+
* Errors:
|
|
290
|
+
* - `UNAUTHENTICATED` (401) when no bearer is present
|
|
291
|
+
* - `SESSION_EXPIRED` (401) when the bearer's exp has passed
|
|
292
|
+
*/
|
|
293
|
+
whoami(): Promise<Envelope<WhoamiResult>>;
|
|
294
|
+
/**
|
|
295
|
+
* Rotate the access token using a refresh token. Returns a fresh
|
|
296
|
+
* session pair (new access token + same refresh token; gateway may
|
|
297
|
+
* also rotate the refresh token per project policy).
|
|
298
|
+
*
|
|
299
|
+
* Errors:
|
|
300
|
+
* - `REFRESH_TOKEN_INVALID` (400) when the refresh token is unknown,
|
|
301
|
+
* expired, or revoked
|
|
302
|
+
*/
|
|
303
|
+
refreshToken(input: RefreshTokenInput): Promise<Envelope<{
|
|
304
|
+
session: AuthResult["session"];
|
|
305
|
+
}>>;
|
|
306
|
+
/**
|
|
307
|
+
* Check whether the bearer's session is currently valid. Does NOT
|
|
308
|
+
* throw on expiry or invalid token — returns `{ valid: false }`
|
|
309
|
+
* inside the envelope. The intended use is health-checking a session
|
|
310
|
+
* without surfacing an error to the end-user (the SDK consumer
|
|
311
|
+
* typically wants to redirect to sign-in rather than surface a 401).
|
|
312
|
+
*/
|
|
313
|
+
verifySession(): Promise<Envelope<VerifySessionResult>>;
|
|
314
|
+
/**
|
|
315
|
+
* The project's hosted sign-in page URL and WebAuthn `rpId`. Unauthenticated and cacheable; no credential is sent,
|
|
316
|
+
* even when a partner token is configured. Take both values as given: an unknown org, a deleted project and a
|
|
317
|
+
* non-Gate project all answer the same `PROJECT_NOT_FOUND`, so a failure here says nothing about which.
|
|
318
|
+
*/
|
|
319
|
+
hosted(): Promise<Envelope<HostedGateInfo>>;
|
|
320
|
+
/**
|
|
321
|
+
* Initiate an external-IdP sign-in flow (Google / GitHub / Microsoft).
|
|
322
|
+
* The SDK POSTs to the gateway's authorize endpoint, receives the
|
|
323
|
+
* provider's authorization URL with a signed-state JWT (carrying PKCE
|
|
324
|
+
* verifier + the supplied `redirectUri`), and redirects the browser.
|
|
325
|
+
*
|
|
326
|
+
* After the user authenticates with the IdP, the gateway processes the
|
|
327
|
+
* callback and redirects the browser back to `redirectUri` with session
|
|
328
|
+
* tokens in the URL fragment. Use `parseSignInCallback()` on the
|
|
329
|
+
* destination page to extract them.
|
|
330
|
+
*
|
|
331
|
+
* Example:
|
|
332
|
+
* await gate.signInWithProvider({
|
|
333
|
+
* provider: 'google',
|
|
334
|
+
* redirectUri: 'https://app.example.com/auth/callback',
|
|
335
|
+
* });
|
|
336
|
+
* // …user lands at /auth/callback#access_token=…&refresh_token=…
|
|
337
|
+
*
|
|
338
|
+
* Generic OIDC requires authorization-endpoint discovery and is not
|
|
339
|
+
* yet wired; use a hosted provider (google/github/microsoft) for now.
|
|
340
|
+
*/
|
|
341
|
+
signInWithProvider(input: {
|
|
342
|
+
provider: "google" | "github" | "microsoft" | "oidc" | "saml";
|
|
343
|
+
redirectUri: string;
|
|
344
|
+
}): Promise<void>;
|
|
345
|
+
/**
|
|
346
|
+
* Parse session tokens out of the URL fragment delivered by an
|
|
347
|
+
* IdP callback redirect. Returns the session payload on success or an
|
|
348
|
+
* error object on failure. Pass `window.location.hash` (or any
|
|
349
|
+
* `#`-prefixed string) — leading `#` is stripped automatically.
|
|
350
|
+
*
|
|
351
|
+
* Side-effect-free: does not call the gateway and does not mutate
|
|
352
|
+
* any session storage. The consumer is responsible for persisting
|
|
353
|
+
* the returned tokens (e.g. via the app's auth context).
|
|
354
|
+
*/
|
|
355
|
+
parseSignInCallback(hash: string): SignInCallbackResult;
|
|
356
|
+
/**
|
|
357
|
+
* Passwordless sub-namespace per ch01 §12.1 — OTP + Magic Link flows
|
|
358
|
+
* for email-based authentication without a stored password.
|
|
359
|
+
*
|
|
360
|
+
* Wire endpoints (LIVE on the Gate end-user plane — verified against
|
|
361
|
+
* staging): OTP → `POST /@<projectSlug>/gate/otp/{request,verify}`
|
|
362
|
+
* (routes/otp.ts), Magic Link → `POST /@<projectSlug>/gate/magic-link/
|
|
363
|
+
* {send,redeem}` (routes/magic-link.ts). NOTE: these are the gateway's
|
|
364
|
+
* canonical paths; the SDK ergonomic method names (`requestMagicLink`/
|
|
365
|
+
* `verifyMagicLink`) do not mirror the path segments (`send`/`redeem`).
|
|
366
|
+
* (The earlier `passwordless/*` SDK paths were interface-first scaffold
|
|
367
|
+
* that never matched the shipped gateway routes — reconciled here.)
|
|
368
|
+
*/
|
|
369
|
+
passwordless: {
|
|
370
|
+
/**
|
|
371
|
+
* Request a one-time passcode delivered to the supplied email.
|
|
372
|
+
* The OTP is short-lived (typically 5 min per ch03 §3.4) and
|
|
373
|
+
* single-use; redemption via `verifyOtp` mints a session.
|
|
374
|
+
*/
|
|
375
|
+
requestOtp(input: RequestOtpInput): Promise<Envelope<{
|
|
376
|
+
requested: boolean;
|
|
377
|
+
}>>;
|
|
378
|
+
/**
|
|
379
|
+
* Verify a one-time passcode previously sent via `requestOtp`.
|
|
380
|
+
* On success returns the same `AuthResult` shape as `signIn` —
|
|
381
|
+
* a fresh session bound to the end-user identity.
|
|
382
|
+
*
|
|
383
|
+
* Errors:
|
|
384
|
+
* - INVALID_CREDENTIALS (401) on wrong / expired / consumed OTP
|
|
385
|
+
* (ambiguous on purpose — enumeration defense)
|
|
386
|
+
*/
|
|
387
|
+
verifyOtp(input: VerifyOtpInput): Promise<Envelope<AuthResult>>;
|
|
388
|
+
/**
|
|
389
|
+
* Request a magic-link emailed to the supplied address. The link
|
|
390
|
+
* carries an opaque short-lived token (typically 15 min per ch03
|
|
391
|
+
* §3.3); clicking the link lands at the customer's chosen
|
|
392
|
+
* redirect URL with the token in the query string, which the
|
|
393
|
+
* customer's frontend then exchanges via `verifyMagicLink`.
|
|
394
|
+
*/
|
|
395
|
+
requestMagicLink(input: RequestMagicLinkInput): Promise<Envelope<{
|
|
396
|
+
requested: boolean;
|
|
397
|
+
}>>;
|
|
398
|
+
/**
|
|
399
|
+
* Verify a magic-link token previously delivered via
|
|
400
|
+
* `requestMagicLink`. On success returns the same `AuthResult`
|
|
401
|
+
* shape as `signIn`.
|
|
402
|
+
*
|
|
403
|
+
* Errors:
|
|
404
|
+
* - INVALID_CREDENTIALS (401) on wrong / expired / consumed
|
|
405
|
+
* token (same enumeration-defense rationale as verifyOtp)
|
|
406
|
+
*/
|
|
407
|
+
verifyMagicLink(input: VerifyMagicLinkInput): Promise<Envelope<AuthResult>>;
|
|
408
|
+
/**
|
|
409
|
+
* Extract the opaque magic-link token from the landing-page URL's query
|
|
410
|
+
* string (the gateway redirects to `<configured-redirect>?token=…&project=…`).
|
|
411
|
+
* Pure + side-effect-free — pass `window.location.search`. Feed the
|
|
412
|
+
* returned `token` to `verifyMagicLink({ token })` to mint the session.
|
|
413
|
+
*
|
|
414
|
+
* This is the magic-link counterpart to `parseSignInCallback` (which parses
|
|
415
|
+
* the SSO *hash fragment* for session tokens) — magic-link delivers an
|
|
416
|
+
* opaque token in the *query string*, so the two are not interchangeable.
|
|
417
|
+
*/
|
|
418
|
+
parseMagicLinkCallback(search: string): MagicLinkCallbackResult;
|
|
419
|
+
};
|
|
420
|
+
/**
|
|
421
|
+
* Project-scoped end-user IdP provider-config management (ch04 §1.6).
|
|
422
|
+
* PROJECT_ADMIN+ required; end-user JWTs rejected at the route. Only
|
|
423
|
+
* `create()` is bound — the REST create the Gate Studio
|
|
424
|
+
* `FederationPresetsPanel` routes to when it drops the `gate_flows`
|
|
425
|
+
* `__addFromPreset` sentinel. Gate-admin surface.
|
|
426
|
+
*/
|
|
427
|
+
identityProviders: {
|
|
428
|
+
create(input: CreateIdpInput): Promise<Envelope<IdpConfig>>;
|
|
429
|
+
list(): Promise<Envelope<IdpConfig[]>>;
|
|
430
|
+
update(configId: string, patch: PatchIdpInput): Promise<Envelope<IdpConfig>>;
|
|
431
|
+
testProvider(configId: string): Promise<Envelope<FederationTestProviderResult>>;
|
|
432
|
+
};
|
|
433
|
+
/**
|
|
434
|
+
* Per-project magic-link redirect-URL allowlist management (blessed
|
|
435
|
+
* shape). Gate-admin surface alongside `identityProviders`
|
|
436
|
+
* — PROJECT_ADMIN+ required, distinct from the end-user-facing
|
|
437
|
+
* `passwordless.requestMagicLink`/`verifyMagicLink` send/verify flow.
|
|
438
|
+
*/
|
|
439
|
+
magicLinkRedirects: {
|
|
440
|
+
list(): Promise<Envelope<{
|
|
441
|
+
redirects: MagicLinkRedirect[];
|
|
442
|
+
}>>;
|
|
443
|
+
add(input: AddMagicLinkRedirectInput): Promise<Envelope<{
|
|
444
|
+
redirect: MagicLinkRedirect;
|
|
445
|
+
}>>;
|
|
446
|
+
remove(id: string): Promise<Envelope<RemoveMagicLinkRedirectResult>>;
|
|
447
|
+
};
|
|
448
|
+
};
|
|
449
|
+
/** Singleton bound to the module-level `configureGate()` config.
|
|
450
|
+
* v0.4.0+: per-instance clients via `createGateClient(config)`. */
|
|
451
|
+
declare const gate: {
|
|
452
|
+
/**
|
|
453
|
+
* Create a new end-user identity for the configured project. Returns
|
|
454
|
+
* the new user record + an initial session per ch01 §12.2. Emits a
|
|
455
|
+
* `data.write.auth.signup` audit event per ch01 §12.5.
|
|
456
|
+
*
|
|
457
|
+
* Errors (closed taxonomy per ch01 §2):
|
|
458
|
+
* - `EMAIL_ALREADY_REGISTERED` (409) when the email collides
|
|
459
|
+
* - `INVALID_FIELD_VALUE` (400) on schema violation (password policy, malformed email)
|
|
460
|
+
* - `TIER_FEATURE_GATED` (403) when the project's tier blocks email/password
|
|
461
|
+
*/
|
|
462
|
+
signUp(input: SignUpInput): Promise<Envelope<AuthResult>>;
|
|
463
|
+
/**
|
|
464
|
+
* Sign in an existing end-user with email + password. Returns the
|
|
465
|
+
* user record + a fresh session. Emits a `data.write.auth.signin`
|
|
466
|
+
* audit event.
|
|
467
|
+
*
|
|
468
|
+
* Errors:
|
|
469
|
+
* - `INVALID_CREDENTIALS` (401) on bad email/password (ambiguous on
|
|
470
|
+
* purpose — does not distinguish "user not found" vs "password
|
|
471
|
+
* wrong" to avoid enumeration)
|
|
472
|
+
*/
|
|
473
|
+
signIn(input: SignInInput): Promise<Envelope<AuthResult>>;
|
|
474
|
+
/**
|
|
475
|
+
* Sign out — revoke the bound refresh token (or an explicit one, if
|
|
476
|
+
* supplied). Emits a `data.write.auth.signout` audit event.
|
|
477
|
+
*
|
|
478
|
+
* Errors:
|
|
479
|
+
* - `UNAUTHENTICATED` (401) when no session is present
|
|
480
|
+
* - `REFRESH_TOKEN_INVALID` (400) when the supplied refresh token
|
|
481
|
+
* doesn't match the bearer's session
|
|
482
|
+
*/
|
|
483
|
+
signOut(input?: SignOutInput): Promise<Envelope<{
|
|
484
|
+
revoked: boolean;
|
|
485
|
+
}>>;
|
|
486
|
+
/**
|
|
487
|
+
* Return the caller's identity claims from the bearer JWT. Useful in
|
|
488
|
+
* Standalone mode where the SDK consumer wants to surface the user's
|
|
489
|
+
* roles / groups without parsing the JWT itself.
|
|
490
|
+
*
|
|
491
|
+
* Errors:
|
|
492
|
+
* - `UNAUTHENTICATED` (401) when no bearer is present
|
|
493
|
+
* - `SESSION_EXPIRED` (401) when the bearer's exp has passed
|
|
494
|
+
*/
|
|
495
|
+
whoami(): Promise<Envelope<WhoamiResult>>;
|
|
496
|
+
/**
|
|
497
|
+
* Rotate the access token using a refresh token. Returns a fresh
|
|
498
|
+
* session pair (new access token + same refresh token; gateway may
|
|
499
|
+
* also rotate the refresh token per project policy).
|
|
500
|
+
*
|
|
501
|
+
* Errors:
|
|
502
|
+
* - `REFRESH_TOKEN_INVALID` (400) when the refresh token is unknown,
|
|
503
|
+
* expired, or revoked
|
|
504
|
+
*/
|
|
505
|
+
refreshToken(input: RefreshTokenInput): Promise<Envelope<{
|
|
506
|
+
session: AuthResult["session"];
|
|
507
|
+
}>>;
|
|
508
|
+
/**
|
|
509
|
+
* Check whether the bearer's session is currently valid. Does NOT
|
|
510
|
+
* throw on expiry or invalid token — returns `{ valid: false }`
|
|
511
|
+
* inside the envelope. The intended use is health-checking a session
|
|
512
|
+
* without surfacing an error to the end-user (the SDK consumer
|
|
513
|
+
* typically wants to redirect to sign-in rather than surface a 401).
|
|
514
|
+
*/
|
|
515
|
+
verifySession(): Promise<Envelope<VerifySessionResult>>;
|
|
516
|
+
/**
|
|
517
|
+
* The project's hosted sign-in page URL and WebAuthn `rpId`. Unauthenticated and cacheable; no credential is sent,
|
|
518
|
+
* even when a partner token is configured. Take both values as given: an unknown org, a deleted project and a
|
|
519
|
+
* non-Gate project all answer the same `PROJECT_NOT_FOUND`, so a failure here says nothing about which.
|
|
520
|
+
*/
|
|
521
|
+
hosted(): Promise<Envelope<HostedGateInfo>>;
|
|
522
|
+
/**
|
|
523
|
+
* Initiate an external-IdP sign-in flow (Google / GitHub / Microsoft).
|
|
524
|
+
* The SDK POSTs to the gateway's authorize endpoint, receives the
|
|
525
|
+
* provider's authorization URL with a signed-state JWT (carrying PKCE
|
|
526
|
+
* verifier + the supplied `redirectUri`), and redirects the browser.
|
|
527
|
+
*
|
|
528
|
+
* After the user authenticates with the IdP, the gateway processes the
|
|
529
|
+
* callback and redirects the browser back to `redirectUri` with session
|
|
530
|
+
* tokens in the URL fragment. Use `parseSignInCallback()` on the
|
|
531
|
+
* destination page to extract them.
|
|
532
|
+
*
|
|
533
|
+
* Example:
|
|
534
|
+
* await gate.signInWithProvider({
|
|
535
|
+
* provider: 'google',
|
|
536
|
+
* redirectUri: 'https://app.example.com/auth/callback',
|
|
537
|
+
* });
|
|
538
|
+
* // …user lands at /auth/callback#access_token=…&refresh_token=…
|
|
539
|
+
*
|
|
540
|
+
* Generic OIDC requires authorization-endpoint discovery and is not
|
|
541
|
+
* yet wired; use a hosted provider (google/github/microsoft) for now.
|
|
542
|
+
*/
|
|
543
|
+
signInWithProvider(input: {
|
|
544
|
+
provider: "google" | "github" | "microsoft" | "oidc" | "saml";
|
|
545
|
+
redirectUri: string;
|
|
546
|
+
}): Promise<void>;
|
|
547
|
+
/**
|
|
548
|
+
* Parse session tokens out of the URL fragment delivered by an
|
|
549
|
+
* IdP callback redirect. Returns the session payload on success or an
|
|
550
|
+
* error object on failure. Pass `window.location.hash` (or any
|
|
551
|
+
* `#`-prefixed string) — leading `#` is stripped automatically.
|
|
552
|
+
*
|
|
553
|
+
* Side-effect-free: does not call the gateway and does not mutate
|
|
554
|
+
* any session storage. The consumer is responsible for persisting
|
|
555
|
+
* the returned tokens (e.g. via the app's auth context).
|
|
556
|
+
*/
|
|
557
|
+
parseSignInCallback(hash: string): SignInCallbackResult;
|
|
558
|
+
/**
|
|
559
|
+
* Passwordless sub-namespace per ch01 §12.1 — OTP + Magic Link flows
|
|
560
|
+
* for email-based authentication without a stored password.
|
|
561
|
+
*
|
|
562
|
+
* Wire endpoints (LIVE on the Gate end-user plane — verified against
|
|
563
|
+
* staging): OTP → `POST /@<projectSlug>/gate/otp/{request,verify}`
|
|
564
|
+
* (routes/otp.ts), Magic Link → `POST /@<projectSlug>/gate/magic-link/
|
|
565
|
+
* {send,redeem}` (routes/magic-link.ts). NOTE: these are the gateway's
|
|
566
|
+
* canonical paths; the SDK ergonomic method names (`requestMagicLink`/
|
|
567
|
+
* `verifyMagicLink`) do not mirror the path segments (`send`/`redeem`).
|
|
568
|
+
* (The earlier `passwordless/*` SDK paths were interface-first scaffold
|
|
569
|
+
* that never matched the shipped gateway routes — reconciled here.)
|
|
570
|
+
*/
|
|
571
|
+
passwordless: {
|
|
572
|
+
/**
|
|
573
|
+
* Request a one-time passcode delivered to the supplied email.
|
|
574
|
+
* The OTP is short-lived (typically 5 min per ch03 §3.4) and
|
|
575
|
+
* single-use; redemption via `verifyOtp` mints a session.
|
|
576
|
+
*/
|
|
577
|
+
requestOtp(input: RequestOtpInput): Promise<Envelope<{
|
|
578
|
+
requested: boolean;
|
|
579
|
+
}>>;
|
|
580
|
+
/**
|
|
581
|
+
* Verify a one-time passcode previously sent via `requestOtp`.
|
|
582
|
+
* On success returns the same `AuthResult` shape as `signIn` —
|
|
583
|
+
* a fresh session bound to the end-user identity.
|
|
584
|
+
*
|
|
585
|
+
* Errors:
|
|
586
|
+
* - INVALID_CREDENTIALS (401) on wrong / expired / consumed OTP
|
|
587
|
+
* (ambiguous on purpose — enumeration defense)
|
|
588
|
+
*/
|
|
589
|
+
verifyOtp(input: VerifyOtpInput): Promise<Envelope<AuthResult>>;
|
|
590
|
+
/**
|
|
591
|
+
* Request a magic-link emailed to the supplied address. The link
|
|
592
|
+
* carries an opaque short-lived token (typically 15 min per ch03
|
|
593
|
+
* §3.3); clicking the link lands at the customer's chosen
|
|
594
|
+
* redirect URL with the token in the query string, which the
|
|
595
|
+
* customer's frontend then exchanges via `verifyMagicLink`.
|
|
596
|
+
*/
|
|
597
|
+
requestMagicLink(input: RequestMagicLinkInput): Promise<Envelope<{
|
|
598
|
+
requested: boolean;
|
|
599
|
+
}>>;
|
|
600
|
+
/**
|
|
601
|
+
* Verify a magic-link token previously delivered via
|
|
602
|
+
* `requestMagicLink`. On success returns the same `AuthResult`
|
|
603
|
+
* shape as `signIn`.
|
|
604
|
+
*
|
|
605
|
+
* Errors:
|
|
606
|
+
* - INVALID_CREDENTIALS (401) on wrong / expired / consumed
|
|
607
|
+
* token (same enumeration-defense rationale as verifyOtp)
|
|
608
|
+
*/
|
|
609
|
+
verifyMagicLink(input: VerifyMagicLinkInput): Promise<Envelope<AuthResult>>;
|
|
610
|
+
/**
|
|
611
|
+
* Extract the opaque magic-link token from the landing-page URL's query
|
|
612
|
+
* string (the gateway redirects to `<configured-redirect>?token=…&project=…`).
|
|
613
|
+
* Pure + side-effect-free — pass `window.location.search`. Feed the
|
|
614
|
+
* returned `token` to `verifyMagicLink({ token })` to mint the session.
|
|
615
|
+
*
|
|
616
|
+
* This is the magic-link counterpart to `parseSignInCallback` (which parses
|
|
617
|
+
* the SSO *hash fragment* for session tokens) — magic-link delivers an
|
|
618
|
+
* opaque token in the *query string*, so the two are not interchangeable.
|
|
619
|
+
*/
|
|
620
|
+
parseMagicLinkCallback(search: string): MagicLinkCallbackResult;
|
|
621
|
+
};
|
|
622
|
+
/**
|
|
623
|
+
* Project-scoped end-user IdP provider-config management (ch04 §1.6).
|
|
624
|
+
* PROJECT_ADMIN+ required; end-user JWTs rejected at the route. Only
|
|
625
|
+
* `create()` is bound — the REST create the Gate Studio
|
|
626
|
+
* `FederationPresetsPanel` routes to when it drops the `gate_flows`
|
|
627
|
+
* `__addFromPreset` sentinel. Gate-admin surface.
|
|
628
|
+
*/
|
|
629
|
+
identityProviders: {
|
|
630
|
+
create(input: CreateIdpInput): Promise<Envelope<IdpConfig>>;
|
|
631
|
+
list(): Promise<Envelope<IdpConfig[]>>;
|
|
632
|
+
update(configId: string, patch: PatchIdpInput): Promise<Envelope<IdpConfig>>;
|
|
633
|
+
testProvider(configId: string): Promise<Envelope<FederationTestProviderResult>>;
|
|
634
|
+
};
|
|
635
|
+
/**
|
|
636
|
+
* Per-project magic-link redirect-URL allowlist management (blessed
|
|
637
|
+
* shape). Gate-admin surface alongside `identityProviders`
|
|
638
|
+
* — PROJECT_ADMIN+ required, distinct from the end-user-facing
|
|
639
|
+
* `passwordless.requestMagicLink`/`verifyMagicLink` send/verify flow.
|
|
640
|
+
*/
|
|
641
|
+
magicLinkRedirects: {
|
|
642
|
+
list(): Promise<Envelope<{
|
|
643
|
+
redirects: MagicLinkRedirect[];
|
|
644
|
+
}>>;
|
|
645
|
+
add(input: AddMagicLinkRedirectInput): Promise<Envelope<{
|
|
646
|
+
redirect: MagicLinkRedirect;
|
|
647
|
+
}>>;
|
|
648
|
+
remove(id: string): Promise<Envelope<RemoveMagicLinkRedirectResult>>;
|
|
649
|
+
};
|
|
650
|
+
};
|
|
651
|
+
/** Convenience type alias mirroring the `gate` runtime export.
|
|
652
|
+
* Identical shape as the per-instance `GateClient` returned from
|
|
653
|
+
* `createGateClient`. */
|
|
654
|
+
type GateNamespace = ReturnType<typeof makeGateNamespace>;
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* `createGateClient(config)` — per-instance Gate SDK factory (v0.4.0).
|
|
658
|
+
*
|
|
659
|
+
* Returns a self-contained `GateClient` that does not depend on the
|
|
660
|
+
* module-level `configureGate()` singleton. Multiple clients can coexist
|
|
661
|
+
* in the same process, each scoped to its own project + baseUrl + mode —
|
|
662
|
+
* useful for multi-tenant Backends-For-Frontends (one client per
|
|
663
|
+
* incoming request's resolved tenant) or for apps that maintain both a
|
|
664
|
+
* Standalone and Native binding against the same SDK instance.
|
|
665
|
+
*
|
|
666
|
+
* Per v2.5.68 URL grammar, supply `projectSlug` for
|
|
667
|
+
* canonical `/@<slug>/gate/...` routing. Slug is the only customer-facing
|
|
668
|
+
* project addressing form — project ids are internal-only
|
|
669
|
+
* (`feedback_slug_addressing_v2_5_68`); the retired `/v2/projects/...`
|
|
670
|
+
* mounts were dropped at pass17 (`feedback_v2_path_is_an_error`).
|
|
671
|
+
*
|
|
672
|
+
* Example:
|
|
673
|
+
* const client = createGateClient({
|
|
674
|
+
* baseUrl: 'https://formelo.api.k9o.io',
|
|
675
|
+
* projectSlug: 'partner-console-staging',
|
|
676
|
+
* mode: 'native',
|
|
677
|
+
* });
|
|
678
|
+
* await client.signIn({ email, password });
|
|
679
|
+
*/
|
|
680
|
+
|
|
681
|
+
/** Shape of the per-instance client returned by `createGateClient`. */
|
|
682
|
+
type GateClient = ReturnType<typeof makeGateNamespace>;
|
|
683
|
+
/** Construct a Gate client bound to the supplied config. The config is
|
|
684
|
+
* validated up-front and stored on the instance; subsequent calls do not
|
|
685
|
+
* re-read process-level state. Throws `TypeError` on invalid config. */
|
|
686
|
+
declare function createGateClient(config: GateConfig): GateClient;
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* Regional host resolution.
|
|
690
|
+
*
|
|
691
|
+
* The region-free org host `<org>.api[-staging].k9o.io` redirects GET/HEAD only and REFUSES a request that carries a
|
|
692
|
+
* body, an `Authorization` header or a cookie (`400 K9O_INVALID_REQUEST_SHAPE`, `region_free_host_takes_no_credentials`),
|
|
693
|
+
* so credentials must go to `<org>.api[-staging]-<rgn>.k9o.io`. An SDK learns the region with ONE unauthenticated
|
|
694
|
+
* `HEAD https://<org>.api[-staging].k9o.io/`, takes the `308` `Location`, and caches the regional origin.
|
|
695
|
+
*
|
|
696
|
+
* Properties this module holds:
|
|
697
|
+
* - Only a region-free org host (shape `<org>.api.k9o.io` or `<org>.api-staging.k9o.io`) is ever probed. A regional,
|
|
698
|
+
* custom, self-hosted or dev baseUrl is used exactly as given.
|
|
699
|
+
* - The probe carries NO credential and none of the configured default headers (they may hold one).
|
|
700
|
+
* - The `Location` is trusted only if it is `https`, has no userinfo/port, and its host is exactly the SAME org on
|
|
701
|
+
* the SAME apex family with a 4-character region code. Anything else is ignored and the configured baseUrl stays,
|
|
702
|
+
* so a hostile redirect can never receive a credential.
|
|
703
|
+
* - Not a redirect (the platform has not cut over, or the host answers directly), or any failure: the configured
|
|
704
|
+
* baseUrl stays and the server's own refusal, if any, is what the caller sees. A definite answer is cached for the
|
|
705
|
+
* life of the client's config; a network failure is not cached.
|
|
706
|
+
*/
|
|
707
|
+
/** The slice of a client config this module needs (structural, so core and gate share one implementation). */
|
|
708
|
+
type RegionConfig = {
|
|
709
|
+
baseUrl: string;
|
|
710
|
+
fetch?: typeof globalThis.fetch | undefined;
|
|
711
|
+
};
|
|
712
|
+
/** The regional origin a `Location` may name for `host`, or null if it is not exactly that. Pure. */
|
|
713
|
+
declare function regionalOriginFromLocation(host: string, location: string, base: string): string | null;
|
|
714
|
+
/** The origin requests for this client go to: the cached regional origin once learned, else the configured baseUrl. */
|
|
715
|
+
declare function resolveRegionalOrigin(config: RegionConfig): Promise<string>;
|
|
716
|
+
|
|
717
|
+
export { AuthResult, type CreateIdpInput, type DirectorySyncInput, Envelope, type GateClient, GateConfig, type GateNamespace, HostedGateInfo, type IdentityProvidersNamespace, type IdpConfig, type IdpProviderKind, type IdpTierGating, MagicLinkCallbackResult, type PatchIdpInput, RefreshTokenInput, type RegionConfig, RequestMagicLinkInput, RequestOtpInput, SignInCallbackResult, SignInInput, SignOutInput, SignUpInput, VerifyMagicLinkInput, VerifyOtpInput, VerifySessionResult, WhoamiResult, createGateClient, gate, regionalOriginFromLocation, resolveRegionalOrigin };
|