@c1m-public/platform-auth 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access/index.d.ts +1 -153
- package/dist/access/index.js +307 -2
- package/dist/access/next.d.ts +2 -3
- package/dist/access/next.js +335 -5
- package/dist/index-BnchfjP_.d.ts +235 -0
- package/dist/index-CbsCWtku.d.ts +154 -0
- package/dist/index.d.ts +1 -230
- package/dist/index.js +534 -3
- package/dist/next.d.ts +2 -3
- package/dist/next.js +536 -7
- package/package.json +1 -1
- package/dist/chunk-FBC2NUH7.js +0 -83
- package/dist/chunk-Q7YI7RMG.js +0 -404
- package/dist/chunk-U67NBJND.js +0 -267
- package/dist/chunk-ZWSJVE5S.js +0 -52
- package/dist/internal-D6RafCm2.d.ts +0 -6
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/** Platform-operator permission keys. */
|
|
2
|
+
declare const PLATFORM_PERMISSIONS: readonly ["affiliates.finance.manage", "affiliates.partners.manage", "affiliates.programmes.manage", "affiliates.view", "linkservice.domains.manage", "linkservice.links.manage", "linkservice.qr.manage", "linkservice.view", "platform.admin.view", "platform.audit.view", "platform.auth.manage", "platform.billing.manage", "platform.channels.manage", "platform.channels.view", "platform.config.manage", "platform.docs.manage", "platform.docs.view", "platform.observability.manage", "platform.observability.view", "platform.offboarding.view", "platform.ops.manage", "platform.support.impersonate", "platform.support.sessions", "platform.tenants.archive", "platform.tenants.manage", "platform.tenants.restore", "platform.users.deactivate", "platform.users.delete", "platform.users.invite", "platform.users.manage_access", "platform.users.reactivate", "platform.users.view"];
|
|
3
|
+
type PlatformPermissionKey = (typeof PLATFORM_PERMISSIONS)[number];
|
|
4
|
+
/** Dash-owner permission keys (granted at dash scope, mirrored from the membership role). */
|
|
5
|
+
declare const DASH_PERMISSIONS: readonly ["dash.apps.manage", "dash.billing.manage", "dash.channels.manage", "dash.customers.manage", "dash.domains.manage", "dash.members.manage", "dash.ownership.transfer", "dash.plans.manage", "dash.publish", "dash.settings.manage", "dash.workspaces.admin", "dash.workspaces.manage"];
|
|
6
|
+
type DashPermissionKey = (typeof DASH_PERMISSIONS)[number];
|
|
7
|
+
/** Membership-mirrored dash role bundles (grant keys at dash scope). */
|
|
8
|
+
declare const DASH_ROLES: readonly ["dash.admin", "dash.owner"];
|
|
9
|
+
type DashRole = (typeof DASH_ROLES)[number];
|
|
10
|
+
/** Lead-broker workload permission keys. */
|
|
11
|
+
declare const LEADBROKER_PERMISSIONS: readonly ["leadbroker.finance.manage", "leadbroker.leads.dispatch", "leadbroker.leads.review", "leadbroker.leads.view", "leadbroker.policy.manage"];
|
|
12
|
+
type LeadBrokerPermissionKey = (typeof LEADBROKER_PERMISSIONS)[number];
|
|
13
|
+
/** Workspace-staff permission keys. */
|
|
14
|
+
declare const WORKSPACE_PERMISSIONS: readonly ["workspace.channels.manage", "workspace.channels.secrets", "workspace.channels.view", "workspace.crm.manage", "workspace.crm.view", "workspace.customers.manage", "workspace.customers.view", "workspace.orders.manage", "workspace.orders.view", "workspace.payments.record", "workspace.site.edit", "workspace.site.view", "workspace.staff.manage"];
|
|
15
|
+
type WorkspacePermissionKey = (typeof WORKSPACE_PERMISSIONS)[number];
|
|
16
|
+
/** Assignable workspace-staff role bundles (grant keys at workspace scope). */
|
|
17
|
+
declare const WORKSPACE_ROLES: readonly ["workspace.editor", "workspace.frontdesk", "workspace.manager"];
|
|
18
|
+
type WorkspaceRole = (typeof WORKSPACE_ROLES)[number];
|
|
19
|
+
/** Every permission key the backend can grant, across all scopes. */
|
|
20
|
+
type PermissionKey = PlatformPermissionKey | DashPermissionKey | LeadBrokerPermissionKey | WorkspacePermissionKey;
|
|
21
|
+
|
|
22
|
+
/** Onboarding pipeline stages, in funnel order. Labels and copy stay with the app; the strings are the backend's. */
|
|
23
|
+
declare const PIPELINE_STAGES: readonly ["created", "awaiting_payment", "provisioning", "attention", "active"];
|
|
24
|
+
type PipelineStage = (typeof PIPELINE_STAGES)[number];
|
|
25
|
+
declare function isPipelineStage(value: unknown): value is PipelineStage;
|
|
26
|
+
|
|
27
|
+
type AccessErrorCode = "unauthenticated" | "forbidden" | "unavailable" | "invalid_snapshot";
|
|
28
|
+
/**
|
|
29
|
+
* Typed failure for loading or validating an access snapshot. `unauthenticated`
|
|
30
|
+
* = no/expired session (401); `forbidden` = the backend refused the snapshot
|
|
31
|
+
* (403; e.g. wrong audience); `unavailable` = transport/5xx; `invalid_snapshot`
|
|
32
|
+
* = the payload did not match the contract.
|
|
33
|
+
*/
|
|
34
|
+
declare class AccessSnapshotError extends Error {
|
|
35
|
+
readonly code: AccessErrorCode;
|
|
36
|
+
readonly status: number | undefined;
|
|
37
|
+
constructor(code: AccessErrorCode, message: string, status?: number);
|
|
38
|
+
}
|
|
39
|
+
declare function isAccessSnapshotError(error: unknown, code?: AccessErrorCode): error is AccessSnapshotError;
|
|
40
|
+
|
|
41
|
+
/** Scope a permission entry applies to. Mirrors c1m-server authz.Scope*. */
|
|
42
|
+
type AccessScopeType = "platform" | "saas_app" | "workspace";
|
|
43
|
+
interface AccessEntry {
|
|
44
|
+
/** Permission key, e.g. "platform.users.manage_access". */
|
|
45
|
+
key: string;
|
|
46
|
+
scope_type: AccessScopeType;
|
|
47
|
+
/** "" for platform scope; saas_app slug or "*" for saas_app scope; workspace id for workspace scope. */
|
|
48
|
+
scope_id: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The resolved authorization snapshot for one subject, as returned by
|
|
52
|
+
* `GET /api/v1/platform/access`. This is the *output* of the backend resolver
|
|
53
|
+
* (base-role grant ∪ scoped grants), never the grant rows themselves.
|
|
54
|
+
*/
|
|
55
|
+
interface AccessSnapshot {
|
|
56
|
+
subject_id: string;
|
|
57
|
+
/** Monotonic; bumps on any grant/role change. Use for optimistic concurrency and cache keys. */
|
|
58
|
+
access_version: number;
|
|
59
|
+
is_owner: boolean;
|
|
60
|
+
active: boolean;
|
|
61
|
+
/** Platform operator base role (derived; display only — never authorize on it). */
|
|
62
|
+
platform_role: string;
|
|
63
|
+
permissions: AccessEntry[];
|
|
64
|
+
/**
|
|
65
|
+
* Dash bundle (`dash.owner` / `dash.admin`) per saas_app id, mirrored from
|
|
66
|
+
* the subject's dash membership. This is the admission list for the dash
|
|
67
|
+
* area: the dashes this subject runs. What they may *do* on one is a normal
|
|
68
|
+
* `hasPermission(snapshot, key, { saasApp })` check — platform managers hold
|
|
69
|
+
* their authority platform-wide and so appear here not at all.
|
|
70
|
+
*/
|
|
71
|
+
dash_roles: Record<string, string>;
|
|
72
|
+
/** Effective workspace-staff permission keys per workspace id. */
|
|
73
|
+
workspace_permissions: Record<string, string[]>;
|
|
74
|
+
/** Workspace-staff role bundle per workspace id (display only). */
|
|
75
|
+
workspace_roles: Record<string, string>;
|
|
76
|
+
}
|
|
77
|
+
declare function emptySnapshot(subjectId?: string): AccessSnapshot;
|
|
78
|
+
/** Runtime validator for the wire payload. Throws AccessSnapshotError("invalid_snapshot"). */
|
|
79
|
+
declare function parseAccessSnapshot(input: unknown): AccessSnapshot;
|
|
80
|
+
|
|
81
|
+
interface PermissionCheckOptions {
|
|
82
|
+
/**
|
|
83
|
+
* SaaS app (dash) slug the check is about. Omit for "anywhere": platform
|
|
84
|
+
* entries and any saas_app entry satisfy the check.
|
|
85
|
+
*/
|
|
86
|
+
saasApp?: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Mirrors c1m-server authz.entryCoversApp: platform scope covers every app;
|
|
90
|
+
* saas_app scope covers "*" or a case-insensitive slug match; workspace-scoped
|
|
91
|
+
* entries never satisfy an app-level check.
|
|
92
|
+
*/
|
|
93
|
+
declare function entryCoversApp(entry: AccessEntry, saasApp: string | undefined): boolean;
|
|
94
|
+
/** True when the subject is active and holds `key` for the given app (or anywhere). */
|
|
95
|
+
declare function hasPermission(snapshot: AccessSnapshot, key: string, opts?: PermissionCheckOptions): boolean;
|
|
96
|
+
declare function hasAnyPermission(snapshot: AccessSnapshot, keys: readonly string[], opts?: PermissionCheckOptions): boolean;
|
|
97
|
+
declare function hasAllPermissions(snapshot: AccessSnapshot, keys: readonly string[], opts?: PermissionCheckOptions): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Workspace-staff check. Platform owners always pass (they own every
|
|
100
|
+
* workspace); otherwise the workspace's effective permission list decides.
|
|
101
|
+
* Platform/saas_app entries never confer workspace-staff permissions.
|
|
102
|
+
*/
|
|
103
|
+
declare function hasWorkspacePermission(snapshot: AccessSnapshot, workspaceId: string, key: string): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* The dashes this subject runs, from the mirrored dash bundle grants — the
|
|
106
|
+
* admission list for the Admin Center's dash area. Platform managers are not
|
|
107
|
+
* listed: their reach is platform-wide, so admit them with
|
|
108
|
+
* `hasPermission(snapshot, "platform.tenants.manage")` instead.
|
|
109
|
+
*/
|
|
110
|
+
declare function managedDashes(snapshot: AccessSnapshot): Array<{
|
|
111
|
+
saasApp: string;
|
|
112
|
+
role: string;
|
|
113
|
+
}>;
|
|
114
|
+
/** The dash bundle held on one dash, or "" when the subject holds none there. */
|
|
115
|
+
declare function dashRole(snapshot: AccessSnapshot, saasApp: string): string;
|
|
116
|
+
declare function isPlatformOwner(snapshot: AccessSnapshot): boolean;
|
|
117
|
+
/**
|
|
118
|
+
* The saas_app scopes under which `key` is held. Returns `{ all: true }` when a
|
|
119
|
+
* platform-scoped or "*" entry grants it everywhere; otherwise the explicit
|
|
120
|
+
* app slugs (empty = nowhere). Mirrors authz.AppPermissionScope.
|
|
121
|
+
*/
|
|
122
|
+
declare function appScopes(snapshot: AccessSnapshot, key: string): {
|
|
123
|
+
all: boolean;
|
|
124
|
+
apps: string[];
|
|
125
|
+
};
|
|
126
|
+
/** Distinct permission keys held for `saasApp` (or anywhere). Handy for nav/badges. */
|
|
127
|
+
declare function permissionsFor(snapshot: AccessSnapshot, opts?: PermissionCheckOptions): string[];
|
|
128
|
+
|
|
129
|
+
/** A value that may be fixed or resolved per call (env read at request time). */
|
|
130
|
+
type Resolvable<T = string> = T | (() => T);
|
|
131
|
+
|
|
132
|
+
declare const DEFAULT_ACCESS_ENDPOINT_PATH = "/api/v1/platform/access";
|
|
133
|
+
interface FetchAccessSnapshotOptions {
|
|
134
|
+
/** Backend origin, e.g. https://api.example.com (no trailing slash needed). */
|
|
135
|
+
apiUrl: Resolvable;
|
|
136
|
+
/** Bearer access token for the platform surface. */
|
|
137
|
+
accessToken: string;
|
|
138
|
+
/** Defaults to /api/v1/platform/access. */
|
|
139
|
+
endpointPath?: string;
|
|
140
|
+
fetchTimeoutMs?: number;
|
|
141
|
+
fetchImpl?: typeof fetch;
|
|
142
|
+
/** Extra headers. Authorization and Accept are always set here. */
|
|
143
|
+
headers?: HeadersInit;
|
|
144
|
+
/** Incoming BFF request; its client identity (IP, geo, UA) is forwarded to the backend. */
|
|
145
|
+
request?: Request;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Framework-neutral fetch of the resolved access snapshot. Throws
|
|
149
|
+
* AccessSnapshotError: 401 → unauthenticated, 403 → forbidden, other non-2xx or
|
|
150
|
+
* network failure → unavailable, malformed body → invalid_snapshot.
|
|
151
|
+
*/
|
|
152
|
+
declare function fetchAccessSnapshot(opts: FetchAccessSnapshotOptions): Promise<AccessSnapshot>;
|
|
153
|
+
|
|
154
|
+
export { type AccessSnapshot as A, isAccessSnapshotError as B, isPipelineStage as C, DASH_PERMISSIONS as D, isPlatformOwner as E, type FetchAccessSnapshotOptions as F, managedDashes as G, parseAccessSnapshot as H, permissionsFor as I, LEADBROKER_PERMISSIONS as L, type PermissionCheckOptions as P, type Resolvable as R, WORKSPACE_PERMISSIONS as W, type AccessEntry as a, type AccessErrorCode as b, type AccessScopeType as c, AccessSnapshotError as d, DASH_ROLES as e, DEFAULT_ACCESS_ENDPOINT_PATH as f, type DashPermissionKey as g, type DashRole as h, type LeadBrokerPermissionKey as i, PIPELINE_STAGES as j, PLATFORM_PERMISSIONS as k, type PermissionKey as l, type PipelineStage as m, type PlatformPermissionKey as n, WORKSPACE_ROLES as o, type WorkspacePermissionKey as p, type WorkspaceRole as q, appScopes as r, dashRole as s, emptySnapshot as t, entryCoversApp as u, fetchAccessSnapshot as v, hasAllPermissions as w, hasAnyPermission as x, hasPermission as y, hasWorkspacePermission as z };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,231 +1,2 @@
|
|
|
1
|
+
export { a as AUTH_ERROR_MESSAGES, b as AuthResponse, C as CookieOptions, D as DeviceIdentity, c as DeviceIdentityConfig, d as DeviceIdentityStore, H as HANDOFF_ERROR_FALLBACK, e as HANDOFF_ERROR_MESSAGES, f as HandoffSource, g as HandoffSourceConfig, h as HandoffSourceTarget, i as HandoffTarget, j as HandoffTargetConfig, k as RefreshedSession, l as SSO_ERROR_MESSAGES, S as SessionData, m as SessionGateDecision, n as SessionGateInput, o as SessionRefresher, p as SessionRefresherConfig, q as SessionUser, T as TokenPayload, r as authErrorMessage, s as brokerPaths, t as createDeviceIdentity, u as createHandoffSource, v as createHandoffTarget, w as createSessionRefresher, x as decodeBase64Url, y as decodeDefaultSession, z as decodeTokenPayload, B as deleteCookie, E as evaluateSessionGate, F as handoffErrorMessage, G as hasSessionShape, I as hasTokenAudience, J as isAuthErrorCode, K as isHandoffErrorCode, L as isTokenExpired, M as isTokenExpiringSoon, N as parseAuthResponse, O as parseRefreshEnvelope, P as readCookie, Q as safeInternalPath, U as serializeCookie, V as setCookie, W as sourceStartPath, X as tokenMaxAgeSeconds } from './index-BnchfjP_.js';
|
|
1
2
|
export { applyForwardedClientHeaders, forwardedRequestHeaders } from '@c1m-public/transport';
|
|
2
|
-
import { R as Resolvable, A as AsyncResolvable } from './internal-D6RafCm2.js';
|
|
3
|
-
|
|
4
|
-
interface SessionUser {
|
|
5
|
-
id: string;
|
|
6
|
-
email: string;
|
|
7
|
-
name: string;
|
|
8
|
-
role: string;
|
|
9
|
-
is_active: boolean;
|
|
10
|
-
email_verified: boolean;
|
|
11
|
-
created_at: string;
|
|
12
|
-
last_login_at?: string;
|
|
13
|
-
has_passkey?: boolean;
|
|
14
|
-
}
|
|
15
|
-
interface SessionData {
|
|
16
|
-
user: SessionUser;
|
|
17
|
-
token: string;
|
|
18
|
-
exp: number;
|
|
19
|
-
iat: number;
|
|
20
|
-
}
|
|
21
|
-
type TokenPayload = Record<string, unknown> & {
|
|
22
|
-
sub?: string;
|
|
23
|
-
exp?: number;
|
|
24
|
-
iat?: number;
|
|
25
|
-
actor_id?: string;
|
|
26
|
-
effective_user_id?: string;
|
|
27
|
-
customer_id?: string;
|
|
28
|
-
user_id?: string;
|
|
29
|
-
aud?: string | string[];
|
|
30
|
-
email?: string;
|
|
31
|
-
name?: string;
|
|
32
|
-
role?: string;
|
|
33
|
-
is_active?: boolean;
|
|
34
|
-
email_verified?: boolean;
|
|
35
|
-
created_at?: string;
|
|
36
|
-
has_passkeys?: boolean;
|
|
37
|
-
};
|
|
38
|
-
declare function decodeBase64Url(input: string): string | null;
|
|
39
|
-
declare function decodeTokenPayload(token: string): TokenPayload | null;
|
|
40
|
-
declare function hasTokenAudience(token: string, requiredAudience: string): boolean;
|
|
41
|
-
/** Cookie max-age clamped to the token's remaining lifetime. */
|
|
42
|
-
declare function tokenMaxAgeSeconds(token: string, configuredMaxAge: number): number;
|
|
43
|
-
declare function isTokenExpired(token: string): boolean;
|
|
44
|
-
declare function isTokenExpiringSoon(token: string, bufferSeconds?: number): boolean;
|
|
45
|
-
declare function decodeDefaultSession(token: string): SessionData | null;
|
|
46
|
-
/** Backend auth response shape shared by verify-code, OIDC complete, and handoff exchange. */
|
|
47
|
-
interface AuthResponse {
|
|
48
|
-
access_token: string;
|
|
49
|
-
refresh_token: string;
|
|
50
|
-
token_type: string;
|
|
51
|
-
expires_at: string;
|
|
52
|
-
user: Record<string, unknown>;
|
|
53
|
-
}
|
|
54
|
-
declare function parseAuthResponse(value: unknown): AuthResponse | null;
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Strict same-origin return path: must start with `/`, not `//` or contain `://`,
|
|
58
|
-
* no encoded slashes or control chars, and round-trip URL parsing unchanged.
|
|
59
|
-
* Returns the value verbatim (query/hash kept) or null.
|
|
60
|
-
*/
|
|
61
|
-
declare function safeInternalPath(raw: string | null | undefined): string | null;
|
|
62
|
-
|
|
63
|
-
interface CookieOptions {
|
|
64
|
-
httpOnly?: boolean;
|
|
65
|
-
secure?: boolean;
|
|
66
|
-
sameSite?: "lax" | "strict" | "none";
|
|
67
|
-
path?: string;
|
|
68
|
-
maxAge?: number;
|
|
69
|
-
}
|
|
70
|
-
declare function readCookie(request: Request, name: string): string | null;
|
|
71
|
-
declare function serializeCookie(name: string, value: string, options?: CookieOptions): string;
|
|
72
|
-
declare function setCookie(response: Response, name: string, value: string, options?: CookieOptions): Response;
|
|
73
|
-
declare function deleteCookie(response: Response, name: string, options?: Pick<CookieOptions, "path" | "secure">): Response;
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Per-browser identity sent as `X-Client-Device-ID`; c1m-server refuses to
|
|
77
|
-
* create a session without it. Informational only, no authority.
|
|
78
|
-
*/
|
|
79
|
-
interface DeviceIdentity {
|
|
80
|
-
value: string;
|
|
81
|
-
created: boolean;
|
|
82
|
-
}
|
|
83
|
-
interface DeviceIdentityConfig {
|
|
84
|
-
cookieName: string;
|
|
85
|
-
secure?: boolean;
|
|
86
|
-
maxAgeSeconds?: number;
|
|
87
|
-
}
|
|
88
|
-
declare function createDeviceIdentity(config: DeviceIdentityConfig): {
|
|
89
|
-
read(request: Request): DeviceIdentity;
|
|
90
|
-
persist(response: Response, identity: DeviceIdentity): Response;
|
|
91
|
-
};
|
|
92
|
-
type DeviceIdentityStore = ReturnType<typeof createDeviceIdentity>;
|
|
93
|
-
|
|
94
|
-
declare const HANDOFF_ERROR_MESSAGES: Record<string, string>;
|
|
95
|
-
declare const HANDOFF_ERROR_FALLBACK = "Sign-in failed \u2014 please try again.";
|
|
96
|
-
declare const SSO_ERROR_MESSAGES: Record<string, string>;
|
|
97
|
-
/** Every sign-in failure code this package knows: handoff, admission, and SSO. */
|
|
98
|
-
declare const AUTH_ERROR_MESSAGES: Record<string, string>;
|
|
99
|
-
declare function handoffErrorMessage(code: string | null | undefined): string;
|
|
100
|
-
declare function isHandoffErrorCode(code: string | null | undefined): boolean;
|
|
101
|
-
/**
|
|
102
|
-
* Resolve any sign-in failure code to copy. `overrides` wins, so a surface can
|
|
103
|
-
* reword a shared code or add its own without forking the whole map.
|
|
104
|
-
*/
|
|
105
|
-
declare function authErrorMessage(code: string | null | undefined, overrides?: Record<string, string>): string;
|
|
106
|
-
declare function isAuthErrorCode(code: string | null | undefined, overrides?: Record<string, string>): boolean;
|
|
107
|
-
|
|
108
|
-
declare function sourceStartPath(app: string): string;
|
|
109
|
-
declare function brokerPaths(app: string): {
|
|
110
|
-
readonly start: `/api/v1/platform/auth/handoffs/${string}/start`;
|
|
111
|
-
readonly exchange: `/api/v1/platform/auth/handoffs/${string}/exchange`;
|
|
112
|
-
};
|
|
113
|
-
interface HandoffTargetConfig {
|
|
114
|
-
app: string;
|
|
115
|
-
apiUrl: Resolvable;
|
|
116
|
-
audience: string;
|
|
117
|
-
clientType: string;
|
|
118
|
-
sources: Record<string, Resolvable>;
|
|
119
|
-
defaultSource: string;
|
|
120
|
-
cookiePrefix: string;
|
|
121
|
-
loginPath: string;
|
|
122
|
-
defaultReturnPath: string;
|
|
123
|
-
device: DeviceIdentityStore;
|
|
124
|
-
/** Write session cookies onto `response` (or return void if written via a framework store). */
|
|
125
|
-
establishSession: (session: AuthResponse, response: Response, request: Request) => Promise<Response | void> | Response | void;
|
|
126
|
-
secureCookies?: boolean;
|
|
127
|
-
timeoutMs?: number;
|
|
128
|
-
/** @deprecated use `timeoutMs`. */
|
|
129
|
-
fetchTimeoutMs?: number;
|
|
130
|
-
fetch?: typeof fetch;
|
|
131
|
-
}
|
|
132
|
-
declare function createHandoffTarget(config: HandoffTargetConfig): {
|
|
133
|
-
cookies: {
|
|
134
|
-
readonly state: `${string}state`;
|
|
135
|
-
readonly verifier: `${string}verifier`;
|
|
136
|
-
readonly from: `${string}from`;
|
|
137
|
-
};
|
|
138
|
-
/** GET `?source=&from=` */
|
|
139
|
-
start(request: Request): Promise<Response>;
|
|
140
|
-
/** GET `?code=&state=` */
|
|
141
|
-
callback(request: Request): Promise<Response>;
|
|
142
|
-
};
|
|
143
|
-
type HandoffTarget = ReturnType<typeof createHandoffTarget>;
|
|
144
|
-
interface HandoffSourceTarget {
|
|
145
|
-
origin: Resolvable;
|
|
146
|
-
callbackPath?: string;
|
|
147
|
-
loginPath?: string;
|
|
148
|
-
}
|
|
149
|
-
interface HandoffSourceConfig {
|
|
150
|
-
apiUrl: Resolvable;
|
|
151
|
-
clientType: string;
|
|
152
|
-
targets: Record<string, HandoffSourceTarget>;
|
|
153
|
-
/** Live bearer or null when signed out; refresh an expiring token before returning it. */
|
|
154
|
-
getAccessToken: (request: Request) => Promise<string | null> | string | null;
|
|
155
|
-
loginPath: string;
|
|
156
|
-
timeoutMs?: number;
|
|
157
|
-
/** @deprecated use `timeoutMs`. */
|
|
158
|
-
fetchTimeoutMs?: number;
|
|
159
|
-
fetch?: typeof fetch;
|
|
160
|
-
}
|
|
161
|
-
declare function createHandoffSource(config: HandoffSourceConfig): {
|
|
162
|
-
/** GET `/api/auth/handoffs/{app}/start?code_challenge=&state=` */
|
|
163
|
-
start(request: Request, app: string): Promise<Response>;
|
|
164
|
-
};
|
|
165
|
-
type HandoffSource = ReturnType<typeof createHandoffSource>;
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Coalesced refresh-token exchange for a BFF proxy: same refresh token within
|
|
169
|
-
* a short window shares one backend call. Per-process best effort; backend
|
|
170
|
-
* reuse detection is the correctness guarantee.
|
|
171
|
-
*/
|
|
172
|
-
interface RefreshedSession {
|
|
173
|
-
accessToken: string;
|
|
174
|
-
refreshToken?: string;
|
|
175
|
-
}
|
|
176
|
-
interface SessionRefresherConfig {
|
|
177
|
-
/** Backend origin, no /api/v1. May resolve asynchronously (a tenant-scoped origin). */
|
|
178
|
-
apiUrl: AsyncResolvable<string>;
|
|
179
|
-
/** e.g. /api/v1/platform/auth/refresh; empty when `apiUrl` already resolves to the full URL. */
|
|
180
|
-
refreshPath: string;
|
|
181
|
-
/** Extra request headers, e.g. a service credential and its tenant selector. */
|
|
182
|
-
headers?: AsyncResolvable<HeadersInit | undefined>;
|
|
183
|
-
clientType: string;
|
|
184
|
-
audience: string;
|
|
185
|
-
singleflightTtlMs?: number;
|
|
186
|
-
maxSingleflights?: number;
|
|
187
|
-
timeoutMs?: number;
|
|
188
|
-
/** @deprecated use `timeoutMs`. */
|
|
189
|
-
fetchTimeoutMs?: number;
|
|
190
|
-
fetch?: typeof fetch;
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Two refresh envelopes exist: the platform one (flat, with token_type and
|
|
194
|
-
* expires_at) and the end-user one (`{ data: { access_token, refresh_token? } }`,
|
|
195
|
-
* where a rotated refresh token is optional). Both carry the access token the
|
|
196
|
-
* same way; that is all a refresh needs.
|
|
197
|
-
*/
|
|
198
|
-
declare function parseRefreshEnvelope(value: unknown): RefreshedSession | null;
|
|
199
|
-
declare function createSessionRefresher(config: SessionRefresherConfig): {
|
|
200
|
-
refresh(refreshToken: string): Promise<RefreshedSession | null>;
|
|
201
|
-
size(): number;
|
|
202
|
-
};
|
|
203
|
-
type SessionRefresher = ReturnType<typeof createSessionRefresher>;
|
|
204
|
-
|
|
205
|
-
declare function hasSessionShape(token: string | undefined | null): boolean;
|
|
206
|
-
type SessionGateDecision = {
|
|
207
|
-
kind: "pass";
|
|
208
|
-
refreshed?: RefreshedSession;
|
|
209
|
-
} | {
|
|
210
|
-
kind: "redirect_home";
|
|
211
|
-
refreshed?: RefreshedSession;
|
|
212
|
-
} | {
|
|
213
|
-
kind: "anonymous_public";
|
|
214
|
-
} | {
|
|
215
|
-
kind: "unauthorized_api";
|
|
216
|
-
} | {
|
|
217
|
-
kind: "redirect_login";
|
|
218
|
-
};
|
|
219
|
-
interface SessionGateInput {
|
|
220
|
-
accessToken?: string | null;
|
|
221
|
-
refreshToken?: string | null;
|
|
222
|
-
audience: string;
|
|
223
|
-
refresher: Pick<SessionRefresher, "refresh">;
|
|
224
|
-
isPublic: boolean;
|
|
225
|
-
isLoginPath: boolean;
|
|
226
|
-
isApiPath: boolean;
|
|
227
|
-
expiringSoonBufferSeconds?: number;
|
|
228
|
-
}
|
|
229
|
-
declare function evaluateSessionGate(input: SessionGateInput): Promise<SessionGateDecision>;
|
|
230
|
-
|
|
231
|
-
export { AUTH_ERROR_MESSAGES, type AuthResponse, type CookieOptions, type DeviceIdentity, type DeviceIdentityConfig, type DeviceIdentityStore, HANDOFF_ERROR_FALLBACK, HANDOFF_ERROR_MESSAGES, type HandoffSource, type HandoffSourceConfig, type HandoffSourceTarget, type HandoffTarget, type HandoffTargetConfig, type RefreshedSession, SSO_ERROR_MESSAGES, type SessionData, type SessionGateDecision, type SessionGateInput, type SessionRefresher, type SessionRefresherConfig, type SessionUser, type TokenPayload, authErrorMessage, brokerPaths, createDeviceIdentity, createHandoffSource, createHandoffTarget, createSessionRefresher, decodeBase64Url, decodeDefaultSession, decodeTokenPayload, deleteCookie, evaluateSessionGate, handoffErrorMessage, hasSessionShape, hasTokenAudience, isAuthErrorCode, isHandoffErrorCode, isTokenExpired, isTokenExpiringSoon, parseAuthResponse, parseRefreshEnvelope, readCookie, safeInternalPath, serializeCookie, setCookie, sourceStartPath, tokenMaxAgeSeconds };
|