@finueva/auth 0.18.0 → 0.19.0

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.js CHANGED
@@ -2291,7 +2291,7 @@ const passkeyClient = () => {
2291
2291
  };
2292
2292
  };
2293
2293
  //#endregion
2294
- //#region ../../node_modules/.pnpm/@chiballc+utils@2.5.1_@hono+zod-openapi@1.5.1_hono@4.13.0_zod@4.4.3__hono@4.13.0_magic-_dfcdb59639d9fe73412dad0223379a88/node_modules/@chiballc/utils/dist/index.mjs
2294
+ //#region ../../node_modules/.pnpm/@chiballc+utils@2.5.1_@hono+zod-openapi@1.5.1_hono@4.13.0_zod@4.4.3__hono@4.13.0_magic-_80fa16dd1813631ddeb36d2ee29b8660/node_modules/@chiballc/utils/dist/index.mjs
2295
2295
  function isPromise(arg) {
2296
2296
  return arg && typeof arg.then === "function";
2297
2297
  }
@@ -2557,7 +2557,18 @@ const messages = {
2557
2557
  platform_target_unavailable: "The platform administration target is unavailable.",
2558
2558
  platform_quorum_unavailable: "Platform administration quorum is unavailable.",
2559
2559
  platform_recovery_required: "Platform administration requires separate recovery.",
2560
- identity_authority_unavailable: "Authentication is temporarily unavailable."
2560
+ identity_authority_unavailable: "Authentication is temporarily unavailable.",
2561
+ two_factor_required: "A second authentication factor is required.",
2562
+ two_factor_code_invalid: "The verification code is invalid.",
2563
+ two_factor_challenge_expired: "The second-factor challenge has ended. Sign in again.",
2564
+ two_factor_locked: "Second-factor verification is temporarily locked.",
2565
+ recent_sign_in_required: "A recent sign-in is required.",
2566
+ enterprise_recovery_required: "Enterprise administration evidence requires operator recovery.",
2567
+ recent_authentication_required: "A ready recent-authentication action is required.",
2568
+ organization_closure_confirmation_mismatch: "The confirmation does not match the organization.",
2569
+ organization_closure_cancellation_ended: "The closure cancellation period has ended.",
2570
+ ceremony_return_refused: "The return address is not registered for this application.",
2571
+ password_sign_in_required: "A password sign-in method is required for this passkey change."
2561
2572
  };
2562
2573
  var AuthError = class extends Error {
2563
2574
  code;
@@ -2965,7 +2976,7 @@ function normalizeIdInput(value) {
2965
2976
  return value;
2966
2977
  }
2967
2978
  function normalizeOrganization(value) {
2968
- exact(value, [
2979
+ exact$3(value, [
2969
2980
  "capabilities",
2970
2981
  "id",
2971
2982
  "lifecycle",
@@ -2975,7 +2986,7 @@ function normalizeOrganization(value) {
2975
2986
  "slug"
2976
2987
  ]);
2977
2988
  if (!isId(value.id) || !boundedString(value.name, 255) || !boundedString(value.slug, 255) || value.lifecycle !== "ordinary" && value.lifecycle !== "managed" || !role(value.role) || !isObject(value.capabilities)) throw authorityUnavailable();
2978
- exact(value.capabilities, [
2989
+ exact$3(value.capabilities, [
2979
2990
  "readInvitations",
2980
2991
  "readMembers",
2981
2992
  "readTeams"
@@ -3037,7 +3048,7 @@ function normalizeOrganizationCreationInput(name, slug, idempotencyKey) {
3037
3048
  };
3038
3049
  }
3039
3050
  function normalizeCreatedOrganization(value) {
3040
- exact(value, [
3051
+ exact$3(value, [
3041
3052
  "id",
3042
3053
  "name",
3043
3054
  "slug"
@@ -3057,7 +3068,7 @@ function normalizeOrganizationTeamCreationInput(name, idempotencyKey) {
3057
3068
  };
3058
3069
  }
3059
3070
  function normalizeCreatedOrganizationTeam(value) {
3060
- exact(value, ["id", "name"]);
3071
+ exact$3(value, ["id", "name"]);
3061
3072
  if (!isId(value.id) || !boundedString(value.name, 255)) throw authorityUnavailable();
3062
3073
  return {
3063
3074
  id: value.id,
@@ -3084,7 +3095,7 @@ function normalizeOrganizationMemberInvitationCreationInput(value) {
3084
3095
  };
3085
3096
  }
3086
3097
  function normalizeCreatedOrganizationMemberInvitation(value) {
3087
- exact(value, ["expiresAt", "id"]);
3098
+ exact$3(value, ["expiresAt", "id"]);
3088
3099
  if (!isId(value.id)) throw authorityUnavailable();
3089
3100
  return {
3090
3101
  id: value.id,
@@ -3101,7 +3112,7 @@ function normalizeOrganizationInvitationAdministrationInput(idempotencyKey) {
3101
3112
  return { idempotencyKey };
3102
3113
  }
3103
3114
  function normalizeCanceledOrganizationInvitation(value) {
3104
- exact(value, ["status"]);
3115
+ exact$3(value, ["status"]);
3105
3116
  if (value.status !== "canceled") throw authorityUnavailable();
3106
3117
  return { status: "canceled" };
3107
3118
  }
@@ -3110,17 +3121,106 @@ function normalizeOrganizationMembershipRemovalInput(idempotencyKey) {
3110
3121
  return { idempotencyKey };
3111
3122
  }
3112
3123
  function normalizeRemovedOrganizationMember(value) {
3113
- exact(value, ["status"]);
3124
+ exact$3(value, ["status"]);
3114
3125
  if (value.status !== "removed") throw authorityUnavailable();
3115
3126
  return { status: "removed" };
3116
3127
  }
3128
+ function normalizeSuspendedOrganizationMemberStatus(value) {
3129
+ exact$3(value, ["status"]);
3130
+ if (value.status !== "suspended") throw authorityUnavailable();
3131
+ return { status: "suspended" };
3132
+ }
3133
+ function normalizeRestoredOrganizationMember(value) {
3134
+ exact$3(value, ["memberId", "status"]);
3135
+ if (value.status !== "restored" || !isId(value.memberId)) throw authorityUnavailable();
3136
+ return {
3137
+ status: "restored",
3138
+ memberId: value.memberId
3139
+ };
3140
+ }
3141
+ const suspensionIdPattern = /^organization_membership_suspension_v1_[A-Za-z0-9_-]{43}$/;
3142
+ function normalizeSuspendedOrganizationMembers(value) {
3143
+ exact$3(value, ["members", "nextCursor"]);
3144
+ if (!Array.isArray(value.members) || value.members.length > 100) throw authorityUnavailable();
3145
+ return {
3146
+ members: unique(value.members.map((member) => {
3147
+ exact$3(member, [
3148
+ "email",
3149
+ "id",
3150
+ "image",
3151
+ "name",
3152
+ "role",
3153
+ "suspendedAt",
3154
+ "teamIds",
3155
+ "userId"
3156
+ ]);
3157
+ if (typeof member.id !== "string" || !suspensionIdPattern.test(member.id) || !isId(member.userId) || !boundedString(member.name, 255) || typeof member.email !== "string" || member.email.length > 320 || !email.test(member.email) || member.role !== "admin" && member.role !== "member" || !Array.isArray(member.teamIds) || member.teamIds.length > 100) throw authorityUnavailable();
3158
+ return {
3159
+ id: member.id,
3160
+ userId: member.userId,
3161
+ name: member.name,
3162
+ email: member.email,
3163
+ image: nullableHttpsUrl(member.image),
3164
+ role: member.role,
3165
+ teamIds: unique(member.teamIds.map((teamId) => normalizeResponseId(teamId)), (item) => item),
3166
+ suspendedAt: responseDate(member.suspendedAt)
3167
+ };
3168
+ }), (item) => item.id),
3169
+ nextCursor: nullableCursor(value.nextCursor)
3170
+ };
3171
+ }
3172
+ function normalizeDepartedOrganizationMembers(value) {
3173
+ exact$3(value, ["members", "nextCursor"]);
3174
+ if (!Array.isArray(value.members) || value.members.length > 100) throw authorityUnavailable();
3175
+ return {
3176
+ members: unique(value.members.map((member) => {
3177
+ exact$3(member, [
3178
+ "departedAt",
3179
+ "departure",
3180
+ "email",
3181
+ "image",
3182
+ "name",
3183
+ "userId"
3184
+ ]);
3185
+ if (!isId(member.userId) || !boundedString(member.name, 255) || typeof member.email !== "string" || member.email.length > 320 || !email.test(member.email) || member.departure !== "removed" && member.departure !== "left") throw authorityUnavailable();
3186
+ return {
3187
+ userId: member.userId,
3188
+ name: member.name,
3189
+ email: member.email,
3190
+ image: nullableHttpsUrl(member.image),
3191
+ departure: member.departure,
3192
+ departedAt: responseDate(member.departedAt)
3193
+ };
3194
+ }), (item) => item.userId),
3195
+ nextCursor: nullableCursor(value.nextCursor)
3196
+ };
3197
+ }
3117
3198
  function normalizeOrganizationDeparture(value) {
3118
- exact(value, ["status"]);
3199
+ exact$3(value, ["status"]);
3119
3200
  if (value.status !== "left") throw authorityUnavailable();
3120
3201
  return { status: "left" };
3121
3202
  }
3203
+ function normalizeOrganizationTeamMembershipInput(idempotencyKey) {
3204
+ if (!boundedString(idempotencyKey, 255)) throw new AuthError("invalid_request", 400);
3205
+ return { idempotencyKey };
3206
+ }
3207
+ function normalizeAddedOrganizationTeamMember(value) {
3208
+ exact$3(value, ["status"]);
3209
+ if (value.status !== "added") throw authorityUnavailable();
3210
+ return { status: "added" };
3211
+ }
3212
+ function normalizeRemovedOrganizationTeamMember(value) {
3213
+ exact$3(value, ["status"]);
3214
+ if (value.status !== "removed") throw authorityUnavailable();
3215
+ return { status: "removed" };
3216
+ }
3217
+ function normalizeDeletedOrganizationTeam(value) {
3218
+ exact$3(value, ["status"]);
3219
+ if (value.status !== "deleted") throw authorityUnavailable();
3220
+ return { status: "deleted" };
3221
+ }
3122
3222
  function normalizeOrganizations(value) {
3123
- exact(value, ["nextCursor", "organizations"]);
3223
+ exact$3(value, ["nextCursor", "organizations"]);
3124
3224
  if (!Array.isArray(value.organizations) || value.organizations.length > 100) throw authorityUnavailable();
3125
3225
  return {
3126
3226
  organizations: unique(value.organizations.map(normalizeOrganization), (item) => item.id),
@@ -3128,11 +3228,11 @@ function normalizeOrganizations(value) {
3128
3228
  };
3129
3229
  }
3130
3230
  function normalizeOrganizationMembers(value) {
3131
- exact(value, ["members", "nextCursor"]);
3231
+ exact$3(value, ["members", "nextCursor"]);
3132
3232
  if (!Array.isArray(value.members) || value.members.length > 100) throw authorityUnavailable();
3133
3233
  return {
3134
3234
  members: unique(value.members.map((member) => {
3135
- exact(member, [
3235
+ exact$3(member, [
3136
3236
  "email",
3137
3237
  "id",
3138
3238
  "image",
@@ -3161,11 +3261,11 @@ function normalizeOrganizationMembers(value) {
3161
3261
  };
3162
3262
  }
3163
3263
  function normalizeOrganizationTeams(value) {
3164
- exact(value, ["nextCursor", "teams"]);
3264
+ exact$3(value, ["nextCursor", "teams"]);
3165
3265
  if (!Array.isArray(value.teams) || value.teams.length > 100) throw authorityUnavailable();
3166
3266
  return {
3167
3267
  teams: unique(value.teams.map((team) => {
3168
- exact(team, [
3268
+ exact$3(team, [
3169
3269
  "category",
3170
3270
  "createdAt",
3171
3271
  "id",
@@ -3183,7 +3283,7 @@ function normalizeOrganizationTeams(value) {
3183
3283
  };
3184
3284
  }
3185
3285
  function normalizeOrganizationTeamMembers(value) {
3186
- exact(value, ["memberIds", "nextCursor"]);
3286
+ exact$3(value, ["memberIds", "nextCursor"]);
3187
3287
  if (!Array.isArray(value.memberIds) || value.memberIds.length > 100) throw authorityUnavailable();
3188
3288
  return {
3189
3289
  memberIds: unique(value.memberIds.map((item) => normalizeResponseId(item)), (item) => item),
@@ -3191,7 +3291,7 @@ function normalizeOrganizationTeamMembers(value) {
3191
3291
  };
3192
3292
  }
3193
3293
  function normalizeOrganizationInvitation(value) {
3194
- exact(value, [
3294
+ exact$3(value, [
3195
3295
  "createdAt",
3196
3296
  "email",
3197
3297
  "expiresAt",
@@ -3202,7 +3302,7 @@ function normalizeOrganizationInvitation(value) {
3202
3302
  "teamIds"
3203
3303
  ]);
3204
3304
  if (!isId(value.id) || typeof value.email !== "string" || value.email.length > 320 || !email.test(value.email) || !role(value.role) || value.status !== "pending" || !Array.isArray(value.teamIds) || value.teamIds.length > 100 || !isObject(value.inviter)) throw authorityUnavailable();
3205
- exact(value.inviter, ["membershipId", "name"]);
3305
+ exact$3(value.inviter, ["membershipId", "name"]);
3206
3306
  if (!isId(value.inviter.membershipId) || !boundedString(value.inviter.name, 255)) throw authorityUnavailable();
3207
3307
  return {
3208
3308
  id: value.id,
@@ -3219,7 +3319,7 @@ function normalizeOrganizationInvitation(value) {
3219
3319
  };
3220
3320
  }
3221
3321
  function normalizeOrganizationInvitations(value) {
3222
- exact(value, ["invitations", "nextCursor"]);
3322
+ exact$3(value, ["invitations", "nextCursor"]);
3223
3323
  if (!Array.isArray(value.invitations) || value.invitations.length > 100) throw authorityUnavailable();
3224
3324
  return {
3225
3325
  invitations: unique(value.invitations.map(normalizeOrganizationInvitation), (item) => item.id),
@@ -3227,7 +3327,7 @@ function normalizeOrganizationInvitations(value) {
3227
3327
  };
3228
3328
  }
3229
3329
  function normalizeReceivedInvitation(value) {
3230
- exact(value, [
3330
+ exact$3(value, [
3231
3331
  "expiresAt",
3232
3332
  "id",
3233
3333
  "inviterName",
@@ -3236,7 +3336,7 @@ function normalizeReceivedInvitation(value) {
3236
3336
  "teams"
3237
3337
  ]);
3238
3338
  if (!isId(value.id) || !boundedString(value.inviterName, 255) || !role(value.role) || !Array.isArray(value.teams) || value.teams.length > 100 || !isObject(value.organization)) throw authorityUnavailable();
3239
- exact(value.organization, [
3339
+ exact$3(value.organization, [
3240
3340
  "id",
3241
3341
  "logo",
3242
3342
  "name",
@@ -3253,7 +3353,7 @@ function normalizeReceivedInvitation(value) {
3253
3353
  },
3254
3354
  role: value.role,
3255
3355
  teams: unique(value.teams.map((team) => {
3256
- exact(team, ["id", "name"]);
3356
+ exact$3(team, ["id", "name"]);
3257
3357
  if (!isId(team.id) || !boundedString(team.name, 255)) throw authorityUnavailable();
3258
3358
  return {
3259
3359
  id: team.id,
@@ -3265,7 +3365,7 @@ function normalizeReceivedInvitation(value) {
3265
3365
  };
3266
3366
  }
3267
3367
  function normalizeReceivedInvitations(value) {
3268
- exact(value, ["invitations", "nextCursor"]);
3368
+ exact$3(value, ["invitations", "nextCursor"]);
3269
3369
  if (!Array.isArray(value.invitations) || value.invitations.length > 100) throw authorityUnavailable();
3270
3370
  return {
3271
3371
  invitations: unique(value.invitations.map(normalizeReceivedInvitation), (item) => item.id),
@@ -3294,6 +3394,10 @@ function normalizeInvitationAcceptance(value, invitationId) {
3294
3394
  if (!isObject(value) || !isObject(value.invitation) || !isObject(value.member) || value.invitation.id !== invitationId || value.invitation.status !== "accepted" || !isId(value.invitation.organizationId) || value.member.organizationId !== value.invitation.organizationId) throw authorityUnavailable();
3295
3395
  return { organizationId: value.invitation.organizationId };
3296
3396
  }
3397
+ function normalizeInvitationDecline(value, invitationId) {
3398
+ if (!isObject(value) || !isObject(value.invitation) || value.invitation.id !== invitationId || value.invitation.status !== "rejected" || value.member !== null) throw authorityUnavailable();
3399
+ return { status: "declined" };
3400
+ }
3297
3401
  function normalizeWorkspaceSelection(value) {
3298
3402
  if (!isObject(value)) throw new AuthError("invalid_workspace_selection", 422);
3299
3403
  const keys = Object.keys(value);
@@ -3358,6 +3462,73 @@ function fromOrganizationMembershipRemovalError(value, status, retryAfter) {
3358
3462
  if (status === 422 && isObject(value) && value.code === "RECOVERY_REQUIRED") return new AuthError("membership_removal_recovery_required", 422);
3359
3463
  return fromOrganizationMutationAuthorityError(value, status, retryAfter);
3360
3464
  }
3465
+ function fromOrganizationClosureError(value, status, retryAfter) {
3466
+ const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
3467
+ if (status === 409 && code === "CONFIRMATION_MISMATCH") return new AuthError("organization_closure_confirmation_mismatch", 409);
3468
+ if (status === 409 && code === "RECENT_AUTHENTICATION_REQUIRED") return new AuthError("recent_authentication_required", 409);
3469
+ if (status === 409 && code === "CANCELLATION_WINDOW_ENDED") return new AuthError("organization_closure_cancellation_ended", 409);
3470
+ return fromOrganizationMutationAuthorityError(value, status, retryAfter);
3471
+ }
3472
+ function normalizeOrganizationClosureStartInput(value) {
3473
+ if (!isObject(value) || Object.keys(value).sort().join(",") !== "confirmationName,idempotencyKey") throw new TypeError("organization closure input is invalid");
3474
+ if (!boundedString(value.confirmationName, 255)) throw new TypeError("confirmationName is invalid");
3475
+ return {
3476
+ confirmationName: value.confirmationName,
3477
+ idempotencyKey: normalizeAuthorityIdempotencyKey(value.idempotencyKey)
3478
+ };
3479
+ }
3480
+ function normalizeOrganizationClosureCancelInput(value) {
3481
+ if (!isObject(value) || Object.keys(value).join(",") !== "idempotencyKey") throw new TypeError("organization closure cancellation input is invalid");
3482
+ return { idempotencyKey: normalizeAuthorityIdempotencyKey(value.idempotencyKey) };
3483
+ }
3484
+ function closureWindow(value) {
3485
+ const startedAt = responseDate(value.startedAt);
3486
+ const cancelUntil = responseDate(value.cancelUntil);
3487
+ if (cancelUntil.getTime() - startedAt.getTime() !== 720 * 60 * 60 * 1e3 || typeof value.canCancel !== "boolean") throw authorityUnavailable();
3488
+ return {
3489
+ startedAt: startedAt.toISOString(),
3490
+ cancelUntil: cancelUntil.toISOString(),
3491
+ canCancel: value.canCancel
3492
+ };
3493
+ }
3494
+ function normalizeOrganizationClosure(value) {
3495
+ exact$3(value, [
3496
+ "cancelUntil",
3497
+ "canCancel",
3498
+ "organizationId",
3499
+ "startedAt",
3500
+ "state"
3501
+ ]);
3502
+ if (!isId(value.organizationId) || value.state !== "closing" && value.state !== "cancelled") throw authorityUnavailable();
3503
+ const window = closureWindow(value);
3504
+ if (value.state === "cancelled" && window.canCancel) throw authorityUnavailable();
3505
+ return {
3506
+ organizationId: value.organizationId,
3507
+ state: value.state,
3508
+ ...window
3509
+ };
3510
+ }
3511
+ function normalizeClosingOrganizations(value) {
3512
+ exact$3(value, ["organizations"]);
3513
+ if (!Array.isArray(value.organizations) || value.organizations.length > 20) throw authorityUnavailable();
3514
+ return { organizations: unique(value.organizations.map((item) => {
3515
+ exact$3(item, [
3516
+ "cancelUntil",
3517
+ "canCancel",
3518
+ "id",
3519
+ "name",
3520
+ "slug",
3521
+ "startedAt"
3522
+ ]);
3523
+ if (!isId(item.id) || !boundedString(item.name, 255) || item.slug !== null && !boundedString(item.slug, 255)) throw authorityUnavailable();
3524
+ return {
3525
+ id: item.id,
3526
+ name: item.name,
3527
+ slug: item.slug,
3528
+ ...closureWindow(item)
3529
+ };
3530
+ }), (item) => item.id) };
3531
+ }
3361
3532
  function normalizePlatformRoleChangeRecentAuthenticationInput(value) {
3362
3533
  if (!isObject(value) || Object.keys(value).sort().join(",") !== "changeReference,expectedGlobalRevision,expectedTargetRevision,idempotencyKey,reasonCategory,requestedRoles,targetUserId") throw new TypeError("recent authentication input is invalid");
3363
3534
  if (!isId(value.targetUserId)) throw new TypeError("targetUserId is invalid");
@@ -3410,7 +3581,7 @@ function normalizeOrganizationOwnershipTransferInput(value) {
3410
3581
  };
3411
3582
  }
3412
3583
  function normalizeOrganizationManualRoleChangeResult(value) {
3413
- exact(value, [
3584
+ exact$3(value, [
3414
3585
  "status",
3415
3586
  "memberId",
3416
3587
  "manualRole",
@@ -3424,7 +3595,7 @@ function normalizeOrganizationManualRoleChangeResult(value) {
3424
3595
  };
3425
3596
  }
3426
3597
  function normalizeOrganizationMemberAuthority(value, organizationId, memberId) {
3427
- exact(value, [
3598
+ exact$3(value, [
3428
3599
  "organizationId",
3429
3600
  "actor",
3430
3601
  "target"
@@ -3442,7 +3613,7 @@ function normalizeOrganizationMemberAuthority(value, organizationId, memberId) {
3442
3613
  };
3443
3614
  }
3444
3615
  function normalizeOrganizationOwnershipTransferResult(value) {
3445
- exact(value, [
3616
+ exact$3(value, [
3446
3617
  "status",
3447
3618
  "outgoingOwner",
3448
3619
  "successor"
@@ -3455,7 +3626,7 @@ function normalizeOrganizationOwnershipTransferResult(value) {
3455
3626
  };
3456
3627
  }
3457
3628
  function normalizeOrganizationAuthorityMemberOutcome(value, includesStatus = false) {
3458
- exact(value, [
3629
+ exact$3(value, [
3459
3630
  "memberId",
3460
3631
  "manualRole",
3461
3632
  "role",
@@ -3488,7 +3659,7 @@ function normalizePlatformBootstrapRoleChangeInput(value) {
3488
3659
  return request;
3489
3660
  }
3490
3661
  function normalizePlatformRoleApproval(value) {
3491
- exact(value, [
3662
+ exact$3(value, [
3492
3663
  "status",
3493
3664
  "targetUserId",
3494
3665
  "targetRevision",
@@ -3515,7 +3686,7 @@ function normalizePlatformRoleApproval(value) {
3515
3686
  };
3516
3687
  }
3517
3688
  function normalizePlatformStatus(value) {
3518
- exact(value, [
3689
+ exact$3(value, [
3519
3690
  "eligible",
3520
3691
  "globalRevision",
3521
3692
  "roles"
@@ -3530,7 +3701,7 @@ function normalizePlatformStatus(value) {
3530
3701
  };
3531
3702
  }
3532
3703
  function normalizeRecentAuthenticationStatus(value) {
3533
- exact(value, ["status"]);
3704
+ exact$3(value, ["status"]);
3534
3705
  if (value.status !== "pending" && value.status !== "ready") throw authorityUnavailable();
3535
3706
  return { status: value.status };
3536
3707
  }
@@ -3643,7 +3814,7 @@ function normalizeProfileImage(value) {
3643
3814
  function isId(value) {
3644
3815
  return typeof value === "string" && id.test(value);
3645
3816
  }
3646
- function exact(value, keys) {
3817
+ function exact$3(value, keys) {
3647
3818
  if (!isObject(value) || Object.keys(value).sort().join(",") !== [...keys].sort().join(",")) throw authorityUnavailable();
3648
3819
  }
3649
3820
  function boundedString(value, maximum) {
@@ -3683,6 +3854,18 @@ function unique(items, key) {
3683
3854
  if (new Set(items.map(key)).size !== items.length) throw authorityUnavailable();
3684
3855
  return items;
3685
3856
  }
3857
+ function credentialSessionId(token) {
3858
+ const parts = token.split(".");
3859
+ if (parts.length !== 3 || !/^[A-Za-z0-9_-]+$/.test(parts[1])) return void 0;
3860
+ try {
3861
+ const base64 = parts[1].replaceAll("-", "+").replaceAll("_", "/");
3862
+ const decoded = atob(base64.padEnd(base64.length + (4 - base64.length % 4) % 4, "="));
3863
+ const payload = JSON.parse(decoded);
3864
+ return isObject(payload) && typeof payload.sid === "string" && payload.sid.length > 0 ? payload.sid : void 0;
3865
+ } catch {
3866
+ return;
3867
+ }
3868
+ }
3686
3869
  function isObject(value) {
3687
3870
  return typeof value === "object" && value !== null && !Array.isArray(value);
3688
3871
  }
@@ -4496,6 +4679,406 @@ function byteLength(value) {
4496
4679
  return new TextEncoder().encode(value).byteLength;
4497
4680
  }
4498
4681
  //#endregion
4682
+ //#region src/sessions.ts
4683
+ const idPattern$2 = /^[A-Za-z0-9_-]{1,128}$(?![\s\S])/;
4684
+ const MAX_SESSIONS = 50;
4685
+ const itemKeys$1 = [
4686
+ "createdAt",
4687
+ "current",
4688
+ "expiresAt",
4689
+ "id",
4690
+ "ipAddress",
4691
+ "updatedAt",
4692
+ "userAgent"
4693
+ ];
4694
+ function exact$2(value, keys) {
4695
+ return isObject(value) && Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
4696
+ }
4697
+ function date$2(value) {
4698
+ if (typeof value !== "string") throw authorityUnavailable();
4699
+ const parsed = new Date(value);
4700
+ if (!Number.isFinite(parsed.getTime()) || parsed.toISOString() !== value) throw authorityUnavailable();
4701
+ return parsed;
4702
+ }
4703
+ function text(value, maximum) {
4704
+ if (value === null) return null;
4705
+ if (typeof value !== "string" || value.length === 0 || value.length > maximum || /[^\x20-\x7e]/.test(value)) throw authorityUnavailable();
4706
+ return value;
4707
+ }
4708
+ function normalizeSessionId(value) {
4709
+ if (typeof value !== "string" || !idPattern$2.test(value)) throw new TypeError("sessionId is invalid");
4710
+ return value;
4711
+ }
4712
+ function normalizeSessionSummary(value) {
4713
+ if (!exact$2(value, itemKeys$1) || typeof value.id !== "string" || !idPattern$2.test(value.id)) throw authorityUnavailable();
4714
+ if (typeof value.current !== "boolean") throw authorityUnavailable();
4715
+ return {
4716
+ id: value.id,
4717
+ current: value.current,
4718
+ createdAt: date$2(value.createdAt),
4719
+ updatedAt: date$2(value.updatedAt),
4720
+ expiresAt: date$2(value.expiresAt),
4721
+ userAgent: text(value.userAgent, 512),
4722
+ ipAddress: text(value.ipAddress, 64)
4723
+ };
4724
+ }
4725
+ function normalizeSessionInventory(value) {
4726
+ if (!exact$2(value, ["sessions", "truncated"]) || !Array.isArray(value.sessions) || value.sessions.length > MAX_SESSIONS || typeof value.truncated !== "boolean") throw authorityUnavailable();
4727
+ const sessions = value.sessions.map(normalizeSessionSummary);
4728
+ if (new Set(sessions.map((session) => session.id)).size !== sessions.length) throw authorityUnavailable();
4729
+ if (sessions.filter((session) => session.current).length !== 1) throw authorityUnavailable();
4730
+ return {
4731
+ sessions,
4732
+ truncated: value.truncated
4733
+ };
4734
+ }
4735
+ function normalizeSessionRevocation(value) {
4736
+ if (!exact$2(value, ["status"]) || value.status !== "revoked") throw authorityUnavailable();
4737
+ }
4738
+ function normalizeOtherSessionRevocation(value) {
4739
+ if (!exact$2(value, ["revoked"]) || !Number.isSafeInteger(value.revoked) || value.revoked < 0) throw authorityUnavailable();
4740
+ return { revoked: value.revoked };
4741
+ }
4742
+ function fromSessionInventoryError(_value, status, retryAfter) {
4743
+ if (status === 400) return new AuthError("invalid_request", 400);
4744
+ if (status === 401) return new AuthError("authentication_required", 401);
4745
+ if (status === 403) return new AuthError("request_origin_denied", 403);
4746
+ if (status === 404 || status === 409) return new AuthError("state_conflict", 409);
4747
+ if (status === 429) return new AuthError("auth_request_rate_limited", 429, parseRetryAfter(retryAfter));
4748
+ return authorityUnavailable();
4749
+ }
4750
+ //#endregion
4751
+ //#region src/passkeys.ts
4752
+ const idPattern$1 = /^[A-Za-z0-9_-]{1,128}$(?![\s\S])/;
4753
+ const MAX_PASSKEYS = 50;
4754
+ const MAX_RETURN_BYTES = 2048;
4755
+ const PASSKEY_NAME_MAX_LENGTH = 64;
4756
+ const itemKeys = [
4757
+ "backedUp",
4758
+ "createdAt",
4759
+ "deviceType",
4760
+ "id",
4761
+ "name"
4762
+ ];
4763
+ function exact$1(value, keys) {
4764
+ return isObject(value) && Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
4765
+ }
4766
+ function date$1(value) {
4767
+ if (typeof value !== "string") throw authorityUnavailable();
4768
+ const parsed = new Date(value);
4769
+ if (!Number.isFinite(parsed.getTime()) || parsed.toISOString() !== value) throw authorityUnavailable();
4770
+ return parsed;
4771
+ }
4772
+ function returnInput(value) {
4773
+ if (!isObject(value)) throw new TypeError("ceremony input is invalid");
4774
+ const { applicationId, returnTo } = value;
4775
+ if (typeof applicationId !== "string" || !idPattern$1.test(applicationId)) throw new TypeError("applicationId is invalid");
4776
+ if (typeof returnTo !== "string" || new TextEncoder().encode(returnTo).byteLength > MAX_RETURN_BYTES || !URL.canParse(returnTo) || new URL(returnTo).toString() !== returnTo) throw new TypeError("returnTo is invalid");
4777
+ return {
4778
+ applicationId,
4779
+ returnTo
4780
+ };
4781
+ }
4782
+ function normalizeCeremonyHandoffInput(value) {
4783
+ const base = returnInput(value);
4784
+ const input = value;
4785
+ switch (input.purpose) {
4786
+ case "passkey_enrollment": return {
4787
+ purpose: input.purpose,
4788
+ ...base
4789
+ };
4790
+ case "passkey_removal": return {
4791
+ purpose: input.purpose,
4792
+ ...base,
4793
+ passkeyId: normalizePasskeyId(input.passkeyId)
4794
+ };
4795
+ case "recent_authentication": {
4796
+ const request = input.request;
4797
+ if (!isObject(request)) throw new TypeError("request is invalid");
4798
+ const organizationId = normalizeIdInput(request.organizationId);
4799
+ if (request.action === "organization_ownership_transfer") {
4800
+ const { action: _action, organizationId: _organizationId, ...transfer } = request;
4801
+ return {
4802
+ purpose: input.purpose,
4803
+ ...base,
4804
+ request: {
4805
+ action: request.action,
4806
+ organizationId,
4807
+ ...normalizeOrganizationOwnershipTransferInput(transfer)
4808
+ }
4809
+ };
4810
+ }
4811
+ if (request.action === "organization_closure_start") {
4812
+ const { action: _action, organizationId: _organizationId, ...closure } = request;
4813
+ return {
4814
+ purpose: input.purpose,
4815
+ ...base,
4816
+ request: {
4817
+ action: request.action,
4818
+ organizationId,
4819
+ ...normalizeOrganizationClosureStartInput(closure)
4820
+ }
4821
+ };
4822
+ }
4823
+ if (request.action === "organization_closure_cancel") {
4824
+ const { action: _action, organizationId: _organizationId, ...closure } = request;
4825
+ return {
4826
+ purpose: input.purpose,
4827
+ ...base,
4828
+ request: {
4829
+ action: request.action,
4830
+ organizationId,
4831
+ ...normalizeOrganizationClosureCancelInput(closure)
4832
+ }
4833
+ };
4834
+ }
4835
+ throw new TypeError("request action is invalid");
4836
+ }
4837
+ default: throw new TypeError("purpose is invalid");
4838
+ }
4839
+ }
4840
+ function normalizeCeremonyHandoff(value) {
4841
+ if (!exact$1(value, ["expiresAt", "url"]) || typeof value.url !== "string") throw authorityUnavailable();
4842
+ let url;
4843
+ try {
4844
+ url = new URL(value.url);
4845
+ } catch {
4846
+ throw authorityUnavailable();
4847
+ }
4848
+ const local = url.hostname === "localhost" || url.hostname.endsWith(".localhost");
4849
+ if (url.protocol !== "https:" && !(local && url.protocol === "http:") || url.username || url.password || url.pathname !== "/api/v1/auth/ceremony/start" || url.search || !/^#code=[A-Za-z0-9_-]{43}$/.test(url.hash)) throw authorityUnavailable();
4850
+ return {
4851
+ url: url.toString(),
4852
+ expiresAt: date$1(value.expiresAt)
4853
+ };
4854
+ }
4855
+ function normalizePasskeyId(value) {
4856
+ if (typeof value !== "string" || !idPattern$1.test(value)) throw new TypeError("passkeyId is invalid");
4857
+ return value;
4858
+ }
4859
+ function normalizePasskeyName(value) {
4860
+ if (typeof value !== "string") throw new TypeError("name is invalid");
4861
+ const name = value.trim();
4862
+ if (!name || name.length > PASSKEY_NAME_MAX_LENGTH || /[\p{Cc}\p{Cf}]/u.test(name)) throw new TypeError("name is invalid");
4863
+ return name;
4864
+ }
4865
+ function normalizePasskeySummary(value) {
4866
+ if (!exact$1(value, itemKeys) || typeof value.id !== "string" || !idPattern$1.test(value.id)) throw authorityUnavailable();
4867
+ if (value.name !== null && (typeof value.name !== "string" || value.name.length > PASSKEY_NAME_MAX_LENGTH)) throw authorityUnavailable();
4868
+ if (value.deviceType !== "singleDevice" && value.deviceType !== "multiDevice") throw authorityUnavailable();
4869
+ if (typeof value.backedUp !== "boolean") throw authorityUnavailable();
4870
+ return {
4871
+ id: value.id,
4872
+ name: value.name,
4873
+ createdAt: value.createdAt === null ? null : date$1(value.createdAt),
4874
+ deviceType: value.deviceType,
4875
+ backedUp: value.backedUp
4876
+ };
4877
+ }
4878
+ function normalizePasskeyInventory(value) {
4879
+ if (!exact$1(value, ["passkeys", "truncated"]) || !Array.isArray(value.passkeys) || value.passkeys.length > MAX_PASSKEYS || typeof value.truncated !== "boolean") throw authorityUnavailable();
4880
+ const passkeys = value.passkeys.map(normalizePasskeySummary);
4881
+ if (new Set(passkeys.map((passkey) => passkey.id)).size !== passkeys.length) throw authorityUnavailable();
4882
+ return {
4883
+ passkeys,
4884
+ truncated: value.truncated
4885
+ };
4886
+ }
4887
+ function normalizePasskeyRename(value) {
4888
+ if (!exact$1(value, ["status"]) || value.status !== "renamed") throw authorityUnavailable();
4889
+ }
4890
+ function fromCeremonyHandoffError(value, status, retryAfter) {
4891
+ const code = isObject(value) ? value.code : void 0;
4892
+ if (status === 400 && code === "RETURN_ADDRESS_REFUSED") return new AuthError("ceremony_return_refused", 400);
4893
+ if (status === 400) return new AuthError("invalid_request", 400);
4894
+ if (status === 401) return new AuthError("authentication_required", 401);
4895
+ if (status === 403) return new AuthError("request_origin_denied", 403);
4896
+ if (status === 404) return new AuthError("state_conflict", 409);
4897
+ if (status === 409 && code === "PASSWORD_REQUIRED") return new AuthError("password_sign_in_required", 409);
4898
+ if (status === 409) return new AuthError("state_conflict", 409);
4899
+ if (status === 429) return new AuthError("auth_request_rate_limited", 429, parseRetryAfter(retryAfter));
4900
+ return authorityUnavailable();
4901
+ }
4902
+ //#endregion
4903
+ //#region src/two-factor.ts
4904
+ const totpCode = /^[0-9]{6}$(?![\s\S])/;
4905
+ const backupCode = /^[A-Za-z0-9]{5}-[A-Za-z0-9]{5}$(?![\s\S])/;
4906
+ const base32Secret = /^[A-Z2-7]{16,128}=*$(?![\s\S])/;
4907
+ const BACKUP_CODE_COUNT = 10;
4908
+ const MAX_TOTP_URI_LENGTH = 1024;
4909
+ function normalizeTwoFactorCode(value, name = "code") {
4910
+ if (typeof value !== "string" || value.length > 32) throw new TypeError(`${name} is invalid`);
4911
+ const code = value.replace(/\s+/g, "");
4912
+ if (totpCode.test(code)) return {
4913
+ route: "two-factor/verify-totp",
4914
+ code
4915
+ };
4916
+ if (backupCode.test(code)) return {
4917
+ route: "two-factor/verify-backup-code",
4918
+ code
4919
+ };
4920
+ throw new TypeError(`${name} is invalid`);
4921
+ }
4922
+ function normalizeTotpCode(value) {
4923
+ const normalized = normalizeTwoFactorCode(value);
4924
+ if (normalized.route !== "two-factor/verify-totp") throw new TypeError("code is invalid");
4925
+ return normalized.code;
4926
+ }
4927
+ function normalizeTwoFactorStepUp(value) {
4928
+ if (!isObject(value)) throw new TypeError("two-factor step-up input is invalid");
4929
+ const keys = Object.keys(value);
4930
+ if (keys.length !== 2 || !keys.includes("password") || !keys.includes("code")) throw new TypeError("two-factor step-up input is invalid");
4931
+ const input = value;
4932
+ return {
4933
+ password: normalizePassword(input.password),
4934
+ code: normalizeTwoFactorCode(input.code).code
4935
+ };
4936
+ }
4937
+ function isTwoFactorChallenge(value) {
4938
+ return isObject(value) && value.twoFactorRedirect === true;
4939
+ }
4940
+ function normalizeBackupCodes(value) {
4941
+ if (!Array.isArray(value) || value.length !== BACKUP_CODE_COUNT || value.some((code) => typeof code !== "string" || !backupCode.test(code)) || new Set(value).size !== value.length) throw authorityUnavailable();
4942
+ return [...value];
4943
+ }
4944
+ function normalizeRegeneratedBackupCodes(value) {
4945
+ if (!isObject(value) || value.status !== true) throw authorityUnavailable();
4946
+ return normalizeBackupCodes(value.backupCodes);
4947
+ }
4948
+ function normalizeTwoFactorEnrollment(value) {
4949
+ if (!isObject(value) || typeof value.totpURI !== "string" || value.totpURI.length > MAX_TOTP_URI_LENGTH) throw authorityUnavailable();
4950
+ let uri;
4951
+ try {
4952
+ uri = new URL(value.totpURI);
4953
+ } catch {
4954
+ throw authorityUnavailable();
4955
+ }
4956
+ const secret = uri.searchParams.get("secret");
4957
+ if (uri.protocol !== "otpauth:" || uri.host !== "totp" || !secret || !base32Secret.test(secret) || (uri.searchParams.get("digits") ?? "6") !== "6" || (uri.searchParams.get("period") ?? "30") !== "30") throw authorityUnavailable();
4958
+ return {
4959
+ totpUri: uri.toString(),
4960
+ secret,
4961
+ backupCodes: normalizeBackupCodes(value.backupCodes)
4962
+ };
4963
+ }
4964
+ function normalizeTwoFactorStatus(value) {
4965
+ if (value === null) throw new AuthError("authentication_required", 401);
4966
+ if (!isObject(value) || !isObject(value.user) || typeof value.user.twoFactorEnabled !== "boolean") throw authorityUnavailable();
4967
+ return { enabled: value.user.twoFactorEnabled };
4968
+ }
4969
+ function fromTwoFactorAuthorityError(value, status, retryAfter) {
4970
+ const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
4971
+ if (code === "INVALID_CODE" || code === "INVALID_BACKUP_CODE") return new AuthError("two_factor_code_invalid", 401);
4972
+ if (code === "INVALID_TWO_FACTOR_COOKIE" || code === "TOO_MANY_ATTEMPTS_REQUEST_NEW_CODE") return new AuthError("two_factor_challenge_expired", 401);
4973
+ if (code === "ACCOUNT_TEMPORARILY_LOCKED") return new AuthError("two_factor_locked", 429, parseRetryAfter(retryAfter));
4974
+ if (code === "SESSION_NOT_FRESH") return new AuthError("recent_sign_in_required", 403);
4975
+ if (code === "TWO_FACTOR_ALREADY_ENABLED" || code === "TWO_FACTOR_NOT_ENABLED" || code === "TOTP_NOT_ENABLED" || code === "TWO_FACTOR_SIGN_IN_ONLY") return new AuthError("state_conflict", 409);
4976
+ if (status === 413) return new AuthError("invalid_auth_input", 422);
4977
+ return fromAccountAuthorityError(value, status, retryAfter);
4978
+ }
4979
+ //#endregion
4980
+ //#region src/enterprise.ts
4981
+ const idPattern = /^[A-Za-z0-9_-]{1,128}$(?![\s\S])/;
4982
+ const credentialPattern = /^[A-Za-z0-9_-]{16,64}\.[A-Za-z0-9_-]{43}$(?![\s\S])/;
4983
+ const connectionKeys = [
4984
+ "capability",
4985
+ "clientId",
4986
+ "domainVerified",
4987
+ "enabled",
4988
+ "id",
4989
+ "issuer",
4990
+ "memberJit",
4991
+ "requireVerifiedEmail",
4992
+ "roleMappingConfigured",
4993
+ "updatedAt",
4994
+ "validatedAt"
4995
+ ];
4996
+ const stateKeys = [
4997
+ "currentCredentialId",
4998
+ "retiringExpiresAt",
4999
+ "revision",
5000
+ "revokedAt",
5001
+ "status"
5002
+ ];
5003
+ function exact(value, keys) {
5004
+ return isObject(value) && Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
5005
+ }
5006
+ function date(value, nullable) {
5007
+ if (value === null && nullable) return null;
5008
+ if (typeof value !== "string") throw authorityUnavailable();
5009
+ const parsed = new Date(value);
5010
+ if (!Number.isFinite(parsed.getTime())) throw authorityUnavailable();
5011
+ return parsed;
5012
+ }
5013
+ function bool(value) {
5014
+ if (typeof value !== "boolean") throw authorityUnavailable();
5015
+ return value;
5016
+ }
5017
+ function normalizeEnterpriseConnections(value) {
5018
+ if (!exact(value, ["connections"]) || !Array.isArray(value.connections) || value.connections.length > 10) throw authorityUnavailable();
5019
+ return value.connections.map((item) => {
5020
+ if (!exact(item, connectionKeys)) throw authorityUnavailable();
5021
+ if (typeof item.id !== "string" || !idPattern.test(item.id) || typeof item.issuer !== "string" || !item.issuer.startsWith("https://") || item.issuer.length > 2048 || typeof item.clientId !== "string" || item.clientId.length === 0 || item.clientId.length > 256 || item.capability !== "federated_sign_in" && item.capability !== "managed_lifecycle") throw authorityUnavailable();
5022
+ return {
5023
+ id: item.id,
5024
+ issuer: item.issuer,
5025
+ clientId: item.clientId,
5026
+ capability: item.capability,
5027
+ enabled: bool(item.enabled),
5028
+ domainVerified: bool(item.domainVerified),
5029
+ validatedAt: date(item.validatedAt, true),
5030
+ memberJit: bool(item.memberJit),
5031
+ requireVerifiedEmail: bool(item.requireVerifiedEmail),
5032
+ roleMappingConfigured: bool(item.roleMappingConfigured),
5033
+ updatedAt: date(item.updatedAt, false)
5034
+ };
5035
+ });
5036
+ }
5037
+ function normalizeScimCredentialState(value, extraKeys = []) {
5038
+ if (!exact(value, [...stateKeys, ...extraKeys])) throw authorityUnavailable();
5039
+ const status = value.status;
5040
+ if (status !== "active" && status !== "revoked" && status !== "unissued") throw authorityUnavailable();
5041
+ const revision = value.revision;
5042
+ if (revision !== null && (!Number.isSafeInteger(revision) || revision < 0)) throw authorityUnavailable();
5043
+ const currentCredentialId = value.currentCredentialId;
5044
+ if (currentCredentialId !== null && (typeof currentCredentialId !== "string" || !idPattern.test(currentCredentialId))) throw authorityUnavailable();
5045
+ if (status === "unissued" !== (revision === null)) throw authorityUnavailable();
5046
+ return {
5047
+ status,
5048
+ revision,
5049
+ currentCredentialId,
5050
+ retiringExpiresAt: date(value.retiringExpiresAt, true),
5051
+ revokedAt: date(value.revokedAt, true)
5052
+ };
5053
+ }
5054
+ function normalizeScimCredentialIssuance(value) {
5055
+ const state = normalizeScimCredentialState(value, ["credential"]);
5056
+ const credential = value.credential;
5057
+ if (state.status !== "active" || typeof credential !== "string" || !credentialPattern.test(credential)) throw authorityUnavailable();
5058
+ return {
5059
+ ...state,
5060
+ credential
5061
+ };
5062
+ }
5063
+ function normalizeRevision(value) {
5064
+ if (!Number.isSafeInteger(value) || value < 0) throw new TypeError("expectedRevision is invalid");
5065
+ return value;
5066
+ }
5067
+ function normalizeOverlapSeconds(value) {
5068
+ if (!Number.isSafeInteger(value) || value < 0 || value > 86400) throw new TypeError("overlapSeconds is invalid");
5069
+ return value;
5070
+ }
5071
+ function fromEnterpriseAdministrationError(value, status, retryAfter) {
5072
+ const code = isObject(value) && typeof value.code === "string" ? value.code : void 0;
5073
+ if (status === 401) return new AuthError("authentication_required", 401);
5074
+ if (status === 403) return new AuthError("access_denied", 403);
5075
+ if (status === 409) return new AuthError("state_conflict", 409);
5076
+ if (status === 422 || code === "RECOVERY_REQUIRED") return new AuthError("enterprise_recovery_required", 422);
5077
+ if (status === 400 || status === 413 || status === 415) return new AuthError("invalid_request", 400);
5078
+ if (status === 429) return new AuthError("auth_request_rate_limited", 429, parseRetryAfter(retryAfter));
5079
+ return authorityUnavailable();
5080
+ }
5081
+ //#endregion
4499
5082
  //#region src/user-api/credential.ts
4500
5083
  function userApiApplication(input) {
4501
5084
  if (!input || typeof input.applicationId !== "string" || !/^[A-Za-z0-9_-]{1,128}$(?![\s\S])/.test(input.applicationId) || input.forceRefresh !== void 0 && typeof input.forceRefresh !== "boolean") throw new TypeError("User API credential input is invalid");
@@ -4509,7 +5092,7 @@ function normalizeUserApiCredential(value, startedAt) {
4509
5092
  expiresAt: new Date(startedAt + value.expiresIn * 1e3)
4510
5093
  };
4511
5094
  }
4512
- function createUserApiCredentialCache(issue, now) {
5095
+ function createUserApiCredentialCache(issue, now, currentSessionId = () => void 0) {
4513
5096
  let generation = 0;
4514
5097
  let cached;
4515
5098
  let pending;
@@ -4519,6 +5102,12 @@ function createUserApiCredentialCache(issue, now) {
4519
5102
  });
4520
5103
  return {
4521
5104
  hasAuthority: () => Boolean(cached || pending),
5105
+ retainSession(sessionId) {
5106
+ if (cached?.sessionId === sessionId && !pending) return;
5107
+ generation += 1;
5108
+ cached = void 0;
5109
+ pending = void 0;
5110
+ },
4522
5111
  clear() {
4523
5112
  generation += 1;
4524
5113
  cached = void 0;
@@ -4542,10 +5131,14 @@ function createUserApiCredentialCache(issue, now) {
4542
5131
  const value = normalizeUserApiCredential(await issue(applicationId), startedAt);
4543
5132
  if (epoch !== generation) throw new AuthError("state_conflict", 409);
4544
5133
  if (now() < startedAt || value.expiresAt.getTime() <= now()) throw new AuthError("authentication_required", 401);
5134
+ const sessionId = credentialSessionId(value.token);
5135
+ const observed = currentSessionId();
5136
+ if (observed !== void 0 && sessionId !== void 0 && sessionId !== observed) throw new AuthError("authentication_required", 401);
4545
5137
  cached = {
4546
5138
  applicationId,
4547
5139
  token: value.token,
4548
- expiresAt: value.expiresAt.getTime()
5140
+ expiresAt: value.expiresAt.getTime(),
5141
+ sessionId
4549
5142
  };
4550
5143
  return value;
4551
5144
  })().finally(() => {
@@ -4578,7 +5171,7 @@ function createAuthClient(options) {
4578
5171
  method: "POST",
4579
5172
  headers: { "content-type": "application/json; charset=utf-8" },
4580
5173
  body: { applicationId }
4581
- }), now);
5174
+ }), now, () => sessionId);
4582
5175
  const betterAuth = createAuthClient$1({
4583
5176
  baseURL: authOrigin,
4584
5177
  basePath: "/api/v1/auth",
@@ -4740,9 +5333,12 @@ function createAuthClient(options) {
4740
5333
  credentialGeneration += 1;
4741
5334
  }
4742
5335
  function updateSession(session) {
4743
- const unboundCredential = !sessionId && (credential || credentialRequests.size > 0 || userApiCredentials.hasAuthority());
4744
5336
  const changedSession = sessionId === void 0 ? !sessionAuthorityObserved || session !== null : !session || session.id !== sessionId || session.user.id !== sessionUserId;
4745
- if (!session || unboundCredential || sessionId && (session.id !== sessionId || session.user.id !== sessionUserId)) clearCredential();
5337
+ if (!session || sessionId && (session.id !== sessionId || session.user.id !== sessionUserId)) clearCredential();
5338
+ else if (!sessionId) {
5339
+ if (credential && credential.sessionId !== session.id) credential = void 0;
5340
+ userApiCredentials.retainSession(session.id);
5341
+ }
4746
5342
  if (changedSession || recentAuthenticationStartAttempt && (recentAuthenticationStartAttempt.sessionId !== session?.id || recentAuthenticationStartAttempt.userId !== session?.user.id)) recentAuthenticationStartAttempt = void 0;
4747
5343
  if (changedSession) sessionAuthorityEpoch += 1;
4748
5344
  sessionAuthorityObserved = true;
@@ -4884,6 +5480,39 @@ function createAuthClient(options) {
4884
5480
  mapError
4885
5481
  })).value;
4886
5482
  }
5483
+ async function resolveSuspension(organizationId, suspensionId, idempotencyKey, resolution) {
5484
+ const organization = normalizeIdInput(organizationId);
5485
+ const suspension = normalizeIdInput(suspensionId);
5486
+ const body = normalizeOrganizationMembershipRemovalInput(idempotencyKey);
5487
+ if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
5488
+ const generation = authorityGeneration;
5489
+ const value = await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", organization, "suspended-members", suspension, resolution), {
5490
+ fetch: fetchImpl,
5491
+ timeoutMs,
5492
+ method: "POST",
5493
+ headers: { "content-type": "application/json" },
5494
+ body,
5495
+ mapError: fromOrganizationMembershipRemovalError
5496
+ });
5497
+ if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
5498
+ return value;
5499
+ }
5500
+ async function teamMembershipMutation(ids, idempotencyKey, url) {
5501
+ const [organization, team, member] = ids.map(normalizeIdInput);
5502
+ const body = normalizeOrganizationTeamMembershipInput(idempotencyKey);
5503
+ if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
5504
+ const generation = authorityGeneration;
5505
+ const value = await requestJson(url(organization, team, member), {
5506
+ fetch: fetchImpl,
5507
+ timeoutMs,
5508
+ method: "POST",
5509
+ headers: { "content-type": "application/json" },
5510
+ body,
5511
+ mapError: fromOrganizationMutationAuthorityError
5512
+ });
5513
+ if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
5514
+ return value;
5515
+ }
4887
5516
  async function organizationRead(path, input, normalize) {
4888
5517
  if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
4889
5518
  const generation = authorityGeneration;
@@ -4903,6 +5532,71 @@ function createAuthClient(options) {
4903
5532
  throw error;
4904
5533
  }
4905
5534
  }
5535
+ async function sessionInventoryRequest(method, path, normalize) {
5536
+ if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
5537
+ const generation = authorityGeneration;
5538
+ const value = await requestJson(joinURL(authOrigin, "api/v1/auth/sessions", path), {
5539
+ fetch: fetchImpl,
5540
+ timeoutMs,
5541
+ method,
5542
+ ...method === "POST" ? {
5543
+ headers: { "content-type": "application/json; charset=utf-8" },
5544
+ body: {}
5545
+ } : {},
5546
+ mapError: fromSessionInventoryError
5547
+ });
5548
+ if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
5549
+ return normalize(value);
5550
+ }
5551
+ async function ceremonyRequest(method, path, body, normalize) {
5552
+ if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
5553
+ const generation = authorityGeneration;
5554
+ const value = await requestJson(joinURL(authOrigin, "api/v1/auth", path), {
5555
+ fetch: fetchImpl,
5556
+ timeoutMs,
5557
+ method,
5558
+ ...body ? {
5559
+ headers: { "content-type": "application/json" },
5560
+ body
5561
+ } : {},
5562
+ mapError: fromCeremonyHandoffError
5563
+ });
5564
+ if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
5565
+ return normalize(value);
5566
+ }
5567
+ function scimCredentialPath(organizationId, connectionId) {
5568
+ return `${normalizeIdInput(organizationId)}/connections/${normalizeIdInput(connectionId)}/scim-credential`;
5569
+ }
5570
+ async function enterpriseRequest(method, path, body, normalize) {
5571
+ if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
5572
+ const generation = authorityGeneration;
5573
+ const value = await requestJson(joinURL(authOrigin, "api/v1/auth/enterprise/organizations", path), {
5574
+ fetch: fetchImpl,
5575
+ timeoutMs,
5576
+ method,
5577
+ ...body ? {
5578
+ headers: { "content-type": "application/json" },
5579
+ body
5580
+ } : {},
5581
+ mapError: fromEnterpriseAdministrationError
5582
+ });
5583
+ if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
5584
+ return normalize(value);
5585
+ }
5586
+ async function closureMutation(organizationId, operation, body) {
5587
+ if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
5588
+ const generation = authorityGeneration;
5589
+ const value = await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", organizationId, "closure", operation), {
5590
+ fetch: fetchImpl,
5591
+ timeoutMs,
5592
+ method: "POST",
5593
+ headers: { "content-type": "application/json" },
5594
+ body,
5595
+ mapError: fromOrganizationClosureError
5596
+ });
5597
+ if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
5598
+ return normalizeOrganizationClosure(value);
5599
+ }
4906
5600
  function assertRecentAuthenticationOrigin() {
4907
5601
  if (appOrigin !== authOrigin) throw new TypeError("recent authentication requires the exact Auth Origin");
4908
5602
  }
@@ -4990,6 +5684,20 @@ function createAuthClient(options) {
4990
5684
  ...normalizeOrganizationOwnershipTransferInput(input)
4991
5685
  });
4992
5686
  },
5687
+ async startOrganizationClosureRecentAuthentication(organizationId, input) {
5688
+ return startRecentAuthentication({
5689
+ action: "organization_closure_start",
5690
+ organizationId: normalizeIdInput(organizationId),
5691
+ ...normalizeOrganizationClosureStartInput(input)
5692
+ });
5693
+ },
5694
+ async startOrganizationClosureCancellationRecentAuthentication(organizationId, input) {
5695
+ return startRecentAuthentication({
5696
+ action: "organization_closure_cancel",
5697
+ organizationId: normalizeIdInput(organizationId),
5698
+ ...normalizeOrganizationClosureCancelInput(input)
5699
+ });
5700
+ },
4993
5701
  async approveBootstrapPlatformRoleChange(input) {
4994
5702
  assertRecentAuthenticationOrigin();
4995
5703
  if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
@@ -5073,6 +5781,26 @@ function createAuthClient(options) {
5073
5781
  invitationRequest = request;
5074
5782
  return request;
5075
5783
  },
5784
+ async declineInvitation(input) {
5785
+ const invitation = normalizeInvitationInput(input);
5786
+ if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest || recentAuthenticationStartRequest) throw new AuthError("state_conflict", 409);
5787
+ const generation = authorityGeneration;
5788
+ try {
5789
+ const value = await requestJson(joinURL(authOrigin, "api/v1/auth/organization/reject-invitation"), {
5790
+ fetch: fetchImpl,
5791
+ timeoutMs,
5792
+ method: "POST",
5793
+ headers: { "content-type": "application/json; charset=utf-8" },
5794
+ body: invitation,
5795
+ mapError: fromInvitationAuthorityError
5796
+ });
5797
+ if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
5798
+ return normalizeInvitationDecline(value, invitation.invitationId);
5799
+ } catch (error) {
5800
+ if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
5801
+ throw fromInvitationError(error);
5802
+ }
5803
+ },
5076
5804
  getSession,
5077
5805
  async listOrganizations(input) {
5078
5806
  try {
@@ -5187,6 +5915,35 @@ function createAuthClient(options) {
5187
5915
  if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
5188
5916
  return normalizeRemovedOrganizationMember(value);
5189
5917
  },
5918
+ async suspendOrganizationMember(organizationId, memberId, idempotencyKey) {
5919
+ const organization = normalizeIdInput(organizationId);
5920
+ const member = normalizeIdInput(memberId);
5921
+ const body = normalizeOrganizationMembershipRemovalInput(idempotencyKey);
5922
+ if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
5923
+ const generation = authorityGeneration;
5924
+ const value = await requestJson(joinURL(authOrigin, "api/v1/auth/organizations", organization, "members", member, "suspend"), {
5925
+ fetch: fetchImpl,
5926
+ timeoutMs,
5927
+ method: "POST",
5928
+ headers: { "content-type": "application/json" },
5929
+ body,
5930
+ mapError: fromOrganizationMembershipRemovalError
5931
+ });
5932
+ if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
5933
+ return normalizeSuspendedOrganizationMemberStatus(value);
5934
+ },
5935
+ async listSuspendedOrganizationMembers(organizationId, input) {
5936
+ return organizationRead(`${normalizeIdInput(organizationId)}/suspended-members`, input, normalizeSuspendedOrganizationMembers);
5937
+ },
5938
+ async listRemovedOrganizationMembers(organizationId, input) {
5939
+ return organizationRead(`${normalizeIdInput(organizationId)}/removed-members`, input, normalizeDepartedOrganizationMembers);
5940
+ },
5941
+ async restoreSuspendedOrganizationMember(organizationId, suspensionId, idempotencyKey) {
5942
+ return normalizeRestoredOrganizationMember(await resolveSuspension(organizationId, suspensionId, idempotencyKey, "restore"));
5943
+ },
5944
+ async removeSuspendedOrganizationMember(organizationId, suspensionId, idempotencyKey) {
5945
+ return normalizeRemovedOrganizationMember(await resolveSuspension(organizationId, suspensionId, idempotencyKey, "remove"));
5946
+ },
5190
5947
  async leaveOrganization(organizationId, idempotencyKey) {
5191
5948
  const organization = normalizeIdInput(organizationId);
5192
5949
  const body = normalizeOrganizationMembershipRemovalInput(idempotencyKey);
@@ -5203,6 +5960,23 @@ function createAuthClient(options) {
5203
5960
  if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
5204
5961
  return normalizeOrganizationDeparture(value);
5205
5962
  },
5963
+ async addOrganizationTeamMember(organizationId, teamId, memberId, idempotencyKey) {
5964
+ return normalizeAddedOrganizationTeamMember(await teamMembershipMutation([
5965
+ organizationId,
5966
+ teamId,
5967
+ memberId
5968
+ ], idempotencyKey, (organization, team, member) => joinURL(authOrigin, "api/v1/auth/organizations", organization, "teams", team, "members", member, "add")));
5969
+ },
5970
+ async removeOrganizationTeamMember(organizationId, teamId, memberId, idempotencyKey) {
5971
+ return normalizeRemovedOrganizationTeamMember(await teamMembershipMutation([
5972
+ organizationId,
5973
+ teamId,
5974
+ memberId
5975
+ ], idempotencyKey, (organization, team, member) => joinURL(authOrigin, "api/v1/auth/organizations", organization, "teams", team, "members", member, "remove")));
5976
+ },
5977
+ async deleteOrganizationTeam(organizationId, teamId, idempotencyKey) {
5978
+ return normalizeDeletedOrganizationTeam(await teamMembershipMutation([organizationId, teamId], idempotencyKey, (organization, team) => joinURL(authOrigin, "api/v1/auth/organizations", organization, "teams", team, "delete")));
5979
+ },
5206
5980
  async updateOrganizationDisplay(organizationId, input) {
5207
5981
  const id = normalizeIdInput(organizationId);
5208
5982
  const desired = normalizeOrganizationDisplayInput(input);
@@ -5269,6 +6043,18 @@ function createAuthClient(options) {
5269
6043
  if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
5270
6044
  return normalizeOrganizationOwnershipTransferResult(value);
5271
6045
  },
6046
+ async startOrganizationClosure(organizationId, input) {
6047
+ return closureMutation(normalizeIdInput(organizationId), "", normalizeOrganizationClosureStartInput(input));
6048
+ },
6049
+ async cancelOrganizationClosure(organizationId, input) {
6050
+ return closureMutation(normalizeIdInput(organizationId), "cancel", normalizeOrganizationClosureCancelInput(input));
6051
+ },
6052
+ async getOrganizationClosure(organizationId) {
6053
+ return organizationRead(`${normalizeIdInput(organizationId)}/closure`, void 0, normalizeOrganizationClosure);
6054
+ },
6055
+ async listClosingOrganizations() {
6056
+ return organizationRead("closing", void 0, normalizeClosingOrganizations);
6057
+ },
5272
6058
  async listOrganizationMembers(organizationId, input) {
5273
6059
  return organizationRead(`${normalizeIdInput(organizationId)}/members`, input, normalizeOrganizationMembers);
5274
6060
  },
@@ -5290,15 +6076,105 @@ function createAuthClient(options) {
5290
6076
  async getReceivedInvitation(invitationId) {
5291
6077
  return organizationRead(`received-invitations/${normalizeIdInput(invitationId)}`, void 0, normalizeReceivedInvitation);
5292
6078
  },
6079
+ async listEnterpriseConnections(organizationId) {
6080
+ return enterpriseRequest("GET", `${normalizeIdInput(organizationId)}/connections`, void 0, normalizeEnterpriseConnections);
6081
+ },
6082
+ async getScimCredential(organizationId, connectionId) {
6083
+ return enterpriseRequest("GET", scimCredentialPath(organizationId, connectionId), void 0, (value) => normalizeScimCredentialState(value));
6084
+ },
6085
+ async issueScimCredential(organizationId, connectionId) {
6086
+ return enterpriseRequest("POST", scimCredentialPath(organizationId, connectionId), {}, normalizeScimCredentialIssuance);
6087
+ },
6088
+ async rotateScimCredential(organizationId, connectionId, input) {
6089
+ const body = {
6090
+ expectedRevision: normalizeRevision(input?.expectedRevision),
6091
+ overlapSeconds: normalizeOverlapSeconds(input?.overlapSeconds)
6092
+ };
6093
+ return enterpriseRequest("POST", `${scimCredentialPath(organizationId, connectionId)}/rotate`, body, normalizeScimCredentialIssuance);
6094
+ },
6095
+ async revokeScimCredential(organizationId, connectionId, input) {
6096
+ const body = { expectedRevision: normalizeRevision(input?.expectedRevision) };
6097
+ return enterpriseRequest("POST", `${scimCredentialPath(organizationId, connectionId)}/revoke`, body, (value) => normalizeScimCredentialState(value));
6098
+ },
5293
6099
  async signIn(input) {
5294
6100
  const body = {
5295
6101
  email: normalizeEmail(input?.email),
5296
6102
  password: normalizePassword(input?.password)
5297
6103
  };
5298
- const result = await runAccountMutation(() => accountRequest("sign-in/email", body));
6104
+ const result = await runAccountMutation(async () => {
6105
+ const value = await accountRequest("sign-in/email", body);
6106
+ if (isTwoFactorChallenge(value)) throw new AuthError("two_factor_required", 401);
6107
+ return value;
6108
+ });
6109
+ if (!result.session) throw new AuthError("authentication_required", 401);
6110
+ return result.session;
6111
+ },
6112
+ async verifyTwoFactor(code) {
6113
+ const normalized = normalizeTwoFactorCode(code);
6114
+ const result = await runAccountMutation(() => accountRequest(normalized.route, { code: normalized.code }, fromTwoFactorAuthorityError));
6115
+ if (!result.session) throw new AuthError("authentication_required", 401);
6116
+ return result.session;
6117
+ },
6118
+ async getTwoFactorStatus() {
6119
+ if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
6120
+ const generation = authorityGeneration;
6121
+ const value = await requestJson(joinURL(authOrigin, "api/v1/auth/get-session"), {
6122
+ fetch: fetchImpl,
6123
+ timeoutMs,
6124
+ method: "GET",
6125
+ headers: { "cache-control": "no-store" }
6126
+ });
6127
+ if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
6128
+ return normalizeTwoFactorStatus(value);
6129
+ },
6130
+ async startTwoFactorEnrollment(password) {
6131
+ const body = { password: normalizePassword(password) };
6132
+ if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
6133
+ const generation = authorityGeneration;
6134
+ const value = await accountRequest("two-factor/enable", body, fromTwoFactorAuthorityError);
6135
+ if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
6136
+ return normalizeTwoFactorEnrollment(value);
6137
+ },
6138
+ async confirmTwoFactorEnrollment(code) {
6139
+ const body = { code: normalizeTotpCode(code) };
6140
+ const result = await runAccountMutation(() => accountRequest("two-factor/verify-totp", body, fromTwoFactorAuthorityError));
6141
+ if (!result.session) throw new AuthError("authentication_required", 401);
6142
+ return result.session;
6143
+ },
6144
+ async disableTwoFactor(input) {
6145
+ const body = normalizeTwoFactorStepUp(input);
6146
+ const result = await runAccountMutation(() => accountRequest("two-factor/disable", body, fromTwoFactorAuthorityError));
5299
6147
  if (!result.session) throw new AuthError("authentication_required", 401);
5300
6148
  return result.session;
5301
6149
  },
6150
+ async regenerateTwoFactorBackupCodes(input) {
6151
+ const body = normalizeTwoFactorStepUp(input);
6152
+ if (signOutRequest || activeAccountMutationGeneration !== void 0 || invitationRequest) throw new AuthError("state_conflict", 409);
6153
+ const generation = authorityGeneration;
6154
+ const value = await accountRequest("two-factor/generate-backup-codes", body, fromTwoFactorAuthorityError);
6155
+ if (generation !== authorityGeneration) throw new AuthError("state_conflict", 409);
6156
+ return normalizeRegeneratedBackupCodes(value);
6157
+ },
6158
+ async listSessions() {
6159
+ return sessionInventoryRequest("GET", "", normalizeSessionInventory);
6160
+ },
6161
+ async revokeSession(sessionId) {
6162
+ await sessionInventoryRequest("POST", `${normalizeSessionId(sessionId)}/revoke`, normalizeSessionRevocation);
6163
+ },
6164
+ async revokeOtherSessions() {
6165
+ return sessionInventoryRequest("POST", "revoke-others", normalizeOtherSessionRevocation);
6166
+ },
6167
+ async createCeremonyHandoff(input) {
6168
+ return ceremonyRequest("POST", "ceremony-handoffs", normalizeCeremonyHandoffInput(input), normalizeCeremonyHandoff);
6169
+ },
6170
+ async listPasskeys() {
6171
+ return ceremonyRequest("GET", "passkeys", void 0, normalizePasskeyInventory);
6172
+ },
6173
+ async renamePasskey(passkeyId, name) {
6174
+ const id = normalizePasskeyId(passkeyId);
6175
+ const body = { name: normalizePasskeyName(name) };
6176
+ await ceremonyRequest("POST", `passkeys/${id}/name`, body, normalizePasskeyRename);
6177
+ },
5302
6178
  async signInWithSocialIdToken(input) {
5303
6179
  const body = socialIdTokenRequest(normalizeSocialIdTokenInput(input));
5304
6180
  const result = await runAccountMutation(() => accountRequest("sign-in/social", body, fromSocialIdTokenAuthorityError));
@@ -5390,9 +6266,12 @@ function createAuthClient(options) {
5390
6266
  if (error) throw error;
5391
6267
  const nextCredential = normalizeDriveCredential(result, now());
5392
6268
  if (generation !== credentialGeneration) throw new AuthError("authentication_required", 401);
6269
+ const issuedFor = credentialSessionId(nextCredential.token);
6270
+ if (sessionId !== void 0 && issuedFor !== void 0 && issuedFor !== sessionId) throw new AuthError("authentication_required", 401);
5393
6271
  if (selectedWorkspaceKey === workspaceKey) credential = {
5394
6272
  key: workspaceKey,
5395
- value: nextCredential
6273
+ value: nextCredential,
6274
+ sessionId: issuedFor
5396
6275
  };
5397
6276
  return nextCredential;
5398
6277
  })().finally(() => {