@draftlab/auth 0.0.3 → 0.1.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.
Files changed (78) hide show
  1. package/dist/allow.d.ts +58 -1
  2. package/dist/allow.js +61 -2
  3. package/dist/client.d.ts +2 -3
  4. package/dist/client.js +2 -2
  5. package/dist/core.d.ts +128 -8
  6. package/dist/core.js +496 -12
  7. package/dist/error.d.ts +242 -1
  8. package/dist/error.js +235 -1
  9. package/dist/index.d.ts +1 -8
  10. package/dist/index.js +1 -12
  11. package/dist/keys.d.ts +1 -1
  12. package/dist/keys.js +138 -3
  13. package/dist/pkce.js +160 -1
  14. package/dist/provider/code.d.ts +227 -3
  15. package/dist/provider/code.js +27 -14
  16. package/dist/provider/facebook.d.ts +2 -3
  17. package/dist/provider/facebook.js +1 -5
  18. package/dist/provider/github.d.ts +2 -3
  19. package/dist/provider/github.js +1 -5
  20. package/dist/provider/google.d.ts +2 -3
  21. package/dist/provider/google.js +1 -5
  22. package/dist/provider/oauth2.d.ts +175 -3
  23. package/dist/provider/oauth2.js +153 -5
  24. package/dist/provider/password.d.ts +384 -3
  25. package/dist/provider/password.js +4 -4
  26. package/dist/provider/provider.d.ts +226 -2
  27. package/dist/random.js +85 -1
  28. package/dist/storage/memory.d.ts +2 -2
  29. package/dist/storage/memory.js +1 -1
  30. package/dist/storage/storage.d.ts +161 -1
  31. package/dist/storage/storage.js +60 -1
  32. package/dist/storage/turso.d.ts +1 -1
  33. package/dist/storage/turso.js +1 -1
  34. package/dist/storage/unstorage.d.ts +2 -2
  35. package/dist/storage/unstorage.js +2 -2
  36. package/dist/subject.d.ts +61 -2
  37. package/dist/themes/theme.d.ts +208 -1
  38. package/dist/themes/theme.js +118 -1
  39. package/dist/ui/base.d.ts +22 -35
  40. package/dist/ui/base.js +388 -3
  41. package/dist/ui/code.d.ts +22 -137
  42. package/dist/ui/code.js +199 -161
  43. package/dist/ui/form.d.ts +8 -6
  44. package/dist/ui/form.js +57 -1
  45. package/dist/ui/icon.d.ts +7 -84
  46. package/dist/ui/icon.js +69 -2
  47. package/dist/ui/password.d.ts +30 -37
  48. package/dist/ui/password.js +340 -237
  49. package/dist/ui/select.d.ts +19 -218
  50. package/dist/ui/select.js +91 -4
  51. package/dist/util.d.ts +71 -1
  52. package/dist/util.js +106 -1
  53. package/package.json +5 -3
  54. package/dist/allow-CixonwTW.d.ts +0 -59
  55. package/dist/allow-DX5cehSc.js +0 -63
  56. package/dist/base-DRutbxgL.js +0 -422
  57. package/dist/code-DJxdFR7p.d.ts +0 -212
  58. package/dist/core-BZHEAefX.d.ts +0 -129
  59. package/dist/core-CDM5o4rs.js +0 -498
  60. package/dist/error-CWAdNAzm.d.ts +0 -243
  61. package/dist/error-DgAKK7b2.js +0 -237
  62. package/dist/form-6XKM_cOk.js +0 -61
  63. package/dist/icon-Ci5uqGB_.js +0 -192
  64. package/dist/keys-EEfxEGfO.js +0 -140
  65. package/dist/oauth2-B7-6Z7Lc.js +0 -155
  66. package/dist/oauth2-CXHukHf2.d.ts +0 -176
  67. package/dist/password-C4KLmO0O.d.ts +0 -385
  68. package/dist/pkce-276Za_rZ.js +0 -162
  69. package/dist/provider-tndlqCzp.d.ts +0 -227
  70. package/dist/random-SXMYlaVr.js +0 -87
  71. package/dist/select-BjySLL8I.js +0 -280
  72. package/dist/storage-BEaqEPNQ.js +0 -62
  73. package/dist/storage-CxKerLlc.d.ts +0 -162
  74. package/dist/subject-DMIMVtaT.d.ts +0 -62
  75. package/dist/theme-C9by7VXf.d.ts +0 -209
  76. package/dist/theme-CswaLtbW.js +0 -120
  77. package/dist/util-CSdHUFOo.js +0 -108
  78. package/dist/util-DbSKG1Xm.d.ts +0 -72
@@ -1,4 +1,385 @@
1
- import "../storage-CxKerLlc.js";
2
- import "../provider-tndlqCzp.js";
3
- import { PBKDF2Hasher, PasswordChangeError, PasswordChangeState, PasswordConfig, PasswordHasher, PasswordLoginError, PasswordProvider, PasswordRegisterError, PasswordRegisterState, PasswordUserData, ScryptHasher } from "../password-C4KLmO0O.js";
1
+ import { Provider } from "./provider.js";
2
+ import { StandardSchemaV1 } from "@standard-schema/spec";
3
+
4
+ //#region src/provider/password.d.ts
5
+
6
+ /**
7
+ * Password-based authentication provider for Draft Auth.
8
+ * Supports user registration, login, and password changes with email verification.
9
+ *
10
+ * ## Quick Setup
11
+ *
12
+ * ```ts
13
+ * import { PasswordUI } from "@draftlab/auth/ui/password"
14
+ * import { PasswordProvider } from "@draftlab/auth/provider/password"
15
+ *
16
+ * export default issuer({
17
+ * providers: {
18
+ * password: PasswordProvider(
19
+ * PasswordUI({
20
+ * copy: {
21
+ * error_email_taken: "This email is already taken."
22
+ * },
23
+ * sendCode: async (email, code) => {
24
+ * await sendEmail(email, `Your verification code: ${code}`)
25
+ * }
26
+ * })
27
+ * )
28
+ * }
29
+ * })
30
+ * ```
31
+ *
32
+ * ## Custom UI Implementation
33
+ *
34
+ * For full control over the user interface, implement the handlers directly:
35
+ *
36
+ * ```ts
37
+ * PasswordProvider({
38
+ * login: async (req, form, error) => {
39
+ * return new Response(renderLoginPage(form, error))
40
+ * },
41
+ * register: async (req, state, form, error) => {
42
+ * return new Response(renderRegisterPage(state, form, error))
43
+ * },
44
+ * change: async (req, state, form, error) => {
45
+ * return new Response(renderChangePage(state, form, error))
46
+ * },
47
+ * sendCode: async (email, code) => {
48
+ * await yourEmailService.send(email, code)
49
+ * }
50
+ * })
51
+ * ```
52
+ *
53
+ * ## Features
54
+ *
55
+ * - **Email verification**: Secure registration with email confirmation codes
56
+ * - **Password hashing**: Built-in Scrypt and PBKDF2 support with secure defaults
57
+ * - **Password validation**: Configurable password strength requirements
58
+ * - **Password reset**: Secure password change flow with email verification
59
+ * - **Session management**: Automatic invalidation on password changes
60
+ *
61
+ * @packageDocumentation
62
+ */
63
+ /**
64
+ * Password hashing interface for secure password storage.
65
+ * Implement this interface to use custom password hashing algorithms.
66
+ *
67
+ * @template T - The hash storage format (usually an object with hash, salt, and params)
68
+ * @internal
69
+ */
70
+ interface PasswordHasher<T> {
71
+ /**
72
+ * Hashes a plaintext password for secure storage.
73
+ *
74
+ * @param password - The plaintext password to hash
75
+ * @returns Promise resolving to the hash data structure
76
+ */
77
+ hash(password: string): Promise<T>;
78
+ /**
79
+ * Verifies a plaintext password against a stored hash.
80
+ *
81
+ * @param password - The plaintext password to verify
82
+ * @param compare - The stored hash data to compare against
83
+ * @returns Promise resolving to true if password matches
84
+ */
85
+ verify(password: string, compare: T): Promise<boolean>;
86
+ }
87
+ /**
88
+ * Configuration for the password authentication provider.
89
+ */
90
+ interface PasswordConfig {
91
+ /**
92
+ * Length of verification codes sent to users.
93
+ * @internal
94
+ * @default 6
95
+ */
96
+ readonly length?: number;
97
+ /**
98
+ * Password hashing implementation to use.
99
+ * @internal
100
+ * @default ScryptHasher()
101
+ */
102
+ readonly hasher?: PasswordHasher<unknown>;
103
+ /**
104
+ * Request handler for rendering the login screen.
105
+ * Receives the request, optional form data, and any login errors.
106
+ *
107
+ * @param req - The HTTP request object
108
+ * @param form - Form data from POST requests (if any)
109
+ * @param error - Login error to display (if any)
110
+ * @returns Promise resolving to the login page response
111
+ *
112
+ * @example
113
+ * ```ts
114
+ * login: async (req, form, error) => {
115
+ * const html = renderLoginPage({
116
+ * email: form?.get('email'),
117
+ * error: error?.type
118
+ * })
119
+ * return new Response(html, {
120
+ * headers: { 'Content-Type': 'text/html' }
121
+ * })
122
+ * }
123
+ * ```
124
+ */
125
+ login: (req: Request, form?: FormData, error?: PasswordLoginError) => Promise<Response>;
126
+ /**
127
+ * Request handler for rendering the registration screen.
128
+ * Handles both initial registration form and email verification.
129
+ *
130
+ * @param req - The HTTP request object
131
+ * @param state - Current registration state (start or code verification)
132
+ * @param form - Form data from POST requests (if any)
133
+ * @param error - Registration error to display (if any)
134
+ * @returns Promise resolving to the registration page response
135
+ *
136
+ * @example
137
+ * ```ts
138
+ * register: async (req, state, form, error) => {
139
+ * if (state.type === 'start') {
140
+ * return new Response(renderRegistrationForm(error))
141
+ * } else {
142
+ * return new Response(renderCodeVerification(state.email, error))
143
+ * }
144
+ * }
145
+ * ```
146
+ */
147
+ register: (req: Request, state: PasswordRegisterState, form?: FormData, error?: PasswordRegisterError) => Promise<Response>;
148
+ /**
149
+ * Request handler for rendering the password change screen.
150
+ * Handles email entry, code verification, and password update steps.
151
+ *
152
+ * @param req - The HTTP request object
153
+ * @param state - Current password change state
154
+ * @param form - Form data from POST requests (if any)
155
+ * @param error - Password change error to display (if any)
156
+ * @returns Promise resolving to the password change page response
157
+ *
158
+ * @example
159
+ * ```ts
160
+ * change: async (req, state, form, error) => {
161
+ * switch (state.type) {
162
+ * case 'start':
163
+ * return new Response(renderEmailForm(error))
164
+ * case 'code':
165
+ * return new Response(renderCodeForm(state.email, error))
166
+ * case 'update':
167
+ * return new Response(renderPasswordForm(error))
168
+ * }
169
+ * }
170
+ * ```
171
+ */
172
+ change: (req: Request, state: PasswordChangeState, form?: FormData, error?: PasswordChangeError) => Promise<Response>;
173
+ /**
174
+ * Callback for sending verification codes to users via email.
175
+ * Implement this to integrate with your email service provider.
176
+ *
177
+ * @param email - The recipient's email address
178
+ * @param code - The verification code to send
179
+ * @returns Promise that resolves when email is sent
180
+ *
181
+ * @example
182
+ * ```ts
183
+ * sendCode: async (email, code) => {
184
+ * await emailService.send({
185
+ * to: email,
186
+ * subject: 'Your verification code',
187
+ * text: `Your verification code is: ${code}`
188
+ * })
189
+ * }
190
+ * ```
191
+ */
192
+ sendCode: (email: string, code: string) => Promise<void>;
193
+ /**
194
+ * Optional password validation function or schema.
195
+ * Can be either a validation function or a standard-schema validator.
196
+ *
197
+ * @param password - The password to validate
198
+ * @returns Error message if invalid, undefined if valid
199
+ *
200
+ * @example
201
+ * ```ts
202
+ * // Function-based validation
203
+ * validatePassword: (password) => {
204
+ * if (password.length < 8) return "Password must be at least 8 characters"
205
+ * if (!/[A-Z]/.test(password)) return "Password must contain uppercase letter"
206
+ * return undefined
207
+ * }
208
+ *
209
+ * // Schema-based validation
210
+ * validatePassword: pipe(
211
+ * string(),
212
+ * minLength(8, "Password must be at least 8 characters"),
213
+ * regex(/[A-Z]/, "Password must contain uppercase letter")
214
+ * )
215
+ * ```
216
+ */
217
+ readonly validatePassword?: StandardSchemaV1 | ((password: string) => Promise<string | undefined> | string | undefined);
218
+ }
219
+ /**
220
+ * Registration flow states that determine which UI to show.
221
+ * The registration process moves through these states sequentially.
222
+ */
223
+ type PasswordRegisterState = {
224
+ /** Initial state: user enters email and password */
225
+ readonly type: "start";
226
+ } | {
227
+ /** Code verification state: user enters emailed verification code */
228
+ readonly type: "code";
229
+ /** The verification code sent to the user */
230
+ readonly code: string;
231
+ /** The user's email address */
232
+ readonly email: string;
233
+ /** The hashed password (ready for storage) */
234
+ readonly password: unknown;
235
+ };
236
+ /**
237
+ * Possible errors during user registration.
238
+ */
239
+ type PasswordRegisterError = {
240
+ /** The verification code entered is incorrect */
241
+ readonly type: "invalid_code";
242
+ } | {
243
+ /** The email address is already registered */
244
+ readonly type: "email_taken";
245
+ } | {
246
+ /** The email address format is invalid */
247
+ readonly type: "invalid_email";
248
+ } | {
249
+ /** The password does not meet requirements */
250
+ readonly type: "invalid_password";
251
+ } | {
252
+ /** Password and confirmation password don't match */
253
+ readonly type: "password_mismatch";
254
+ } | {
255
+ /** Custom validation error from validatePassword callback */
256
+ readonly type: "validation_error";
257
+ readonly message?: string;
258
+ };
259
+ /**
260
+ * Password change flow states that determine which UI to show.
261
+ */
262
+ type PasswordChangeState = {
263
+ /** Initial state: user enters their email address */
264
+ readonly type: "start";
265
+ /** URL to redirect to after successful password change */
266
+ readonly redirect: string;
267
+ } | {
268
+ /** Code verification state: user enters emailed verification code */
269
+ readonly type: "code";
270
+ /** The verification code sent to the user */
271
+ readonly code: string;
272
+ /** The user's email address */
273
+ readonly email: string;
274
+ /** URL to redirect to after completion */
275
+ readonly redirect: string;
276
+ } | {
277
+ /** Password update state: user enters new password */
278
+ readonly type: "update";
279
+ /** URL to redirect to after completion */
280
+ readonly redirect: string;
281
+ /** The verified email address */
282
+ readonly email: string;
283
+ };
284
+ /**
285
+ * Possible errors during password changes.
286
+ */
287
+ type PasswordChangeError = {
288
+ /** The email address format is invalid */
289
+ readonly type: "invalid_email";
290
+ } | {
291
+ /** The verification code entered is incorrect */
292
+ readonly type: "invalid_code";
293
+ } | {
294
+ /** The new password does not meet requirements */
295
+ readonly type: "invalid_password";
296
+ } | {
297
+ /** New password and confirmation don't match */
298
+ readonly type: "password_mismatch";
299
+ } | {
300
+ /** Custom validation error from validatePassword callback */
301
+ readonly type: "validation_error";
302
+ readonly message: string;
303
+ };
304
+ /**
305
+ * Possible errors during login attempts.
306
+ */
307
+ type PasswordLoginError = {
308
+ /** The email address format is invalid */
309
+ readonly type: "invalid_email";
310
+ } | {
311
+ /** The password is incorrect or email not found */
312
+ readonly type: "invalid_password";
313
+ };
314
+ /**
315
+ * User data returned by successful password authentication.
316
+ */
317
+ interface PasswordUserData {
318
+ /** The authenticated user's email address */
319
+ readonly email: string;
320
+ }
321
+ /**
322
+ * Creates a password authentication provider with email verification.
323
+ * Implements secure registration, login, and password change flows.
324
+ *
325
+ * @param config - Provider configuration including UI handlers and email service
326
+ * @returns Provider instance implementing password authentication
327
+ *
328
+ * @example
329
+ * ```ts
330
+ * const provider = PasswordProvider({
331
+ * login: async (req, form, error) => {
332
+ * return new Response(renderLogin(form, error))
333
+ * },
334
+ * register: async (req, state, form, error) => {
335
+ * return new Response(renderRegister(state, form, error))
336
+ * },
337
+ * change: async (req, state, form, error) => {
338
+ * return new Response(renderChange(state, form, error))
339
+ * },
340
+ * sendCode: async (email, code) => {
341
+ * await emailService.send(email, `Code: ${code}`)
342
+ * },
343
+ * validatePassword: (pwd) => {
344
+ * return pwd.length >= 8 ? undefined : "Too short"
345
+ * }
346
+ * })
347
+ * ```
348
+ */
349
+ declare const PasswordProvider: (config: PasswordConfig) => Provider<PasswordUserData>;
350
+ /**
351
+ * PBKDF2 password hasher with configurable iterations.
352
+ * Good choice for compatibility but slower than Scrypt.
353
+ *
354
+ * @param opts - Configuration options
355
+ * @returns Password hasher using PBKDF2 algorithm
356
+ * @internal
357
+ */
358
+ declare const PBKDF2Hasher: (opts?: {
359
+ iterations?: number;
360
+ }) => PasswordHasher<{
361
+ hash: string;
362
+ salt: string;
363
+ iterations: number;
364
+ }>;
365
+ /**
366
+ * Scrypt password hasher with secure defaults.
367
+ * Recommended choice for new applications due to memory-hard properties.
368
+ *
369
+ * @param opts - Scrypt parameters (N, r, p)
370
+ * @returns Password hasher using Scrypt algorithm
371
+ * @internal
372
+ */
373
+ declare const ScryptHasher: (opts?: {
374
+ N?: number;
375
+ r?: number;
376
+ p?: number;
377
+ }) => PasswordHasher<{
378
+ hash: string;
379
+ salt: string;
380
+ N: number;
381
+ r: number;
382
+ p: number;
383
+ }>;
384
+ //#endregion
4
385
  export { PBKDF2Hasher, PasswordChangeError, PasswordChangeState, PasswordConfig, PasswordHasher, PasswordLoginError, PasswordProvider, PasswordRegisterError, PasswordRegisterState, PasswordUserData, ScryptHasher };
@@ -1,7 +1,7 @@
1
- import { getRelativeUrl } from "../util-CSdHUFOo.js";
2
- import { UnknownStateError } from "../error-DgAKK7b2.js";
3
- import { generateUnbiasedDigits, timingSafeCompare } from "../random-SXMYlaVr.js";
4
- import { Storage } from "../storage-BEaqEPNQ.js";
1
+ import { getRelativeUrl } from "../util.js";
2
+ import { UnknownStateError } from "../error.js";
3
+ import { generateUnbiasedDigits, timingSafeCompare } from "../random.js";
4
+ import { Storage } from "../storage/storage.js";
5
5
  import * as jose from "jose";
6
6
  import { randomBytes, scrypt, timingSafeEqual } from "node:crypto";
7
7
  import { TextEncoder } from "node:util";
@@ -1,3 +1,227 @@
1
- import "../storage-CxKerLlc.js";
2
- import { Provider, ProviderError, ProviderOptions, ProviderRoute, ProviderUnknownError } from "../provider-tndlqCzp.js";
1
+ import { StorageAdapter } from "../storage/storage.js";
2
+ import { Router } from "@draftlab/auth-router";
3
+ import { RouterContext } from "@draftlab/auth-router/types";
4
+
5
+ //#region src/provider/provider.d.ts
6
+
7
+ /**
8
+ * OAuth provider system for Draft Auth.
9
+ * Defines the interfaces and utilities for implementing authentication providers
10
+ * that integrate with various OAuth 2.0 services.
11
+ *
12
+ * ## Creating a Provider
13
+ *
14
+ * ```ts
15
+ * export const MyProvider = (config: MyConfig): Provider<MyUserData> => ({
16
+ * type: "my-provider",
17
+ *
18
+ * init(routes, ctx) {
19
+ * routes.get("/authorize", async (c) => {
20
+ * // Redirect to provider's auth URL
21
+ * return c.redirect(authUrl)
22
+ * })
23
+ *
24
+ * routes.get("/callback", async (c) => {
25
+ * // Handle callback and extract user data
26
+ * const userData = await processCallback(c)
27
+ * return await ctx.success(c, userData)
28
+ * })
29
+ * }
30
+ * })
31
+ * ```
32
+ *
33
+ * ## Using Providers
34
+ *
35
+ * ```ts
36
+ * export default issuer({
37
+ * providers: {
38
+ * github: GithubProvider({ ... }),
39
+ * google: GoogleProvider({ ... })
40
+ * }
41
+ * })
42
+ * ```
43
+ */
44
+ /**
45
+ * Router instance used for provider route definitions.
46
+ * Providers use this to register their authorization and callback endpoints.
47
+ */
48
+ type ProviderRoute = Router;
49
+ /**
50
+ * Authentication provider interface that handles OAuth flows.
51
+ * Each provider implements authentication with a specific service (GitHub, Google, etc.).
52
+ *
53
+ * @template Properties - Type of user data returned by successful authentication
54
+ */
55
+ interface Provider<Properties = Record<string, unknown>> {
56
+ /**
57
+ * Unique identifier for this provider type.
58
+ * Used in URLs and provider selection UI.
59
+ *
60
+ * @example "github", "google", "steam"
61
+ */
62
+ readonly type: string;
63
+ /**
64
+ * Initializes the provider by registering required routes.
65
+ * Called during issuer setup to configure authorization and callback endpoints.
66
+ *
67
+ * @param route - Router instance for registering provider endpoints
68
+ * @param options - Provider utilities and configuration
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * init(routes, ctx) {
73
+ * routes.get("/authorize", async (c) => {
74
+ * // Redirect to OAuth provider
75
+ * return c.redirect(buildAuthUrl())
76
+ * })
77
+ *
78
+ * routes.get("/callback", async (c) => {
79
+ * // Process callback and return user data
80
+ * const userData = await handleCallback(c)
81
+ * return await ctx.success(c, userData)
82
+ * })
83
+ * }
84
+ * ```
85
+ */
86
+ init: (route: ProviderRoute, options: ProviderOptions<Properties>) => void;
87
+ }
88
+ /**
89
+ * Utilities and callbacks provided to providers during initialization.
90
+ * Contains methods for state management, user flow completion, and storage access.
91
+ *
92
+ * @template Properties - Type of user data handled by the provider
93
+ */
94
+ interface ProviderOptions<Properties> {
95
+ /**
96
+ * Name of the provider instance as configured in the issuer.
97
+ * Corresponds to the key used in the providers object.
98
+ */
99
+ readonly name: string;
100
+ /**
101
+ * Completes the authentication flow with user data.
102
+ * Called when the provider successfully authenticates a user.
103
+ *
104
+ * @param ctx - Router request context
105
+ * @param properties - User data extracted from the provider
106
+ * @param opts - Optional utilities for session management
107
+ * @returns Response that completes the OAuth flow
108
+ *
109
+ * @example
110
+ * ```ts
111
+ * const userData = { userId: "123", email: "user@example.com" }
112
+ * return await ctx.success(c, userData)
113
+ * ```
114
+ */
115
+ success: (ctx: RouterContext, properties: Properties, opts?: {
116
+ /** Function to invalidate existing user sessions */
117
+ readonly invalidate?: (subject: string) => Promise<void>;
118
+ }) => Promise<Response>;
119
+ /**
120
+ * Forwards a response through the provider context.
121
+ * Used for redirects and custom responses within the OAuth flow.
122
+ *
123
+ * @param ctx - Router request context
124
+ * @param response - Response to forward
125
+ * @returns Forwarded response
126
+ */
127
+ forward: (ctx: RouterContext, response: Response) => Response;
128
+ /**
129
+ * Stores a temporary value with expiration for the current session.
130
+ * Useful for storing OAuth state, PKCE verifiers, and other temporary data.
131
+ *
132
+ * @param ctx - Router request context
133
+ * @param key - Storage key identifier
134
+ * @param maxAge - TTL in seconds
135
+ * @param value - Value to store
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * // Store OAuth state for 10 minutes
140
+ * await ctx.set(c, "oauth_state", 600, { state, redirectUri })
141
+ * ```
142
+ */
143
+ set: <T>(ctx: RouterContext, key: string, maxAge: number, value: T) => Promise<void>;
144
+ /**
145
+ * Retrieves a previously stored temporary value.
146
+ *
147
+ * @param ctx - Router request context
148
+ * @param key - Storage key identifier
149
+ * @returns Promise resolving to the stored value or undefined if not found/expired
150
+ *
151
+ * @example
152
+ * ```ts
153
+ * const oauthState = await ctx.get<OAuthState>(c, "oauth_state")
154
+ * if (!oauthState) {
155
+ * throw new Error("OAuth state expired")
156
+ * }
157
+ * ```
158
+ */
159
+ get: <T>(ctx: RouterContext, key: string) => Promise<T | undefined>;
160
+ /**
161
+ * Removes a stored temporary value.
162
+ *
163
+ * @param ctx - Router request context
164
+ * @param key - Storage key identifier
165
+ *
166
+ * @example
167
+ * ```ts
168
+ * // Clean up OAuth state after use
169
+ * await ctx.unset(c, "oauth_state")
170
+ * ```
171
+ */
172
+ unset: (ctx: RouterContext, key: string) => Promise<void>;
173
+ /**
174
+ * Invalidates all sessions for a given subject (user).
175
+ * Forces logout across all devices and applications.
176
+ *
177
+ * @param subject - Subject identifier to invalidate
178
+ *
179
+ * @example
180
+ * ```ts
181
+ * // Force logout on password change
182
+ * await ctx.invalidate(userId)
183
+ * ```
184
+ */
185
+ invalidate: (subject: string) => Promise<void>;
186
+ /**
187
+ * Storage adapter for persistent data operations.
188
+ * Provides access to the configured storage backend.
189
+ */
190
+ readonly storage: StorageAdapter;
191
+ }
192
+ /**
193
+ * Base error class for provider-related errors.
194
+ * Extend this class to create specific provider error types.
195
+ *
196
+ * @example
197
+ * ```ts
198
+ * export class GitHubApiError extends ProviderError {
199
+ * constructor(message: string, public readonly statusCode: number) {
200
+ * super(message)
201
+ * }
202
+ * }
203
+ * ```
204
+ */
205
+ declare class ProviderError extends Error {
206
+ constructor(message: string);
207
+ }
208
+ /**
209
+ * Error thrown when a provider encounters an unknown or unexpected error.
210
+ * Used as a fallback for unhandled error conditions.
211
+ *
212
+ * @example
213
+ * ```ts
214
+ * catch (error) {
215
+ * if (error instanceof SomeSpecificError) {
216
+ * // Handle specific error
217
+ * } else {
218
+ * throw new ProviderUnknownError(`Unexpected error: ${error}`)
219
+ * }
220
+ * }
221
+ * ```
222
+ */
223
+ declare class ProviderUnknownError extends ProviderError {
224
+ constructor(message?: string);
225
+ }
226
+ //#endregion
3
227
  export { Provider, ProviderError, ProviderOptions, ProviderRoute, ProviderUnknownError };