@spfn/auth 0.3.0-beta.2 → 0.3.0-beta.20

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.
Files changed (43) hide show
  1. package/README.md +1382 -23
  2. package/dist/client-proof.d.ts +45 -15
  3. package/dist/client-proof.js +198 -4
  4. package/dist/client-proof.js.map +1 -1
  5. package/dist/client.d.ts +92 -1
  6. package/dist/client.js +58 -0
  7. package/dist/client.js.map +1 -1
  8. package/dist/config.d.ts +302 -0
  9. package/dist/config.js +134 -4
  10. package/dist/config.js.map +1 -1
  11. package/dist/errors.d.ts +370 -3
  12. package/dist/errors.js +245 -2
  13. package/dist/errors.js.map +1 -1
  14. package/dist/index.d.ts +185 -2
  15. package/dist/index.js +256 -2
  16. package/dist/index.js.map +1 -1
  17. package/dist/machine-principals-BD4tnASp.d.ts +2739 -0
  18. package/dist/nextjs/api.js +350 -12
  19. package/dist/nextjs/api.js.map +1 -1
  20. package/dist/nextjs/client.d.ts +28 -1
  21. package/dist/nextjs/client.js +24 -3
  22. package/dist/nextjs/client.js.map +1 -1
  23. package/dist/nextjs/server.d.ts +173 -3
  24. package/dist/nextjs/server.js +372 -10
  25. package/dist/nextjs/server.js.map +1 -1
  26. package/dist/server.d.ts +3761 -414
  27. package/dist/server.js +5865 -1043
  28. package/dist/server.js.map +1 -1
  29. package/dist/{session-DTHahDQ9.d.ts → session-Dfwu5g2W.d.ts} +28 -1
  30. package/migrations/20260810112144_colorful_tomorrow_man/migration.sql +18 -0
  31. package/migrations/20260810112144_colorful_tomorrow_man/snapshot.json +3576 -0
  32. package/migrations/20260901091716_fine_arclight/migration.sql +21 -0
  33. package/migrations/20260901091716_fine_arclight/snapshot.json +3849 -0
  34. package/migrations/20260906155957_natural_moonstone/migration.sql +33 -0
  35. package/migrations/20260906155957_natural_moonstone/snapshot.json +4275 -0
  36. package/migrations/20260907020904_giant_eternals/migration.sql +21 -0
  37. package/migrations/20260907020904_giant_eternals/snapshot.json +4561 -0
  38. package/migrations/20260907044807_eminent_angel/migration.sql +2 -0
  39. package/migrations/20260907044807_eminent_angel/snapshot.json +4561 -0
  40. package/migrations/20260918083158_foamy_roughhouse/migration.sql +55 -0
  41. package/migrations/20260918083158_foamy_roughhouse/snapshot.json +5271 -0
  42. package/package.json +9 -6
  43. package/dist/authenticate-55LeXHqZ.d.ts +0 -1447
package/dist/index.d.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import * as _spfn_core_nextjs from '@spfn/core/nextjs';
2
- import { P as PermissionConfig, R as RoleConfig, m as mainAuthRouter, S as SendVerificationCodeResult, a as RegisterResult, L as LoginResult, b as RotateKeyResult, K as KeySummary, c as RevokeAllKeysResult, I as IssueOneTimeTokenResult, O as OAuthStartResult, d as OAuthNativeResult, U as UserProfile, e as ProfileInfo } from './authenticate-55LeXHqZ.js';
3
- export { A as AuthInitOptions, f as AuthSession, g as PERMISSION_CATEGORIES, h as PermissionCategory, V as VERIFICATION_PURPOSES, i as VERIFICATION_TARGET_TYPES, j as VerificationPurpose, k as VerificationTargetType } from './authenticate-55LeXHqZ.js';
2
+ import { P as PermissionConfig, R as RoleConfig, m as mainAuthRouter, S as SendVerificationCodeResult, a as RegisterResult, b as RequestSignupLinkResult, C as ConfirmSignupLinkResult, c as RequestPasswordResetResult, d as ConfirmPasswordResetResult, L as LoginResult, e as StartDeviceAuthResult, D as DeviceAuthInfoResult, F as FinishPasskeyEnrollmentResult, f as PasskeySummary, g as RotateKeyResult, K as KeySummary, h as RevokeAllKeysResult, I as IssueOneTimeTokenResult, O as OAuthStartResult, i as OAuthNativeResult, U as UserProfile, j as ProfileInfo, k as OAuth2ConsentView, l as OAuth2AuthorizationCodeIssued, n as OAuth2GrantSummary } from './machine-principals-BD4tnASp.js';
3
+ export { A as AuthInitOptions, o as AuthSession, p as PERMISSION_CATEGORIES, q as PermissionCategory, V as VERIFICATION_PURPOSES, r as VERIFICATION_TARGET_TYPES, s as VerificationPurpose, t as VerificationTargetType } from './machine-principals-BD4tnASp.js';
4
+ import * as _simplewebauthn_server from '@simplewebauthn/server';
4
5
  import * as _spfn_core_route from '@spfn/core/route';
5
6
  import { HttpMethod } from '@spfn/core/route';
6
7
  export { A as ACCOUNT_DELETION_REQUESTED_BY, a as ACCOUNT_DELETION_REQUEST_STATUSES, b as AccountDeletionRequestStatus, c as AccountDeletionRequestedBy, I as INVITATION_STATUSES, d as InvitationStatus, e as KEY_ALGORITHM, f as KEY_DEVICE_NAME_MAX_LENGTH, g as KEY_PLATFORM, K as KeyAlgorithmType, h as KeyPlatformType, P as PURGE_STRATEGIES, i as PurgeStrategy, S as SOCIAL_PROVIDERS, j as SocialProvider, U as USER_STATUSES, k as UserStatus } from './types-DYyhze28.js';
7
8
  import * as _sinclair_typebox from '@sinclair/typebox';
9
+ import 'drizzle-orm/pg-core';
8
10
  import 'hono';
9
11
  import '@spfn/auth/server';
10
12
 
@@ -125,6 +127,59 @@ declare const authApi: _spfn_core_nextjs.Client<_spfn_core_route.Router<{
125
127
  platform: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ios" | "android" | "web" | "desktop">[]>>;
126
128
  }>;
127
129
  }, RegisterResult>;
130
+ requestSignupLink: _spfn_core_route.RouteDef<{
131
+ body: _sinclair_typebox.TObject<{
132
+ email: _sinclair_typebox.TString;
133
+ returnPath: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
134
+ }>;
135
+ }, {}, RequestSignupLinkResult>;
136
+ confirmSignupLink: _spfn_core_route.RouteDef<{
137
+ body: _sinclair_typebox.TObject<{
138
+ token: _sinclair_typebox.TString;
139
+ }>;
140
+ }, {}, ConfirmSignupLinkResult>;
141
+ completeSignup: _spfn_core_route.RouteDef<{
142
+ body: _sinclair_typebox.TObject<{
143
+ password: _sinclair_typebox.TString;
144
+ metadata: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TUnknown>>;
145
+ }>;
146
+ }, {
147
+ body: _sinclair_typebox.TObject<{
148
+ setupSecret: _sinclair_typebox.TString;
149
+ publicKey: _sinclair_typebox.TString;
150
+ keyId: _sinclair_typebox.TString;
151
+ fingerprint: _sinclair_typebox.TString;
152
+ algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
153
+ deviceName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
154
+ platform: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ios" | "android" | "web" | "desktop">[]>>;
155
+ }>;
156
+ }, RegisterResult>;
157
+ requestPasswordReset: _spfn_core_route.RouteDef<{
158
+ body: _sinclair_typebox.TObject<{
159
+ email: _sinclair_typebox.TString;
160
+ returnPath: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
161
+ }>;
162
+ }, {}, RequestPasswordResetResult>;
163
+ confirmPasswordReset: _spfn_core_route.RouteDef<{
164
+ body: _sinclair_typebox.TObject<{
165
+ token: _sinclair_typebox.TString;
166
+ }>;
167
+ }, {}, ConfirmPasswordResetResult>;
168
+ completePasswordReset: _spfn_core_route.RouteDef<{
169
+ body: _sinclair_typebox.TObject<{
170
+ password: _sinclair_typebox.TString;
171
+ }>;
172
+ }, {
173
+ body: _sinclair_typebox.TObject<{
174
+ setupSecret: _sinclair_typebox.TString;
175
+ publicKey: _sinclair_typebox.TString;
176
+ keyId: _sinclair_typebox.TString;
177
+ fingerprint: _sinclair_typebox.TString;
178
+ algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
179
+ deviceName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
180
+ platform: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ios" | "android" | "web" | "desktop">[]>>;
181
+ }>;
182
+ }, RegisterResult>;
128
183
  login: _spfn_core_route.RouteDef<{
129
184
  body: _sinclair_typebox.TObject<{
130
185
  email: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
@@ -142,6 +197,97 @@ declare const authApi: _spfn_core_nextjs.Client<_spfn_core_route.Router<{
142
197
  platform: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ios" | "android" | "web" | "desktop">[]>>;
143
198
  }>;
144
199
  }, LoginResult>;
200
+ startDeviceAuth: _spfn_core_route.RouteDef<{
201
+ body: _sinclair_typebox.TObject<{
202
+ publicKey: _sinclair_typebox.TString;
203
+ keyId: _sinclair_typebox.TString;
204
+ fingerprint: _sinclair_typebox.TString;
205
+ algorithm: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>>;
206
+ deviceName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
207
+ platform: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ios" | "android" | "web" | "desktop">[]>>;
208
+ }>;
209
+ }, {}, StartDeviceAuthResult>;
210
+ pollDeviceAuth: _spfn_core_route.RouteDef<{
211
+ body: _sinclair_typebox.TObject<{
212
+ deviceCode: _sinclair_typebox.TString;
213
+ }>;
214
+ }, {}, {
215
+ status: "pending";
216
+ intervalMillis: number;
217
+ } | {
218
+ email?: string | undefined;
219
+ phone?: string | undefined;
220
+ status: "approved";
221
+ userId: string;
222
+ publicId: string;
223
+ passwordChangeRequired: boolean;
224
+ }>;
225
+ getDeviceAuthInfo: _spfn_core_route.RouteDef<{
226
+ body: _sinclair_typebox.TObject<{
227
+ userCode: _sinclair_typebox.TString;
228
+ }>;
229
+ }, {}, DeviceAuthInfoResult>;
230
+ approveDeviceAuth: _spfn_core_route.RouteDef<{
231
+ body: _sinclair_typebox.TObject<{
232
+ userCode: _sinclair_typebox.TString;
233
+ }>;
234
+ }, {}, DeviceAuthInfoResult>;
235
+ denyDeviceAuth: _spfn_core_route.RouteDef<{
236
+ body: _sinclair_typebox.TObject<{
237
+ userCode: _sinclair_typebox.TString;
238
+ }>;
239
+ }, {}, void>;
240
+ passkeyRegisterOptions: _spfn_core_route.RouteDef<{
241
+ body: _sinclair_typebox.TObject<{
242
+ currentPassword: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
243
+ }>;
244
+ }, {}, _simplewebauthn_server.PublicKeyCredentialCreationOptionsJSON>;
245
+ passkeyRegisterVerify: _spfn_core_route.RouteDef<{
246
+ body: _sinclair_typebox.TObject<{
247
+ response: _sinclair_typebox.TUnknown;
248
+ label: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
249
+ }>;
250
+ }, {}, FinishPasskeyEnrollmentResult>;
251
+ passkeyLoginOptions: _spfn_core_route.RouteDef<{
252
+ body: _sinclair_typebox.TObject<{}>;
253
+ }, {}, _simplewebauthn_server.PublicKeyCredentialRequestOptionsJSON>;
254
+ passkeyLoginVerify: _spfn_core_route.RouteDef<{
255
+ body: _sinclair_typebox.TObject<{
256
+ response: _sinclair_typebox.TUnknown;
257
+ }>;
258
+ }, {
259
+ body: _sinclair_typebox.TObject<{
260
+ publicKey: _sinclair_typebox.TString;
261
+ keyId: _sinclair_typebox.TString;
262
+ fingerprint: _sinclair_typebox.TString;
263
+ algorithm: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ES256" | "RS256">[]>;
264
+ oldKeyId: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
265
+ deviceName: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
266
+ platform: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"ios" | "android" | "web" | "desktop">[]>>;
267
+ }>;
268
+ }, LoginResult>;
269
+ listPasskeys: _spfn_core_route.RouteDef<{
270
+ body: _sinclair_typebox.TObject<{}>;
271
+ }, {}, {
272
+ passkeys: PasskeySummary[];
273
+ }>;
274
+ renamePasskey: _spfn_core_route.RouteDef<{
275
+ body: _sinclair_typebox.TObject<{
276
+ passkeyId: _sinclair_typebox.TString;
277
+ label: _sinclair_typebox.TString;
278
+ }>;
279
+ }, {}, {
280
+ passkeyId: string;
281
+ label: string;
282
+ }>;
283
+ revokePasskey: _spfn_core_route.RouteDef<{
284
+ body: _sinclair_typebox.TObject<{
285
+ passkeyId: _sinclair_typebox.TString;
286
+ currentPassword: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
287
+ }>;
288
+ }, {}, {
289
+ passkeyId: string;
290
+ }>;
145
291
  logout: _spfn_core_route.RouteDef<{}, {}, void>;
146
292
  rotateKey: _spfn_core_route.RouteDef<{}, {
147
293
  body: _sinclair_typebox.TObject<{
@@ -607,6 +753,43 @@ declare const authApi: _spfn_core_nextjs.Client<_spfn_core_route.Router<{
607
753
  createdAt: string | null;
608
754
  };
609
755
  }>;
756
+ registerOAuth2Client: _spfn_core_route.RouteDef<{}, {}, Response>;
757
+ getOAuth2Authorize: _spfn_core_route.RouteDef<{
758
+ query: _sinclair_typebox.TObject<{
759
+ client_id: _sinclair_typebox.TString;
760
+ redirect_uri: _sinclair_typebox.TString;
761
+ code_challenge: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
762
+ code_challenge_method: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
763
+ resource: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
764
+ scope: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
765
+ state: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
766
+ }>;
767
+ }, {}, OAuth2ConsentView>;
768
+ createOAuth2AuthorizationCode: _spfn_core_route.RouteDef<{
769
+ body: _sinclair_typebox.TObject<{
770
+ approve: _sinclair_typebox.TBoolean;
771
+ client_id: _sinclair_typebox.TString;
772
+ redirect_uri: _sinclair_typebox.TString;
773
+ code_challenge: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
774
+ code_challenge_method: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
775
+ resource: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
776
+ scope: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
777
+ state: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
778
+ }>;
779
+ }, {}, OAuth2AuthorizationCodeIssued>;
780
+ oauth2Token: _spfn_core_route.RouteDef<{}, {}, Response>;
781
+ oauth2Revoke: _spfn_core_route.RouteDef<{}, {}, Response>;
782
+ listOAuth2Grants: _spfn_core_route.RouteDef<{}, {}, {
783
+ grants: OAuth2GrantSummary[];
784
+ }>;
785
+ revokeOAuth2Grant: _spfn_core_route.RouteDef<{
786
+ params: _sinclair_typebox.TObject<{
787
+ id: _sinclair_typebox.TNumber;
788
+ }>;
789
+ }, {}, {
790
+ revoked: boolean;
791
+ }>;
792
+ oauth2AuthorizationServerMetadata: _spfn_core_route.RouteDef<{}, {}, Response>;
610
793
  }>>;
611
794
  type AuthRouter = typeof mainAuthRouter;
612
795
 
package/dist/index.js CHANGED
@@ -16,7 +16,8 @@ import {
16
16
  UnauthorizedError,
17
17
  ForbiddenError,
18
18
  ConflictError,
19
- NotFoundError
19
+ NotFoundError,
20
+ HttpError
20
21
  } from "@spfn/core/errors";
21
22
  var InvalidCredentialsError = class extends UnauthorizedError {
22
23
  constructor(data = {}) {
@@ -131,12 +132,54 @@ var InvalidKeyFingerprintError = class extends ValidationError {
131
132
  this.name = "InvalidKeyFingerprintError";
132
133
  }
133
134
  };
135
+ var KeyAlgorithmMismatchError = class extends ValidationError {
136
+ constructor(data = {}) {
137
+ super({
138
+ message: data.message || "Public key type does not match the declared algorithm",
139
+ details: data.details
140
+ });
141
+ this.name = "KeyAlgorithmMismatchError";
142
+ }
143
+ };
134
144
  var KeyNotFoundError = class extends NotFoundError {
135
145
  constructor(data = {}) {
136
146
  super({ message: data.message || "Key not found", details: data.details });
137
147
  this.name = "KeyNotFoundError";
138
148
  }
139
149
  };
150
+ var DeviceAuthNotFoundError = class extends NotFoundError {
151
+ constructor(data = {}) {
152
+ super({ message: data.message || "Device authorization not found", details: data.details });
153
+ this.name = "DeviceAuthNotFoundError";
154
+ }
155
+ };
156
+ var DeviceAuthExpiredError = class extends ValidationError {
157
+ constructor(data = {}) {
158
+ super({
159
+ message: data.message || "This device code has expired. Start again on the other device.",
160
+ details: data.details
161
+ });
162
+ this.name = "DeviceAuthExpiredError";
163
+ }
164
+ };
165
+ var DeviceAuthAlreadyHandledError = class extends ConflictError {
166
+ constructor(data = {}) {
167
+ super({
168
+ message: data.message || "This device request has already been answered",
169
+ details: data.details
170
+ });
171
+ this.name = "DeviceAuthAlreadyHandledError";
172
+ }
173
+ };
174
+ var DeviceAuthDeniedError = class extends ForbiddenError {
175
+ constructor(data = {}) {
176
+ super({
177
+ message: data.message || "This device request was denied",
178
+ details: data.details
179
+ });
180
+ this.name = "DeviceAuthDeniedError";
181
+ }
182
+ };
140
183
  var NonceKeyBindingError = class extends ValidationError {
141
184
  constructor(data = {}) {
142
185
  super({
@@ -155,6 +198,42 @@ var NativeSignInUnsupportedError = class extends ValidationError {
155
198
  this.name = "NativeSignInUnsupportedError";
156
199
  }
157
200
  };
201
+ var InvalidSignupLinkError = class extends ValidationError {
202
+ constructor(data = {}) {
203
+ super({
204
+ message: data.message || "This signup link is no longer valid. Request a new one.",
205
+ details: data.details
206
+ });
207
+ this.name = "InvalidSignupLinkError";
208
+ }
209
+ };
210
+ var InvalidSignupSetupSessionError = class extends UnauthorizedError {
211
+ constructor(data = {}) {
212
+ super({
213
+ message: data.message || "Password setup session is invalid or has expired. Start the signup again.",
214
+ details: data.details
215
+ });
216
+ this.name = "InvalidSignupSetupSessionError";
217
+ }
218
+ };
219
+ var PasswordResetLinkError = class extends UnauthorizedError {
220
+ constructor(data = {}) {
221
+ super({
222
+ message: data.message || "This password reset link is no longer valid. Request a new one.",
223
+ details: data.details
224
+ });
225
+ this.name = "PasswordResetLinkError";
226
+ }
227
+ };
228
+ var PasswordResetSessionError = class extends UnauthorizedError {
229
+ constructor(data = {}) {
230
+ super({
231
+ message: data.message || "Password reset session is invalid or has expired. Request a new link.",
232
+ details: data.details
233
+ });
234
+ this.name = "PasswordResetSessionError";
235
+ }
236
+ };
158
237
  var UnverifiedEmailLinkError = class extends ValidationError {
159
238
  constructor(data = {}) {
160
239
  super({
@@ -222,6 +301,110 @@ var InsufficientRoleError = class extends ForbiddenError {
222
301
  this.name = "InsufficientRoleError";
223
302
  }
224
303
  };
304
+ var PasskeyChallengeError = class extends UnauthorizedError {
305
+ constructor(data = {}) {
306
+ super({
307
+ message: data.message || "This passkey challenge is no longer valid. Try again.",
308
+ details: data.details
309
+ });
310
+ this.name = "PasskeyChallengeError";
311
+ }
312
+ };
313
+ var PasskeyVerificationError = class extends UnauthorizedError {
314
+ constructor(data = {}) {
315
+ super({
316
+ message: data.message || "Passkey verification failed.",
317
+ details: data.details
318
+ });
319
+ this.name = "PasskeyVerificationError";
320
+ }
321
+ };
322
+ var PasskeyNotFoundError = class extends NotFoundError {
323
+ constructor(data = {}) {
324
+ super({
325
+ message: data.message || "Passkey not found",
326
+ details: data.details
327
+ });
328
+ this.name = "PasskeyNotFoundError";
329
+ }
330
+ };
331
+ var PasskeyAlreadyRegisteredError = class extends ConflictError {
332
+ constructor(data = {}) {
333
+ super({
334
+ message: data.message || "This passkey is already registered",
335
+ details: data.details
336
+ });
337
+ this.name = "PasskeyAlreadyRegisteredError";
338
+ }
339
+ };
340
+ var RecentAuthenticationRequiredError = class extends ForbiddenError {
341
+ code = "RECENT_AUTH_REQUIRED";
342
+ constructor(data = {}) {
343
+ super({
344
+ message: data.message || "Confirm it is you before changing passkeys. Sign in again or send your current password.",
345
+ details: data.details
346
+ });
347
+ this.name = "RecentAuthenticationRequiredError";
348
+ }
349
+ };
350
+ var LastRecoveryCredentialError = class extends ConflictError {
351
+ code = "LAST_RECOVERY_CREDENTIAL";
352
+ constructor(data = {}) {
353
+ super({
354
+ message: data.message || "This is the only way you can sign in. Set a password or link a social account before removing it.",
355
+ details: data.details
356
+ });
357
+ this.name = "LastRecoveryCredentialError";
358
+ }
359
+ };
360
+ var PasskeyConfigError = class extends HttpError {
361
+ constructor(data) {
362
+ super({
363
+ message: data.message,
364
+ statusCode: 500,
365
+ details: data.details
366
+ });
367
+ this.name = "PasskeyConfigError";
368
+ }
369
+ };
370
+ var OAuth2UnknownClientError = class extends ValidationError {
371
+ constructor(data = {}) {
372
+ super({
373
+ message: data.message || "Unknown OAuth client",
374
+ details: { error: "unknown_client", ...data.details }
375
+ });
376
+ this.name = "OAuth2UnknownClientError";
377
+ }
378
+ };
379
+ var OAuth2RedirectUriMismatchError = class extends ValidationError {
380
+ constructor(data = {}) {
381
+ super({
382
+ message: data.message || "redirect_uri does not match a registered URI for this client",
383
+ details: { error: "redirect_uri_mismatch", ...data.details }
384
+ });
385
+ this.name = "OAuth2RedirectUriMismatchError";
386
+ }
387
+ };
388
+ var OAuth2AuthorizeRedirectError = class extends ValidationError {
389
+ constructor(data) {
390
+ super({
391
+ message: data.message || `OAuth authorize request refused: ${data.error}`,
392
+ details: {
393
+ error: data.error,
394
+ redirectUri: data.redirectUri,
395
+ state: data.state,
396
+ ...data.details
397
+ }
398
+ });
399
+ this.name = "OAuth2AuthorizeRedirectError";
400
+ }
401
+ };
402
+ var OAuth2GrantNotFoundError = class extends NotFoundError {
403
+ constructor(data = {}) {
404
+ super({ message: data.message || "No such connected application", details: data.details });
405
+ this.name = "OAuth2GrantNotFoundError";
406
+ }
407
+ };
225
408
 
226
409
  // src/errors/index.ts
227
410
  var authErrorRegistry = new ErrorRegistry();
@@ -243,15 +426,35 @@ authErrorRegistry.append([
243
426
  InvalidVerificationCodeError,
244
427
  InvalidVerificationTokenError,
245
428
  InvalidKeyFingerprintError,
429
+ KeyAlgorithmMismatchError,
246
430
  NonceKeyBindingError,
247
431
  NativeSignInUnsupportedError,
248
432
  UnverifiedEmailLinkError,
433
+ InvalidSignupLinkError,
434
+ InvalidSignupSetupSessionError,
435
+ PasswordResetLinkError,
436
+ PasswordResetSessionError,
249
437
  KeyNotFoundError,
250
438
  KeyIdAlreadyRegisteredError,
439
+ DeviceAuthNotFoundError,
440
+ DeviceAuthExpiredError,
441
+ DeviceAuthAlreadyHandledError,
442
+ DeviceAuthDeniedError,
251
443
  VerificationTokenPurposeMismatchError,
252
444
  VerificationTokenTargetMismatchError,
253
445
  InsufficientPermissionsError,
254
- InsufficientRoleError
446
+ InsufficientRoleError,
447
+ PasskeyChallengeError,
448
+ PasskeyVerificationError,
449
+ PasskeyNotFoundError,
450
+ PasskeyAlreadyRegisteredError,
451
+ RecentAuthenticationRequiredError,
452
+ LastRecoveryCredentialError,
453
+ PasskeyConfigError,
454
+ OAuth2UnknownClientError,
455
+ OAuth2RedirectUriMismatchError,
456
+ OAuth2AuthorizeRedirectError,
457
+ OAuth2GrantNotFoundError
255
458
  ]);
256
459
 
257
460
  // src/generated/route-map.ts
@@ -259,7 +462,15 @@ var routeMap = {
259
462
  sendVerificationCode: { method: "POST", path: "/_auth/codes" },
260
463
  verifyCode: { method: "POST", path: "/_auth/codes/verify" },
261
464
  register: { method: "POST", path: "/_auth/register" },
465
+ requestSignupLink: { method: "POST", path: "/_auth/signup/email" },
466
+ confirmSignupLink: { method: "POST", path: "/_auth/signup/email/confirm" },
467
+ completeSignup: { method: "POST", path: "/_auth/signup/password" },
262
468
  login: { method: "POST", path: "/_auth/login" },
469
+ startDeviceAuth: { method: "POST", path: "/_auth/device/start" },
470
+ pollDeviceAuth: { method: "POST", path: "/_auth/device/poll" },
471
+ getDeviceAuthInfo: { method: "POST", path: "/_auth/device/info" },
472
+ approveDeviceAuth: { method: "POST", path: "/_auth/device/approve" },
473
+ denyDeviceAuth: { method: "POST", path: "/_auth/device/deny" },
263
474
  logout: { method: "POST", path: "/_auth/logout" },
264
475
  rotateKey: { method: "POST", path: "/_auth/keys/rotate" },
265
476
  listKeys: { method: "POST", path: "/_auth/keys/list" },
@@ -268,6 +479,16 @@ var routeMap = {
268
479
  changePassword: { method: "PUT", path: "/_auth/password" },
269
480
  getAuthSession: { method: "GET", path: "/_auth/session" },
270
481
  issueOneTimeToken: { method: "POST", path: "/_auth/tokens" },
482
+ requestPasswordReset: { method: "POST", path: "/_auth/password/reset" },
483
+ confirmPasswordReset: { method: "POST", path: "/_auth/password/reset/confirm" },
484
+ completePasswordReset: { method: "POST", path: "/_auth/password/reset/complete" },
485
+ passkeyRegisterOptions: { method: "POST", path: "/_auth/passkeys/register/options" },
486
+ passkeyRegisterVerify: { method: "POST", path: "/_auth/passkeys/register/verify" },
487
+ passkeyLoginOptions: { method: "POST", path: "/_auth/passkeys/login/options" },
488
+ passkeyLoginVerify: { method: "POST", path: "/_auth/passkeys/login/verify" },
489
+ listPasskeys: { method: "POST", path: "/_auth/passkeys/list" },
490
+ renamePasskey: { method: "POST", path: "/_auth/passkeys/rename" },
491
+ revokePasskey: { method: "POST", path: "/_auth/passkeys/revoke" },
271
492
  getInvitation: { method: "GET", path: "/_auth/invitations/:token" },
272
493
  acceptInvitation: { method: "POST", path: "/_auth/invitations/accept" },
273
494
  createInvitation: { method: "POST", path: "/_auth/invitations" },
@@ -3075,6 +3296,39 @@ var PlatformSchema = Type.Union(
3075
3296
  KEY_PLATFORM.map((platform) => Type.Literal(platform)),
3076
3297
  { description: "Platform the key lives on" }
3077
3298
  );
3299
+ var PublicKeySchema = Type.String({
3300
+ maxLength: 2048,
3301
+ description: "Client public key, SPKI DER in base64"
3302
+ });
3303
+ var KeyIdSchema = Type.String({
3304
+ maxLength: 64,
3305
+ description: "Key identifier"
3306
+ });
3307
+ var FingerprintSchema = Type.String({
3308
+ maxLength: 128,
3309
+ description: "SHA-256 hex fingerprint of the public key"
3310
+ });
3311
+ var UserCodeSchema = Type.String({
3312
+ minLength: 8,
3313
+ maxLength: 16,
3314
+ description: "Device user code as displayed, e.g. WXYZ-2345. Dashes, spaces and case are ignored."
3315
+ });
3316
+ var DeviceAuthPollResponseSchema = Type.Union([
3317
+ Type.Object({
3318
+ status: Type.Literal("pending"),
3319
+ intervalMillis: Type.Integer({ description: "Milliseconds to wait before polling again" })
3320
+ }),
3321
+ Type.Object({
3322
+ status: Type.Literal("approved"),
3323
+ userId: Type.String(),
3324
+ publicId: Type.String(),
3325
+ email: Type.Optional(Type.String()),
3326
+ phone: Type.Optional(Type.String()),
3327
+ passwordChangeRequired: Type.Boolean()
3328
+ })
3329
+ ], {
3330
+ description: "Pending, or the login the approval produced"
3331
+ });
3078
3332
  var PasswordSchema = Type.String({
3079
3333
  minLength: 8,
3080
3334
  maxLength: 72,