@authyon/server 0.2.0-beta.15 → 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/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonServerClient } from './authyonServerClient-DQzhfaja.js';
2
- export { b as AccessTokenSource, c as Approval, d as ApprovalAssurance, e as ApprovalPayload, f as ApprovalStatus, g as ApprovalWebAuthnOptions, h as AuditEvent, i as AuthyonJwksDiscoveryOptions, j as AuthyonJwtClaims, k as AuthyonServerClientOptions, C as ClientCredentials, l as ClientRequestContext, m as ConfirmApprovalInput, n as ConsumedApproval, o as CreateApprovalInput, p as CreateCredentialInput, q as CreateOrganizationInput, r as CreatePermissionInput, s as CreateTenantCredentialInput, t as CreateUserInput, u as CredentialCreator, v as CredentialDetail, w as CredentialListOptions, x as CredentialPermissionsInput, E as EnvironmentUser, F as FetchHttpAdapter, y as HttpAdapterRequest, z as HttpLogEvent, B as HttpLogger, I as IntrospectResult, D as InviteTenantMemberInput, J as JsonWebKeySet, G as JwksTokenVerifier, K as JwksTokenVerifierOptions, L as LoggingHttpAdapter, M as LoginActivity, O as OpenIdConfiguration, N as Organization, P as OtpCheckResult, Q as Paged, R as PaginationOptions, S as Permission, T as PermissionsByRole, U as ReservedPermissions, V as Role, W as RoleGrant, X as RoleInput, Y as RoleList, Z as RolePermissions, _ as SafeJwtAlgorithm, $ as SubjectApprovals, a0 as SubjectSecurity, a1 as TenantClientValidationResult, a2 as TenantCredentialIssued, a3 as TenantCredentialSummary, a4 as TenantMember, a5 as TenantMemberPage, a6 as TenantMembership, a7 as TenantScopedClient, a8 as TokenResult, a9 as TokenVerificationError, aa as TokenVerificationErrorCode, ab as UpdateOrganizationInput, ac as User, ad as UserScopedClient, ae as ValidateResult, af as VerifiedAccessToken, ag as createClient, ah as normalizeClientIp } from './authyonServerClient-DQzhfaja.js';
3
- export { b as AbilityConditions, c as AbilityEvent, d as AbilityListener, e as AbilityRequirement, f as AbilityRule, A as AbilitySubject, g as AuthorizationContext, a as AuthorizationError, h as AuthorizationOptions, i as AuthyonAbility, j as AuthyonAbilityBuilder, k as AuthyonAbilityOptions, l as AuthyonPermissionSource, E as ExpressAuthorizationMiddlewareOptions, m as ExpressNext, n as ExpressRequestLike, o as ExpressResponseLike, P as PermissionGroup, R as RequestAuthorizationOptions, p as authorizeRequest, q as authorizeToken, r as createAuthorizationErrorResponse, s as createAuthyonAbility, t as createAuthyonRules, u as createExpressAuthorizationMiddleware, v as hasPermission, w as hasPermissionGroup } from './authorization-WlwcTBwG.js';
1
+ import { H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonServerClient } from './authyonServerClient-1_1qNRDa.js';
2
+ export { b as AcceptTenantInviteInput, c as AccessTokenSource, d as Approval, e as ApprovalAssurance, f as ApprovalPayload, g as ApprovalStatus, h as ApprovalWebAuthnOptions, i as AuditEvent, j as AuthyonJwksDiscoveryOptions, k as AuthyonJwtClaims, l as AuthyonServerClientOptions, C as ClientCredentials, m as ClientRequestContext, n as ConfirmApprovalInput, o as ConsumedApproval, p as CreateApprovalInput, q as CreateCredentialInput, r as CreateOrganizationInput, s as CreatePermissionInput, t as CreateTenantCredentialInput, u as CreateUserInput, v as CredentialCreator, w as CredentialDetail, x as CredentialListOptions, y as CredentialPermissionsInput, E as EnvironmentUser, F as FetchHttpAdapter, z as HttpAdapterRequest, B as HttpLogEvent, D as HttpLogger, I as IntrospectResult, G as InviteTenantMemberInput, J as JsonWebKeySet, K as JwksTokenVerifier, L as JwksTokenVerifierOptions, M as LoggingHttpAdapter, N as LoginActivity, O as OpenIdConfiguration, P as Organization, Q as OtpCheckResult, R as Paged, S as PaginationOptions, T as Permission, U as PermissionsByRole, V as ReservedPermissions, W as Role, X as RoleGrant, Y as RoleInput, Z as RoleList, _ as RolePermissions, $ as SafeJwtAlgorithm, a0 as SecurityMethods, a1 as SubjectApprovals, a2 as SubjectSecurity, a3 as TenantClientValidationResult, a4 as TenantCredentialIssued, a5 as TenantCredentialSummary, a6 as TenantInvite, a7 as TenantInviteAccepted, a8 as TenantInviteInput, a9 as TenantInviteIssued, aa as TenantInvitePreview, ab as TenantInviteStatus, ac as TenantMember, ad as TenantMemberPage, ae as TenantMembership, af as TenantScopedClient, ag as TokenResult, ah as TokenVerificationError, ai as TokenVerificationErrorCode, aj as UpdateOrganizationInput, ak as User, al as UserScopedClient, am as ValidateResult, an as VerifiedAccessToken, ao as createClient, ap as normalizeClientIp } from './authyonServerClient-1_1qNRDa.js';
3
+ export { b as AbilityConditions, c as AbilityEvent, d as AbilityListener, e as AbilityRequirement, f as AbilityRule, A as AbilitySubject, g as AuthorizationContext, a as AuthorizationError, h as AuthorizationOptions, i as AuthyonAbility, j as AuthyonAbilityBuilder, k as AuthyonAbilityOptions, l as AuthyonPermissionSource, E as ExpressAuthorizationMiddlewareOptions, m as ExpressNext, n as ExpressRequestLike, o as ExpressResponseLike, P as PermissionGroup, R as RequestAuthorizationOptions, p as authorizeRequest, q as authorizeToken, r as createAuthorizationErrorResponse, s as createAuthyonAbility, t as createAuthyonRules, u as createExpressAuthorizationMiddleware, v as hasPermission, w as hasPermissionGroup } from './authorization-BvjIWPcU.js';
4
4
  import 'jose';
5
5
 
6
6
  declare const ErrorCodes: {
@@ -27,6 +27,7 @@ declare const ErrorCodes: {
27
27
  readonly UserNotFound: "user_not_found";
28
28
  readonly TemporarilyUnavailable: "temporarily_unavailable";
29
29
  readonly InsufficientScope: "insufficient_scope";
30
+ readonly CredentialThrottled: "credential_throttled";
30
31
  readonly ApprovalNotFound: "authorization_not_found";
31
32
  readonly SessionRevoked: "session_revoked";
32
33
  readonly TwoFactorTooManyFailures: "user.2fa.too_many_failures";
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  JsonHttpClient,
8
8
  LoggingHttpAdapter,
9
9
  createSharedTransport
10
- } from "./chunk-WPPEV5BA.js";
10
+ } from "./chunk-TDJNBD3Z.js";
11
11
  import {
12
12
  AuthorizationError,
13
13
  AuthyonAbility,
@@ -152,8 +152,22 @@ function path(id, suffix = "") {
152
152
  throw new TypeError("Authyon: an approval id is required.");
153
153
  return `/auth/authorizations/${encodeURIComponent(id)}${suffix}`;
154
154
  }
155
+ var NO_METHODS = {
156
+ password: false,
157
+ authenticator: false,
158
+ emailCode: false,
159
+ passkey: false,
160
+ passkeyCount: 0,
161
+ recoveryCodes: 0,
162
+ sso: [],
163
+ twoFactor: false
164
+ };
155
165
  function subjectSecurity(request) {
156
166
  return {
167
+ methods: async () => {
168
+ const me = await request("/auth/me");
169
+ return me.security ?? NO_METHODS;
170
+ },
157
171
  approvals: {
158
172
  get: (id) => request(path(id)),
159
173
  webauthnOptions: (id) => request(path(id, "/webauthn/options"), { method: "POST" }),
@@ -191,6 +205,31 @@ var UserScopedClient = class {
191
205
  remove: (tenantId, userId) => __privateGet(this, _request).call(this, `/auth/tenants/${segment(tenantId)}/members/${segment(userId)}`, {
192
206
  method: "DELETE"
193
207
  })
208
+ },
209
+ /**
210
+ * Invites by e-mail or by link, acting as the user. Requires the
211
+ * `tenants:members:invite` permission on the tenant.
212
+ */
213
+ invites: {
214
+ list: (tenantId) => __privateGet(this, _request).call(this, `/auth/tenants/${segment(tenantId)}/invites`),
215
+ /** Always returns `acceptUrl`; `sendEmail: false` skips the e-mail. */
216
+ create: (tenantId, input) => __privateGet(this, _request).call(this, `/auth/tenants/${segment(tenantId)}/invites`, {
217
+ method: "POST",
218
+ body: {
219
+ email: input.email,
220
+ roles: input.roles,
221
+ sendEmail: input.sendEmail ?? true,
222
+ redirectUri: input.redirectUri
223
+ }
224
+ }),
225
+ /** New link (the previous one stops working), mailed unless `sendEmail` is `false`. */
226
+ resend: (tenantId, inviteId, input = {}) => __privateGet(this, _request).call(this, `/auth/tenants/${segment(tenantId)}/invites/${segment(inviteId)}/resend`, {
227
+ method: "POST",
228
+ body: { sendEmail: input.sendEmail ?? true }
229
+ }),
230
+ revoke: (tenantId, inviteId) => __privateGet(this, _request).call(this, `/auth/tenants/${segment(tenantId)}/invites/${segment(inviteId)}`, {
231
+ method: "DELETE"
232
+ })
194
233
  }
195
234
  };
196
235
  __privateSet(this, _request, scopedRequest(request, token));
@@ -484,6 +523,61 @@ var AuthyonServerClient = class {
484
523
  { method: "DELETE", envBearer: true }
485
524
  )
486
525
  },
526
+ /**
527
+ * Invites by e-mail or by link — for addresses that may not have an
528
+ * account yet; accepting creates it. Managing them needs the
529
+ * credential's `authyon:users:write` scope (listing, `authyon:tenants:read`).
530
+ */
531
+ invites: {
532
+ /** GET /env/tenants/{tenantId}/invites — every invite with its status, newest first. */
533
+ list: (tenantId) => this.request(`/env/tenants/${encodeURIComponent(tenantId)}/invites`, { envBearer: true }),
534
+ /**
535
+ * POST /env/tenants/{tenantId}/invites — invite an address. Always
536
+ * returns `acceptUrl`; with `sendEmail: false` Authyon does not mail
537
+ * it and you deliver the link yourself. Valid 7 days, single use, and
538
+ * not readable again later.
539
+ */
540
+ create: (tenantId, input) => this.request(`/env/tenants/${encodeURIComponent(tenantId)}/invites`, {
541
+ method: "POST",
542
+ envBearer: true,
543
+ body: {
544
+ email: input.email,
545
+ roles: input.roles,
546
+ sendEmail: input.sendEmail ?? true,
547
+ redirectUri: input.redirectUri
548
+ }
549
+ }),
550
+ /** POST .../invites/{inviteId}/resend — new link (the previous one stops working), mailed unless `sendEmail` is `false`. */
551
+ resend: (tenantId, inviteId, input = {}) => this.request(
552
+ `/env/tenants/${encodeURIComponent(tenantId)}/invites/${encodeURIComponent(inviteId)}/resend`,
553
+ { method: "POST", envBearer: true, body: { sendEmail: input.sendEmail ?? true } }
554
+ ),
555
+ /** DELETE /env/tenants/{tenantId}/invites/{inviteId} — revoke a pending invite. */
556
+ revoke: (tenantId, inviteId) => this.request(
557
+ `/env/tenants/${encodeURIComponent(tenantId)}/invites/${encodeURIComponent(inviteId)}`,
558
+ { method: "DELETE", envBearer: true }
559
+ ),
560
+ /**
561
+ * POST /auth/tenant-invites/preview — for a backend hosting the accept
562
+ * page. Public: needs only `envKey`, the token is the credential.
563
+ */
564
+ preview: (token) => this.request("/auth/tenant-invites/preview", { method: "POST", body: { token } }),
565
+ /**
566
+ * Joins the tenant; for an address with no account, also creates it
567
+ * (password required) with the e-mail already confirmed. Does not
568
+ * sign the user in.
569
+ *
570
+ * Without metadata: POST /auth/tenant-invites/accept — public, needs
571
+ * only `envKey`. With `publicMetadata`/`privateMetadata`: POST
572
+ * /env/tenant-invites/accept with the environment credential
573
+ * (`authyon:users:write`), since only your backend may set them.
574
+ */
575
+ accept: (input) => input.publicMetadata !== void 0 || input.privateMetadata !== void 0 ? this.request("/env/tenant-invites/accept", {
576
+ method: "POST",
577
+ envBearer: true,
578
+ body: input
579
+ }) : this.request("/auth/tenant-invites/accept", { method: "POST", body: input })
580
+ },
487
581
  roles: {
488
582
  /** GET /env/tenants/{tenantId}/roles — list a tenant's roles. */
489
583
  list: (tenantId) => this.request(`/env/tenants/${encodeURIComponent(tenantId)}/roles`, { envBearer: true }),
@@ -555,8 +649,9 @@ var AuthyonServerClient = class {
555
649
  };
556
650
  // ── Security: one-time codes and approvals ───────────────────────────────
557
651
  //
558
- // Everything here runs with the environment credential, which needs the
559
- // `authyon:financial:authorize` scope. Keep that credential on the server.
652
+ // Everything here runs with the environment credential: `otp` needs the
653
+ // `authyon:otp:verify` scope, `approvals` needs `authyon:financial:authorize`.
654
+ // Keep those credentials on the server.
560
655
  this.security = {
561
656
  otp: {
562
657
  /**
@@ -564,7 +659,8 @@ var AuthyonServerClient = class {
564
659
  * app (TOTP) code. A wrong code returns `{ valid: false }` instead of
565
660
  * throwing. Each code is accepted once; 3 wrong codes in a row sign the
566
661
  * user out everywhere (`sessionsRevoked: true`); 5 lock the check for 15
567
- * minutes (`rate_limited`).
662
+ * minutes (`rate_limited`). More than 50 wrong codes in 10 minutes from the
663
+ * same credential pause it (`credential_throttled`). Needs `authyon:otp:verify`.
568
664
  */
569
665
  check: (userId, code) => this.request(`/env/users/${segment(userId)}/otp/verify`, {
570
666
  method: "POST",
@@ -728,6 +824,28 @@ var AuthyonServerClient = class {
728
824
  _clientSecret = new WeakMap();
729
825
  var TenantScopedClient = class {
730
826
  constructor(server, credentials) {
827
+ /** Invites to the token's tenant, by e-mail or by link. */
828
+ this.invites = {
829
+ /** GET /tenant/invites — every invite with its status, newest first. */
830
+ list: () => this.request("/tenant/invites"),
831
+ /** POST /tenant/invites — always returns `acceptUrl`; `sendEmail: false` skips the e-mail. */
832
+ create: (input) => this.request("/tenant/invites", {
833
+ method: "POST",
834
+ body: {
835
+ email: input.email,
836
+ roles: input.roles,
837
+ sendEmail: input.sendEmail ?? true,
838
+ redirectUri: input.redirectUri
839
+ }
840
+ }),
841
+ /** POST /tenant/invites/{inviteId}/resend — new link (the previous one stops working), mailed unless `sendEmail` is `false`. */
842
+ resend: (inviteId, input = {}) => this.request(`/tenant/invites/${encodeURIComponent(inviteId)}/resend`, {
843
+ method: "POST",
844
+ body: { sendEmail: input.sendEmail ?? true }
845
+ }),
846
+ /** DELETE /tenant/invites/{inviteId} — revoke a pending invite. */
847
+ revoke: (inviteId) => this.request(`/tenant/invites/${encodeURIComponent(inviteId)}`, { method: "DELETE" })
848
+ };
731
849
  this.members = {
732
850
  /**
733
851
  * GET /tenant/members — members of the token's tenant.
package/dist/next.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
- import { R as RequestAuthorizationOptions, A as AbilitySubject, a as AuthorizationError } from './authorization-B82XXf3B.cjs';
3
- import { A as AuthyonServerClient } from './authyonServerClient-DQzhfaja.cjs';
2
+ import { R as RequestAuthorizationOptions, A as AbilitySubject, a as AuthorizationError } from './authorization-C0Mg5gUv.cjs';
3
+ import { A as AuthyonServerClient } from './authyonServerClient-1_1qNRDa.cjs';
4
4
  import 'jose';
5
5
 
6
6
  interface ServerPermissionGuardFallbackContext {
package/dist/next.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
- import { R as RequestAuthorizationOptions, A as AbilitySubject, a as AuthorizationError } from './authorization-WlwcTBwG.js';
3
- import { A as AuthyonServerClient } from './authyonServerClient-DQzhfaja.js';
2
+ import { R as RequestAuthorizationOptions, A as AbilitySubject, a as AuthorizationError } from './authorization-BvjIWPcU.js';
3
+ import { A as AuthyonServerClient } from './authyonServerClient-1_1qNRDa.js';
4
4
  import 'jose';
5
5
 
6
6
  interface ServerPermissionGuardFallbackContext {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@authyon/server",
3
- "version": "0.2.0-beta.15",
3
+ "version": "0.2.0-beta.16",
4
4
  "description": "Authyon SDK for backends — server-to-server organization/member management and access-token verification.",
5
5
  "license": "MIT",
6
6
  "type": "module",