@authyon/auth 0.2.0-beta.2 → 0.2.0-beta.21
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/README.md +62 -21
- package/dist/{ability-g6nBpOQM.d.cts → ability-BTcayvkM.d.cts} +324 -10
- package/dist/{ability-g6nBpOQM.d.ts → ability-BTcayvkM.d.ts} +324 -10
- package/dist/{chunk-EHZEUM47.js → chunk-3XJY6BCI.js} +6 -0
- package/dist/index.cjs +235 -36
- package/dist/index.d.cts +48 -21
- package/dist/index.d.ts +48 -21
- package/dist/index.js +225 -31
- package/dist/react/index.d.cts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +1 -1
- package/package.json +1 -1
|
@@ -1,3 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security methods active on the user's account, as returned in the
|
|
3
|
+
* `security` field of `GET /auth/me` and `POST /auth/validate`.
|
|
4
|
+
*/
|
|
5
|
+
interface SecurityMethods {
|
|
6
|
+
/** A password is set (false for accounts created only through SSO or magic link). */
|
|
7
|
+
password: boolean;
|
|
8
|
+
/** Authenticator app (TOTP one-time codes). */
|
|
9
|
+
authenticator: boolean;
|
|
10
|
+
/** One-time codes sent by email. */
|
|
11
|
+
emailCode: boolean;
|
|
12
|
+
/** At least one passkey registered. */
|
|
13
|
+
passkey: boolean;
|
|
14
|
+
passkeyCount: number;
|
|
15
|
+
/** Unused recovery codes left. */
|
|
16
|
+
recoveryCodes: number;
|
|
17
|
+
/** SSO providers linked to the account, e.g. `["google", "github"]`. */
|
|
18
|
+
sso: string[];
|
|
19
|
+
/** Any second factor is active (authenticator, email code or passkey). */
|
|
20
|
+
twoFactor: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** Lifecycle of an approval. */
|
|
23
|
+
type ApprovalStatus = "pending" | "approved" | "denied" | "consumed" | "expired";
|
|
24
|
+
/**
|
|
25
|
+
* Free-form JSON object describing what the customer approves (up to 16 KiB).
|
|
26
|
+
* The API stores it, shows it back to the customer and binds its canonical
|
|
27
|
+
* hash (keys sorted) to the approval.
|
|
28
|
+
*/
|
|
29
|
+
type ApprovalPayload = Record<string, unknown>;
|
|
30
|
+
/** Evidence of how the customer proved their identity when approving. */
|
|
31
|
+
interface ApprovalAssurance {
|
|
32
|
+
/** `urn:authyon:loa:3` (passkey) or `urn:authyon:loa:2` (authenticator code). */
|
|
33
|
+
acr: string;
|
|
34
|
+
/** Authentication methods, e.g. `["pwd", "otp"]` or `["pwd", "webauthn"]`. */
|
|
35
|
+
amr: string[];
|
|
36
|
+
/** When the second factor was verified (ISO 8601). */
|
|
37
|
+
authTime: string;
|
|
38
|
+
}
|
|
39
|
+
/** A request for the customer to approve something with a second factor. */
|
|
40
|
+
interface Approval {
|
|
41
|
+
id: string;
|
|
42
|
+
status: ApprovalStatus;
|
|
43
|
+
subjectId: string;
|
|
44
|
+
tenantId?: string | null;
|
|
45
|
+
/** The payload given to `create()`, with keys in canonical order. */
|
|
46
|
+
payload: ApprovalPayload;
|
|
47
|
+
/** SHA-256 (hex) of the canonical payload. */
|
|
48
|
+
payloadHash: string;
|
|
49
|
+
createdAt: string;
|
|
50
|
+
expiresAt: string;
|
|
51
|
+
decidedAt?: string | null;
|
|
52
|
+
consumedAt?: string | null;
|
|
53
|
+
/** Present once approved. */
|
|
54
|
+
assurance?: ApprovalAssurance | null;
|
|
55
|
+
}
|
|
56
|
+
/** Second factor sent with `confirm()`. */
|
|
57
|
+
type ConfirmApprovalInput = {
|
|
58
|
+
method: "authenticator";
|
|
59
|
+
/** Six-digit code from the customer's authenticator app. */
|
|
60
|
+
code: string;
|
|
61
|
+
} | {
|
|
62
|
+
method: "webauthn";
|
|
63
|
+
/** Assertion for the options returned by `webauthnOptions()`. */
|
|
64
|
+
webAuthn: {
|
|
65
|
+
ceremonyToken: string;
|
|
66
|
+
/** JSON-serialized `PublicKeyCredential` from `navigator.credentials.get()`. */
|
|
67
|
+
assertionJson: string;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
/** Passkey assertion options for approving one approval. */
|
|
71
|
+
interface ApprovalWebAuthnOptions {
|
|
72
|
+
ceremonyToken: string;
|
|
73
|
+
/** JSON `PublicKeyCredentialRequestOptions` to pass to `navigator.credentials.get()`. */
|
|
74
|
+
optionsJson: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
1
77
|
interface HttpAdapterRequest {
|
|
2
78
|
url: string;
|
|
3
79
|
method: string;
|
|
@@ -55,14 +131,53 @@ declare class LoggingHttpAdapter implements HttpAdapter {
|
|
|
55
131
|
private log;
|
|
56
132
|
}
|
|
57
133
|
|
|
134
|
+
/** Customer-side operations on an approval (`/auth/authorizations`). */
|
|
135
|
+
interface SubjectApprovals {
|
|
136
|
+
/** GET /auth/authorizations/{id} — the pending payload, to show before asking for the code. */
|
|
137
|
+
get(id: string): Promise<Approval>;
|
|
138
|
+
/** POST /auth/authorizations/{id}/webauthn/options — passkey options for approving it. */
|
|
139
|
+
webauthnOptions(id: string): Promise<ApprovalWebAuthnOptions>;
|
|
140
|
+
/**
|
|
141
|
+
* POST /auth/authorizations/{id}/confirm — approves it.
|
|
142
|
+
*
|
|
143
|
+
* Pass the authenticator code or passkey assertion to verify the second
|
|
144
|
+
* factor inline (recommended). Without `input`, the session itself must
|
|
145
|
+
* have used a passkey or authenticator code within the last 5 minutes,
|
|
146
|
+
* otherwise the API answers `step_up_required`.
|
|
147
|
+
*/
|
|
148
|
+
confirm(id: string, input?: ConfirmApprovalInput): Promise<Approval>;
|
|
149
|
+
/** POST /auth/authorizations/{id}/reject — the customer declines it. */
|
|
150
|
+
reject(id: string): Promise<Approval>;
|
|
151
|
+
}
|
|
152
|
+
/** The `security` namespace an end-user client exposes. */
|
|
153
|
+
interface SubjectSecurity {
|
|
154
|
+
/**
|
|
155
|
+
* GET /auth/me — which security methods the signed-in user has active
|
|
156
|
+
* (password, authenticator, email code, passkeys, recovery codes, SSO).
|
|
157
|
+
*/
|
|
158
|
+
methods(): Promise<SecurityMethods>;
|
|
159
|
+
/** Approve or reject what your backend asked the customer to confirm. */
|
|
160
|
+
readonly approvals: SubjectApprovals;
|
|
161
|
+
}
|
|
162
|
+
|
|
58
163
|
interface PaginationOptions {
|
|
59
164
|
skip?: number;
|
|
60
165
|
take?: number;
|
|
61
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* The envelope every paged endpoint answers with.
|
|
169
|
+
*
|
|
170
|
+
* `page` is the 1-based current page and `perPage` is how many items a page
|
|
171
|
+
* holds — the same sense `take` has on the way in. Up to Authyon API
|
|
172
|
+
* 2026-10-21 the two were named `perPage` (holding the page number) and
|
|
173
|
+
* `pageSize` (holding the limit), so reading them by their names gave the
|
|
174
|
+
* wrong value without failing. Clients on the older API see `page` undefined
|
|
175
|
+
* and `perPage` holding a page number.
|
|
176
|
+
*/
|
|
62
177
|
interface Paged<T> {
|
|
63
178
|
data: T[];
|
|
64
|
-
|
|
65
|
-
|
|
179
|
+
page: number;
|
|
180
|
+
perPage: number;
|
|
66
181
|
total: number;
|
|
67
182
|
pages: number;
|
|
68
183
|
hasNext: boolean;
|
|
@@ -93,12 +208,17 @@ interface Organization {
|
|
|
93
208
|
name?: string;
|
|
94
209
|
description?: string;
|
|
95
210
|
roles?: string[];
|
|
211
|
+
/** JSON-encoded values for the organization's configured custom fields. */
|
|
212
|
+
customFields?: string;
|
|
213
|
+
/** JSON-encoded metadata visible to members of the organization. */
|
|
214
|
+
publicMetadata?: string;
|
|
96
215
|
}
|
|
97
216
|
/** POST /auth/tenants — creates an organization owned by the signed-in user. */
|
|
98
217
|
interface CreateOrganizationInput {
|
|
99
218
|
name?: string;
|
|
100
219
|
slug?: string;
|
|
101
220
|
description?: string;
|
|
221
|
+
customFields?: Record<string, unknown>;
|
|
102
222
|
}
|
|
103
223
|
/** GET /auth/tenants/{organizationId}/members — confirmed against the live API. */
|
|
104
224
|
interface OrganizationMember {
|
|
@@ -114,6 +234,109 @@ interface InviteMemberInput {
|
|
|
114
234
|
email: string;
|
|
115
235
|
roles: string[];
|
|
116
236
|
}
|
|
237
|
+
/**
|
|
238
|
+
* POST /auth/tenants/{organizationId}/invites — invite an address that may not
|
|
239
|
+
* have an account yet; accepting creates it. `sendEmail` defaults to `true`;
|
|
240
|
+
* `false` only returns the link, for delivery through your own channel.
|
|
241
|
+
*/
|
|
242
|
+
interface OrganizationInviteInput {
|
|
243
|
+
email: string;
|
|
244
|
+
roles?: string[];
|
|
245
|
+
sendEmail?: boolean;
|
|
246
|
+
/**
|
|
247
|
+
* Where to send the invitee after they accept. Must be registered exactly in
|
|
248
|
+
* the environment's redirect URIs (the same list SSO and magic link use);
|
|
249
|
+
* otherwise the API rejects the invite. Comes back on `preview` and `accept`.
|
|
250
|
+
*/
|
|
251
|
+
redirectUri?: string;
|
|
252
|
+
}
|
|
253
|
+
/** Returned when an invite is created or re-issued. `acceptUrl` is only ever
|
|
254
|
+
* readable here — the API keeps a hash of the token, not the token. */
|
|
255
|
+
interface OrganizationInviteIssued {
|
|
256
|
+
id: string;
|
|
257
|
+
tenantId: string;
|
|
258
|
+
email: string;
|
|
259
|
+
roles: string[];
|
|
260
|
+
acceptUrl: string;
|
|
261
|
+
expiresAt: string;
|
|
262
|
+
emailSent: boolean;
|
|
263
|
+
redirectUri: string | null;
|
|
264
|
+
}
|
|
265
|
+
type OrganizationInviteStatus = "pending" | "accepted" | "revoked" | "expired";
|
|
266
|
+
interface OrganizationInvite {
|
|
267
|
+
id: string;
|
|
268
|
+
tenantId: string;
|
|
269
|
+
email: string;
|
|
270
|
+
roles: string[];
|
|
271
|
+
status: OrganizationInviteStatus;
|
|
272
|
+
createdAt: string;
|
|
273
|
+
expiresAt: string;
|
|
274
|
+
emailSentAt: string | null;
|
|
275
|
+
acceptedAt: string | null;
|
|
276
|
+
acceptedByUserId: string | null;
|
|
277
|
+
revokedAt: string | null;
|
|
278
|
+
invitedByUserId: string | null;
|
|
279
|
+
redirectUri: string | null;
|
|
280
|
+
}
|
|
281
|
+
/** POST /auth/tenant-invites/preview — what an accept page shows before the invitee commits. */
|
|
282
|
+
interface OrganizationInvitePreview {
|
|
283
|
+
tenantId: string;
|
|
284
|
+
tenantName: string;
|
|
285
|
+
email: string;
|
|
286
|
+
roles: string[];
|
|
287
|
+
expiresAt: string;
|
|
288
|
+
/** True: accepting only needs the token. False: send a password (and a username when `usernameRequired`). */
|
|
289
|
+
accountExists: boolean;
|
|
290
|
+
usernameRequired: boolean;
|
|
291
|
+
/** Where the issuer asked to send the invitee after accepting, or `null`. */
|
|
292
|
+
redirectUri: string | null;
|
|
293
|
+
}
|
|
294
|
+
/** Options for POST /auth/password-reset/request. */
|
|
295
|
+
interface PasswordResetRequestOptions {
|
|
296
|
+
/**
|
|
297
|
+
* Where to send the person after they change the password. Must be
|
|
298
|
+
* registered exactly in the environment's redirect URIs (the same list SSO
|
|
299
|
+
* and magic link use); otherwise the request fails with
|
|
300
|
+
* `user.password_reset.redirect_uri.not_allowed`. Comes back on
|
|
301
|
+
* `validatePasswordReset` and `confirmPasswordReset`.
|
|
302
|
+
*/
|
|
303
|
+
redirectUri?: string;
|
|
304
|
+
}
|
|
305
|
+
/** POST /auth/password-reset/validate — what a live reset token is for. */
|
|
306
|
+
interface PasswordResetPreview {
|
|
307
|
+
email: string;
|
|
308
|
+
expiresAt: string;
|
|
309
|
+
/** Where the reset was asked to end, or `null`. */
|
|
310
|
+
redirectUri: string | null;
|
|
311
|
+
}
|
|
312
|
+
/** POST /auth/password-reset/confirm — the password is changed. */
|
|
313
|
+
interface PasswordResetCompleted {
|
|
314
|
+
/** Where the reset was asked to end, or `null`. Navigating there is up to you. */
|
|
315
|
+
redirectUri: string | null;
|
|
316
|
+
}
|
|
317
|
+
/** POST /auth/tenant-invites/accept — everything but `token` is ignored when the address already has an account. */
|
|
318
|
+
interface AcceptOrganizationInviteInput {
|
|
319
|
+
token: string;
|
|
320
|
+
username?: string;
|
|
321
|
+
password?: string;
|
|
322
|
+
firstName?: string;
|
|
323
|
+
lastName?: string;
|
|
324
|
+
/**
|
|
325
|
+
* @deprecated Use `publicMetadata` / `privateMetadata` through
|
|
326
|
+
* `@authyon/server` (`environment.tenants.invites.accept`), which runs on
|
|
327
|
+
* your backend with the environment credential. Still accepted for now.
|
|
328
|
+
*/
|
|
329
|
+
customFields?: Record<string, unknown>;
|
|
330
|
+
}
|
|
331
|
+
interface OrganizationInviteAccepted {
|
|
332
|
+
tenantId: string;
|
|
333
|
+
tenantName: string;
|
|
334
|
+
userId: string;
|
|
335
|
+
/** True when accepting created the account (email already confirmed). The invitee still signs in normally. */
|
|
336
|
+
accountCreated: boolean;
|
|
337
|
+
/** Where the issuer asked to send the invitee, or `null`. Redirecting is up to the accept page. */
|
|
338
|
+
redirectUri: string | null;
|
|
339
|
+
}
|
|
117
340
|
/** Authenticated user profile. */
|
|
118
341
|
interface User {
|
|
119
342
|
id: string;
|
|
@@ -130,6 +353,8 @@ interface User {
|
|
|
130
353
|
activeOrganization?: Organization | null;
|
|
131
354
|
/** Actions the user must complete before continuing (e.g. confirm e-mail). */
|
|
132
355
|
pendencies?: string[];
|
|
356
|
+
/** Security methods active on the account (authenticator, email code, passkey, SSO…). */
|
|
357
|
+
security?: SecurityMethods;
|
|
133
358
|
}
|
|
134
359
|
/** Token pair issued by login / refresh / tenant switch. */
|
|
135
360
|
interface Session {
|
|
@@ -157,6 +382,8 @@ interface RegisterInput {
|
|
|
157
382
|
email: string;
|
|
158
383
|
username?: string;
|
|
159
384
|
password: string;
|
|
385
|
+
/** Values for custom user fields configured in the environment. */
|
|
386
|
+
customFields?: Record<string, unknown>;
|
|
160
387
|
}
|
|
161
388
|
interface LoginInput {
|
|
162
389
|
/** Provide `email` or `username`. */
|
|
@@ -289,6 +516,12 @@ type AuthState = "signed_out" | "authenticated" | "expired";
|
|
|
289
516
|
interface AuthyonClientOptions {
|
|
290
517
|
/** Publishable environment key (`pk_live_...` / `pk_test_...`). */
|
|
291
518
|
envKey: string;
|
|
519
|
+
/**
|
|
520
|
+
* Originating client IP to forward on every API call as `X-Forwarded-For`.
|
|
521
|
+
* Browsers cannot reliably discover their public IP by themselves; set this
|
|
522
|
+
* only when your application receives it from trusted infrastructure.
|
|
523
|
+
*/
|
|
524
|
+
clientIp?: string;
|
|
292
525
|
/** API origin. Defaults to `https://api.authyon.com`; HTTPS is required outside loopback. */
|
|
293
526
|
baseUrl?: string;
|
|
294
527
|
/** Allow an HTTP `baseUrl`. Intended only for explicitly trusted local development. */
|
|
@@ -312,6 +545,7 @@ interface AuthyonClientOptions {
|
|
|
312
545
|
|
|
313
546
|
declare class AuthyonClient {
|
|
314
547
|
private readonly envKey;
|
|
548
|
+
private readonly clientIp?;
|
|
315
549
|
private readonly baseUrl;
|
|
316
550
|
private readonly storage;
|
|
317
551
|
private readonly autoRefresh;
|
|
@@ -415,14 +649,33 @@ declare class AuthyonClient {
|
|
|
415
649
|
* the endpoint differs, override via a raw call to your own backend.
|
|
416
650
|
*/
|
|
417
651
|
revokeSession: (sessionId: string) => Promise<void>;
|
|
418
|
-
/**
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
652
|
+
/**
|
|
653
|
+
* POST /auth/password-reset/request — resolves whether or not the address
|
|
654
|
+
* has an account (no account enumeration). `redirectUri` is where the
|
|
655
|
+
* person lands after changing the password; it must be one of the
|
|
656
|
+
* environment's registered redirect URIs, or the call rejects with
|
|
657
|
+
* `user.password_reset.redirect_uri.not_allowed`.
|
|
658
|
+
*/
|
|
659
|
+
requestPasswordReset: (email: string, options?: PasswordResetRequestOptions) => Promise<void>;
|
|
660
|
+
/**
|
|
661
|
+
* POST /auth/password-reset/validate — checks a reset token without
|
|
662
|
+
* spending it, so the reset page can refuse a dead link before asking for
|
|
663
|
+
* a password. Rejects with `user.password_reset.invalid` (401) when the
|
|
664
|
+
* token is unknown, used or expired.
|
|
665
|
+
*/
|
|
666
|
+
validatePasswordReset: (token: string) => Promise<PasswordResetPreview>;
|
|
667
|
+
/**
|
|
668
|
+
* POST /auth/password-reset/confirm — sets a new password and revokes all
|
|
669
|
+
* refresh tokens. Resolves with the `redirectUri` the reset was requested
|
|
670
|
+
* with (`null` when there was none); following it is up to the caller.
|
|
671
|
+
*/
|
|
672
|
+
confirmPasswordReset: (token: string, newPassword: string) => Promise<PasswordResetCompleted>;
|
|
422
673
|
};
|
|
423
674
|
readonly organization: {
|
|
424
|
-
/** GET /auth/tenants —
|
|
425
|
-
list: (
|
|
675
|
+
/** GET /auth/tenants — filterable list of organization memberships. */
|
|
676
|
+
list: (params?: {
|
|
677
|
+
search?: string;
|
|
678
|
+
} & PaginationOptions) => Promise<Organization[]>;
|
|
426
679
|
/**
|
|
427
680
|
* POST /auth/tenants — creates an organization owned by the signed-in
|
|
428
681
|
* user (only available when self-service organization creation is
|
|
@@ -448,11 +701,53 @@ declare class AuthyonClient {
|
|
|
448
701
|
* (`user.activities()`, `@authyon/server`'s `environment.users.list()`).
|
|
449
702
|
*/
|
|
450
703
|
list: (organizationId: string, params?: PaginationOptions) => Promise<Paged<OrganizationMember>>;
|
|
451
|
-
/**
|
|
704
|
+
/**
|
|
705
|
+
* POST /auth/tenants/{organizationId}/members — add an existing
|
|
706
|
+
* environment user by e-mail (no e-mail is sent). To invite an address
|
|
707
|
+
* that may not have an account yet, use `organization.invites.create`.
|
|
708
|
+
*/
|
|
452
709
|
invite: (organizationId: string, params: InviteMemberInput) => Promise<void>;
|
|
453
710
|
/** DELETE /auth/tenants/{organizationId}/members/{userId} — remove a member. */
|
|
454
711
|
remove: (organizationId: string, userId: string) => Promise<void>;
|
|
455
712
|
};
|
|
713
|
+
/**
|
|
714
|
+
* Invites by e-mail or by link. Managing them requires the
|
|
715
|
+
* `tenants:members:invite` permission on the organization; `preview` and
|
|
716
|
+
* `accept` are public — the token in the link is the credential.
|
|
717
|
+
*/
|
|
718
|
+
invites: {
|
|
719
|
+
/** GET /auth/tenants/{organizationId}/invites — every invite with its status, newest first. */
|
|
720
|
+
list: (organizationId: string) => Promise<OrganizationInvite[]>;
|
|
721
|
+
/**
|
|
722
|
+
* POST /auth/tenants/{organizationId}/invites — invite an address.
|
|
723
|
+
* Always returns `acceptUrl`; with `sendEmail: false` Authyon does not
|
|
724
|
+
* mail it and you deliver the link yourself. The link is valid for 7
|
|
725
|
+
* days, once, and can't be read again later.
|
|
726
|
+
*/
|
|
727
|
+
create: (organizationId: string, params: OrganizationInviteInput) => Promise<OrganizationInviteIssued>;
|
|
728
|
+
/**
|
|
729
|
+
* POST /auth/tenants/{organizationId}/invites/{inviteId}/resend — issue
|
|
730
|
+
* a new link (the previous one stops working), mailing it unless
|
|
731
|
+
* `sendEmail` is `false`.
|
|
732
|
+
*/
|
|
733
|
+
resend: (organizationId: string, inviteId: string, params?: {
|
|
734
|
+
sendEmail?: boolean;
|
|
735
|
+
}) => Promise<OrganizationInviteIssued>;
|
|
736
|
+
/** DELETE /auth/tenants/{organizationId}/invites/{inviteId} — revoke a pending invite. */
|
|
737
|
+
revoke: (organizationId: string, inviteId: string) => Promise<void>;
|
|
738
|
+
/**
|
|
739
|
+
* POST /auth/tenant-invites/preview — public. Read the `token` query
|
|
740
|
+
* parameter of the invite link and pick the form: one click when
|
|
741
|
+
* `accountExists`, sign-up otherwise.
|
|
742
|
+
*/
|
|
743
|
+
preview: (token: string) => Promise<OrganizationInvitePreview>;
|
|
744
|
+
/**
|
|
745
|
+
* POST /auth/tenant-invites/accept — public. Joins the organization; for
|
|
746
|
+
* an address with no account, also creates it (password required) with
|
|
747
|
+
* the e-mail already confirmed. Does not sign the user in.
|
|
748
|
+
*/
|
|
749
|
+
accept: (params: AcceptOrganizationInviteInput) => Promise<OrganizationInviteAccepted>;
|
|
750
|
+
};
|
|
456
751
|
roles: {
|
|
457
752
|
/** GET /auth/tenants/{organizationId}/roles — roles available in the organization. */
|
|
458
753
|
list: (organizationId: string) => Promise<Role[]>;
|
|
@@ -502,6 +797,13 @@ declare class AuthyonClient {
|
|
|
502
797
|
assertionStart: (challengeToken: string) => Promise<WebAuthnCeremonyStart>;
|
|
503
798
|
};
|
|
504
799
|
};
|
|
800
|
+
/**
|
|
801
|
+
* `security.approvals`: approve or reject what your backend asked the
|
|
802
|
+
* customer to confirm (`@authyon/server` → `security.approvals.create`).
|
|
803
|
+
* Show the payload with `get()`, then `confirm()` with the customer's
|
|
804
|
+
* authenticator code or passkey, or `reject()`.
|
|
805
|
+
*/
|
|
806
|
+
readonly security: SubjectSecurity;
|
|
505
807
|
/**
|
|
506
808
|
* POST /auth/introspect — lightweight token introspection (RFC 7662).
|
|
507
809
|
*
|
|
@@ -578,6 +880,13 @@ interface AuthyonPermissionSource {
|
|
|
578
880
|
/** OAuth scopes are also accepted and interpreted as Authyon permissions. */
|
|
579
881
|
scope?: string | null;
|
|
580
882
|
}
|
|
883
|
+
/** A declarative group of permissions evaluated against an Authyon permission source. */
|
|
884
|
+
interface PermissionGroup {
|
|
885
|
+
/** Permissions that must all be granted. */
|
|
886
|
+
allOf?: readonly string[];
|
|
887
|
+
/** Permissions where at least one must be granted. */
|
|
888
|
+
anyOf?: readonly string[];
|
|
889
|
+
}
|
|
581
890
|
interface AuthyonAbilityOptions {
|
|
582
891
|
rules?: readonly AbilityRule[];
|
|
583
892
|
/** Rules added when the source contains a matching Authyon role. */
|
|
@@ -611,7 +920,12 @@ declare class AuthyonAbilityBuilder {
|
|
|
611
920
|
declare function createAuthyonAbility(source?: AuthyonPermissionSource, options?: AuthyonAbilityOptions): AuthyonAbility;
|
|
612
921
|
/** Checks an Authyon permission string using the same wildcard rules as an ability. */
|
|
613
922
|
declare function hasPermission(source: AuthyonPermissionSource | readonly string[], requiredPermission: string): boolean;
|
|
923
|
+
/**
|
|
924
|
+
* Checks a permission group using Authyon's standard permission and wildcard rules.
|
|
925
|
+
* Empty or omitted groups do not add authorization requirements.
|
|
926
|
+
*/
|
|
927
|
+
declare function hasPermissionGroup(source: AuthyonPermissionSource | readonly string[], group: PermissionGroup): boolean;
|
|
614
928
|
/** Converts Authyon's `subject:action` permission strings to authorization rules. */
|
|
615
929
|
declare function createAuthyonRules(source?: AuthyonPermissionSource, options?: AuthyonAbilityOptions): AbilityRule[];
|
|
616
930
|
|
|
617
|
-
export {
|
|
931
|
+
export { type SecurityMethods as $, AuthyonClient as A, type HttpLogger as B, type ConfirmApprovalInput as C, type InviteMemberInput as D, type LoginInput as E, FetchHttpAdapter as F, type LoginResult as G, type HttpAdapter as H, type IntrospectResult as I, type OrganizationInvite as J, type OrganizationInviteAccepted as K, LoggingHttpAdapter as L, type OrganizationInviteInput as M, type OrganizationInviteIssued as N, type Organization as O, type OrganizationInvitePreview as P, type OrganizationInviteStatus as Q, type OrganizationMember as R, type Paged as S, type TokenStorage as T, type PaginationOptions as U, type PasswordResetCompleted as V, type PasswordResetPreview as W, type PasswordResetRequestOptions as X, type PermissionGroup as Y, type RegisterInput as Z, type Role as _, type HttpLoggerOptions as a, type Session as a0, type SessionControllerOptions as a1, type SessionInfo as a2, type SessionSnapshot as a3, type SessionSnapshotListener as a4, type SessionStatus as a5, type SsoProvider as a6, type SubjectApprovals as a7, type SubjectSecurity as a8, type TwoFactorChallenge as a9, type TwoFactorMethod as aa, type TwoFactorStatus as ab, type User as ac, type ValidateResult as ad, type VerifyTwoFactorInput as ae, type WebAuthnAssertion as af, type WebAuthnCeremonyStart as ag, type WebAuthnCredential as ah, createAuthyonAbility as ai, createAuthyonRules as aj, createClient as ak, hasPermission as al, hasPermissionGroup as am, type AbilityConditions as b, type AbilityEvent as c, type AbilityListener as d, type AbilityRule as e, type AbilitySubject as f, type AcceptOrganizationInviteInput as g, type Activity as h, type Approval as i, type ApprovalAssurance as j, type ApprovalPayload as k, type ApprovalStatus as l, type ApprovalWebAuthnOptions as m, type AuthEvent as n, type AuthState as o, type AuthStateListener as p, type AuthenticatorSetup as q, AuthyonAbility as r, AuthyonAbilityBuilder as s, type AuthyonAbilityOptions as t, type AuthyonClientOptions as u, type AuthyonPermissionSource as v, AuthyonSessionController as w, type CreateOrganizationInput as x, type HttpAdapterRequest as y, type HttpLogEvent as z };
|
|
@@ -201,6 +201,11 @@ function hasPermission(source, requiredPermission) {
|
|
|
201
201
|
const permissionSource = isPermissionList(source) ? { permissions: source } : source;
|
|
202
202
|
return createAuthyonAbility(permissionSource).can(requirement.action, requirement.subject);
|
|
203
203
|
}
|
|
204
|
+
function hasPermissionGroup(source, group) {
|
|
205
|
+
const hasAll = (group.allOf ?? []).every((permission) => hasPermission(source, permission));
|
|
206
|
+
const hasAny = !group.anyOf?.length || group.anyOf.some((permission) => hasPermission(source, permission));
|
|
207
|
+
return hasAll && hasAny;
|
|
208
|
+
}
|
|
204
209
|
function isPermissionList(source) {
|
|
205
210
|
return Array.isArray(source);
|
|
206
211
|
}
|
|
@@ -319,5 +324,6 @@ export {
|
|
|
319
324
|
AuthyonAbilityBuilder,
|
|
320
325
|
createAuthyonAbility,
|
|
321
326
|
hasPermission,
|
|
327
|
+
hasPermissionGroup,
|
|
322
328
|
createAuthyonRules
|
|
323
329
|
};
|