@authyon/server 0.2.0-beta.0 → 0.2.0-beta.2
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/README.md +126 -2
- package/dist/browser.cjs +21 -0
- package/dist/browser.d.cts +2 -0
- package/dist/browser.d.ts +2 -0
- package/dist/browser.js +4 -0
- package/dist/index.cjs +909 -70
- package/dist/index.d.cts +352 -65
- package/dist/index.d.ts +352 -65
- package/dist/index.js +895 -69
- package/package.json +58 -36
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,97 @@
|
|
|
1
|
+
import { JSONWebKeySet, JWTPayload, JWSHeaderParameters } from 'jose';
|
|
2
|
+
|
|
3
|
+
interface ClientRequestContext {
|
|
4
|
+
/** Real end-user IP, resolved only from infrastructure trusted by the application. */
|
|
5
|
+
clientIp?: string;
|
|
6
|
+
}
|
|
7
|
+
/** Rejects header injection and values that are not a single IPv4 or IPv6 address. */
|
|
8
|
+
declare function normalizeClientIp(value: string): string;
|
|
9
|
+
|
|
10
|
+
interface HttpAdapterRequest {
|
|
11
|
+
url: string;
|
|
12
|
+
method: string;
|
|
13
|
+
headers: Record<string, string>;
|
|
14
|
+
body?: BodyInit | null;
|
|
15
|
+
signal: AbortSignal;
|
|
16
|
+
}
|
|
17
|
+
/** Transport contract accepted by both Authyon clients. */
|
|
18
|
+
interface HttpAdapter {
|
|
19
|
+
request(request: HttpAdapterRequest): Promise<Response>;
|
|
20
|
+
}
|
|
21
|
+
type HttpLogEvent = {
|
|
22
|
+
type: "request";
|
|
23
|
+
method: string;
|
|
24
|
+
url: string;
|
|
25
|
+
timestamp: number;
|
|
26
|
+
} | {
|
|
27
|
+
type: "response";
|
|
28
|
+
method: string;
|
|
29
|
+
url: string;
|
|
30
|
+
status: number;
|
|
31
|
+
durationMs: number;
|
|
32
|
+
requestId?: string;
|
|
33
|
+
timestamp: number;
|
|
34
|
+
} | {
|
|
35
|
+
type: "error";
|
|
36
|
+
method: string;
|
|
37
|
+
url: string;
|
|
38
|
+
errorName: string;
|
|
39
|
+
durationMs: number;
|
|
40
|
+
timestamp: number;
|
|
41
|
+
};
|
|
42
|
+
/** Receives sanitized HTTP lifecycle events. Headers, bodies and query values are never exposed. */
|
|
43
|
+
type HttpLogger = (event: HttpLogEvent) => void;
|
|
44
|
+
/**
|
|
45
|
+
* Mutable logging configuration. Change `enabled` at runtime to enable or disable logging
|
|
46
|
+
* without recreating the Authyon client.
|
|
47
|
+
*/
|
|
48
|
+
interface HttpLoggerOptions {
|
|
49
|
+
enabled: boolean;
|
|
50
|
+
logger?: HttpLogger;
|
|
51
|
+
}
|
|
52
|
+
/** Default adapter backed by the platform's Fetch API. */
|
|
53
|
+
declare class FetchHttpAdapter implements HttpAdapter {
|
|
54
|
+
private readonly fetchImpl;
|
|
55
|
+
constructor(fetchImpl?: typeof fetch);
|
|
56
|
+
request(request: HttpAdapterRequest): Promise<Response>;
|
|
57
|
+
}
|
|
58
|
+
/** Adds safe, configurable lifecycle logging to any HTTP adapter. */
|
|
59
|
+
declare class LoggingHttpAdapter implements HttpAdapter {
|
|
60
|
+
private readonly adapter;
|
|
61
|
+
private readonly options;
|
|
62
|
+
constructor(adapter: HttpAdapter, options: HttpLoggerOptions);
|
|
63
|
+
request(request: HttpAdapterRequest): Promise<Response>;
|
|
64
|
+
private log;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
interface PaginationOptions {
|
|
68
|
+
skip?: number;
|
|
69
|
+
take?: number;
|
|
70
|
+
}
|
|
71
|
+
interface Paged<T> {
|
|
72
|
+
data: T[];
|
|
73
|
+
perPage?: number;
|
|
74
|
+
pageSize: number;
|
|
75
|
+
total: number;
|
|
76
|
+
pages: number;
|
|
77
|
+
hasNext: boolean;
|
|
78
|
+
hasPrev: boolean;
|
|
79
|
+
}
|
|
80
|
+
interface IntrospectResult {
|
|
81
|
+
active: boolean;
|
|
82
|
+
sub?: string;
|
|
83
|
+
username?: string | null;
|
|
84
|
+
email?: string | null;
|
|
85
|
+
roles?: string[] | null;
|
|
86
|
+
permissions?: string[];
|
|
87
|
+
client_id?: string;
|
|
88
|
+
scope?: string;
|
|
89
|
+
exp?: number;
|
|
90
|
+
iat?: number;
|
|
91
|
+
jti?: string;
|
|
92
|
+
token_type?: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
1
95
|
/** GET/POST /env/tenants — confirmed against the live API. */
|
|
2
96
|
interface Organization {
|
|
3
97
|
id: string;
|
|
@@ -24,6 +118,8 @@ interface User {
|
|
|
24
118
|
id: string;
|
|
25
119
|
email: string;
|
|
26
120
|
username?: string;
|
|
121
|
+
/** Environment-level roles from the database-validated user profile. */
|
|
122
|
+
roles?: string[];
|
|
27
123
|
permissions?: string[];
|
|
28
124
|
}
|
|
29
125
|
interface RoleGrant {
|
|
@@ -74,21 +170,6 @@ interface EnvironmentUser {
|
|
|
74
170
|
/** JSON-encoded string. */
|
|
75
171
|
customFields?: string;
|
|
76
172
|
}
|
|
77
|
-
/** POST /auth/introspect (RFC 7662) — confirmed against the live API. */
|
|
78
|
-
interface IntrospectResult {
|
|
79
|
-
active: boolean;
|
|
80
|
-
sub?: string;
|
|
81
|
-
username?: string | null;
|
|
82
|
-
email?: string | null;
|
|
83
|
-
roles?: string[] | null;
|
|
84
|
-
permissions?: string[];
|
|
85
|
-
client_id?: string;
|
|
86
|
-
scope?: string;
|
|
87
|
-
exp?: number;
|
|
88
|
-
iat?: number;
|
|
89
|
-
jti?: string;
|
|
90
|
-
token_type?: string;
|
|
91
|
-
}
|
|
92
173
|
/**
|
|
93
174
|
* POST /auth/validate — confirmed against the live API. The wire shape is
|
|
94
175
|
* `{ valid, reason, profile }`, not `{ user, organization }` as the
|
|
@@ -199,24 +280,8 @@ type LoginActivity = AuditEvent;
|
|
|
199
280
|
/**
|
|
200
281
|
* Envelope every `skip`/`take`-paginated list endpoint returns, confirmed
|
|
201
282
|
* live for `/env/users`, `/env/audit` and `/env/audit/login-activity`.
|
|
202
|
-
* Endpoints without `skip`/`take` params
|
|
203
|
-
* bare array instead.
|
|
283
|
+
* Endpoints without `skip`/`take` params return a bare array instead.
|
|
204
284
|
*/
|
|
205
|
-
interface Page<T> {
|
|
206
|
-
data: T[];
|
|
207
|
-
/** Item count actually returned for this page. */
|
|
208
|
-
perPage?: number;
|
|
209
|
-
pageSize: number;
|
|
210
|
-
total: number;
|
|
211
|
-
pages: number;
|
|
212
|
-
hasNext: boolean;
|
|
213
|
-
hasPrev: boolean;
|
|
214
|
-
}
|
|
215
|
-
/** Pagination options accepted by list endpoints. */
|
|
216
|
-
interface PageParams {
|
|
217
|
-
skip?: number;
|
|
218
|
-
take?: number;
|
|
219
|
-
}
|
|
220
285
|
/** OAuth 2.0 client-credentials pair minted in the Authyon console. */
|
|
221
286
|
interface ClientCredentials {
|
|
222
287
|
clientId: string;
|
|
@@ -257,18 +322,75 @@ interface AuthyonServerClientOptions {
|
|
|
257
322
|
clientSecret?: string;
|
|
258
323
|
/** API origin. Defaults to `https://api.authyon.com`. */
|
|
259
324
|
baseUrl?: string;
|
|
260
|
-
/**
|
|
325
|
+
/** Allow an HTTP `baseUrl`. Intended only for explicitly trusted local development. */
|
|
326
|
+
allowInsecureHttp?: boolean;
|
|
327
|
+
/** Maximum duration of each HTTP request. Defaults to 15 seconds; set to `0` to disable. */
|
|
328
|
+
timeoutMs?: number;
|
|
329
|
+
/** Custom HTTP adapter for tracing, mocks or an alternative HTTP stack. */
|
|
330
|
+
httpAdapter?: HttpAdapter;
|
|
331
|
+
/** Safe HTTP lifecycle logging. Disabled unless this option is provided with `enabled: true`. */
|
|
332
|
+
httpLogger?: HttpLoggerOptions;
|
|
333
|
+
/** @deprecated Prefer `httpAdapter: new FetchHttpAdapter(customFetch)`. */
|
|
261
334
|
fetch?: typeof fetch;
|
|
262
335
|
}
|
|
263
336
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
337
|
+
type SafeJwtAlgorithm = "RS256" | "PS256" | "ES256" | "EdDSA";
|
|
338
|
+
interface AuthyonJwtClaims extends JWTPayload {
|
|
339
|
+
sub: string;
|
|
340
|
+
iss: string;
|
|
341
|
+
aud: string | string[];
|
|
342
|
+
exp: number;
|
|
343
|
+
iat: number;
|
|
344
|
+
email?: string;
|
|
345
|
+
username?: string;
|
|
346
|
+
roles?: string[];
|
|
347
|
+
permissions?: string[];
|
|
348
|
+
scope?: string;
|
|
349
|
+
}
|
|
350
|
+
interface VerifiedAccessToken {
|
|
351
|
+
claims: AuthyonJwtClaims;
|
|
352
|
+
protectedHeader: JWSHeaderParameters;
|
|
271
353
|
}
|
|
354
|
+
interface JwksTokenVerifierOptions {
|
|
355
|
+
/** Exact trusted issuer from Authyon OpenID discovery. */
|
|
356
|
+
issuer: string;
|
|
357
|
+
/** Audience assigned to the API consuming this token. */
|
|
358
|
+
audience: string | string[];
|
|
359
|
+
/** Trusted HTTPS JWKS endpoint. Never derive this value from the token header. */
|
|
360
|
+
jwksUri?: string;
|
|
361
|
+
/** Static trusted keys for pinned or offline verification. */
|
|
362
|
+
jwks?: JSONWebKeySet;
|
|
363
|
+
algorithms?: readonly SafeJwtAlgorithm[];
|
|
364
|
+
acceptedTokenTypes?: readonly string[];
|
|
365
|
+
clockToleranceSeconds?: number;
|
|
366
|
+
maxTokenAgeSeconds?: number;
|
|
367
|
+
jwksTimeoutMs?: number;
|
|
368
|
+
jwksCacheMs?: number;
|
|
369
|
+
jwksCooldownMs?: number;
|
|
370
|
+
}
|
|
371
|
+
interface AuthyonJwksDiscoveryOptions extends Omit<JwksTokenVerifierOptions, "issuer" | "jwksUri" | "jwks"> {
|
|
372
|
+
/** Optional pin; discovery fails if Authyon advertises a different issuer. */
|
|
373
|
+
issuer?: string;
|
|
374
|
+
/** Override the client environment key used by the discovery endpoint. */
|
|
375
|
+
publishableKey?: string;
|
|
376
|
+
}
|
|
377
|
+
type TokenVerificationErrorCode = "token.invalid" | "token.expired" | "token.not_active" | "token.invalid_claims" | "token.invalid_signature" | "token.key_unavailable";
|
|
378
|
+
declare class TokenVerificationError extends Error {
|
|
379
|
+
readonly code: TokenVerificationErrorCode;
|
|
380
|
+
constructor(code: TokenVerificationErrorCode, options?: {
|
|
381
|
+
cause?: unknown;
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
/** Secure, cached JWT signature and claims verifier backed by a trusted remote JWKS. */
|
|
385
|
+
declare class JwksTokenVerifier {
|
|
386
|
+
private readonly options;
|
|
387
|
+
private readonly verifyKey;
|
|
388
|
+
private readonly algorithms;
|
|
389
|
+
private readonly acceptedTokenTypes;
|
|
390
|
+
constructor(options: JwksTokenVerifierOptions);
|
|
391
|
+
verifyAccessToken(token: string): Promise<VerifiedAccessToken>;
|
|
392
|
+
}
|
|
393
|
+
|
|
272
394
|
/**
|
|
273
395
|
* Server-side Authyon client: environment/tenant administration (OAuth
|
|
274
396
|
* client-credentials) plus access-token verification (publishable key).
|
|
@@ -279,10 +401,9 @@ declare class AuthyonServerClient {
|
|
|
279
401
|
private readonly envKey?;
|
|
280
402
|
private readonly clientId?;
|
|
281
403
|
private readonly clientSecret?;
|
|
282
|
-
private readonly
|
|
283
|
-
private readonly
|
|
284
|
-
private
|
|
285
|
-
private environmentTokenInFlight;
|
|
404
|
+
private readonly transport;
|
|
405
|
+
private readonly http;
|
|
406
|
+
private readonly environmentTokenProvider;
|
|
286
407
|
constructor(options?: AuthyonServerClientOptions);
|
|
287
408
|
private request;
|
|
288
409
|
/** Mints (and caches) an environment access token from `clientId`/`clientSecret`. */
|
|
@@ -293,10 +414,12 @@ declare class AuthyonServerClient {
|
|
|
293
414
|
/** GET /.well-known/openid-configuration — OIDC discovery document. */
|
|
294
415
|
openidConfiguration: (publishableKey?: string) => Promise<OpenIdConfiguration>;
|
|
295
416
|
};
|
|
417
|
+
/** Discovers Authyon's trusted issuer/JWKS and creates a cached local access-token verifier. */
|
|
418
|
+
createJwksTokenVerifier(options: AuthyonJwksDiscoveryOptions): Promise<JwksTokenVerifier>;
|
|
296
419
|
/** POST /auth/introspect — lightweight token introspection (RFC 7662). */
|
|
297
|
-
introspect(token: string): Promise<IntrospectResult>;
|
|
420
|
+
introspect(token: string, context?: ClientRequestContext): Promise<IntrospectResult>;
|
|
298
421
|
/** POST /auth/validate — recommended: cross-checks DB state, catches revocation immediately. */
|
|
299
|
-
validate(token: string): Promise<ValidateResult>;
|
|
422
|
+
validate(token: string, context?: ClientRequestContext): Promise<ValidateResult>;
|
|
300
423
|
readonly environmentAuth: {
|
|
301
424
|
/** POST /env/oauth/token — exchanges environment client credentials for an access token. */
|
|
302
425
|
token: (credentials: ClientCredentials) => Promise<TokenResult>;
|
|
@@ -317,7 +440,7 @@ declare class AuthyonServerClient {
|
|
|
317
440
|
/** GET /env/users — paginated list of users in the environment. */
|
|
318
441
|
list: (params?: {
|
|
319
442
|
search?: string;
|
|
320
|
-
} &
|
|
443
|
+
} & PaginationOptions) => Promise<Paged<EnvironmentUser>>;
|
|
321
444
|
/** POST /env/users — create a user in the environment; returns only the new id. */
|
|
322
445
|
create: (input: CreateUserInput) => Promise<{
|
|
323
446
|
id: string;
|
|
@@ -354,8 +477,10 @@ declare class AuthyonServerClient {
|
|
|
354
477
|
removeTenant: (userId: string, tenantId: string) => Promise<void>;
|
|
355
478
|
};
|
|
356
479
|
tenants: {
|
|
357
|
-
/** GET /env/tenants — list tenants in the environment. */
|
|
358
|
-
list: (
|
|
480
|
+
/** GET /env/tenants — paginated, searchable list of tenants in the environment. */
|
|
481
|
+
list: (params?: {
|
|
482
|
+
search?: string;
|
|
483
|
+
} & PaginationOptions) => Promise<Paged<Organization>>;
|
|
359
484
|
/** POST /env/tenants — create a tenant in the environment. */
|
|
360
485
|
create: (input: CreateOrganizationInput) => Promise<Organization>;
|
|
361
486
|
/** GET /env/tenants/{tenantId} — fetch a tenant by id. */
|
|
@@ -372,7 +497,7 @@ declare class AuthyonServerClient {
|
|
|
372
497
|
* accepting `skip`/`take`), with the same shape
|
|
373
498
|
* `environment.users.list()` items have.
|
|
374
499
|
*/
|
|
375
|
-
list: (tenantId: string, params?:
|
|
500
|
+
list: (tenantId: string, params?: PaginationOptions) => Promise<EnvironmentUser[]>;
|
|
376
501
|
/** POST /env/tenants/{tenantId}/members — add a member to a tenant. */
|
|
377
502
|
add: (tenantId: string, userId: string, roles?: string[]) => Promise<void>;
|
|
378
503
|
/** DELETE /env/tenants/{tenantId}/members/{userId} — remove a member from a tenant. */
|
|
@@ -423,9 +548,9 @@ declare class AuthyonServerClient {
|
|
|
423
548
|
};
|
|
424
549
|
audit: {
|
|
425
550
|
/** GET /env/audit — paginated list of the environment's audit events. */
|
|
426
|
-
list: (params?:
|
|
551
|
+
list: (params?: PaginationOptions) => Promise<Paged<AuditEvent>>;
|
|
427
552
|
/** GET /env/audit/login-activity — paginated login activity in the environment. */
|
|
428
|
-
loginActivity: (params?:
|
|
553
|
+
loginActivity: (params?: PaginationOptions) => Promise<Paged<LoginActivity>>;
|
|
429
554
|
};
|
|
430
555
|
};
|
|
431
556
|
readonly permissions: {
|
|
@@ -435,7 +560,12 @@ declare class AuthyonServerClient {
|
|
|
435
560
|
revoke: (userId: string, permission: string) => Promise<void>;
|
|
436
561
|
};
|
|
437
562
|
/** @internal used by {@link TenantScopedClient} to share the base URL/fetch/error handling. */
|
|
438
|
-
_requestAsTenant<T>(accessToken: string, path: string, options?:
|
|
563
|
+
_requestAsTenant<T>(accessToken: string, path: string, options?: {
|
|
564
|
+
method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
565
|
+
body?: unknown;
|
|
566
|
+
query?: object;
|
|
567
|
+
headers?: Record<string, string>;
|
|
568
|
+
}): Promise<T>;
|
|
439
569
|
}
|
|
440
570
|
/**
|
|
441
571
|
* Client scoped to a single tenant's OAuth credentials — every call acts on
|
|
@@ -444,9 +574,7 @@ declare class AuthyonServerClient {
|
|
|
444
574
|
*/
|
|
445
575
|
declare class TenantScopedClient {
|
|
446
576
|
private readonly server;
|
|
447
|
-
private readonly
|
|
448
|
-
private token;
|
|
449
|
-
private tokenInFlight;
|
|
577
|
+
private readonly tokenProvider;
|
|
450
578
|
constructor(server: AuthyonServerClient, credentials: ClientCredentials);
|
|
451
579
|
private getAccessToken;
|
|
452
580
|
private request;
|
|
@@ -460,7 +588,7 @@ declare class TenantScopedClient {
|
|
|
460
588
|
* user records), since both are the "admin" member listing as opposed
|
|
461
589
|
* to `/auth/tenants/{id}/members`'s paginated, lightweight one.
|
|
462
590
|
*/
|
|
463
|
-
list: (params?:
|
|
591
|
+
list: (params?: PaginationOptions) => Promise<EnvironmentUser[]>;
|
|
464
592
|
/** POST /tenant/members — add a member to the token's tenant. */
|
|
465
593
|
add: (userId: string, roles?: string[]) => Promise<void>;
|
|
466
594
|
/** DELETE /tenant/members/{userId} — remove a member from the token's tenant. */
|
|
@@ -497,23 +625,182 @@ declare class TenantScopedClient {
|
|
|
497
625
|
/** Convenience factory: `const authyon = createClient({ clientId, clientSecret })`. */
|
|
498
626
|
declare function createClient(options?: AuthyonServerClientOptions): AuthyonServerClient;
|
|
499
627
|
|
|
500
|
-
/**
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
628
|
+
/** Builds a server client while keeping environment credentials grouped. */
|
|
629
|
+
declare class AuthyonServerClientBuilder {
|
|
630
|
+
private readonly options;
|
|
631
|
+
withEnvironmentKey(envKey: string): this;
|
|
632
|
+
withEnvironmentCredentials(clientId: string, clientSecret: string): this;
|
|
633
|
+
withBaseUrl(baseUrl: string, allowInsecureHttp?: boolean): this;
|
|
634
|
+
withTimeout(timeoutMs: number): this;
|
|
635
|
+
withHttpAdapter(httpAdapter: HttpAdapter): this;
|
|
636
|
+
withHttpLogger(httpLogger: HttpLoggerOptions): this;
|
|
637
|
+
build(): AuthyonServerClient;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
declare const ErrorCodes: {
|
|
641
|
+
readonly Unknown: "unknown";
|
|
642
|
+
readonly NetworkError: "request.network_error";
|
|
643
|
+
readonly Timeout: "request.timeout";
|
|
644
|
+
readonly SessionMalformed: "session.malformed";
|
|
645
|
+
readonly NotAuthenticated: "auth.not_authenticated";
|
|
646
|
+
readonly InvalidToken: "auth.invalid_token";
|
|
647
|
+
readonly MissingToken: "auth.missing_token";
|
|
648
|
+
readonly EmailTaken: "user.email_taken";
|
|
649
|
+
readonly PasswordWeak: "user.password_weak";
|
|
650
|
+
readonly PasswordPwned: "user.password_pwned";
|
|
651
|
+
readonly RateLimited: "rate_limited";
|
|
652
|
+
};
|
|
653
|
+
type KnownErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
|
|
654
|
+
type AuthyonErrorCategory = "network" | "timeout" | "authentication" | "authorization" | "validation" | "not_found" | "conflict" | "rate_limit" | "server" | "unknown";
|
|
655
|
+
type AuthyonErrorAction = "retry" | "reauthenticate" | "request_access" | "fix_input" | "not_found" | "resolve_conflict" | "contact_support";
|
|
656
|
+
interface AuthyonErrorInterpretation {
|
|
657
|
+
category: AuthyonErrorCategory;
|
|
658
|
+
action: AuthyonErrorAction;
|
|
659
|
+
retryable: boolean;
|
|
660
|
+
retryAfter?: number;
|
|
661
|
+
requestId?: string;
|
|
662
|
+
}
|
|
663
|
+
/** Shared RFC 7807 error implementation used by both public SDKs. */
|
|
506
664
|
declare class AuthyonError extends Error {
|
|
507
665
|
readonly status: number;
|
|
508
666
|
readonly code: string;
|
|
509
667
|
readonly title: string;
|
|
510
668
|
readonly detail?: string;
|
|
669
|
+
readonly requestId?: string;
|
|
670
|
+
readonly retryAfter?: number;
|
|
671
|
+
readonly cause?: unknown;
|
|
511
672
|
constructor(status: number, body: Partial<{
|
|
512
673
|
title: string;
|
|
513
674
|
detail: string;
|
|
514
675
|
code: string;
|
|
515
|
-
}
|
|
676
|
+
}>, options?: {
|
|
677
|
+
requestId?: string;
|
|
678
|
+
retryAfter?: number;
|
|
679
|
+
cause?: unknown;
|
|
680
|
+
});
|
|
516
681
|
is(code: string): boolean;
|
|
682
|
+
isAny(...codes: readonly string[]): boolean;
|
|
683
|
+
hasPrefix(prefix: string): boolean;
|
|
684
|
+
isStatus(...statuses: readonly number[]): boolean;
|
|
685
|
+
/** Stable interpretation for UI decisions, retries, telemetry and support flows. */
|
|
686
|
+
interpret(): AuthyonErrorInterpretation;
|
|
687
|
+
get category(): AuthyonErrorCategory;
|
|
688
|
+
get retryable(): boolean;
|
|
689
|
+
toJSON(): Record<string, unknown>;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
type AbilitySubject = string | Record<string, unknown>;
|
|
693
|
+
type AbilityConditions = Record<string, unknown>;
|
|
694
|
+
interface AbilityRule {
|
|
695
|
+
action: string | string[];
|
|
696
|
+
subject: string | string[];
|
|
697
|
+
inverted?: boolean;
|
|
698
|
+
conditions?: AbilityConditions;
|
|
699
|
+
fields?: string[];
|
|
700
|
+
reason?: string;
|
|
701
|
+
}
|
|
702
|
+
interface AuthyonPermissionSource {
|
|
703
|
+
permissions?: readonly string[] | null;
|
|
704
|
+
roles?: readonly string[] | null;
|
|
705
|
+
/** OAuth scopes are also accepted and interpreted as Authyon permissions. */
|
|
706
|
+
scope?: string | null;
|
|
707
|
+
}
|
|
708
|
+
interface AuthyonAbilityOptions {
|
|
709
|
+
rules?: readonly AbilityRule[];
|
|
710
|
+
/** Rules added when the source contains a matching Authyon role. */
|
|
711
|
+
roleRules?: Readonly<Record<string, readonly AbilityRule[]>>;
|
|
712
|
+
roles?: readonly string[] | null;
|
|
713
|
+
detectSubjectType?: (subject: Record<string, unknown>) => string;
|
|
714
|
+
}
|
|
715
|
+
type AbilityEvent = "updated";
|
|
716
|
+
type AbilityListener = (rules: readonly AbilityRule[]) => void;
|
|
717
|
+
/** Isomorphic, deny-by-default authorization engine backed by Authyon permissions. */
|
|
718
|
+
declare class AuthyonAbility {
|
|
719
|
+
private readonly detectSubjectType;
|
|
720
|
+
private currentRules;
|
|
721
|
+
private readonly listeners;
|
|
722
|
+
constructor(rules?: readonly AbilityRule[], detectSubjectType?: (subject: Record<string, unknown>) => string);
|
|
723
|
+
get rules(): readonly AbilityRule[];
|
|
724
|
+
can(action: string, subject: AbilitySubject, field?: string): boolean;
|
|
725
|
+
cannot(action: string, subject: AbilitySubject, field?: string): boolean;
|
|
726
|
+
rulesFor(action: string, subject: string): readonly AbilityRule[];
|
|
727
|
+
update(rules: readonly AbilityRule[]): void;
|
|
728
|
+
on(event: AbilityEvent, listener: AbilityListener): () => void;
|
|
729
|
+
}
|
|
730
|
+
/** Fluent rule builder with CASL-like `can` and `cannot` methods. */
|
|
731
|
+
declare class AuthyonAbilityBuilder {
|
|
732
|
+
readonly rules: AbilityRule[];
|
|
733
|
+
can(action: string | string[], subject: string | string[], conditions?: AbilityConditions, fields?: string[]): this;
|
|
734
|
+
cannot(action: string | string[], subject: string | string[], conditions?: AbilityConditions, fields?: string[], reason?: string): this;
|
|
735
|
+
build(options?: Pick<AuthyonAbilityOptions, "detectSubjectType">): AuthyonAbility;
|
|
736
|
+
}
|
|
737
|
+
/** Creates an ability from Authyon permissions, OAuth scope and optional role rules. */
|
|
738
|
+
declare function createAuthyonAbility(source?: AuthyonPermissionSource, options?: AuthyonAbilityOptions): AuthyonAbility;
|
|
739
|
+
/** Checks an Authyon permission string using the same wildcard rules as an ability. */
|
|
740
|
+
declare function hasPermission(source: AuthyonPermissionSource | readonly string[], requiredPermission: string): boolean;
|
|
741
|
+
/** Converts Authyon's `subject:action` permission strings to authorization rules. */
|
|
742
|
+
declare function createAuthyonRules(source?: AuthyonPermissionSource, options?: AuthyonAbilityOptions): AbilityRule[];
|
|
743
|
+
|
|
744
|
+
interface AbilityRequirement {
|
|
745
|
+
action: string;
|
|
746
|
+
subject: AbilitySubject;
|
|
747
|
+
field?: string;
|
|
748
|
+
}
|
|
749
|
+
interface AuthorizationContext {
|
|
750
|
+
token: string;
|
|
751
|
+
userId?: string;
|
|
752
|
+
ability: AuthyonAbility;
|
|
753
|
+
permissions: readonly string[];
|
|
754
|
+
roles: readonly string[];
|
|
755
|
+
}
|
|
756
|
+
interface AuthorizationOptions extends AuthyonAbilityOptions {
|
|
757
|
+
requirement?: AbilityRequirement;
|
|
758
|
+
/** Uses database-backed validation by default; introspection can be selected when desired. */
|
|
759
|
+
verification?: "validate" | "introspect" | "jwks";
|
|
760
|
+
/** Required for local JWKS verification. Create once and reuse its key cache. */
|
|
761
|
+
jwksVerifier?: JwksTokenVerifier;
|
|
762
|
+
/** Real end-user IP, obtained from trusted application infrastructure. */
|
|
763
|
+
clientIp?: string;
|
|
764
|
+
}
|
|
765
|
+
declare class AuthorizationError extends Error {
|
|
766
|
+
readonly status: 401 | 403 | 503;
|
|
767
|
+
readonly code: "authorization.unauthenticated" | "authorization.forbidden" | "authorization.unavailable";
|
|
768
|
+
constructor(status: 401 | 403 | 503, code: "authorization.unauthenticated" | "authorization.forbidden" | "authorization.unavailable", message: string);
|
|
769
|
+
}
|
|
770
|
+
/** Validates a bearer token and creates an Authyon-backed ability for server runtimes. */
|
|
771
|
+
declare function authorizeToken(client: AuthyonServerClient, token: string, options?: AuthorizationOptions): Promise<AuthorizationContext>;
|
|
772
|
+
/** Works with Web Request objects used by Next.js Route Handlers and other Fetch runtimes. */
|
|
773
|
+
declare function authorizeRequest(client: AuthyonServerClient, request: Pick<Request, "headers">, options?: RequestAuthorizationOptions): Promise<AuthorizationContext>;
|
|
774
|
+
interface RequestAuthorizationOptions extends AuthorizationOptions {
|
|
775
|
+
/** Platform-aware resolver. Only read headers that your trusted proxy overwrites. */
|
|
776
|
+
resolveClientIp?: (request: Pick<Request, "headers">) => string | undefined;
|
|
777
|
+
}
|
|
778
|
+
interface ExpressRequestLike {
|
|
779
|
+
headers: Record<string, string | string[] | undefined>;
|
|
780
|
+
ip?: string;
|
|
781
|
+
socket?: {
|
|
782
|
+
remoteAddress?: string;
|
|
783
|
+
};
|
|
784
|
+
authyon?: AuthorizationContext;
|
|
785
|
+
}
|
|
786
|
+
interface ExpressResponseLike {
|
|
787
|
+
status(code: number): ExpressResponseLike;
|
|
788
|
+
json(body: unknown): unknown;
|
|
789
|
+
}
|
|
790
|
+
type ExpressNext = (error?: unknown) => void;
|
|
791
|
+
interface ExpressAuthorizationMiddlewareOptions extends AuthorizationOptions {
|
|
792
|
+
/** Property assigned to the request. Defaults to `authyon`. */
|
|
793
|
+
requestProperty?: string;
|
|
794
|
+
/** Pass authorization errors to Express error middleware instead of writing a JSON response. */
|
|
795
|
+
passErrorsToNext?: boolean;
|
|
796
|
+
/** Trust Express's proxy-aware `request.ip`. Disabled by default. */
|
|
797
|
+
trustProxy?: boolean;
|
|
798
|
+
/** Overrides all built-in IP resolution; return only a trusted, single client IP. */
|
|
799
|
+
resolveClientIp?: (request: ExpressRequestLike) => string | undefined;
|
|
517
800
|
}
|
|
801
|
+
/** Dependency-free middleware compatible with Express and similar Connect frameworks. */
|
|
802
|
+
declare function createExpressAuthorizationMiddleware(client: AuthyonServerClient, options?: ExpressAuthorizationMiddlewareOptions): (request: ExpressRequestLike & Record<string, unknown>, response: ExpressResponseLike, next: ExpressNext) => Promise<void>;
|
|
803
|
+
/** Converts an authorization error into a Fetch Response suitable for Next.js. */
|
|
804
|
+
declare function createAuthorizationErrorResponse(error: unknown): Response;
|
|
518
805
|
|
|
519
|
-
export { type AuditEvent, AuthyonError, AuthyonServerClient, type AuthyonServerClientOptions, type ClientCredentials, type CreateOrganizationInput, type CreatePermissionInput, type CreateUserInput, type EnvironmentUser, type IntrospectResult, type JsonWebKeySet, type LoginActivity, type OpenIdConfiguration, type Organization, type
|
|
806
|
+
export { type AbilityConditions, type AbilityEvent, type AbilityListener, type AbilityRequirement, type AbilityRule, type AbilitySubject, type AuditEvent, type AuthorizationContext, AuthorizationError, type AuthorizationOptions, AuthyonAbility, AuthyonAbilityBuilder, type AuthyonAbilityOptions, AuthyonError, type AuthyonErrorAction, type AuthyonErrorCategory, type AuthyonErrorInterpretation, type AuthyonJwksDiscoveryOptions, type AuthyonJwtClaims, type AuthyonPermissionSource, AuthyonServerClient, AuthyonServerClientBuilder, type AuthyonServerClientOptions, type ClientCredentials, type ClientRequestContext, type CreateOrganizationInput, type CreatePermissionInput, type CreateUserInput, type EnvironmentUser, ErrorCodes, type ExpressAuthorizationMiddlewareOptions, type ExpressNext, type ExpressRequestLike, type ExpressResponseLike, FetchHttpAdapter, type HttpAdapter, type HttpAdapterRequest, type HttpLogEvent, type HttpLogger, type HttpLoggerOptions, type IntrospectResult, type JsonWebKeySet, JwksTokenVerifier, type JwksTokenVerifierOptions, type KnownErrorCode, LoggingHttpAdapter, type LoginActivity, type OpenIdConfiguration, type Organization, type Paged, type PaginationOptions, type Permission, type PermissionsByRole, type RequestAuthorizationOptions, type ReservedPermissions, type Role, type RoleGrant, type RoleInput, type RoleList, type RolePermissions, type SafeJwtAlgorithm, type TenantMembership, TenantScopedClient, type TokenResult, TokenVerificationError, type TokenVerificationErrorCode, type UpdateOrganizationInput, type User, type ValidateResult, type VerifiedAccessToken, authorizeRequest, authorizeToken, createAuthorizationErrorResponse, createAuthyonAbility, createAuthyonRules, createClient, createExpressAuthorizationMiddleware, hasPermission, normalizeClientIp };
|