@better-auth/api-key 1.5.0 → 1.5.1-beta.2

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.
@@ -0,0 +1,555 @@
1
+ import * as better_auth0 from "better-auth";
2
+ import { Statements } from "better-auth/plugins/access";
3
+ import { Awaitable, GenericEndpointContext, HookEndpointContext, LiteralString } from "@better-auth/core";
4
+ import { InferOptionSchema } from "better-auth/types";
5
+
6
+ //#region src/schema.d.ts
7
+ declare const apiKeySchema: ({
8
+ defaultRateLimitMax,
9
+ defaultTimeWindow
10
+ }: {
11
+ defaultTimeWindow: number;
12
+ defaultRateLimitMax: number;
13
+ }) => {
14
+ apikey: {
15
+ fields: {
16
+ configId: {
17
+ type: "string";
18
+ required: true;
19
+ defaultValue: string;
20
+ input: false;
21
+ index: true;
22
+ };
23
+ /**
24
+ * The name of the key.
25
+ */
26
+ name: {
27
+ type: "string";
28
+ required: false;
29
+ input: false;
30
+ };
31
+ /**
32
+ * Shows the first few characters of the API key
33
+ * This allows you to show those few characters in the UI to make it easier for users to identify the API key.
34
+ */
35
+ start: {
36
+ type: "string";
37
+ required: false;
38
+ input: false;
39
+ };
40
+ /**
41
+ * The ID of the entity that owns this key (userId or organizationId based on config's `references` setting).
42
+ */
43
+ referenceId: {
44
+ type: "string";
45
+ required: true;
46
+ input: false;
47
+ index: true;
48
+ };
49
+ /**
50
+ * The prefix of the key.
51
+ */
52
+ prefix: {
53
+ type: "string";
54
+ required: false;
55
+ input: false;
56
+ };
57
+ /**
58
+ * The hashed key value.
59
+ */
60
+ key: {
61
+ type: "string";
62
+ required: true;
63
+ input: false;
64
+ index: true;
65
+ };
66
+ /**
67
+ * The interval to refill the key in milliseconds.
68
+ */
69
+ refillInterval: {
70
+ type: "number";
71
+ required: false;
72
+ input: false;
73
+ };
74
+ /**
75
+ * The amount to refill the remaining count of the key.
76
+ */
77
+ refillAmount: {
78
+ type: "number";
79
+ required: false;
80
+ input: false;
81
+ };
82
+ /**
83
+ * The date and time when the key was last refilled.
84
+ */
85
+ lastRefillAt: {
86
+ type: "date";
87
+ required: false;
88
+ input: false;
89
+ };
90
+ /**
91
+ * Whether the key is enabled.
92
+ */
93
+ enabled: {
94
+ type: "boolean";
95
+ required: false;
96
+ input: false;
97
+ defaultValue: true;
98
+ };
99
+ /**
100
+ * Whether the key has rate limiting enabled.
101
+ */
102
+ rateLimitEnabled: {
103
+ type: "boolean";
104
+ required: false;
105
+ input: false;
106
+ defaultValue: true;
107
+ };
108
+ /**
109
+ * The time window in milliseconds for the rate limit.
110
+ */
111
+ rateLimitTimeWindow: {
112
+ type: "number";
113
+ required: false;
114
+ input: false;
115
+ defaultValue: number;
116
+ };
117
+ /**
118
+ * The maximum number of requests allowed within the `rateLimitTimeWindow`.
119
+ */
120
+ rateLimitMax: {
121
+ type: "number";
122
+ required: false;
123
+ input: false;
124
+ defaultValue: number;
125
+ };
126
+ /**
127
+ * The number of requests made within the rate limit time window
128
+ */
129
+ requestCount: {
130
+ type: "number";
131
+ required: false;
132
+ input: false;
133
+ defaultValue: number;
134
+ };
135
+ /**
136
+ * The remaining number of requests before the key is revoked.
137
+ *
138
+ * If this is null, then the key is not revoked.
139
+ *
140
+ * If `refillInterval` & `refillAmount` are provided, than this will refill accordingly.
141
+ */
142
+ remaining: {
143
+ type: "number";
144
+ required: false;
145
+ input: false;
146
+ };
147
+ /**
148
+ * The date and time of the last request made to the key.
149
+ */
150
+ lastRequest: {
151
+ type: "date";
152
+ required: false;
153
+ input: false;
154
+ };
155
+ /**
156
+ * The date and time when the key will expire.
157
+ */
158
+ expiresAt: {
159
+ type: "date";
160
+ required: false;
161
+ input: false;
162
+ };
163
+ /**
164
+ * The date and time when the key was created.
165
+ */
166
+ createdAt: {
167
+ type: "date";
168
+ required: true;
169
+ input: false;
170
+ };
171
+ /**
172
+ * The date and time when the key was last updated.
173
+ */
174
+ updatedAt: {
175
+ type: "date";
176
+ required: true;
177
+ input: false;
178
+ };
179
+ /**
180
+ * The permissions of the key.
181
+ */
182
+ permissions: {
183
+ type: "string";
184
+ required: false;
185
+ input: false;
186
+ };
187
+ /**
188
+ * Any additional metadata you want to store with the key.
189
+ */
190
+ metadata: {
191
+ type: "string";
192
+ required: false;
193
+ input: true;
194
+ transform: {
195
+ input(value: better_auth0.DBPrimitive): string;
196
+ output(value: better_auth0.DBPrimitive): any;
197
+ };
198
+ };
199
+ };
200
+ };
201
+ };
202
+ //#endregion
203
+ //#region src/types.d.ts
204
+ interface ApiKeyOptions {
205
+ schema?: InferOptionSchema<ReturnType<typeof apiKeySchema>> | undefined;
206
+ }
207
+ interface ApiKeyConfigurationOptions {
208
+ /**
209
+ * The name for this set of API key configurations. Must be unique across different configurations.
210
+ */
211
+ configId?: LiteralString | undefined;
212
+ /**
213
+ * The header name to check for API key
214
+ * @default "x-api-key"
215
+ */
216
+ apiKeyHeaders?: (string | string[]) | undefined;
217
+ /**
218
+ * Disable hashing of the API key.
219
+ *
220
+ * ⚠️ Security Warning: It's strongly recommended to not disable hashing.
221
+ * Storing API keys in plaintext makes them vulnerable to database breaches, potentially exposing all your users' API keys.
222
+ *
223
+ * @default false
224
+ */
225
+ disableKeyHashing?: boolean | undefined;
226
+ /**
227
+ * The function to get the API key from the context
228
+ */
229
+ customAPIKeyGetter?: ((ctx: HookEndpointContext) => string | null) | undefined;
230
+ /**
231
+ * A custom function to validate the API key
232
+ */
233
+ customAPIKeyValidator?: ((options: {
234
+ ctx: GenericEndpointContext;
235
+ key: string;
236
+ }) => Awaitable<boolean>) | undefined;
237
+ /**
238
+ * custom key generation function
239
+ */
240
+ customKeyGenerator?: (options: {
241
+ /**
242
+ * The length of the API key to generate
243
+ */
244
+ length: number;
245
+ /**
246
+ * The prefix of the API key to generate
247
+ */
248
+ prefix: string | undefined;
249
+ }) => Awaitable<string>;
250
+ /**
251
+ * The configuration for storing the starting characters of the API key in the database.
252
+ *
253
+ * Useful if you want to display the starting characters of an API key in the UI.
254
+ */
255
+ startingCharactersConfig?: {
256
+ /**
257
+ * Whether to store the starting characters in the database. If false, we will set `start` to `null`.
258
+ *
259
+ * @default true
260
+ */
261
+ shouldStore?: boolean;
262
+ /**
263
+ * The length of the starting characters to store in the database.
264
+ *
265
+ * This includes the prefix length.
266
+ *
267
+ * @default 6
268
+ */
269
+ charactersLength?: number;
270
+ } | undefined;
271
+ /**
272
+ * The length of the API key. Longer is better. Default is 64. (Doesn't include the prefix length)
273
+ * @default 64
274
+ */
275
+ defaultKeyLength?: number | undefined;
276
+ /**
277
+ * The prefix of the API key.
278
+ *
279
+ * Note: We recommend you append an underscore to the prefix to make the prefix more identifiable. (eg `hello_`)
280
+ */
281
+ defaultPrefix?: string | undefined;
282
+ /**
283
+ * The maximum length of the prefix.
284
+ *
285
+ * @default 32
286
+ */
287
+ maximumPrefixLength?: number | undefined;
288
+ /**
289
+ * Whether to require a name for the API key.
290
+ *
291
+ * @default false
292
+ */
293
+ requireName?: boolean | undefined;
294
+ /**
295
+ * The minimum length of the prefix.
296
+ *
297
+ * @default 1
298
+ */
299
+ minimumPrefixLength?: number | undefined;
300
+ /**
301
+ * The maximum length of the name.
302
+ *
303
+ * @default 32
304
+ */
305
+ maximumNameLength?: number | undefined;
306
+ /**
307
+ * The minimum length of the name.
308
+ *
309
+ * @default 1
310
+ */
311
+ minimumNameLength?: number | undefined;
312
+ /**
313
+ * Whether to enable metadata for an API key.
314
+ *
315
+ * @default false
316
+ */
317
+ enableMetadata?: boolean | undefined;
318
+ /**
319
+ * Customize the key expiration.
320
+ */
321
+ keyExpiration?: {
322
+ /**
323
+ * The default expires time in milliseconds.
324
+ *
325
+ * If `null`, then there will be no expiration time.
326
+ *
327
+ * @default null
328
+ */
329
+ defaultExpiresIn?: number | null;
330
+ /**
331
+ * Whether to disable the expires time passed from the client.
332
+ *
333
+ * If `true`, the expires time will be based on the default values.
334
+ *
335
+ * @default false
336
+ */
337
+ disableCustomExpiresTime?: boolean;
338
+ /**
339
+ * The minimum expiresIn value allowed to be set from the client. in days.
340
+ *
341
+ * @default 1
342
+ */
343
+ minExpiresIn?: number;
344
+ /**
345
+ * The maximum expiresIn value allowed to be set from the client. in days.
346
+ *
347
+ * @default 365
348
+ */
349
+ maxExpiresIn?: number;
350
+ } | undefined;
351
+ /**
352
+ * Default rate limiting options.
353
+ */
354
+ rateLimit?: {
355
+ /**
356
+ * Whether to enable rate limiting.
357
+ *
358
+ * @default true
359
+ */
360
+ enabled?: boolean;
361
+ /**
362
+ * The duration in milliseconds where each request is counted.
363
+ *
364
+ * Once the `maxRequests` is reached, the request will be rejected until the `timeWindow` has passed, at which point the `timeWindow` will be reset.
365
+ *
366
+ * @default 1000 * 60 * 60 * 24 // 1 day
367
+ */
368
+ timeWindow?: number;
369
+ /**
370
+ * Maximum amount of requests allowed within a window
371
+ *
372
+ * Once the `maxRequests` is reached, the request will be rejected until the `timeWindow` has passed, at which point the `timeWindow` will be reset.
373
+ *
374
+ * @default 10 // 10 requests per day
375
+ */
376
+ maxRequests?: number;
377
+ } | undefined;
378
+ /**
379
+ * An API Key can represent a valid session, so we automatically mock a session for the user if we find a valid API key in the request headers.
380
+ *
381
+ * ⚠︎ This is not recommended for production use, as it can lead to security issues.
382
+ * @default false
383
+ */
384
+ enableSessionForAPIKeys?: boolean | undefined;
385
+ /**
386
+ * Permissions for the API key.
387
+ */
388
+ permissions?: {
389
+ /**
390
+ * The default permissions for the API key.
391
+ */
392
+ defaultPermissions?: Statements | ((referenceId: string, ctx: GenericEndpointContext) => Awaitable<Statements>);
393
+ } | undefined;
394
+ /**
395
+ * Storage backend for API keys.
396
+ *
397
+ * - `"database"`: Store API keys in the database adapter (default)
398
+ * - `"secondary-storage"`: Store API keys in the configured secondary storage (e.g., Redis)
399
+ *
400
+ * @default "database"
401
+ */
402
+ storage?: "database" | "secondary-storage" | undefined;
403
+ /**
404
+ * When `storage` is `"secondary-storage"`, enable fallback to database if key is not found in secondary storage.
405
+ *
406
+ * Useful for gradual migration from database to secondary storage.
407
+ *
408
+ * @default false
409
+ */
410
+ fallbackToDatabase?: boolean | undefined;
411
+ /**
412
+ * Custom storage methods for API keys.
413
+ *
414
+ * If provided, these methods will be used instead of `ctx.context.secondaryStorage`.
415
+ * Custom methods take precedence over global secondary storage.
416
+ *
417
+ * Useful when you want to use a different storage backend specifically for API keys,
418
+ * or when you need custom logic for storage operations.
419
+ */
420
+ customStorage?: {
421
+ /**
422
+ * Get a value from storage
423
+ */
424
+ get: (key: string) => Awaitable<unknown>;
425
+ /**
426
+ * Set a value in storage
427
+ */
428
+ set: (key: string, value: string, ttl?: number | undefined) => Awaitable<void | null | unknown>;
429
+ /**
430
+ * Delete a value from storage
431
+ */
432
+ delete: (key: string) => Awaitable<void | null | string>;
433
+ } | undefined;
434
+ /**
435
+ * Defer non-critical updates (rate limiting counters, timestamps, remaining count)
436
+ * to run after the response is sent using the global `advanced.backgroundTasks` handler.
437
+ *
438
+ * Requires `advanced.backgroundTasks.handler` to be configured in the main auth options.
439
+ *
440
+ * ⚠️ Warning: Enabling this introduces eventual consistency where the response
441
+ * returns optimistic data before the database is updated. If the deferred update
442
+ * fails, the database will have stale values. Only enable if your application
443
+ * can tolerate this trade-off for improved latency.
444
+ *
445
+ * @default false
446
+ */
447
+ deferUpdates?: boolean | undefined;
448
+ /**
449
+ * What the API key references. This determines ownership over the API key.
450
+ *
451
+ * @default "user"
452
+ */
453
+ references?: "user" | "organization" | undefined;
454
+ }
455
+ type ApiKey = {
456
+ /**
457
+ * ID
458
+ */
459
+ id: string;
460
+ /**
461
+ * The configuration ID this key belongs to.
462
+ * Use this to look up the configuration to determine the reference type (user vs organization).
463
+ */
464
+ configId: string;
465
+ /**
466
+ * The name of the key
467
+ */
468
+ name: string | null;
469
+ /**
470
+ * Shows the first few characters of the API key, including the prefix.
471
+ * This allows you to show those few characters in the UI to make it easier for users to identify the API key.
472
+ */
473
+ start: string | null;
474
+ /**
475
+ * The API Key prefix. Stored as plain text.
476
+ */
477
+ prefix: string | null;
478
+ /**
479
+ * The hashed API key value
480
+ */
481
+ key: string;
482
+ /**
483
+ * The ID of the entity that owns this key (userId or organizationId based on config's `references` setting)
484
+ */
485
+ referenceId: string;
486
+ /**
487
+ * The interval in milliseconds between refills of the `remaining` count
488
+ *
489
+ * @example 3600000 // refill every hour (3600000ms = 1h)
490
+ */
491
+ refillInterval: number | null;
492
+ /**
493
+ * The amount to refill
494
+ */
495
+ refillAmount: number | null;
496
+ /**
497
+ * The last refill date
498
+ */
499
+ lastRefillAt: Date | null;
500
+ /**
501
+ * Sets if key is enabled or disabled
502
+ *
503
+ * @default true
504
+ */
505
+ enabled: boolean;
506
+ /**
507
+ * Whether the key has rate limiting enabled.
508
+ */
509
+ rateLimitEnabled: boolean;
510
+ /**
511
+ * The duration in milliseconds
512
+ */
513
+ rateLimitTimeWindow: number | null;
514
+ /**
515
+ * Maximum amount of requests allowed within a window
516
+ */
517
+ rateLimitMax: number | null;
518
+ /**
519
+ * The number of requests made within the rate limit time window
520
+ */
521
+ requestCount: number;
522
+ /**
523
+ * Remaining requests (every time API key is used this should updated and should be updated on refill as well)
524
+ */
525
+ remaining: number | null;
526
+ /**
527
+ * When last request occurred
528
+ */
529
+ lastRequest: Date | null;
530
+ /**
531
+ * Expiry date of a key
532
+ */
533
+ expiresAt: Date | null;
534
+ /**
535
+ * created at
536
+ */
537
+ createdAt: Date;
538
+ /**
539
+ * updated at
540
+ */
541
+ updatedAt: Date;
542
+ /**
543
+ * Extra metadata about the apiKey
544
+ */
545
+ metadata: Record<string, any> | null;
546
+ /**
547
+ * Permissions for the API key
548
+ */
549
+ permissions?: ({
550
+ [key: string]: string[];
551
+ } | null) | undefined;
552
+ };
553
+ //#endregion
554
+ export { ApiKeyConfigurationOptions as n, ApiKeyOptions as r, ApiKey as t };
555
+ //# sourceMappingURL=types-CCe5L05Y.d.mts.map