@authyon/server 0.2.0-beta.12 → 0.2.0-beta.15
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 +51 -62
- package/dist/{authorization-DWlLfYQJ.d.cts → authorization-B82XXf3B.d.cts} +1 -1
- package/dist/{authorization-wrZ5ull7.d.ts → authorization-WlwcTBwG.d.ts} +1 -1
- package/dist/{authyonServerClient-t82mwTws.d.cts → authyonServerClient-DQzhfaja.d.cts} +163 -115
- package/dist/{authyonServerClient-t82mwTws.d.ts → authyonServerClient-DQzhfaja.d.ts} +163 -115
- package/dist/bff.cjs +36 -6
- package/dist/bff.d.cts +1 -1
- package/dist/bff.d.ts +1 -1
- package/dist/bff.js +1 -1
- package/dist/{chunk-56H66KLG.js → chunk-WPPEV5BA.js} +36 -6
- package/dist/index.cjs +142 -147
- package/dist/index.d.cts +34 -9
- package/dist/index.d.ts +34 -9
- package/dist/index.js +92 -125
- package/dist/next.d.cts +2 -2
- package/dist/next.d.ts +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -120,7 +120,7 @@ await authyon.environment.audit.list({ take: 50 });
|
|
|
120
120
|
|
|
121
121
|
Veja [`examples/organizationMembership.ts`](./examples/organizationMembership.ts) para o fluxo completo, incluindo as rotas de backend que o `@authyon/auth` chamaria.
|
|
122
122
|
|
|
123
|
-
Namespaces disponíveis: `environment.users`, `environment.tenants` (com `.members` e `.roles` aninhados), `environment.roles`, `environment.permissions`, `environment.audit`.
|
|
123
|
+
Namespaces disponíveis: `environment.users`, `environment.tenants` (com `.members` e `.roles` aninhados), `environment.roles`, `environment.permissions`, `environment.audit`. OTP e aprovações ficam em `security` (veja abaixo).
|
|
124
124
|
|
|
125
125
|
## Autorização local
|
|
126
126
|
|
|
@@ -191,6 +191,37 @@ Chamadas server-side propagam `clientIp` em `X-Forwarded-For`. O middleware Expr
|
|
|
191
191
|
await authyon.validate(token, { clientIp: "203.0.113.10" });
|
|
192
192
|
```
|
|
193
193
|
|
|
194
|
+
## Segurança (`security.*`)
|
|
195
|
+
|
|
196
|
+
OTP e aprovações ficam agrupados em `authyon.security`. Exige uma credencial de ambiente
|
|
197
|
+
com o escopo `authyon:financial:authorize`. Guia completo:
|
|
198
|
+
[`docs/security-otp-approvals.md`](../../docs/security-otp-approvals.md).
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
// security.otp — só validar o código do app autenticador
|
|
202
|
+
const result = await authyon.security.otp.check(customerId, code);
|
|
203
|
+
if (!result.valid) console.log(result.attemptsRemaining, result.sessionsRevoked);
|
|
204
|
+
|
|
205
|
+
// security.approvals — aprovação presa a um payload livre e de uso único
|
|
206
|
+
const { id } = await authyon.security.approvals.create({
|
|
207
|
+
subjectId: customerId,
|
|
208
|
+
payload: { type: "pix", amount: 150.5, to: "maria@example.com" },
|
|
209
|
+
});
|
|
210
|
+
// ...cliente confirma com @authyon/auth → security.approvals.confirm
|
|
211
|
+
const { payload } = await authyon.security.approvals.consume(id);
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
| Método | Endpoint |
|
|
215
|
+
| ------------------------------------ | --------------------------------------- |
|
|
216
|
+
| `security.otp.check(userId, code)` | `POST /env/users/{userId}/otp/verify` |
|
|
217
|
+
| `security.approvals.create(input)` | `POST /env/authorizations` |
|
|
218
|
+
| `security.approvals.get(id)` | `GET /env/authorizations/{id}` |
|
|
219
|
+
| `security.approvals.consume(id, p?)` | `POST /env/authorizations/{id}/consume` |
|
|
220
|
+
|
|
221
|
+
Cada código vale uma vez; 3 erros seguidos deslogam o usuário de todos os dispositivos e
|
|
222
|
+
5 bloqueiam a verificação por 15 minutos. Se o seu servidor guarda o token do cliente
|
|
223
|
+
(BFF), o lado do cliente está em `authyon.user(accessToken).security.approvals`.
|
|
224
|
+
|
|
194
225
|
## Administração por tenant (`tenant()`)
|
|
195
226
|
|
|
196
227
|
As credenciais de um tenant são próprias dele — use `authyon.tenant(credentials)` para obter um cliente escopado, que minta e cacheia seu próprio token via `POST /tenant/oauth/token`:
|
|
@@ -298,73 +329,34 @@ const issued = await authyon.environment.tenants.credentials.create(tenantId, {
|
|
|
298
329
|
});
|
|
299
330
|
// Armazene issued.clientSecret no gerenciador de segredos. Não registre a resposta.
|
|
300
331
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
await
|
|
307
|
-
await
|
|
332
|
+
await authyon.environment.tenants.credentials.listPage(tenantId, {
|
|
333
|
+
search: "ERP",
|
|
334
|
+
skip: 0,
|
|
335
|
+
take: 25,
|
|
336
|
+
});
|
|
337
|
+
await authyon.environment.tenants.credentials.get(tenantId, credentialId);
|
|
338
|
+
await authyon.environment.tenants.credentials.create(tenantId, {
|
|
308
339
|
description: "Leitura",
|
|
309
340
|
permissions: ["monkeypay:transactions:read"],
|
|
310
341
|
});
|
|
311
|
-
await
|
|
312
|
-
|
|
342
|
+
await authyon.environment.tenants.credentials.updateScopes(tenantId, credentialId, [
|
|
343
|
+
"monkeypay:transactions:read",
|
|
344
|
+
]);
|
|
345
|
+
await authyon.environment.tenants.credentials.updatePermissions(tenantId, credentialId, {
|
|
313
346
|
permissions: ["monkeypay:transactions:read"],
|
|
314
347
|
});
|
|
315
|
-
const rotated = await
|
|
316
|
-
await
|
|
348
|
+
const rotated = await authyon.environment.tenants.credentials.rotate(tenantId, credentialId);
|
|
349
|
+
await authyon.environment.tenants.credentials.revoke(tenantId, credentialId);
|
|
317
350
|
```
|
|
318
351
|
|
|
319
|
-
|
|
320
|
-
rotação retornam o segredo uma única vez. Alterar permissões substitui a lista
|
|
352
|
+
Criação e rotação retornam o segredo uma única vez. Alterar permissões substitui a lista
|
|
321
353
|
completa. A concessão OAuth continua recebendo apenas `clientId`/`clientSecret`;
|
|
322
354
|
`scopes` não é um parâmetro de redução de acesso na troca de token.
|
|
323
355
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
**token de usuário da plataforma**, sem fallback para credenciais de máquina.
|
|
327
|
-
Se a API exigir `auth.step_up_required`, solicite confirmação de senha na sua
|
|
328
|
-
aplicação e chame explicitamente `platform.auth.stepUp(currentPassword)` antes
|
|
329
|
-
de tentar a operação novamente. O SDK não repete mutações automaticamente.
|
|
330
|
-
|
|
331
|
-
## Convites e remoção de acesso
|
|
332
|
-
|
|
333
|
-
### Workspace
|
|
334
|
-
|
|
335
|
-
```ts
|
|
336
|
-
const team = await platform.workspaces.team(workspaceId);
|
|
337
|
-
const invite = await platform.workspaces.members.invite(workspaceId, {
|
|
338
|
-
email: "pessoa@example.com",
|
|
339
|
-
role: "auditor", // ou "admin", sempre explícito
|
|
340
|
-
});
|
|
341
|
-
// invite.acceptUrl é sensível: entregue somente à pessoa convidada.
|
|
342
|
-
await platform.workspaces.invites.revoke(workspaceId, invite.inviteId);
|
|
343
|
-
await platform.workspaces.members.changeRole(workspaceId, memberId, "auditor");
|
|
344
|
-
await platform.workspaces.members.remove(workspaceId, memberId);
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
`memberId` vem de `team.members`, e não é `userId`. O proprietário tem
|
|
348
|
-
`memberId: null`; a API protege proprietário, acesso próprio e permissões de
|
|
349
|
-
administração. `workspaces.invites.create` é um alias para `members.invite`.
|
|
350
|
-
Convites pendentes ficam em `team.pendingInvites`; revogar o convite invalida o
|
|
351
|
-
link. Para retirar acesso após aceite, remova o membro.
|
|
352
|
-
|
|
353
|
-
A pessoa convidada pode consultar/aceitar o convite por uma rota server-side:
|
|
354
|
-
|
|
355
|
-
```ts
|
|
356
|
-
const preview = await authyon.workspaceInvites.preview(invitationToken);
|
|
357
|
-
await authyon.workspaceInvites.accept(invitationToken, {
|
|
358
|
-
name: "Pessoa",
|
|
359
|
-
password: registrationPassword,
|
|
360
|
-
});
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
Esses métodos não enviam token de usuário nem credenciais de ambiente. Nome e
|
|
364
|
-
senha são necessários quando `preview.requiresRegistration` for verdadeiro;
|
|
365
|
-
para uma conta existente, use `accept(invitationToken)`.
|
|
356
|
+
Todas as operações usam os endpoints externos `/env` com a credencial de
|
|
357
|
+
ambiente configurada no cliente. O SDK não repete mutações automaticamente.
|
|
366
358
|
|
|
367
|
-
|
|
359
|
+
## Membros do tenant
|
|
368
360
|
|
|
369
361
|
```ts
|
|
370
362
|
const user = authyon.user(() => getCurrentUserAccessToken());
|
|
@@ -379,9 +371,6 @@ await user.tenants.members.remove(tenantId, userId);
|
|
|
379
371
|
await authyon.environment.tenants.members.add(tenantId, userId, ["reader"]);
|
|
380
372
|
await authyon.environment.tenants.members.remove(tenantId, userId);
|
|
381
373
|
// Os métodos tenant(credentials).members.add/remove existentes continuam disponíveis.
|
|
382
|
-
// Administração com sessão da plataforma:
|
|
383
|
-
await platform.tenants.members.add(scope, userId, ["reader"]);
|
|
384
|
-
await platform.tenants.members.remove(scope, userId);
|
|
385
374
|
```
|
|
386
375
|
|
|
387
376
|
Configure `envKey` para `user()`. O convite de tenant associa um usuário já
|
|
@@ -392,8 +381,8 @@ atendendo esse fluxo. Nunca importe `@authyon/server` no browser.
|
|
|
392
381
|
|
|
393
382
|
## Compatibilidade e segurança do transporte
|
|
394
383
|
|
|
395
|
-
|
|
396
|
-
|
|
384
|
+
As chamadas exigem os endpoints externos atuais da API e a migração
|
|
385
|
+
`ClientCredentialMetadata` para metadados
|
|
397
386
|
persistidos. O SDK não altera o banco nem publica uma versão automaticamente.
|
|
398
387
|
|
|
399
388
|
O adaptador Fetch agora rejeita redirects para evitar reenviar tokens/segredos;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { G as JwksTokenVerifier, A as AuthyonServerClient } from './authyonServerClient-DQzhfaja.cjs';
|
|
2
2
|
|
|
3
3
|
type AbilitySubject = string | Record<string, unknown>;
|
|
4
4
|
type AbilityConditions = Record<string, unknown>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { G as JwksTokenVerifier, A as AuthyonServerClient } from './authyonServerClient-DQzhfaja.js';
|
|
2
2
|
|
|
3
3
|
type AbilitySubject = string | Record<string, unknown>;
|
|
4
4
|
type AbilityConditions = Record<string, unknown>;
|
|
@@ -401,14 +401,6 @@ type CreateCredentialInput = CredentialPermissionsInput & {
|
|
|
401
401
|
description?: string;
|
|
402
402
|
lifetimeDays?: number | null;
|
|
403
403
|
};
|
|
404
|
-
interface CredentialScope {
|
|
405
|
-
workspaceId: string;
|
|
406
|
-
environmentId: string;
|
|
407
|
-
tenantId?: string;
|
|
408
|
-
}
|
|
409
|
-
interface TenantManagementScope extends CredentialScope {
|
|
410
|
-
tenantId: string;
|
|
411
|
-
}
|
|
412
404
|
interface CredentialCreator {
|
|
413
405
|
id: string | null;
|
|
414
406
|
type: string;
|
|
@@ -424,64 +416,6 @@ interface CredentialDetail extends TenantCredentialSummary {
|
|
|
424
416
|
lifetimeSeconds: number | null;
|
|
425
417
|
accessTokenLifetimeSeconds: number;
|
|
426
418
|
}
|
|
427
|
-
type WorkspaceRole = "admin" | "auditor";
|
|
428
|
-
interface WorkspaceMember {
|
|
429
|
-
memberId: string | null;
|
|
430
|
-
userId: string;
|
|
431
|
-
email: string;
|
|
432
|
-
name: string;
|
|
433
|
-
role: string;
|
|
434
|
-
isOwner: boolean;
|
|
435
|
-
isSelf: boolean;
|
|
436
|
-
invitedByName: string | null;
|
|
437
|
-
joinedAt: string;
|
|
438
|
-
lastLoginAt: string | null;
|
|
439
|
-
}
|
|
440
|
-
interface WorkspaceInvite {
|
|
441
|
-
id: string;
|
|
442
|
-
email: string;
|
|
443
|
-
role: string;
|
|
444
|
-
invitedByName: string | null;
|
|
445
|
-
createdAt: string;
|
|
446
|
-
expiresAt: string;
|
|
447
|
-
}
|
|
448
|
-
interface WorkspaceTeam {
|
|
449
|
-
workspaceId: string;
|
|
450
|
-
workspaceName: string;
|
|
451
|
-
callerRole: string;
|
|
452
|
-
canManage: boolean;
|
|
453
|
-
members: WorkspaceMember[];
|
|
454
|
-
pendingInvites: WorkspaceInvite[];
|
|
455
|
-
}
|
|
456
|
-
interface InviteWorkspaceMemberInput {
|
|
457
|
-
email: string;
|
|
458
|
-
role: WorkspaceRole;
|
|
459
|
-
}
|
|
460
|
-
interface WorkspaceInviteIssued {
|
|
461
|
-
inviteId: string;
|
|
462
|
-
email: string;
|
|
463
|
-
role: string;
|
|
464
|
-
/** Sensitive bearer link returned at issuance. Do not log or persist in public storage. */
|
|
465
|
-
acceptUrl: string;
|
|
466
|
-
expiresAt: string;
|
|
467
|
-
}
|
|
468
|
-
interface WorkspaceInvitePreview {
|
|
469
|
-
workspaceName: string;
|
|
470
|
-
email: string;
|
|
471
|
-
role: string;
|
|
472
|
-
expiresAt: string;
|
|
473
|
-
requiresRegistration: boolean;
|
|
474
|
-
}
|
|
475
|
-
interface WorkspaceInviteAccepted {
|
|
476
|
-
workspaceId: string;
|
|
477
|
-
workspaceName: string;
|
|
478
|
-
role: string;
|
|
479
|
-
accountCreated: boolean;
|
|
480
|
-
}
|
|
481
|
-
interface AcceptWorkspaceInviteInput {
|
|
482
|
-
name?: string;
|
|
483
|
-
password?: string;
|
|
484
|
-
}
|
|
485
419
|
interface InviteTenantMemberInput {
|
|
486
420
|
email: string;
|
|
487
421
|
roles?: string[];
|
|
@@ -508,51 +442,95 @@ interface JsonRequestOptions {
|
|
|
508
442
|
|
|
509
443
|
type ManagementRequest = <T>(path: string, options?: JsonRequestOptions) => Promise<T>;
|
|
510
444
|
|
|
511
|
-
/**
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
445
|
+
/** Lifecycle of an approval. */
|
|
446
|
+
type ApprovalStatus = "pending" | "approved" | "denied" | "consumed" | "expired";
|
|
447
|
+
/**
|
|
448
|
+
* Free-form JSON object describing what the customer approves (up to 16 KiB).
|
|
449
|
+
* The API stores it, shows it back to the customer and binds its canonical
|
|
450
|
+
* hash (keys sorted) to the approval.
|
|
451
|
+
*/
|
|
452
|
+
type ApprovalPayload = Record<string, unknown>;
|
|
453
|
+
/** Evidence of how the customer proved their identity when approving. */
|
|
454
|
+
interface ApprovalAssurance {
|
|
455
|
+
/** `urn:authyon:loa:3` (passkey) or `urn:authyon:loa:2` (authenticator code). */
|
|
456
|
+
acr: string;
|
|
457
|
+
/** Authentication methods, e.g. `["pwd", "otp"]` or `["pwd", "webauthn"]`. */
|
|
458
|
+
amr: string[];
|
|
459
|
+
/** When the second factor was verified (ISO 8601). */
|
|
460
|
+
authTime: string;
|
|
461
|
+
}
|
|
462
|
+
/** A request for the customer to approve something with a second factor. */
|
|
463
|
+
interface Approval {
|
|
464
|
+
id: string;
|
|
465
|
+
status: ApprovalStatus;
|
|
466
|
+
subjectId: string;
|
|
467
|
+
tenantId?: string | null;
|
|
468
|
+
/** The payload given to `create()`, with keys in canonical order. */
|
|
469
|
+
payload: ApprovalPayload;
|
|
470
|
+
/** SHA-256 (hex) of the canonical payload. */
|
|
471
|
+
payloadHash: string;
|
|
472
|
+
createdAt: string;
|
|
473
|
+
expiresAt: string;
|
|
474
|
+
decidedAt?: string | null;
|
|
475
|
+
consumedAt?: string | null;
|
|
476
|
+
/** Present once approved. */
|
|
477
|
+
assurance?: ApprovalAssurance | null;
|
|
478
|
+
}
|
|
479
|
+
/** Second factor sent with `confirm()`. */
|
|
480
|
+
type ConfirmApprovalInput = {
|
|
481
|
+
method: "authenticator";
|
|
482
|
+
/** Six-digit code from the customer's authenticator app. */
|
|
483
|
+
code: string;
|
|
484
|
+
} | {
|
|
485
|
+
method: "webauthn";
|
|
486
|
+
/** Assertion for the options returned by `webauthnOptions()`. */
|
|
487
|
+
webAuthn: {
|
|
488
|
+
ceremonyToken: string;
|
|
489
|
+
/** JSON-serialized `PublicKeyCredential` from `navigator.credentials.get()`. */
|
|
490
|
+
assertionJson: string;
|
|
549
491
|
};
|
|
492
|
+
};
|
|
493
|
+
/** Passkey assertion options for approving one approval. */
|
|
494
|
+
interface ApprovalWebAuthnOptions {
|
|
495
|
+
ceremonyToken: string;
|
|
496
|
+
/** JSON `PublicKeyCredentialRequestOptions` to pass to `navigator.credentials.get()`. */
|
|
497
|
+
optionsJson: string;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/** Customer-side operations on an approval (`/auth/authorizations`). */
|
|
501
|
+
interface SubjectApprovals {
|
|
502
|
+
/** GET /auth/authorizations/{id} — the pending payload, to show before asking for the code. */
|
|
503
|
+
get(id: string): Promise<Approval>;
|
|
504
|
+
/** POST /auth/authorizations/{id}/webauthn/options — passkey options for approving it. */
|
|
505
|
+
webauthnOptions(id: string): Promise<ApprovalWebAuthnOptions>;
|
|
506
|
+
/**
|
|
507
|
+
* POST /auth/authorizations/{id}/confirm — approves it.
|
|
508
|
+
*
|
|
509
|
+
* Pass the authenticator code or passkey assertion to verify the second
|
|
510
|
+
* factor inline (recommended). Without `input`, the session itself must
|
|
511
|
+
* have used a passkey or authenticator code within the last 5 minutes,
|
|
512
|
+
* otherwise the API answers `step_up_required`.
|
|
513
|
+
*/
|
|
514
|
+
confirm(id: string, input?: ConfirmApprovalInput): Promise<Approval>;
|
|
515
|
+
/** POST /auth/authorizations/{id}/reject — the customer declines it. */
|
|
516
|
+
reject(id: string): Promise<Approval>;
|
|
517
|
+
}
|
|
518
|
+
/** The `security` namespace an end-user client exposes. */
|
|
519
|
+
interface SubjectSecurity {
|
|
520
|
+
/** Approve or reject what your backend asked the customer to confirm. */
|
|
521
|
+
readonly approvals: SubjectApprovals;
|
|
550
522
|
}
|
|
523
|
+
|
|
551
524
|
/** End-user operations require a user token and the environment publishable key. */
|
|
552
525
|
declare class UserScopedClient {
|
|
553
526
|
#private;
|
|
554
527
|
/** @hidden */
|
|
555
528
|
constructor(request: ManagementRequest, token: AccessTokenSource);
|
|
529
|
+
/**
|
|
530
|
+
* The customer's side of `security.approvals`, for backends (BFF) that hold
|
|
531
|
+
* the customer's access token: `get`, `webauthnOptions`, `confirm`, `reject`.
|
|
532
|
+
*/
|
|
533
|
+
readonly security: SubjectSecurity;
|
|
556
534
|
readonly tenants: {
|
|
557
535
|
members: {
|
|
558
536
|
list: (tenantId: string, options?: PaginationOptions) => Promise<TenantMemberPage>;
|
|
@@ -562,14 +540,55 @@ declare class UserScopedClient {
|
|
|
562
540
|
};
|
|
563
541
|
};
|
|
564
542
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
/**
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
543
|
+
|
|
544
|
+
/** `security.approvals.create()` — something awaiting the customer's approval. */
|
|
545
|
+
interface CreateApprovalInput {
|
|
546
|
+
/** Environment user who must approve. */
|
|
547
|
+
subjectId: string;
|
|
548
|
+
/** Any JSON object (up to 16 KiB) describing what is being approved. Default `{}`. */
|
|
549
|
+
payload?: ApprovalPayload;
|
|
550
|
+
/** Restrict approval to a session in this tenant. */
|
|
551
|
+
tenantId?: string;
|
|
552
|
+
/** Lifetime in seconds, clamped to 60–600. Default 300. */
|
|
553
|
+
expiresInSeconds?: number;
|
|
554
|
+
/**
|
|
555
|
+
* Optional. Sent as the `Idempotency-Key` header (max 128 chars): retrying
|
|
556
|
+
* with the same key and payload returns the same approval; the same key
|
|
557
|
+
* with a different payload fails with `idempotency_conflict`.
|
|
558
|
+
*/
|
|
559
|
+
idempotencyKey?: string;
|
|
572
560
|
}
|
|
561
|
+
/** `security.approvals.consume()` — single-use redemption result. */
|
|
562
|
+
interface ConsumedApproval {
|
|
563
|
+
id: string;
|
|
564
|
+
status: "consumed";
|
|
565
|
+
consumedAt: string;
|
|
566
|
+
/** The approved payload — execute exactly this. */
|
|
567
|
+
payload: ApprovalPayload;
|
|
568
|
+
payloadHash: string;
|
|
569
|
+
assurance: ApprovalAssurance | null;
|
|
570
|
+
}
|
|
571
|
+
/** `security.otp.check()` result. */
|
|
572
|
+
type OtpCheckResult = {
|
|
573
|
+
valid: true;
|
|
574
|
+
userId: string;
|
|
575
|
+
/** Always `"otp"` (authenticator app). */
|
|
576
|
+
method: string;
|
|
577
|
+
verifiedAt: string;
|
|
578
|
+
} | {
|
|
579
|
+
valid: false;
|
|
580
|
+
/**
|
|
581
|
+
* Wrong codes left before the first consequence: the sign-out (3 in a
|
|
582
|
+
* row) or the 15-minute lock (5). `0` when the user was just signed out.
|
|
583
|
+
*/
|
|
584
|
+
attemptsRemaining: number;
|
|
585
|
+
/**
|
|
586
|
+
* True when this was the 3rd wrong code in a row (counted across login
|
|
587
|
+
* 2FA, `security.otp.check` and `security.approvals.confirm`): every
|
|
588
|
+
* session of the user was ended and they must sign in again.
|
|
589
|
+
*/
|
|
590
|
+
sessionsRevoked?: boolean;
|
|
591
|
+
};
|
|
573
592
|
|
|
574
593
|
interface ClientRequestContext {
|
|
575
594
|
/** Real end-user IP, resolved only from infrastructure trusted by the application. */
|
|
@@ -682,11 +701,8 @@ declare class AuthyonServerClient {
|
|
|
682
701
|
* "the token's tenant" rather than one you pass by id.
|
|
683
702
|
*/
|
|
684
703
|
tenant(credentials: ClientCredentials): TenantScopedClient;
|
|
685
|
-
/** Uses only the supplied platform-user access token. */
|
|
686
|
-
platform(token: AccessTokenSource): PlatformScopedClient;
|
|
687
704
|
/** Uses an end-user token; the configured environment key selects the environment. */
|
|
688
705
|
user(token: AccessTokenSource): UserScopedClient;
|
|
689
|
-
readonly workspaceInvites: WorkspaceInvitesClient;
|
|
690
706
|
readonly environment: {
|
|
691
707
|
users: {
|
|
692
708
|
/** GET /env/users — paginated list of users in the environment. */
|
|
@@ -823,6 +839,38 @@ declare class AuthyonServerClient {
|
|
|
823
839
|
loginActivity: (params?: PaginationOptions) => Promise<Paged<LoginActivity>>;
|
|
824
840
|
};
|
|
825
841
|
};
|
|
842
|
+
readonly security: {
|
|
843
|
+
otp: {
|
|
844
|
+
/**
|
|
845
|
+
* POST /env/users/{userId}/otp/verify — checks the user's authenticator
|
|
846
|
+
* app (TOTP) code. A wrong code returns `{ valid: false }` instead of
|
|
847
|
+
* throwing. Each code is accepted once; 3 wrong codes in a row sign the
|
|
848
|
+
* user out everywhere (`sessionsRevoked: true`); 5 lock the check for 15
|
|
849
|
+
* minutes (`rate_limited`).
|
|
850
|
+
*/
|
|
851
|
+
check: (userId: string, code: string) => Promise<OtpCheckResult>;
|
|
852
|
+
};
|
|
853
|
+
/**
|
|
854
|
+
* The customer approves a payload with their authenticator code or
|
|
855
|
+
* passkey, once.
|
|
856
|
+
*
|
|
857
|
+
* 1. `create()` the approval with the payload and the customer.
|
|
858
|
+
* 2. The customer confirms it (`@authyon/auth` → `security.approvals.confirm`).
|
|
859
|
+
* 3. `consume()` it right before executing, and execute the returned payload.
|
|
860
|
+
*/
|
|
861
|
+
approvals: {
|
|
862
|
+
/** POST /env/authorizations — registers a payload awaiting the customer's approval. */
|
|
863
|
+
create: (input: CreateApprovalInput) => Promise<Approval>;
|
|
864
|
+
/** GET /env/authorizations/{id} — current status and, once approved, the assurance evidence. */
|
|
865
|
+
get: (id: string) => Promise<Approval>;
|
|
866
|
+
/**
|
|
867
|
+
* POST /env/authorizations/{id}/consume — redeems an approved approval
|
|
868
|
+
* exactly once and returns the approved payload. Pass `payload` to have
|
|
869
|
+
* the API check it matches (`payload_mismatch` otherwise).
|
|
870
|
+
*/
|
|
871
|
+
consume: (id: string, payload?: ApprovalPayload) => Promise<ConsumedApproval>;
|
|
872
|
+
};
|
|
873
|
+
};
|
|
826
874
|
readonly permissions: {
|
|
827
875
|
/** POST /users/{userId}/permissions — grant a permission directly to a user. */
|
|
828
876
|
grant: (userId: string, permission: string) => Promise<void>;
|
|
@@ -897,4 +945,4 @@ declare class TenantScopedClient {
|
|
|
897
945
|
/** Convenience factory: `const authyon = createClient({ clientId, clientSecret })`. */
|
|
898
946
|
declare function createClient(options?: AuthyonServerClientOptions): AuthyonServerClient;
|
|
899
947
|
|
|
900
|
-
export { type
|
|
948
|
+
export { type SubjectApprovals as $, AuthyonServerClient as A, type HttpLogger as B, type ClientCredentials as C, type InviteTenantMemberInput as D, type EnvironmentUser as E, FetchHttpAdapter as F, JwksTokenVerifier as G, type HttpAdapter as H, type IntrospectResult as I, type JsonWebKeySet as J, type JwksTokenVerifierOptions as K, LoggingHttpAdapter as L, type LoginActivity as M, type Organization as N, type OpenIdConfiguration as O, type OtpCheckResult as P, type Paged as Q, type PaginationOptions as R, type Permission as S, type PermissionsByRole as T, type ReservedPermissions as U, type Role as V, type RoleGrant as W, type RoleInput as X, type RoleList as Y, type RolePermissions as Z, type SafeJwtAlgorithm as _, type HttpLoggerOptions as a, type SubjectSecurity as a0, type TenantClientValidationResult as a1, type TenantCredentialIssued as a2, type TenantCredentialSummary as a3, type TenantMember as a4, type TenantMemberPage as a5, type TenantMembership as a6, TenantScopedClient as a7, type TokenResult as a8, TokenVerificationError as a9, type TokenVerificationErrorCode as aa, type UpdateOrganizationInput as ab, type User as ac, UserScopedClient as ad, type ValidateResult as ae, type VerifiedAccessToken as af, createClient as ag, normalizeClientIp as ah, type AccessTokenSource as b, type Approval as c, type ApprovalAssurance as d, type ApprovalPayload as e, type ApprovalStatus as f, type ApprovalWebAuthnOptions as g, type AuditEvent as h, type AuthyonJwksDiscoveryOptions as i, type AuthyonJwtClaims as j, type AuthyonServerClientOptions as k, type ClientRequestContext as l, type ConfirmApprovalInput as m, type ConsumedApproval as n, type CreateApprovalInput as o, type CreateCredentialInput as p, type CreateOrganizationInput as q, type CreatePermissionInput as r, type CreateTenantCredentialInput as s, type CreateUserInput as t, type CredentialCreator as u, type CredentialDetail as v, type CredentialListOptions as w, type CredentialPermissionsInput as x, type HttpAdapterRequest as y, type HttpLogEvent as z };
|