@authyon/auth 0.2.0-beta.14 → 0.2.0-beta.16
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 +43 -24
- package/dist/{ability-DbnbsQEX.d.cts → ability-Cp8ir5Gr.d.cts} +191 -63
- package/dist/{ability-DbnbsQEX.d.ts → ability-Cp8ir5Gr.d.ts} +191 -63
- package/dist/index.cjs +98 -28
- package/dist/index.d.cts +13 -5
- package/dist/index.d.ts +13 -5
- package/dist/index.js +98 -28
- package/dist/react/index.d.cts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -227,18 +227,34 @@ Métodos de sessão/auth ficam soltos no client; os que giram em torno de um rec
|
|
|
227
227
|
|
|
228
228
|
### `authyon.organization`
|
|
229
229
|
|
|
230
|
-
| Método
|
|
231
|
-
|
|
|
232
|
-
| `organization.list({ search?, skip?, take? })`
|
|
233
|
-
| `organization.create(params?)`
|
|
234
|
-
| `organization.get(organizationId)`
|
|
235
|
-
| `organization.rename(organizationId, name)`
|
|
236
|
-
| `organization.switch(slug)`
|
|
237
|
-
| `organization.current()`
|
|
238
|
-
| `organization.members.list(organizationId, params?)`
|
|
239
|
-
| `organization.members.invite(organizationId, params)`
|
|
240
|
-
| `organization.members.remove(organizationId, userId)`
|
|
241
|
-
| `organization.roles.list(organizationId)`
|
|
230
|
+
| Método | Endpoint |
|
|
231
|
+
| ---------------------------------------------------------------- | --------------------------------------------------- |
|
|
232
|
+
| `organization.list({ search?, skip?, take? })` | `GET /auth/tenants` |
|
|
233
|
+
| `organization.create(params?)` | `POST /auth/tenants` |
|
|
234
|
+
| `organization.get(organizationId)` | `GET /auth/tenants/{id}` |
|
|
235
|
+
| `organization.rename(organizationId, name)` | `PATCH /auth/tenants/{id}` |
|
|
236
|
+
| `organization.switch(slug)` | `POST /auth/switch-tenant` |
|
|
237
|
+
| `organization.current()` | — (lê `activeOrganization` da sessão em cache) |
|
|
238
|
+
| `organization.members.list(organizationId, params?)` | `GET /auth/tenants/{id}/members` |
|
|
239
|
+
| `organization.members.invite(organizationId, params)` | `POST /auth/tenants/{id}/members` |
|
|
240
|
+
| `organization.members.remove(organizationId, userId)` | `DELETE /auth/tenants/{id}/members/{userId}` |
|
|
241
|
+
| `organization.roles.list(organizationId)` | `GET /auth/tenants/{id}/roles` |
|
|
242
|
+
| `organization.invites.list(organizationId)` | `GET /auth/tenants/{id}/invites` |
|
|
243
|
+
| `organization.invites.create(organizationId, params)` | `POST /auth/tenants/{id}/invites` |
|
|
244
|
+
| `organization.invites.resend(organizationId, inviteId, params?)` | `POST /auth/tenants/{id}/invites/{inviteId}/resend` |
|
|
245
|
+
| `organization.invites.revoke(organizationId, inviteId)` | `DELETE /auth/tenants/{id}/invites/{inviteId}` |
|
|
246
|
+
| `organization.invites.preview(token)` | `POST /auth/tenant-invites/preview` (público) |
|
|
247
|
+
| `organization.invites.accept(params)` | `POST /auth/tenant-invites/accept` (público) |
|
|
248
|
+
|
|
249
|
+
`organization.members.invite` adiciona um usuário que já existe no ambiente. Para convidar
|
|
250
|
+
um e-mail que talvez ainda não tenha conta, use `organization.invites.create`: a resposta
|
|
251
|
+
sempre traz o `acceptUrl` completo e `sendEmail: false` só gera o link, sem enviar e-mail.
|
|
252
|
+
O link vale 7 dias, uma única vez, e não pode ser lido de novo depois. Na página de aceite,
|
|
253
|
+
leia o `token` da URL, chame `preview(token)` e, se `accountExists` for falso, peça senha
|
|
254
|
+
(e usuário quando `usernameRequired`) antes de `accept`. Aceitar não faz login.
|
|
255
|
+
Passe `redirectUri` no `create` para indicar para onde mandar a pessoa depois do aceite: ele
|
|
256
|
+
precisa estar cadastrado (match exato) nos redirect URIs do ambiente e volta em `preview` e
|
|
257
|
+
`accept` — a página hospedada da Authyon redireciona sozinha; numa página própria, é com você.
|
|
242
258
|
|
|
243
259
|
### `authyon.twoFactor`
|
|
244
260
|
|
|
@@ -273,26 +289,29 @@ Métodos de sessão/auth ficam soltos no client; os que giram em torno de um rec
|
|
|
273
289
|
| `sso.startUrl(provider, params)` | monta a URL de `GET /auth/sso/{provider}/start` (não faz a chamada — navegue até ela) |
|
|
274
290
|
| `sso.exchange(code)` | `POST /auth/sso/exchange` |
|
|
275
291
|
|
|
276
|
-
### `authyon.
|
|
292
|
+
### `authyon.security` (aprovação com OTP/passkey)
|
|
277
293
|
|
|
278
|
-
|
|
279
|
-
|
|
294
|
+
`security.approvals`: o cliente aprova o que o seu backend pediu
|
|
295
|
+
(`@authyon/server` → `security.approvals.create`, com um `payload` livre) usando o código
|
|
296
|
+
do app autenticador ou a passkey. Para só validar um código, use `security.otp.check` no
|
|
297
|
+
`@authyon/server`. Guia completo: [`docs/security-otp-approvals.md`](../../docs/security-otp-approvals.md).
|
|
280
298
|
|
|
281
299
|
```ts
|
|
282
|
-
const pending = await authyon.
|
|
283
|
-
// mostre pending.
|
|
284
|
-
await authyon.
|
|
300
|
+
const pending = await authyon.security.approvals.get(approvalId);
|
|
301
|
+
// mostre pending.payload ao cliente
|
|
302
|
+
await authyon.security.approvals.confirm(approvalId, {
|
|
285
303
|
method: "authenticator",
|
|
286
304
|
code: "123456",
|
|
287
305
|
});
|
|
288
306
|
```
|
|
289
307
|
|
|
290
|
-
| Método
|
|
291
|
-
|
|
|
292
|
-
| `
|
|
293
|
-
| `
|
|
294
|
-
| `
|
|
295
|
-
| `
|
|
308
|
+
| Método | Endpoint |
|
|
309
|
+
| ---------------------------------------- | ------------------------------------------------- |
|
|
310
|
+
| `security.methods()` | `GET /auth/me` (campo `security`) |
|
|
311
|
+
| `security.approvals.get(id)` | `GET /auth/authorizations/{id}` |
|
|
312
|
+
| `security.approvals.webauthnOptions(id)` | `POST /auth/authorizations/{id}/webauthn/options` |
|
|
313
|
+
| `security.approvals.confirm(id, input?)` | `POST /auth/authorizations/{id}/confirm` |
|
|
314
|
+
| `security.approvals.reject(id)` | `POST /auth/authorizations/{id}/reject` |
|
|
296
315
|
|
|
297
316
|
## Invalidação de token
|
|
298
317
|
|
|
@@ -1,24 +1,34 @@
|
|
|
1
|
-
/** Lifecycle of a transaction-bound financial authorization. */
|
|
2
|
-
type FinancialAuthorizationStatus = "pending" | "approved" | "denied" | "consumed" | "expired";
|
|
3
1
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* normalized to four decimal places, metadata keys are sorted).
|
|
2
|
+
* Security methods active on the user's account, as returned in the
|
|
3
|
+
* `security` field of `GET /auth/me` and `POST /auth/validate`.
|
|
7
4
|
*/
|
|
8
|
-
interface
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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>;
|
|
20
30
|
/** Evidence of how the customer proved their identity when approving. */
|
|
21
|
-
interface
|
|
31
|
+
interface ApprovalAssurance {
|
|
22
32
|
/** `urn:authyon:loa:3` (passkey) or `urn:authyon:loa:2` (authenticator code). */
|
|
23
33
|
acr: string;
|
|
24
34
|
/** Authentication methods, e.g. `["pwd", "otp"]` or `["pwd", "webauthn"]`. */
|
|
@@ -26,28 +36,25 @@ interface FinancialAssurance {
|
|
|
26
36
|
/** When the second factor was verified (ISO 8601). */
|
|
27
37
|
authTime: string;
|
|
28
38
|
}
|
|
29
|
-
|
|
39
|
+
/** A request for the customer to approve something with a second factor. */
|
|
40
|
+
interface Approval {
|
|
30
41
|
id: string;
|
|
31
|
-
status:
|
|
42
|
+
status: ApprovalStatus;
|
|
32
43
|
subjectId: string;
|
|
33
44
|
tenantId?: string | null;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
/** SHA-256 (hex) of the canonical transaction. */
|
|
39
|
-
transactionHash: string;
|
|
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;
|
|
40
49
|
createdAt: string;
|
|
41
50
|
expiresAt: string;
|
|
42
51
|
decidedAt?: string | null;
|
|
43
52
|
consumedAt?: string | null;
|
|
44
|
-
/** Full canonical transaction — returned only to the customer (subject) view. */
|
|
45
|
-
transaction?: FinancialTransaction | null;
|
|
46
53
|
/** Present once approved. */
|
|
47
|
-
assurance?:
|
|
54
|
+
assurance?: ApprovalAssurance | null;
|
|
48
55
|
}
|
|
49
|
-
/**
|
|
50
|
-
type
|
|
56
|
+
/** Second factor sent with `confirm()`. */
|
|
57
|
+
type ConfirmApprovalInput = {
|
|
51
58
|
method: "authenticator";
|
|
52
59
|
/** Six-digit code from the customer's authenticator app. */
|
|
53
60
|
code: string;
|
|
@@ -60,15 +67,13 @@ type ConfirmFinancialAuthorizationInput = {
|
|
|
60
67
|
assertionJson: string;
|
|
61
68
|
};
|
|
62
69
|
};
|
|
63
|
-
/** Passkey assertion options for approving one
|
|
64
|
-
interface
|
|
70
|
+
/** Passkey assertion options for approving one approval. */
|
|
71
|
+
interface ApprovalWebAuthnOptions {
|
|
65
72
|
ceremonyToken: string;
|
|
66
73
|
/** JSON `PublicKeyCredentialRequestOptions` to pass to `navigator.credentials.get()`. */
|
|
67
74
|
optionsJson: string;
|
|
68
75
|
}
|
|
69
76
|
|
|
70
|
-
type QueryParams = object;
|
|
71
|
-
|
|
72
77
|
interface HttpAdapterRequest {
|
|
73
78
|
url: string;
|
|
74
79
|
method: string;
|
|
@@ -126,35 +131,34 @@ declare class LoggingHttpAdapter implements HttpAdapter {
|
|
|
126
131
|
private log;
|
|
127
132
|
}
|
|
128
133
|
|
|
129
|
-
|
|
130
|
-
interface
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/** Sends a request already authenticated as the customer (end-user bearer). */
|
|
138
|
-
type SubjectRequest = <T>(path: string, options?: JsonRequestOptions) => Promise<T>;
|
|
139
|
-
/** Customer-side operations on a financial authorization (`/auth/authorizations`). */
|
|
140
|
-
declare function subjectFinancialAuthorizations(request: SubjectRequest): {
|
|
141
|
-
/** GET /auth/authorizations/{id} — the pending transaction, to show before asking for the code. */
|
|
142
|
-
get: (id: string) => Promise<FinancialAuthorization>;
|
|
143
|
-
/** POST /auth/authorizations/{id}/webauthn/options — passkey options for approving this authorization. */
|
|
144
|
-
webauthnOptions: (id: string) => Promise<FinancialWebAuthnOptions>;
|
|
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>;
|
|
145
140
|
/**
|
|
146
|
-
* POST /auth/authorizations/{id}/confirm — approves
|
|
141
|
+
* POST /auth/authorizations/{id}/confirm — approves it.
|
|
147
142
|
*
|
|
148
143
|
* Pass the authenticator code or passkey assertion to verify the second
|
|
149
144
|
* factor inline (recommended). Without `input`, the session itself must
|
|
150
145
|
* have used a passkey or authenticator code within the last 5 minutes,
|
|
151
146
|
* otherwise the API answers `step_up_required`.
|
|
152
147
|
*/
|
|
153
|
-
confirm
|
|
154
|
-
/** POST /auth/authorizations/{id}/reject — the customer declines
|
|
155
|
-
reject
|
|
156
|
-
}
|
|
157
|
-
|
|
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
|
+
}
|
|
158
162
|
|
|
159
163
|
interface PaginationOptions {
|
|
160
164
|
skip?: number;
|
|
@@ -220,6 +224,86 @@ interface InviteMemberInput {
|
|
|
220
224
|
email: string;
|
|
221
225
|
roles: string[];
|
|
222
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* POST /auth/tenants/{organizationId}/invites — invite an address that may not
|
|
229
|
+
* have an account yet; accepting creates it. `sendEmail` defaults to `true`;
|
|
230
|
+
* `false` only returns the link, for delivery through your own channel.
|
|
231
|
+
*/
|
|
232
|
+
interface OrganizationInviteInput {
|
|
233
|
+
email: string;
|
|
234
|
+
roles?: string[];
|
|
235
|
+
sendEmail?: boolean;
|
|
236
|
+
/**
|
|
237
|
+
* Where to send the invitee after they accept. Must be registered exactly in
|
|
238
|
+
* the environment's redirect URIs (the same list SSO and magic link use);
|
|
239
|
+
* otherwise the API rejects the invite. Comes back on `preview` and `accept`.
|
|
240
|
+
*/
|
|
241
|
+
redirectUri?: string;
|
|
242
|
+
}
|
|
243
|
+
/** Returned when an invite is created or re-issued. `acceptUrl` is only ever
|
|
244
|
+
* readable here — the API keeps a hash of the token, not the token. */
|
|
245
|
+
interface OrganizationInviteIssued {
|
|
246
|
+
id: string;
|
|
247
|
+
tenantId: string;
|
|
248
|
+
email: string;
|
|
249
|
+
roles: string[];
|
|
250
|
+
acceptUrl: string;
|
|
251
|
+
expiresAt: string;
|
|
252
|
+
emailSent: boolean;
|
|
253
|
+
redirectUri: string | null;
|
|
254
|
+
}
|
|
255
|
+
type OrganizationInviteStatus = "pending" | "accepted" | "revoked" | "expired";
|
|
256
|
+
interface OrganizationInvite {
|
|
257
|
+
id: string;
|
|
258
|
+
tenantId: string;
|
|
259
|
+
email: string;
|
|
260
|
+
roles: string[];
|
|
261
|
+
status: OrganizationInviteStatus;
|
|
262
|
+
createdAt: string;
|
|
263
|
+
expiresAt: string;
|
|
264
|
+
emailSentAt: string | null;
|
|
265
|
+
acceptedAt: string | null;
|
|
266
|
+
acceptedByUserId: string | null;
|
|
267
|
+
revokedAt: string | null;
|
|
268
|
+
invitedByUserId: string | null;
|
|
269
|
+
redirectUri: string | null;
|
|
270
|
+
}
|
|
271
|
+
/** POST /auth/tenant-invites/preview — what an accept page shows before the invitee commits. */
|
|
272
|
+
interface OrganizationInvitePreview {
|
|
273
|
+
tenantId: string;
|
|
274
|
+
tenantName: string;
|
|
275
|
+
email: string;
|
|
276
|
+
roles: string[];
|
|
277
|
+
expiresAt: string;
|
|
278
|
+
/** True: accepting only needs the token. False: send a password (and a username when `usernameRequired`). */
|
|
279
|
+
accountExists: boolean;
|
|
280
|
+
usernameRequired: boolean;
|
|
281
|
+
/** Where the issuer asked to send the invitee after accepting, or `null`. */
|
|
282
|
+
redirectUri: string | null;
|
|
283
|
+
}
|
|
284
|
+
/** POST /auth/tenant-invites/accept — everything but `token` is ignored when the address already has an account. */
|
|
285
|
+
interface AcceptOrganizationInviteInput {
|
|
286
|
+
token: string;
|
|
287
|
+
username?: string;
|
|
288
|
+
password?: string;
|
|
289
|
+
firstName?: string;
|
|
290
|
+
lastName?: string;
|
|
291
|
+
/**
|
|
292
|
+
* @deprecated Use `publicMetadata` / `privateMetadata` through
|
|
293
|
+
* `@authyon/server` (`environment.tenants.invites.accept`), which runs on
|
|
294
|
+
* your backend with the environment credential. Still accepted for now.
|
|
295
|
+
*/
|
|
296
|
+
customFields?: Record<string, unknown>;
|
|
297
|
+
}
|
|
298
|
+
interface OrganizationInviteAccepted {
|
|
299
|
+
tenantId: string;
|
|
300
|
+
tenantName: string;
|
|
301
|
+
userId: string;
|
|
302
|
+
/** True when accepting created the account (email already confirmed). The invitee still signs in normally. */
|
|
303
|
+
accountCreated: boolean;
|
|
304
|
+
/** Where the issuer asked to send the invitee, or `null`. Redirecting is up to the accept page. */
|
|
305
|
+
redirectUri: string | null;
|
|
306
|
+
}
|
|
223
307
|
/** Authenticated user profile. */
|
|
224
308
|
interface User {
|
|
225
309
|
id: string;
|
|
@@ -236,6 +320,8 @@ interface User {
|
|
|
236
320
|
activeOrganization?: Organization | null;
|
|
237
321
|
/** Actions the user must complete before continuing (e.g. confirm e-mail). */
|
|
238
322
|
pendencies?: string[];
|
|
323
|
+
/** Security methods active on the account (authenticator, email code, passkey, SSO…). */
|
|
324
|
+
security?: SecurityMethods;
|
|
239
325
|
}
|
|
240
326
|
/** Token pair issued by login / refresh / tenant switch. */
|
|
241
327
|
interface Session {
|
|
@@ -565,11 +651,53 @@ declare class AuthyonClient {
|
|
|
565
651
|
* (`user.activities()`, `@authyon/server`'s `environment.users.list()`).
|
|
566
652
|
*/
|
|
567
653
|
list: (organizationId: string, params?: PaginationOptions) => Promise<Paged<OrganizationMember>>;
|
|
568
|
-
/**
|
|
654
|
+
/**
|
|
655
|
+
* POST /auth/tenants/{organizationId}/members — add an existing
|
|
656
|
+
* environment user by e-mail (no e-mail is sent). To invite an address
|
|
657
|
+
* that may not have an account yet, use `organization.invites.create`.
|
|
658
|
+
*/
|
|
569
659
|
invite: (organizationId: string, params: InviteMemberInput) => Promise<void>;
|
|
570
660
|
/** DELETE /auth/tenants/{organizationId}/members/{userId} — remove a member. */
|
|
571
661
|
remove: (organizationId: string, userId: string) => Promise<void>;
|
|
572
662
|
};
|
|
663
|
+
/**
|
|
664
|
+
* Invites by e-mail or by link. Managing them requires the
|
|
665
|
+
* `tenants:members:invite` permission on the organization; `preview` and
|
|
666
|
+
* `accept` are public — the token in the link is the credential.
|
|
667
|
+
*/
|
|
668
|
+
invites: {
|
|
669
|
+
/** GET /auth/tenants/{organizationId}/invites — every invite with its status, newest first. */
|
|
670
|
+
list: (organizationId: string) => Promise<OrganizationInvite[]>;
|
|
671
|
+
/**
|
|
672
|
+
* POST /auth/tenants/{organizationId}/invites — invite an address.
|
|
673
|
+
* Always returns `acceptUrl`; with `sendEmail: false` Authyon does not
|
|
674
|
+
* mail it and you deliver the link yourself. The link is valid for 7
|
|
675
|
+
* days, once, and can't be read again later.
|
|
676
|
+
*/
|
|
677
|
+
create: (organizationId: string, params: OrganizationInviteInput) => Promise<OrganizationInviteIssued>;
|
|
678
|
+
/**
|
|
679
|
+
* POST /auth/tenants/{organizationId}/invites/{inviteId}/resend — issue
|
|
680
|
+
* a new link (the previous one stops working), mailing it unless
|
|
681
|
+
* `sendEmail` is `false`.
|
|
682
|
+
*/
|
|
683
|
+
resend: (organizationId: string, inviteId: string, params?: {
|
|
684
|
+
sendEmail?: boolean;
|
|
685
|
+
}) => Promise<OrganizationInviteIssued>;
|
|
686
|
+
/** DELETE /auth/tenants/{organizationId}/invites/{inviteId} — revoke a pending invite. */
|
|
687
|
+
revoke: (organizationId: string, inviteId: string) => Promise<void>;
|
|
688
|
+
/**
|
|
689
|
+
* POST /auth/tenant-invites/preview — public. Read the `token` query
|
|
690
|
+
* parameter of the invite link and pick the form: one click when
|
|
691
|
+
* `accountExists`, sign-up otherwise.
|
|
692
|
+
*/
|
|
693
|
+
preview: (token: string) => Promise<OrganizationInvitePreview>;
|
|
694
|
+
/**
|
|
695
|
+
* POST /auth/tenant-invites/accept — public. Joins the organization; for
|
|
696
|
+
* an address with no account, also creates it (password required) with
|
|
697
|
+
* the e-mail already confirmed. Does not sign the user in.
|
|
698
|
+
*/
|
|
699
|
+
accept: (params: AcceptOrganizationInviteInput) => Promise<OrganizationInviteAccepted>;
|
|
700
|
+
};
|
|
573
701
|
roles: {
|
|
574
702
|
/** GET /auth/tenants/{organizationId}/roles — roles available in the organization. */
|
|
575
703
|
list: (organizationId: string) => Promise<Role[]>;
|
|
@@ -620,12 +748,12 @@ declare class AuthyonClient {
|
|
|
620
748
|
};
|
|
621
749
|
};
|
|
622
750
|
/**
|
|
623
|
-
*
|
|
624
|
-
* (`@authyon/server` → `
|
|
625
|
-
* Show the
|
|
751
|
+
* `security.approvals`: approve or reject what your backend asked the
|
|
752
|
+
* customer to confirm (`@authyon/server` → `security.approvals.create`).
|
|
753
|
+
* Show the payload with `get()`, then `confirm()` with the customer's
|
|
626
754
|
* authenticator code or passkey, or `reject()`.
|
|
627
755
|
*/
|
|
628
|
-
readonly
|
|
756
|
+
readonly security: SubjectSecurity;
|
|
629
757
|
/**
|
|
630
758
|
* POST /auth/introspect — lightweight token introspection (RFC 7662).
|
|
631
759
|
*
|
|
@@ -750,4 +878,4 @@ declare function hasPermissionGroup(source: AuthyonPermissionSource | readonly s
|
|
|
750
878
|
/** Converts Authyon's `subject:action` permission strings to authorization rules. */
|
|
751
879
|
declare function createAuthyonRules(source?: AuthyonPermissionSource, options?: AuthyonAbilityOptions): AbilityRule[];
|
|
752
880
|
|
|
753
|
-
export { type
|
|
881
|
+
export { type SessionInfo 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 PermissionGroup as V, type RegisterInput as W, type Role as X, type SecurityMethods as Y, type Session as Z, type SessionControllerOptions as _, type HttpLoggerOptions as a, type SessionSnapshot as a0, type SessionSnapshotListener as a1, type SessionStatus as a2, type SsoProvider as a3, type SubjectApprovals as a4, type SubjectSecurity as a5, type TwoFactorChallenge as a6, type TwoFactorMethod as a7, type TwoFactorStatus as a8, type User as a9, type ValidateResult as aa, type VerifyTwoFactorInput as ab, type WebAuthnAssertion as ac, type WebAuthnCeremonyStart as ad, type WebAuthnCredential as ae, createAuthyonAbility as af, createAuthyonRules as ag, createClient as ah, hasPermission as ai, hasPermissionGroup as aj, 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 };
|
|
@@ -1,24 +1,34 @@
|
|
|
1
|
-
/** Lifecycle of a transaction-bound financial authorization. */
|
|
2
|
-
type FinancialAuthorizationStatus = "pending" | "approved" | "denied" | "consumed" | "expired";
|
|
3
1
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* normalized to four decimal places, metadata keys are sorted).
|
|
2
|
+
* Security methods active on the user's account, as returned in the
|
|
3
|
+
* `security` field of `GET /auth/me` and `POST /auth/validate`.
|
|
7
4
|
*/
|
|
8
|
-
interface
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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>;
|
|
20
30
|
/** Evidence of how the customer proved their identity when approving. */
|
|
21
|
-
interface
|
|
31
|
+
interface ApprovalAssurance {
|
|
22
32
|
/** `urn:authyon:loa:3` (passkey) or `urn:authyon:loa:2` (authenticator code). */
|
|
23
33
|
acr: string;
|
|
24
34
|
/** Authentication methods, e.g. `["pwd", "otp"]` or `["pwd", "webauthn"]`. */
|
|
@@ -26,28 +36,25 @@ interface FinancialAssurance {
|
|
|
26
36
|
/** When the second factor was verified (ISO 8601). */
|
|
27
37
|
authTime: string;
|
|
28
38
|
}
|
|
29
|
-
|
|
39
|
+
/** A request for the customer to approve something with a second factor. */
|
|
40
|
+
interface Approval {
|
|
30
41
|
id: string;
|
|
31
|
-
status:
|
|
42
|
+
status: ApprovalStatus;
|
|
32
43
|
subjectId: string;
|
|
33
44
|
tenantId?: string | null;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
/** SHA-256 (hex) of the canonical transaction. */
|
|
39
|
-
transactionHash: string;
|
|
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;
|
|
40
49
|
createdAt: string;
|
|
41
50
|
expiresAt: string;
|
|
42
51
|
decidedAt?: string | null;
|
|
43
52
|
consumedAt?: string | null;
|
|
44
|
-
/** Full canonical transaction — returned only to the customer (subject) view. */
|
|
45
|
-
transaction?: FinancialTransaction | null;
|
|
46
53
|
/** Present once approved. */
|
|
47
|
-
assurance?:
|
|
54
|
+
assurance?: ApprovalAssurance | null;
|
|
48
55
|
}
|
|
49
|
-
/**
|
|
50
|
-
type
|
|
56
|
+
/** Second factor sent with `confirm()`. */
|
|
57
|
+
type ConfirmApprovalInput = {
|
|
51
58
|
method: "authenticator";
|
|
52
59
|
/** Six-digit code from the customer's authenticator app. */
|
|
53
60
|
code: string;
|
|
@@ -60,15 +67,13 @@ type ConfirmFinancialAuthorizationInput = {
|
|
|
60
67
|
assertionJson: string;
|
|
61
68
|
};
|
|
62
69
|
};
|
|
63
|
-
/** Passkey assertion options for approving one
|
|
64
|
-
interface
|
|
70
|
+
/** Passkey assertion options for approving one approval. */
|
|
71
|
+
interface ApprovalWebAuthnOptions {
|
|
65
72
|
ceremonyToken: string;
|
|
66
73
|
/** JSON `PublicKeyCredentialRequestOptions` to pass to `navigator.credentials.get()`. */
|
|
67
74
|
optionsJson: string;
|
|
68
75
|
}
|
|
69
76
|
|
|
70
|
-
type QueryParams = object;
|
|
71
|
-
|
|
72
77
|
interface HttpAdapterRequest {
|
|
73
78
|
url: string;
|
|
74
79
|
method: string;
|
|
@@ -126,35 +131,34 @@ declare class LoggingHttpAdapter implements HttpAdapter {
|
|
|
126
131
|
private log;
|
|
127
132
|
}
|
|
128
133
|
|
|
129
|
-
|
|
130
|
-
interface
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/** Sends a request already authenticated as the customer (end-user bearer). */
|
|
138
|
-
type SubjectRequest = <T>(path: string, options?: JsonRequestOptions) => Promise<T>;
|
|
139
|
-
/** Customer-side operations on a financial authorization (`/auth/authorizations`). */
|
|
140
|
-
declare function subjectFinancialAuthorizations(request: SubjectRequest): {
|
|
141
|
-
/** GET /auth/authorizations/{id} — the pending transaction, to show before asking for the code. */
|
|
142
|
-
get: (id: string) => Promise<FinancialAuthorization>;
|
|
143
|
-
/** POST /auth/authorizations/{id}/webauthn/options — passkey options for approving this authorization. */
|
|
144
|
-
webauthnOptions: (id: string) => Promise<FinancialWebAuthnOptions>;
|
|
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>;
|
|
145
140
|
/**
|
|
146
|
-
* POST /auth/authorizations/{id}/confirm — approves
|
|
141
|
+
* POST /auth/authorizations/{id}/confirm — approves it.
|
|
147
142
|
*
|
|
148
143
|
* Pass the authenticator code or passkey assertion to verify the second
|
|
149
144
|
* factor inline (recommended). Without `input`, the session itself must
|
|
150
145
|
* have used a passkey or authenticator code within the last 5 minutes,
|
|
151
146
|
* otherwise the API answers `step_up_required`.
|
|
152
147
|
*/
|
|
153
|
-
confirm
|
|
154
|
-
/** POST /auth/authorizations/{id}/reject — the customer declines
|
|
155
|
-
reject
|
|
156
|
-
}
|
|
157
|
-
|
|
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
|
+
}
|
|
158
162
|
|
|
159
163
|
interface PaginationOptions {
|
|
160
164
|
skip?: number;
|
|
@@ -220,6 +224,86 @@ interface InviteMemberInput {
|
|
|
220
224
|
email: string;
|
|
221
225
|
roles: string[];
|
|
222
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* POST /auth/tenants/{organizationId}/invites — invite an address that may not
|
|
229
|
+
* have an account yet; accepting creates it. `sendEmail` defaults to `true`;
|
|
230
|
+
* `false` only returns the link, for delivery through your own channel.
|
|
231
|
+
*/
|
|
232
|
+
interface OrganizationInviteInput {
|
|
233
|
+
email: string;
|
|
234
|
+
roles?: string[];
|
|
235
|
+
sendEmail?: boolean;
|
|
236
|
+
/**
|
|
237
|
+
* Where to send the invitee after they accept. Must be registered exactly in
|
|
238
|
+
* the environment's redirect URIs (the same list SSO and magic link use);
|
|
239
|
+
* otherwise the API rejects the invite. Comes back on `preview` and `accept`.
|
|
240
|
+
*/
|
|
241
|
+
redirectUri?: string;
|
|
242
|
+
}
|
|
243
|
+
/** Returned when an invite is created or re-issued. `acceptUrl` is only ever
|
|
244
|
+
* readable here — the API keeps a hash of the token, not the token. */
|
|
245
|
+
interface OrganizationInviteIssued {
|
|
246
|
+
id: string;
|
|
247
|
+
tenantId: string;
|
|
248
|
+
email: string;
|
|
249
|
+
roles: string[];
|
|
250
|
+
acceptUrl: string;
|
|
251
|
+
expiresAt: string;
|
|
252
|
+
emailSent: boolean;
|
|
253
|
+
redirectUri: string | null;
|
|
254
|
+
}
|
|
255
|
+
type OrganizationInviteStatus = "pending" | "accepted" | "revoked" | "expired";
|
|
256
|
+
interface OrganizationInvite {
|
|
257
|
+
id: string;
|
|
258
|
+
tenantId: string;
|
|
259
|
+
email: string;
|
|
260
|
+
roles: string[];
|
|
261
|
+
status: OrganizationInviteStatus;
|
|
262
|
+
createdAt: string;
|
|
263
|
+
expiresAt: string;
|
|
264
|
+
emailSentAt: string | null;
|
|
265
|
+
acceptedAt: string | null;
|
|
266
|
+
acceptedByUserId: string | null;
|
|
267
|
+
revokedAt: string | null;
|
|
268
|
+
invitedByUserId: string | null;
|
|
269
|
+
redirectUri: string | null;
|
|
270
|
+
}
|
|
271
|
+
/** POST /auth/tenant-invites/preview — what an accept page shows before the invitee commits. */
|
|
272
|
+
interface OrganizationInvitePreview {
|
|
273
|
+
tenantId: string;
|
|
274
|
+
tenantName: string;
|
|
275
|
+
email: string;
|
|
276
|
+
roles: string[];
|
|
277
|
+
expiresAt: string;
|
|
278
|
+
/** True: accepting only needs the token. False: send a password (and a username when `usernameRequired`). */
|
|
279
|
+
accountExists: boolean;
|
|
280
|
+
usernameRequired: boolean;
|
|
281
|
+
/** Where the issuer asked to send the invitee after accepting, or `null`. */
|
|
282
|
+
redirectUri: string | null;
|
|
283
|
+
}
|
|
284
|
+
/** POST /auth/tenant-invites/accept — everything but `token` is ignored when the address already has an account. */
|
|
285
|
+
interface AcceptOrganizationInviteInput {
|
|
286
|
+
token: string;
|
|
287
|
+
username?: string;
|
|
288
|
+
password?: string;
|
|
289
|
+
firstName?: string;
|
|
290
|
+
lastName?: string;
|
|
291
|
+
/**
|
|
292
|
+
* @deprecated Use `publicMetadata` / `privateMetadata` through
|
|
293
|
+
* `@authyon/server` (`environment.tenants.invites.accept`), which runs on
|
|
294
|
+
* your backend with the environment credential. Still accepted for now.
|
|
295
|
+
*/
|
|
296
|
+
customFields?: Record<string, unknown>;
|
|
297
|
+
}
|
|
298
|
+
interface OrganizationInviteAccepted {
|
|
299
|
+
tenantId: string;
|
|
300
|
+
tenantName: string;
|
|
301
|
+
userId: string;
|
|
302
|
+
/** True when accepting created the account (email already confirmed). The invitee still signs in normally. */
|
|
303
|
+
accountCreated: boolean;
|
|
304
|
+
/** Where the issuer asked to send the invitee, or `null`. Redirecting is up to the accept page. */
|
|
305
|
+
redirectUri: string | null;
|
|
306
|
+
}
|
|
223
307
|
/** Authenticated user profile. */
|
|
224
308
|
interface User {
|
|
225
309
|
id: string;
|
|
@@ -236,6 +320,8 @@ interface User {
|
|
|
236
320
|
activeOrganization?: Organization | null;
|
|
237
321
|
/** Actions the user must complete before continuing (e.g. confirm e-mail). */
|
|
238
322
|
pendencies?: string[];
|
|
323
|
+
/** Security methods active on the account (authenticator, email code, passkey, SSO…). */
|
|
324
|
+
security?: SecurityMethods;
|
|
239
325
|
}
|
|
240
326
|
/** Token pair issued by login / refresh / tenant switch. */
|
|
241
327
|
interface Session {
|
|
@@ -565,11 +651,53 @@ declare class AuthyonClient {
|
|
|
565
651
|
* (`user.activities()`, `@authyon/server`'s `environment.users.list()`).
|
|
566
652
|
*/
|
|
567
653
|
list: (organizationId: string, params?: PaginationOptions) => Promise<Paged<OrganizationMember>>;
|
|
568
|
-
/**
|
|
654
|
+
/**
|
|
655
|
+
* POST /auth/tenants/{organizationId}/members — add an existing
|
|
656
|
+
* environment user by e-mail (no e-mail is sent). To invite an address
|
|
657
|
+
* that may not have an account yet, use `organization.invites.create`.
|
|
658
|
+
*/
|
|
569
659
|
invite: (organizationId: string, params: InviteMemberInput) => Promise<void>;
|
|
570
660
|
/** DELETE /auth/tenants/{organizationId}/members/{userId} — remove a member. */
|
|
571
661
|
remove: (organizationId: string, userId: string) => Promise<void>;
|
|
572
662
|
};
|
|
663
|
+
/**
|
|
664
|
+
* Invites by e-mail or by link. Managing them requires the
|
|
665
|
+
* `tenants:members:invite` permission on the organization; `preview` and
|
|
666
|
+
* `accept` are public — the token in the link is the credential.
|
|
667
|
+
*/
|
|
668
|
+
invites: {
|
|
669
|
+
/** GET /auth/tenants/{organizationId}/invites — every invite with its status, newest first. */
|
|
670
|
+
list: (organizationId: string) => Promise<OrganizationInvite[]>;
|
|
671
|
+
/**
|
|
672
|
+
* POST /auth/tenants/{organizationId}/invites — invite an address.
|
|
673
|
+
* Always returns `acceptUrl`; with `sendEmail: false` Authyon does not
|
|
674
|
+
* mail it and you deliver the link yourself. The link is valid for 7
|
|
675
|
+
* days, once, and can't be read again later.
|
|
676
|
+
*/
|
|
677
|
+
create: (organizationId: string, params: OrganizationInviteInput) => Promise<OrganizationInviteIssued>;
|
|
678
|
+
/**
|
|
679
|
+
* POST /auth/tenants/{organizationId}/invites/{inviteId}/resend — issue
|
|
680
|
+
* a new link (the previous one stops working), mailing it unless
|
|
681
|
+
* `sendEmail` is `false`.
|
|
682
|
+
*/
|
|
683
|
+
resend: (organizationId: string, inviteId: string, params?: {
|
|
684
|
+
sendEmail?: boolean;
|
|
685
|
+
}) => Promise<OrganizationInviteIssued>;
|
|
686
|
+
/** DELETE /auth/tenants/{organizationId}/invites/{inviteId} — revoke a pending invite. */
|
|
687
|
+
revoke: (organizationId: string, inviteId: string) => Promise<void>;
|
|
688
|
+
/**
|
|
689
|
+
* POST /auth/tenant-invites/preview — public. Read the `token` query
|
|
690
|
+
* parameter of the invite link and pick the form: one click when
|
|
691
|
+
* `accountExists`, sign-up otherwise.
|
|
692
|
+
*/
|
|
693
|
+
preview: (token: string) => Promise<OrganizationInvitePreview>;
|
|
694
|
+
/**
|
|
695
|
+
* POST /auth/tenant-invites/accept — public. Joins the organization; for
|
|
696
|
+
* an address with no account, also creates it (password required) with
|
|
697
|
+
* the e-mail already confirmed. Does not sign the user in.
|
|
698
|
+
*/
|
|
699
|
+
accept: (params: AcceptOrganizationInviteInput) => Promise<OrganizationInviteAccepted>;
|
|
700
|
+
};
|
|
573
701
|
roles: {
|
|
574
702
|
/** GET /auth/tenants/{organizationId}/roles — roles available in the organization. */
|
|
575
703
|
list: (organizationId: string) => Promise<Role[]>;
|
|
@@ -620,12 +748,12 @@ declare class AuthyonClient {
|
|
|
620
748
|
};
|
|
621
749
|
};
|
|
622
750
|
/**
|
|
623
|
-
*
|
|
624
|
-
* (`@authyon/server` → `
|
|
625
|
-
* Show the
|
|
751
|
+
* `security.approvals`: approve or reject what your backend asked the
|
|
752
|
+
* customer to confirm (`@authyon/server` → `security.approvals.create`).
|
|
753
|
+
* Show the payload with `get()`, then `confirm()` with the customer's
|
|
626
754
|
* authenticator code or passkey, or `reject()`.
|
|
627
755
|
*/
|
|
628
|
-
readonly
|
|
756
|
+
readonly security: SubjectSecurity;
|
|
629
757
|
/**
|
|
630
758
|
* POST /auth/introspect — lightweight token introspection (RFC 7662).
|
|
631
759
|
*
|
|
@@ -750,4 +878,4 @@ declare function hasPermissionGroup(source: AuthyonPermissionSource | readonly s
|
|
|
750
878
|
/** Converts Authyon's `subject:action` permission strings to authorization rules. */
|
|
751
879
|
declare function createAuthyonRules(source?: AuthyonPermissionSource, options?: AuthyonAbilityOptions): AbilityRule[];
|
|
752
880
|
|
|
753
|
-
export { type
|
|
881
|
+
export { type SessionInfo 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 PermissionGroup as V, type RegisterInput as W, type Role as X, type SecurityMethods as Y, type Session as Z, type SessionControllerOptions as _, type HttpLoggerOptions as a, type SessionSnapshot as a0, type SessionSnapshotListener as a1, type SessionStatus as a2, type SsoProvider as a3, type SubjectApprovals as a4, type SubjectSecurity as a5, type TwoFactorChallenge as a6, type TwoFactorMethod as a7, type TwoFactorStatus as a8, type User as a9, type ValidateResult as aa, type VerifyTwoFactorInput as ab, type WebAuthnAssertion as ac, type WebAuthnCeremonyStart as ad, type WebAuthnCredential as ae, createAuthyonAbility as af, createAuthyonRules as ag, createClient as ah, hasPermission as ai, hasPermissionGroup as aj, 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 };
|
package/dist/index.cjs
CHANGED
|
@@ -40,29 +40,34 @@ __export(index_exports, {
|
|
|
40
40
|
});
|
|
41
41
|
module.exports = __toCommonJS(index_exports);
|
|
42
42
|
|
|
43
|
-
// ../../internal/core/
|
|
43
|
+
// ../../internal/core/security/approvals.ts
|
|
44
44
|
function path(id, suffix = "") {
|
|
45
45
|
if (typeof id !== "string" || !id.trim())
|
|
46
|
-
throw new TypeError("Authyon:
|
|
46
|
+
throw new TypeError("Authyon: an approval id is required.");
|
|
47
47
|
return `/auth/authorizations/${encodeURIComponent(id)}${suffix}`;
|
|
48
48
|
}
|
|
49
|
-
|
|
49
|
+
var NO_METHODS = {
|
|
50
|
+
password: false,
|
|
51
|
+
authenticator: false,
|
|
52
|
+
emailCode: false,
|
|
53
|
+
passkey: false,
|
|
54
|
+
passkeyCount: 0,
|
|
55
|
+
recoveryCodes: 0,
|
|
56
|
+
sso: [],
|
|
57
|
+
twoFactor: false
|
|
58
|
+
};
|
|
59
|
+
function subjectSecurity(request) {
|
|
50
60
|
return {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
* otherwise the API answers `step_up_required`.
|
|
62
|
-
*/
|
|
63
|
-
confirm: (id, input) => request(path(id, "/confirm"), { method: "POST", body: input }),
|
|
64
|
-
/** POST /auth/authorizations/{id}/reject — the customer declines the transaction. */
|
|
65
|
-
reject: (id) => request(path(id, "/reject"), { method: "POST" })
|
|
61
|
+
methods: async () => {
|
|
62
|
+
const me = await request("/auth/me");
|
|
63
|
+
return me.security ?? NO_METHODS;
|
|
64
|
+
},
|
|
65
|
+
approvals: {
|
|
66
|
+
get: (id) => request(path(id)),
|
|
67
|
+
webauthnOptions: (id) => request(path(id, "/webauthn/options"), { method: "POST" }),
|
|
68
|
+
confirm: (id, input) => request(path(id, "/confirm"), { method: "POST", body: input }),
|
|
69
|
+
reject: (id) => request(path(id, "/reject"), { method: "POST" })
|
|
70
|
+
}
|
|
66
71
|
};
|
|
67
72
|
}
|
|
68
73
|
|
|
@@ -83,10 +88,18 @@ var ErrorCodes = {
|
|
|
83
88
|
InvalidSecondFactorCode: "invalid_code",
|
|
84
89
|
VerificationAttemptsExhausted: "verification_attempts_exhausted",
|
|
85
90
|
MethodNotEnrolled: "method_not_enrolled",
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
IdempotencyConflict: "idempotency_conflict"
|
|
91
|
+
InvalidApprovalState: "invalid_authorization_state",
|
|
92
|
+
PayloadMismatch: "payload_mismatch",
|
|
93
|
+
ApprovalNotConsumable: "authorization_not_consumable",
|
|
94
|
+
IdempotencyConflict: "idempotency_conflict",
|
|
95
|
+
UserDisabled: "user_disabled",
|
|
96
|
+
UserNotFound: "user_not_found",
|
|
97
|
+
TemporarilyUnavailable: "temporarily_unavailable",
|
|
98
|
+
InsufficientScope: "insufficient_scope",
|
|
99
|
+
CredentialThrottled: "credential_throttled",
|
|
100
|
+
ApprovalNotFound: "authorization_not_found",
|
|
101
|
+
SessionRevoked: "session_revoked",
|
|
102
|
+
TwoFactorTooManyFailures: "user.2fa.too_many_failures"
|
|
90
103
|
};
|
|
91
104
|
var STANDARD_ERROR_FIELDS = /* @__PURE__ */ new Set([
|
|
92
105
|
"type",
|
|
@@ -600,7 +613,11 @@ var AuthyonClient = class {
|
|
|
600
613
|
appendQuery(`/auth/tenants/${encodeURIComponent(organizationId)}/members`, params),
|
|
601
614
|
{ bearer: true }
|
|
602
615
|
),
|
|
603
|
-
/**
|
|
616
|
+
/**
|
|
617
|
+
* POST /auth/tenants/{organizationId}/members — add an existing
|
|
618
|
+
* environment user by e-mail (no e-mail is sent). To invite an address
|
|
619
|
+
* that may not have an account yet, use `organization.invites.create`.
|
|
620
|
+
*/
|
|
604
621
|
invite: (organizationId, params) => this.request(`/auth/tenants/${encodeURIComponent(organizationId)}/members`, {
|
|
605
622
|
method: "POST",
|
|
606
623
|
bearer: true,
|
|
@@ -612,6 +629,59 @@ var AuthyonClient = class {
|
|
|
612
629
|
{ method: "DELETE", bearer: true }
|
|
613
630
|
)
|
|
614
631
|
},
|
|
632
|
+
/**
|
|
633
|
+
* Invites by e-mail or by link. Managing them requires the
|
|
634
|
+
* `tenants:members:invite` permission on the organization; `preview` and
|
|
635
|
+
* `accept` are public — the token in the link is the credential.
|
|
636
|
+
*/
|
|
637
|
+
invites: {
|
|
638
|
+
/** GET /auth/tenants/{organizationId}/invites — every invite with its status, newest first. */
|
|
639
|
+
list: (organizationId) => this.request(`/auth/tenants/${encodeURIComponent(organizationId)}/invites`, {
|
|
640
|
+
bearer: true
|
|
641
|
+
}),
|
|
642
|
+
/**
|
|
643
|
+
* POST /auth/tenants/{organizationId}/invites — invite an address.
|
|
644
|
+
* Always returns `acceptUrl`; with `sendEmail: false` Authyon does not
|
|
645
|
+
* mail it and you deliver the link yourself. The link is valid for 7
|
|
646
|
+
* days, once, and can't be read again later.
|
|
647
|
+
*/
|
|
648
|
+
create: (organizationId, params) => this.request(`/auth/tenants/${encodeURIComponent(organizationId)}/invites`, {
|
|
649
|
+
method: "POST",
|
|
650
|
+
bearer: true,
|
|
651
|
+
body: {
|
|
652
|
+
email: params.email,
|
|
653
|
+
roles: params.roles,
|
|
654
|
+
sendEmail: params.sendEmail ?? true,
|
|
655
|
+
redirectUri: params.redirectUri
|
|
656
|
+
}
|
|
657
|
+
}),
|
|
658
|
+
/**
|
|
659
|
+
* POST /auth/tenants/{organizationId}/invites/{inviteId}/resend — issue
|
|
660
|
+
* a new link (the previous one stops working), mailing it unless
|
|
661
|
+
* `sendEmail` is `false`.
|
|
662
|
+
*/
|
|
663
|
+
resend: (organizationId, inviteId, params = {}) => this.request(
|
|
664
|
+
`/auth/tenants/${encodeURIComponent(organizationId)}/invites/${encodeURIComponent(inviteId)}/resend`,
|
|
665
|
+
{ method: "POST", bearer: true, body: { sendEmail: params.sendEmail ?? true } }
|
|
666
|
+
),
|
|
667
|
+
/** DELETE /auth/tenants/{organizationId}/invites/{inviteId} — revoke a pending invite. */
|
|
668
|
+
revoke: (organizationId, inviteId) => this.request(
|
|
669
|
+
`/auth/tenants/${encodeURIComponent(organizationId)}/invites/${encodeURIComponent(inviteId)}`,
|
|
670
|
+
{ method: "DELETE", bearer: true }
|
|
671
|
+
),
|
|
672
|
+
/**
|
|
673
|
+
* POST /auth/tenant-invites/preview — public. Read the `token` query
|
|
674
|
+
* parameter of the invite link and pick the form: one click when
|
|
675
|
+
* `accountExists`, sign-up otherwise.
|
|
676
|
+
*/
|
|
677
|
+
preview: (token) => this.request("/auth/tenant-invites/preview", { method: "POST", body: { token } }),
|
|
678
|
+
/**
|
|
679
|
+
* POST /auth/tenant-invites/accept — public. Joins the organization; for
|
|
680
|
+
* an address with no account, also creates it (password required) with
|
|
681
|
+
* the e-mail already confirmed. Does not sign the user in.
|
|
682
|
+
*/
|
|
683
|
+
accept: (params) => this.request("/auth/tenant-invites/accept", { method: "POST", body: params })
|
|
684
|
+
},
|
|
615
685
|
roles: {
|
|
616
686
|
/** GET /auth/tenants/{organizationId}/roles — roles available in the organization. */
|
|
617
687
|
list: (organizationId) => this.request(`/auth/tenants/${encodeURIComponent(organizationId)}/roles`, {
|
|
@@ -687,14 +757,14 @@ var AuthyonClient = class {
|
|
|
687
757
|
})
|
|
688
758
|
}
|
|
689
759
|
};
|
|
690
|
-
// ──
|
|
760
|
+
// ── Security (customer side) ─────────────────────────────────────────────
|
|
691
761
|
/**
|
|
692
|
-
*
|
|
693
|
-
* (`@authyon/server` → `
|
|
694
|
-
* Show the
|
|
762
|
+
* `security.approvals`: approve or reject what your backend asked the
|
|
763
|
+
* customer to confirm (`@authyon/server` → `security.approvals.create`).
|
|
764
|
+
* Show the payload with `get()`, then `confirm()` with the customer's
|
|
695
765
|
* authenticator code or passkey, or `reject()`.
|
|
696
766
|
*/
|
|
697
|
-
this.
|
|
767
|
+
this.security = subjectSecurity(
|
|
698
768
|
(path2, options) => this.request(path2, { ...options, bearer: true })
|
|
699
769
|
);
|
|
700
770
|
if (!options.envKey)
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as TokenStorage, H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonClient } from './ability-
|
|
2
|
-
export { b as AbilityConditions, c as AbilityEvent, d as AbilityListener, e as AbilityRule, f as AbilitySubject, g as
|
|
1
|
+
import { T as TokenStorage, H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonClient } from './ability-Cp8ir5Gr.cjs';
|
|
2
|
+
export { b as AbilityConditions, c as AbilityEvent, d as AbilityListener, e as AbilityRule, f as AbilitySubject, g as AcceptOrganizationInviteInput, h as Activity, i as Approval, j as ApprovalAssurance, k as ApprovalPayload, l as ApprovalStatus, m as ApprovalWebAuthnOptions, n as AuthEvent, o as AuthState, p as AuthStateListener, q as AuthenticatorSetup, r as AuthyonAbility, s as AuthyonAbilityBuilder, t as AuthyonAbilityOptions, u as AuthyonClientOptions, v as AuthyonPermissionSource, w as AuthyonSessionController, C as ConfirmApprovalInput, x as CreateOrganizationInput, F as FetchHttpAdapter, y as HttpAdapterRequest, z as HttpLogEvent, B as HttpLogger, I as IntrospectResult, D as InviteMemberInput, L as LoggingHttpAdapter, E as LoginInput, G as LoginResult, O as Organization, J as OrganizationInvite, K as OrganizationInviteAccepted, M as OrganizationInviteInput, N as OrganizationInviteIssued, P as OrganizationInvitePreview, Q as OrganizationInviteStatus, R as OrganizationMember, S as Paged, U as PaginationOptions, V as PermissionGroup, W as RegisterInput, X as Role, Y as SecurityMethods, Z as Session, _ as SessionControllerOptions, $ as SessionInfo, a0 as SessionSnapshot, a1 as SessionSnapshotListener, a2 as SessionStatus, a3 as SsoProvider, a4 as SubjectApprovals, a5 as SubjectSecurity, a6 as TwoFactorChallenge, a7 as TwoFactorMethod, a8 as TwoFactorStatus, a9 as User, aa as ValidateResult, ab as VerifyTwoFactorInput, ac as WebAuthnAssertion, ad as WebAuthnCeremonyStart, ae as WebAuthnCredential, af as createAuthyonAbility, ag as createAuthyonRules, ah as createClient, ai as hasPermission, aj as hasPermissionGroup } from './ability-Cp8ir5Gr.cjs';
|
|
3
3
|
|
|
4
4
|
declare const ErrorCodes: {
|
|
5
5
|
readonly Unknown: "unknown";
|
|
@@ -17,10 +17,18 @@ declare const ErrorCodes: {
|
|
|
17
17
|
readonly InvalidSecondFactorCode: "invalid_code";
|
|
18
18
|
readonly VerificationAttemptsExhausted: "verification_attempts_exhausted";
|
|
19
19
|
readonly MethodNotEnrolled: "method_not_enrolled";
|
|
20
|
-
readonly
|
|
21
|
-
readonly
|
|
22
|
-
readonly
|
|
20
|
+
readonly InvalidApprovalState: "invalid_authorization_state";
|
|
21
|
+
readonly PayloadMismatch: "payload_mismatch";
|
|
22
|
+
readonly ApprovalNotConsumable: "authorization_not_consumable";
|
|
23
23
|
readonly IdempotencyConflict: "idempotency_conflict";
|
|
24
|
+
readonly UserDisabled: "user_disabled";
|
|
25
|
+
readonly UserNotFound: "user_not_found";
|
|
26
|
+
readonly TemporarilyUnavailable: "temporarily_unavailable";
|
|
27
|
+
readonly InsufficientScope: "insufficient_scope";
|
|
28
|
+
readonly CredentialThrottled: "credential_throttled";
|
|
29
|
+
readonly ApprovalNotFound: "authorization_not_found";
|
|
30
|
+
readonly SessionRevoked: "session_revoked";
|
|
31
|
+
readonly TwoFactorTooManyFailures: "user.2fa.too_many_failures";
|
|
24
32
|
};
|
|
25
33
|
type KnownErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
|
|
26
34
|
type AuthyonErrorCategory = "network" | "timeout" | "authentication" | "authorization" | "validation" | "not_found" | "conflict" | "rate_limit" | "server" | "unknown";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as TokenStorage, H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonClient } from './ability-
|
|
2
|
-
export { b as AbilityConditions, c as AbilityEvent, d as AbilityListener, e as AbilityRule, f as AbilitySubject, g as
|
|
1
|
+
import { T as TokenStorage, H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonClient } from './ability-Cp8ir5Gr.js';
|
|
2
|
+
export { b as AbilityConditions, c as AbilityEvent, d as AbilityListener, e as AbilityRule, f as AbilitySubject, g as AcceptOrganizationInviteInput, h as Activity, i as Approval, j as ApprovalAssurance, k as ApprovalPayload, l as ApprovalStatus, m as ApprovalWebAuthnOptions, n as AuthEvent, o as AuthState, p as AuthStateListener, q as AuthenticatorSetup, r as AuthyonAbility, s as AuthyonAbilityBuilder, t as AuthyonAbilityOptions, u as AuthyonClientOptions, v as AuthyonPermissionSource, w as AuthyonSessionController, C as ConfirmApprovalInput, x as CreateOrganizationInput, F as FetchHttpAdapter, y as HttpAdapterRequest, z as HttpLogEvent, B as HttpLogger, I as IntrospectResult, D as InviteMemberInput, L as LoggingHttpAdapter, E as LoginInput, G as LoginResult, O as Organization, J as OrganizationInvite, K as OrganizationInviteAccepted, M as OrganizationInviteInput, N as OrganizationInviteIssued, P as OrganizationInvitePreview, Q as OrganizationInviteStatus, R as OrganizationMember, S as Paged, U as PaginationOptions, V as PermissionGroup, W as RegisterInput, X as Role, Y as SecurityMethods, Z as Session, _ as SessionControllerOptions, $ as SessionInfo, a0 as SessionSnapshot, a1 as SessionSnapshotListener, a2 as SessionStatus, a3 as SsoProvider, a4 as SubjectApprovals, a5 as SubjectSecurity, a6 as TwoFactorChallenge, a7 as TwoFactorMethod, a8 as TwoFactorStatus, a9 as User, aa as ValidateResult, ab as VerifyTwoFactorInput, ac as WebAuthnAssertion, ad as WebAuthnCeremonyStart, ae as WebAuthnCredential, af as createAuthyonAbility, ag as createAuthyonRules, ah as createClient, ai as hasPermission, aj as hasPermissionGroup } from './ability-Cp8ir5Gr.js';
|
|
3
3
|
|
|
4
4
|
declare const ErrorCodes: {
|
|
5
5
|
readonly Unknown: "unknown";
|
|
@@ -17,10 +17,18 @@ declare const ErrorCodes: {
|
|
|
17
17
|
readonly InvalidSecondFactorCode: "invalid_code";
|
|
18
18
|
readonly VerificationAttemptsExhausted: "verification_attempts_exhausted";
|
|
19
19
|
readonly MethodNotEnrolled: "method_not_enrolled";
|
|
20
|
-
readonly
|
|
21
|
-
readonly
|
|
22
|
-
readonly
|
|
20
|
+
readonly InvalidApprovalState: "invalid_authorization_state";
|
|
21
|
+
readonly PayloadMismatch: "payload_mismatch";
|
|
22
|
+
readonly ApprovalNotConsumable: "authorization_not_consumable";
|
|
23
23
|
readonly IdempotencyConflict: "idempotency_conflict";
|
|
24
|
+
readonly UserDisabled: "user_disabled";
|
|
25
|
+
readonly UserNotFound: "user_not_found";
|
|
26
|
+
readonly TemporarilyUnavailable: "temporarily_unavailable";
|
|
27
|
+
readonly InsufficientScope: "insufficient_scope";
|
|
28
|
+
readonly CredentialThrottled: "credential_throttled";
|
|
29
|
+
readonly ApprovalNotFound: "authorization_not_found";
|
|
30
|
+
readonly SessionRevoked: "session_revoked";
|
|
31
|
+
readonly TwoFactorTooManyFailures: "user.2fa.too_many_failures";
|
|
24
32
|
};
|
|
25
33
|
type KnownErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
|
|
26
34
|
type AuthyonErrorCategory = "network" | "timeout" | "authentication" | "authorization" | "validation" | "not_found" | "conflict" | "rate_limit" | "server" | "unknown";
|
package/dist/index.js
CHANGED
|
@@ -8,29 +8,34 @@ import {
|
|
|
8
8
|
hasPermissionGroup
|
|
9
9
|
} from "./chunk-3XJY6BCI.js";
|
|
10
10
|
|
|
11
|
-
// ../../internal/core/
|
|
11
|
+
// ../../internal/core/security/approvals.ts
|
|
12
12
|
function path(id, suffix = "") {
|
|
13
13
|
if (typeof id !== "string" || !id.trim())
|
|
14
|
-
throw new TypeError("Authyon:
|
|
14
|
+
throw new TypeError("Authyon: an approval id is required.");
|
|
15
15
|
return `/auth/authorizations/${encodeURIComponent(id)}${suffix}`;
|
|
16
16
|
}
|
|
17
|
-
|
|
17
|
+
var NO_METHODS = {
|
|
18
|
+
password: false,
|
|
19
|
+
authenticator: false,
|
|
20
|
+
emailCode: false,
|
|
21
|
+
passkey: false,
|
|
22
|
+
passkeyCount: 0,
|
|
23
|
+
recoveryCodes: 0,
|
|
24
|
+
sso: [],
|
|
25
|
+
twoFactor: false
|
|
26
|
+
};
|
|
27
|
+
function subjectSecurity(request) {
|
|
18
28
|
return {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
* otherwise the API answers `step_up_required`.
|
|
30
|
-
*/
|
|
31
|
-
confirm: (id, input) => request(path(id, "/confirm"), { method: "POST", body: input }),
|
|
32
|
-
/** POST /auth/authorizations/{id}/reject — the customer declines the transaction. */
|
|
33
|
-
reject: (id) => request(path(id, "/reject"), { method: "POST" })
|
|
29
|
+
methods: async () => {
|
|
30
|
+
const me = await request("/auth/me");
|
|
31
|
+
return me.security ?? NO_METHODS;
|
|
32
|
+
},
|
|
33
|
+
approvals: {
|
|
34
|
+
get: (id) => request(path(id)),
|
|
35
|
+
webauthnOptions: (id) => request(path(id, "/webauthn/options"), { method: "POST" }),
|
|
36
|
+
confirm: (id, input) => request(path(id, "/confirm"), { method: "POST", body: input }),
|
|
37
|
+
reject: (id) => request(path(id, "/reject"), { method: "POST" })
|
|
38
|
+
}
|
|
34
39
|
};
|
|
35
40
|
}
|
|
36
41
|
|
|
@@ -51,10 +56,18 @@ var ErrorCodes = {
|
|
|
51
56
|
InvalidSecondFactorCode: "invalid_code",
|
|
52
57
|
VerificationAttemptsExhausted: "verification_attempts_exhausted",
|
|
53
58
|
MethodNotEnrolled: "method_not_enrolled",
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
IdempotencyConflict: "idempotency_conflict"
|
|
59
|
+
InvalidApprovalState: "invalid_authorization_state",
|
|
60
|
+
PayloadMismatch: "payload_mismatch",
|
|
61
|
+
ApprovalNotConsumable: "authorization_not_consumable",
|
|
62
|
+
IdempotencyConflict: "idempotency_conflict",
|
|
63
|
+
UserDisabled: "user_disabled",
|
|
64
|
+
UserNotFound: "user_not_found",
|
|
65
|
+
TemporarilyUnavailable: "temporarily_unavailable",
|
|
66
|
+
InsufficientScope: "insufficient_scope",
|
|
67
|
+
CredentialThrottled: "credential_throttled",
|
|
68
|
+
ApprovalNotFound: "authorization_not_found",
|
|
69
|
+
SessionRevoked: "session_revoked",
|
|
70
|
+
TwoFactorTooManyFailures: "user.2fa.too_many_failures"
|
|
58
71
|
};
|
|
59
72
|
var STANDARD_ERROR_FIELDS = /* @__PURE__ */ new Set([
|
|
60
73
|
"type",
|
|
@@ -568,7 +581,11 @@ var AuthyonClient = class {
|
|
|
568
581
|
appendQuery(`/auth/tenants/${encodeURIComponent(organizationId)}/members`, params),
|
|
569
582
|
{ bearer: true }
|
|
570
583
|
),
|
|
571
|
-
/**
|
|
584
|
+
/**
|
|
585
|
+
* POST /auth/tenants/{organizationId}/members — add an existing
|
|
586
|
+
* environment user by e-mail (no e-mail is sent). To invite an address
|
|
587
|
+
* that may not have an account yet, use `organization.invites.create`.
|
|
588
|
+
*/
|
|
572
589
|
invite: (organizationId, params) => this.request(`/auth/tenants/${encodeURIComponent(organizationId)}/members`, {
|
|
573
590
|
method: "POST",
|
|
574
591
|
bearer: true,
|
|
@@ -580,6 +597,59 @@ var AuthyonClient = class {
|
|
|
580
597
|
{ method: "DELETE", bearer: true }
|
|
581
598
|
)
|
|
582
599
|
},
|
|
600
|
+
/**
|
|
601
|
+
* Invites by e-mail or by link. Managing them requires the
|
|
602
|
+
* `tenants:members:invite` permission on the organization; `preview` and
|
|
603
|
+
* `accept` are public — the token in the link is the credential.
|
|
604
|
+
*/
|
|
605
|
+
invites: {
|
|
606
|
+
/** GET /auth/tenants/{organizationId}/invites — every invite with its status, newest first. */
|
|
607
|
+
list: (organizationId) => this.request(`/auth/tenants/${encodeURIComponent(organizationId)}/invites`, {
|
|
608
|
+
bearer: true
|
|
609
|
+
}),
|
|
610
|
+
/**
|
|
611
|
+
* POST /auth/tenants/{organizationId}/invites — invite an address.
|
|
612
|
+
* Always returns `acceptUrl`; with `sendEmail: false` Authyon does not
|
|
613
|
+
* mail it and you deliver the link yourself. The link is valid for 7
|
|
614
|
+
* days, once, and can't be read again later.
|
|
615
|
+
*/
|
|
616
|
+
create: (organizationId, params) => this.request(`/auth/tenants/${encodeURIComponent(organizationId)}/invites`, {
|
|
617
|
+
method: "POST",
|
|
618
|
+
bearer: true,
|
|
619
|
+
body: {
|
|
620
|
+
email: params.email,
|
|
621
|
+
roles: params.roles,
|
|
622
|
+
sendEmail: params.sendEmail ?? true,
|
|
623
|
+
redirectUri: params.redirectUri
|
|
624
|
+
}
|
|
625
|
+
}),
|
|
626
|
+
/**
|
|
627
|
+
* POST /auth/tenants/{organizationId}/invites/{inviteId}/resend — issue
|
|
628
|
+
* a new link (the previous one stops working), mailing it unless
|
|
629
|
+
* `sendEmail` is `false`.
|
|
630
|
+
*/
|
|
631
|
+
resend: (organizationId, inviteId, params = {}) => this.request(
|
|
632
|
+
`/auth/tenants/${encodeURIComponent(organizationId)}/invites/${encodeURIComponent(inviteId)}/resend`,
|
|
633
|
+
{ method: "POST", bearer: true, body: { sendEmail: params.sendEmail ?? true } }
|
|
634
|
+
),
|
|
635
|
+
/** DELETE /auth/tenants/{organizationId}/invites/{inviteId} — revoke a pending invite. */
|
|
636
|
+
revoke: (organizationId, inviteId) => this.request(
|
|
637
|
+
`/auth/tenants/${encodeURIComponent(organizationId)}/invites/${encodeURIComponent(inviteId)}`,
|
|
638
|
+
{ method: "DELETE", bearer: true }
|
|
639
|
+
),
|
|
640
|
+
/**
|
|
641
|
+
* POST /auth/tenant-invites/preview — public. Read the `token` query
|
|
642
|
+
* parameter of the invite link and pick the form: one click when
|
|
643
|
+
* `accountExists`, sign-up otherwise.
|
|
644
|
+
*/
|
|
645
|
+
preview: (token) => this.request("/auth/tenant-invites/preview", { method: "POST", body: { token } }),
|
|
646
|
+
/**
|
|
647
|
+
* POST /auth/tenant-invites/accept — public. Joins the organization; for
|
|
648
|
+
* an address with no account, also creates it (password required) with
|
|
649
|
+
* the e-mail already confirmed. Does not sign the user in.
|
|
650
|
+
*/
|
|
651
|
+
accept: (params) => this.request("/auth/tenant-invites/accept", { method: "POST", body: params })
|
|
652
|
+
},
|
|
583
653
|
roles: {
|
|
584
654
|
/** GET /auth/tenants/{organizationId}/roles — roles available in the organization. */
|
|
585
655
|
list: (organizationId) => this.request(`/auth/tenants/${encodeURIComponent(organizationId)}/roles`, {
|
|
@@ -655,14 +725,14 @@ var AuthyonClient = class {
|
|
|
655
725
|
})
|
|
656
726
|
}
|
|
657
727
|
};
|
|
658
|
-
// ──
|
|
728
|
+
// ── Security (customer side) ─────────────────────────────────────────────
|
|
659
729
|
/**
|
|
660
|
-
*
|
|
661
|
-
* (`@authyon/server` → `
|
|
662
|
-
* Show the
|
|
730
|
+
* `security.approvals`: approve or reject what your backend asked the
|
|
731
|
+
* customer to confirm (`@authyon/server` → `security.approvals.create`).
|
|
732
|
+
* Show the payload with `get()`, then `confirm()` with the customer's
|
|
663
733
|
* authenticator code or passkey, or `reject()`.
|
|
664
734
|
*/
|
|
665
|
-
this.
|
|
735
|
+
this.security = subjectSecurity(
|
|
666
736
|
(path2, options) => this.request(path2, { ...options, bearer: true })
|
|
667
737
|
);
|
|
668
738
|
if (!options.envKey)
|
package/dist/react/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
3
|
+
import { a9 as User, _ as SessionControllerOptions, A as AuthyonClient, a0 as SessionSnapshot, Z as Session, f as AbilitySubject, t as AuthyonAbilityOptions, r as AuthyonAbility } from '../ability-Cp8ir5Gr.cjs';
|
|
4
|
+
export { w as AuthyonSessionController, a1 as SessionSnapshotListener, a2 as SessionStatus } from '../ability-Cp8ir5Gr.cjs';
|
|
5
5
|
|
|
6
6
|
interface AuthyonProviderProps<TUser extends User = User> extends SessionControllerOptions {
|
|
7
7
|
client: AuthyonClient;
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
3
|
+
import { a9 as User, _ as SessionControllerOptions, A as AuthyonClient, a0 as SessionSnapshot, Z as Session, f as AbilitySubject, t as AuthyonAbilityOptions, r as AuthyonAbility } from '../ability-Cp8ir5Gr.js';
|
|
4
|
+
export { w as AuthyonSessionController, a1 as SessionSnapshotListener, a2 as SessionStatus } from '../ability-Cp8ir5Gr.js';
|
|
5
5
|
|
|
6
6
|
interface AuthyonProviderProps<TUser extends User = User> extends SessionControllerOptions {
|
|
7
7
|
client: AuthyonClient;
|