@guren/server 0.2.0-alpha.7 → 1.0.0-rc.9
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/Application-DtWDHXr1.d.ts +2110 -0
- package/dist/BroadcastManager-AkIWUGJo.d.ts +466 -0
- package/dist/CacheManager-BkvHEOZX.d.ts +244 -0
- package/dist/ConsoleKernel-CqCVrdZs.d.ts +207 -0
- package/dist/EventManager-CmIoLt7r.d.ts +207 -0
- package/dist/Gate-CNkBYf8m.d.ts +268 -0
- package/dist/HealthManager-DUyMIzsZ.d.ts +141 -0
- package/dist/I18nManager-Dtgzsf5n.d.ts +270 -0
- package/dist/LogManager-7mxnkaPM.d.ts +256 -0
- package/dist/MailManager-DpMvYiP9.d.ts +292 -0
- package/dist/Scheduler-BstvSca7.d.ts +469 -0
- package/dist/StorageManager-oZTHqaza.d.ts +337 -0
- package/dist/api-token-JOif2CtG.d.ts +1792 -0
- package/dist/app-key-CsBfRC_Q.d.ts +214 -0
- package/dist/auth/index.d.ts +418 -0
- package/dist/auth/index.js +6742 -0
- package/dist/authorization/index.d.ts +129 -0
- package/dist/authorization/index.js +621 -0
- package/dist/broadcasting/index.d.ts +233 -0
- package/dist/broadcasting/index.js +907 -0
- package/dist/cache/index.d.ts +233 -0
- package/dist/cache/index.js +817 -0
- package/dist/encryption/index.d.ts +222 -0
- package/dist/encryption/index.js +602 -0
- package/dist/events/index.d.ts +155 -0
- package/dist/events/index.js +330 -0
- package/dist/health/index.d.ts +185 -0
- package/dist/health/index.js +379 -0
- package/dist/i18n/index.d.ts +101 -0
- package/dist/i18n/index.js +597 -0
- package/dist/index-9_Jzj5jo.d.ts +7 -0
- package/dist/index.d.ts +2628 -619
- package/dist/index.js +22229 -3116
- package/dist/lambda/index.d.ts +156 -0
- package/dist/lambda/index.js +91 -0
- package/dist/logging/index.d.ts +50 -0
- package/dist/logging/index.js +557 -0
- package/dist/mail/index.d.ts +288 -0
- package/dist/mail/index.js +695 -0
- package/dist/mcp/index.d.ts +139 -0
- package/dist/mcp/index.js +382 -0
- package/dist/notifications/index.d.ts +271 -0
- package/dist/notifications/index.js +741 -0
- package/dist/queue/index.d.ts +423 -0
- package/dist/queue/index.js +958 -0
- package/dist/runtime/index.d.ts +93 -0
- package/dist/runtime/index.js +834 -0
- package/dist/scheduling/index.d.ts +41 -0
- package/dist/scheduling/index.js +836 -0
- package/dist/storage/index.d.ts +196 -0
- package/dist/storage/index.js +832 -0
- package/dist/vite/index.js +203 -3
- package/package.json +93 -6
- package/dist/chunk-FK2XQSBF.js +0 -160
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encryption options.
|
|
3
|
+
*/
|
|
4
|
+
interface EncryptOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Whether to serialize the value before encryption.
|
|
7
|
+
*/
|
|
8
|
+
serialize?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Decryption options.
|
|
12
|
+
*/
|
|
13
|
+
interface DecryptOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Whether to deserialize the value after decryption.
|
|
16
|
+
*/
|
|
17
|
+
deserialize?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Encrypter configuration.
|
|
21
|
+
*/
|
|
22
|
+
interface EncrypterConfig {
|
|
23
|
+
/**
|
|
24
|
+
* Encryption key (base64 encoded, 32 bytes for AES-256).
|
|
25
|
+
*/
|
|
26
|
+
key: string;
|
|
27
|
+
/**
|
|
28
|
+
* Previous encryption keys used for decryption fallback during key rotation.
|
|
29
|
+
*/
|
|
30
|
+
previousKeys?: string[];
|
|
31
|
+
/**
|
|
32
|
+
* Encryption cipher to use.
|
|
33
|
+
*/
|
|
34
|
+
cipher?: 'aes-256-gcm' | 'aes-256-cbc';
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Encrypted payload structure.
|
|
38
|
+
*/
|
|
39
|
+
interface EncryptedPayload {
|
|
40
|
+
/**
|
|
41
|
+
* Initialization vector (base64).
|
|
42
|
+
*/
|
|
43
|
+
iv: string;
|
|
44
|
+
/**
|
|
45
|
+
* Encrypted value (base64).
|
|
46
|
+
*/
|
|
47
|
+
value: string;
|
|
48
|
+
/**
|
|
49
|
+
* Authentication tag for GCM mode (base64).
|
|
50
|
+
*/
|
|
51
|
+
tag?: string;
|
|
52
|
+
/**
|
|
53
|
+
* MAC for CBC mode (hex).
|
|
54
|
+
*/
|
|
55
|
+
mac?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Hash algorithm options.
|
|
59
|
+
*/
|
|
60
|
+
type HashAlgorithm = 'sha256' | 'sha384' | 'sha512' | 'md5' | 'sha1';
|
|
61
|
+
/**
|
|
62
|
+
* HMAC options.
|
|
63
|
+
*/
|
|
64
|
+
interface HmacOptions {
|
|
65
|
+
/**
|
|
66
|
+
* Hash algorithm to use.
|
|
67
|
+
*/
|
|
68
|
+
algorithm?: HashAlgorithm;
|
|
69
|
+
/**
|
|
70
|
+
* Output encoding.
|
|
71
|
+
*/
|
|
72
|
+
encoding?: 'hex' | 'base64';
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Password hash options.
|
|
76
|
+
*/
|
|
77
|
+
interface PasswordHashOptions {
|
|
78
|
+
/**
|
|
79
|
+
* Memory cost (for scrypt/argon2).
|
|
80
|
+
*/
|
|
81
|
+
memory?: number;
|
|
82
|
+
/**
|
|
83
|
+
* CPU cost (for scrypt/argon2).
|
|
84
|
+
*/
|
|
85
|
+
cost?: number;
|
|
86
|
+
/**
|
|
87
|
+
* Salt length in bytes.
|
|
88
|
+
*/
|
|
89
|
+
saltLength?: number;
|
|
90
|
+
/**
|
|
91
|
+
* Key length in bytes.
|
|
92
|
+
*/
|
|
93
|
+
keyLength?: number;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Random string options.
|
|
97
|
+
*/
|
|
98
|
+
interface RandomStringOptions {
|
|
99
|
+
/**
|
|
100
|
+
* Character set to use.
|
|
101
|
+
*/
|
|
102
|
+
charset?: 'alphanumeric' | 'alphabetic' | 'numeric' | 'hex' | 'base64' | 'url-safe';
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Encrypter for secure data encryption using AES.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* const encrypter = new Encrypter({ key: 'base64-encoded-32-byte-key' })
|
|
111
|
+
*
|
|
112
|
+
* // Encrypt
|
|
113
|
+
* const encrypted = encrypter.encrypt({ userId: 123, role: 'admin' })
|
|
114
|
+
*
|
|
115
|
+
* // Decrypt
|
|
116
|
+
* const data = encrypter.decrypt(encrypted)
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
declare class Encrypter {
|
|
120
|
+
/**
|
|
121
|
+
* Encryption key.
|
|
122
|
+
*/
|
|
123
|
+
protected key: Buffer;
|
|
124
|
+
protected previousKeys: Buffer[];
|
|
125
|
+
/**
|
|
126
|
+
* Cipher algorithm.
|
|
127
|
+
*/
|
|
128
|
+
protected cipher: 'aes-256-gcm' | 'aes-256-cbc';
|
|
129
|
+
constructor(config: EncrypterConfig);
|
|
130
|
+
/**
|
|
131
|
+
* Encrypt a value.
|
|
132
|
+
*/
|
|
133
|
+
encrypt(value: unknown, options?: EncryptOptions): string;
|
|
134
|
+
/**
|
|
135
|
+
* Decrypt a value.
|
|
136
|
+
*/
|
|
137
|
+
decrypt<T = unknown>(payload: string, options?: DecryptOptions): T;
|
|
138
|
+
/**
|
|
139
|
+
* Encrypt a string (no serialization).
|
|
140
|
+
*/
|
|
141
|
+
encryptString(value: string): string;
|
|
142
|
+
/**
|
|
143
|
+
* Decrypt a string (no deserialization).
|
|
144
|
+
*/
|
|
145
|
+
decryptString(payload: string): string;
|
|
146
|
+
/**
|
|
147
|
+
* Encrypt using AES-256-GCM.
|
|
148
|
+
*/
|
|
149
|
+
protected encryptGcm(data: string): string;
|
|
150
|
+
/**
|
|
151
|
+
* Decrypt using AES-256-GCM.
|
|
152
|
+
*/
|
|
153
|
+
protected decryptGcm(payload: EncryptedPayload): string;
|
|
154
|
+
/**
|
|
155
|
+
* Encrypt using AES-256-CBC with HMAC.
|
|
156
|
+
*/
|
|
157
|
+
protected encryptCbc(data: string): string;
|
|
158
|
+
/**
|
|
159
|
+
* Decrypt using AES-256-CBC with HMAC verification.
|
|
160
|
+
*/
|
|
161
|
+
protected decryptCbc(payload: EncryptedPayload): string;
|
|
162
|
+
/**
|
|
163
|
+
* Create HMAC for CBC mode.
|
|
164
|
+
*/
|
|
165
|
+
protected createMac(iv: Buffer, encrypted: Buffer, key?: Buffer): string;
|
|
166
|
+
/**
|
|
167
|
+
* Constant-time string comparison.
|
|
168
|
+
*/
|
|
169
|
+
protected secureCompare(a: string, b: string): boolean;
|
|
170
|
+
/**
|
|
171
|
+
* Get the encryption key (base64).
|
|
172
|
+
*/
|
|
173
|
+
getKey(): string;
|
|
174
|
+
protected tryDecryptWithKeys(run: (key: Buffer) => string): string;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Generate a random encryption key.
|
|
178
|
+
*/
|
|
179
|
+
declare function generateKey(): string;
|
|
180
|
+
/**
|
|
181
|
+
* Create an encrypter instance.
|
|
182
|
+
*/
|
|
183
|
+
declare function createEncrypter(config: EncrypterConfig): Encrypter;
|
|
184
|
+
/**
|
|
185
|
+
* Set the global encrypter.
|
|
186
|
+
*/
|
|
187
|
+
declare function setEncrypter(encrypter: Encrypter): void;
|
|
188
|
+
/**
|
|
189
|
+
* Get the global encrypter.
|
|
190
|
+
*/
|
|
191
|
+
declare function getEncrypter(): Encrypter;
|
|
192
|
+
/**
|
|
193
|
+
* Encrypt a value using the global encrypter.
|
|
194
|
+
*/
|
|
195
|
+
declare function encrypt(value: unknown, options?: EncryptOptions): string;
|
|
196
|
+
/**
|
|
197
|
+
* Decrypt a value using the global encrypter.
|
|
198
|
+
*/
|
|
199
|
+
declare function decrypt<T = unknown>(payload: string, options?: DecryptOptions): T;
|
|
200
|
+
|
|
201
|
+
interface AppKeyring {
|
|
202
|
+
current: Buffer;
|
|
203
|
+
previous: Buffer[];
|
|
204
|
+
}
|
|
205
|
+
declare function normalizeAppKey(rawKey: string, envName?: string): string;
|
|
206
|
+
declare function parseAppKey(rawKey: string, envName?: string): Buffer;
|
|
207
|
+
declare function parsePreviousAppKeys(rawKeys: string | undefined, envName?: string): Buffer[];
|
|
208
|
+
declare function getAppKeyringFromEnv(env?: NodeJS.ProcessEnv): AppKeyring;
|
|
209
|
+
declare function deriveAppKey(rootKey: Buffer, purpose: string): Buffer;
|
|
210
|
+
declare function deriveAppKeyring(keyring: AppKeyring, purpose: string): AppKeyring;
|
|
211
|
+
declare function encodeDerivedKey(key: Buffer): string;
|
|
212
|
+
declare function generateAppKey(): string;
|
|
213
|
+
|
|
214
|
+
export { type AppKeyring as A, type DecryptOptions as D, Encrypter as E, type HashAlgorithm as H, type PasswordHashOptions as P, type RandomStringOptions as R, type EncryptOptions as a, type EncryptedPayload as b, type EncrypterConfig as c, type HmacOptions as d, createEncrypter as e, decrypt as f, deriveAppKey as g, deriveAppKeyring as h, encrypt as i, generateAppKey as j, generateKey as k, getAppKeyringFromEnv as l, getEncrypter as m, normalizeAppKey as n, parsePreviousAppKeys as o, parseAppKey as p, encodeDerivedKey as q, setEncrypter as s };
|
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import { g as Authenticatable, G as Guard, U as UserProvider, S as Session, e as AuthCredentials, a7 as PasswordHasher, a8 as PlainObject, a9 as Model } from '../api-token-JOif2CtG.js';
|
|
2
|
+
export { c as API_TOKEN_KEY, b as ApiToken, d as ApiTokenStore, aa as AttachContextOptions, a as AuthContext, A as AuthManager, ab as AuthManagerContract, f as AuthManagerOptions, B as BaseUserProvider, h as BearerTokenMiddlewareOptions, i as CreateApiTokenOptions, j as CreateApiTokenResult, k as GuardContext, l as GuardFactory, M as MemoryApiTokenStore, m as MemoryOAuthStateStore, o as ModelUserProvider, p as OAuthAuthorizeOptions, q as OAuthCallbackPayload, O as OAuthManager, r as OAuthManagerOptions, s as OAuthProviderConfig, t as OAuthProviderFactoryInput, u as OAuthStateConfig, v as OAuthStatePayload, w as OAuthStateStore, x as OAuthTokenResult, y as OAuthUserProfile, P as ProviderFactory, E as buildOAuthAuthorizeUrl, F as buildOAuthRedirectUrl, H as createApiToken, I as createBearerTokenMiddleware, J as createDiscordOAuthProviderConfig, K as createGitHubOAuthProviderConfig, L as createGoogleOAuthProviderConfig, N as createOAuthManager, Q as createOAuthState, T as exchangeOAuthCode, V as fetchOAuthUserProfile, W as getApiToken, X as getApiTokenOrFail, Z as getUserApiTokens, _ as parseApiToken, $ as parseOAuthRedirectUrl, a0 as revokeAllApiTokens, a1 as revokeApiToken, a2 as tokenCan, a3 as tokenCanAll, a4 as tokenCanAny, a5 as verifyApiToken, a6 as verifyOAuthState } from '../api-token-JOif2CtG.js';
|
|
3
|
+
import 'hono';
|
|
4
|
+
|
|
5
|
+
interface SessionGuardOptions {
|
|
6
|
+
provider: UserProvider;
|
|
7
|
+
sessionKey?: string;
|
|
8
|
+
rememberSessionKey?: string;
|
|
9
|
+
session: Session | undefined;
|
|
10
|
+
}
|
|
11
|
+
declare class SessionGuard<User extends Authenticatable = Authenticatable> implements Guard<User> {
|
|
12
|
+
private readonly options;
|
|
13
|
+
private cachedUser;
|
|
14
|
+
constructor(options: SessionGuardOptions);
|
|
15
|
+
private get currentSession();
|
|
16
|
+
private get provider();
|
|
17
|
+
private sessionKey;
|
|
18
|
+
private rememberSessionKey;
|
|
19
|
+
private loadRememberedUser;
|
|
20
|
+
private resolveUser;
|
|
21
|
+
check(): Promise<boolean>;
|
|
22
|
+
guest(): Promise<boolean>;
|
|
23
|
+
user<T = User>(): Promise<T | null>;
|
|
24
|
+
id(): Promise<unknown>;
|
|
25
|
+
private remember;
|
|
26
|
+
login<T = User>(user: T, remember?: boolean): Promise<void>;
|
|
27
|
+
logout(): Promise<void>;
|
|
28
|
+
attempt(credentials: AuthCredentials, remember?: boolean): Promise<boolean>;
|
|
29
|
+
validate(credentials: AuthCredentials): Promise<User | null>;
|
|
30
|
+
session<T extends Session = Session>(): T | undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type Argon2Algorithm = 'argon2id' | 'argon2i' | 'argon2d';
|
|
34
|
+
type SupportedAlgorithm = Argon2Algorithm | 'bcrypt';
|
|
35
|
+
interface BunPasswordHasherOptions {
|
|
36
|
+
/**
|
|
37
|
+
* Hashing algorithm to use. Defaults to Bun's Argon2id implementation.
|
|
38
|
+
*/
|
|
39
|
+
algorithm?: SupportedAlgorithm;
|
|
40
|
+
/** Argon2 memory cost (in kibibytes). */
|
|
41
|
+
memoryCost?: number;
|
|
42
|
+
/** Argon2 time cost (number of iterations). */
|
|
43
|
+
timeCost?: number;
|
|
44
|
+
/** Bcrypt cost factor (log rounds). */
|
|
45
|
+
cost?: number;
|
|
46
|
+
}
|
|
47
|
+
declare class ScryptHasher implements PasswordHasher {
|
|
48
|
+
private readonly algorithm;
|
|
49
|
+
private readonly memoryCost?;
|
|
50
|
+
private readonly timeCost?;
|
|
51
|
+
private readonly cost?;
|
|
52
|
+
constructor(options?: BunPasswordHasherOptions);
|
|
53
|
+
hash(plain: string): Promise<string>;
|
|
54
|
+
verify(hashed: string, plain: string): Promise<boolean>;
|
|
55
|
+
needsRehash(hashed: string): boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
interface NodeHasherOptions {
|
|
59
|
+
/** scrypt cost parameter (N). Defaults to 16384. */
|
|
60
|
+
cost?: number;
|
|
61
|
+
/** scrypt block size (r). Defaults to 8. */
|
|
62
|
+
memory?: number;
|
|
63
|
+
/** Salt length in bytes. Defaults to 16. */
|
|
64
|
+
saltLength?: number;
|
|
65
|
+
/** Derived key length in bytes. Defaults to 64. */
|
|
66
|
+
keyLength?: number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Node.js-compatible password hasher using crypto.scrypt.
|
|
70
|
+
* Use this instead of ScryptHasher when deploying to non-Bun runtimes (e.g. AWS Lambda).
|
|
71
|
+
*/
|
|
72
|
+
declare class NodeHasher implements PasswordHasher {
|
|
73
|
+
private readonly options;
|
|
74
|
+
constructor(options?: NodeHasherOptions);
|
|
75
|
+
hash(plain: string): Promise<string>;
|
|
76
|
+
verify(hashed: string, plain: string): Promise<boolean>;
|
|
77
|
+
needsRehash(hashed: string): boolean;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
declare abstract class AuthenticatableModel<TRecord extends PlainObject = PlainObject> extends Model<TRecord> {
|
|
81
|
+
static readonly createType: PlainObject & {
|
|
82
|
+
password?: string;
|
|
83
|
+
plainPassword?: string;
|
|
84
|
+
};
|
|
85
|
+
protected static passwordField: string;
|
|
86
|
+
protected static passwordHashField: string;
|
|
87
|
+
protected static passwordHasher: PasswordHasher | null;
|
|
88
|
+
protected static resolvePasswordField(): string;
|
|
89
|
+
protected static resolvePasswordHashField(): string;
|
|
90
|
+
protected static resolvePasswordHasher(): PasswordHasher;
|
|
91
|
+
protected static preparePersistencePayload(data: PlainObject): Promise<PlainObject>;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Hash a token using SHA-256 or SHA-512.
|
|
96
|
+
*/
|
|
97
|
+
declare function hashToken(token: string, algorithm?: 'sha256' | 'sha512'): string;
|
|
98
|
+
/**
|
|
99
|
+
* Generate a secure random token.
|
|
100
|
+
*/
|
|
101
|
+
declare function generateToken(length?: number): string;
|
|
102
|
+
/**
|
|
103
|
+
* Generate a random ID (16 bytes = 32 hex chars).
|
|
104
|
+
*/
|
|
105
|
+
declare function generateId(): string;
|
|
106
|
+
/**
|
|
107
|
+
* Securely compare two hex strings using timing-safe comparison.
|
|
108
|
+
*/
|
|
109
|
+
declare function secureCompare(a: string, b: string): boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Securely compare two arbitrary strings using timing-safe comparison.
|
|
112
|
+
* Unlike secureCompare, this works with any string encoding (UUIDs, tokens, etc.).
|
|
113
|
+
*/
|
|
114
|
+
declare function secureStringCompare(a: string, b: string): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Build a URL with token and optional email parameters.
|
|
117
|
+
*/
|
|
118
|
+
declare function buildTokenUrl(baseUrl: string, token: string, email?: string): string;
|
|
119
|
+
/**
|
|
120
|
+
* Parse a URL to extract token and email parameters.
|
|
121
|
+
*/
|
|
122
|
+
declare function parseTokenUrl(url: string): {
|
|
123
|
+
token: string | null;
|
|
124
|
+
email: string | null;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Configuration for password reset tokens.
|
|
129
|
+
*/
|
|
130
|
+
interface PasswordResetConfig {
|
|
131
|
+
/** Token expiration time in milliseconds (default: 1 hour) */
|
|
132
|
+
expiresIn?: number;
|
|
133
|
+
/** Token byte length before encoding (default: 32) */
|
|
134
|
+
tokenLength?: number;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Storage interface for password reset tokens.
|
|
138
|
+
*/
|
|
139
|
+
interface PasswordResetTokenStore {
|
|
140
|
+
/** Store a token ID with associated email and expiration */
|
|
141
|
+
store(tokenId: string, email: string, expiresAt: Date): Promise<void>;
|
|
142
|
+
/** Find email by token ID, returns null if not found or expired */
|
|
143
|
+
find(tokenId: string): Promise<{
|
|
144
|
+
email: string;
|
|
145
|
+
expiresAt: Date;
|
|
146
|
+
} | null>;
|
|
147
|
+
/** Delete a token ID from storage */
|
|
148
|
+
delete(tokenId: string): Promise<void>;
|
|
149
|
+
/** Delete all tokens for an email */
|
|
150
|
+
deleteForEmail(email: string): Promise<void>;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* In-memory token store for testing and development.
|
|
154
|
+
*/
|
|
155
|
+
declare class MemoryPasswordResetStore implements PasswordResetTokenStore {
|
|
156
|
+
private tokens;
|
|
157
|
+
store(tokenId: string, email: string, expiresAt: Date): Promise<void>;
|
|
158
|
+
find(tokenId: string): Promise<{
|
|
159
|
+
email: string;
|
|
160
|
+
expiresAt: Date;
|
|
161
|
+
} | null>;
|
|
162
|
+
delete(tokenId: string): Promise<void>;
|
|
163
|
+
deleteForEmail(email: string): Promise<void>;
|
|
164
|
+
/** Clear all tokens (useful for testing) */
|
|
165
|
+
clear(): void;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Result of creating a password reset token.
|
|
169
|
+
*/
|
|
170
|
+
interface PasswordResetTokenResult {
|
|
171
|
+
/** The plain-text token to send to the user (via email) */
|
|
172
|
+
token: string;
|
|
173
|
+
/** The token ID stored in the backing store */
|
|
174
|
+
tokenId: string;
|
|
175
|
+
/** When the token expires */
|
|
176
|
+
expiresAt: Date;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Create a password reset token for a user.
|
|
180
|
+
*
|
|
181
|
+
* @param email - The user's email address
|
|
182
|
+
* @param store - The token storage implementation
|
|
183
|
+
* @param config - Optional configuration
|
|
184
|
+
* @returns The token result containing plain token and hash
|
|
185
|
+
*/
|
|
186
|
+
declare function createPasswordResetToken(email: string, store: PasswordResetTokenStore, config?: PasswordResetConfig): Promise<PasswordResetTokenResult>;
|
|
187
|
+
/**
|
|
188
|
+
* Verify a password reset token.
|
|
189
|
+
*
|
|
190
|
+
* @param token - The plain-text token from the reset URL
|
|
191
|
+
* @param store - The token storage implementation
|
|
192
|
+
* @param config - Optional configuration (must match createPasswordResetToken config)
|
|
193
|
+
* @returns The email if token is valid, null otherwise
|
|
194
|
+
*/
|
|
195
|
+
declare function verifyPasswordResetToken(token: string, store: PasswordResetTokenStore, _config?: PasswordResetConfig): Promise<string | null>;
|
|
196
|
+
/**
|
|
197
|
+
* Complete a password reset by updating the user's password and invalidating the token.
|
|
198
|
+
*
|
|
199
|
+
* @param token - The plain-text token from the reset URL
|
|
200
|
+
* @param newPassword - The new password (should be validated by caller)
|
|
201
|
+
* @param store - The token storage implementation
|
|
202
|
+
* @param provider - The user provider to look up and update the user
|
|
203
|
+
* @param updatePassword - Function to update the user's password
|
|
204
|
+
* @param config - Optional configuration
|
|
205
|
+
* @returns The user if reset was successful, null if token is invalid
|
|
206
|
+
*/
|
|
207
|
+
declare function completePasswordReset<T extends Authenticatable>(token: string, newPassword: string, store: PasswordResetTokenStore, provider: UserProvider<T>, updatePassword: (user: T, password: string) => Promise<void>, _config?: PasswordResetConfig): Promise<T | null>;
|
|
208
|
+
/**
|
|
209
|
+
* Build a password reset URL from a base URL and token.
|
|
210
|
+
*/
|
|
211
|
+
declare const buildPasswordResetUrl: typeof buildTokenUrl;
|
|
212
|
+
/**
|
|
213
|
+
* Parse a password reset URL to extract the token and optional email.
|
|
214
|
+
*/
|
|
215
|
+
declare const parsePasswordResetUrl: typeof parseTokenUrl;
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Email verification token data stored in the backing store.
|
|
219
|
+
* Only the hashed token is stored for security.
|
|
220
|
+
*/
|
|
221
|
+
interface EmailVerificationToken {
|
|
222
|
+
email: string;
|
|
223
|
+
tokenId: string;
|
|
224
|
+
expiresAt: Date;
|
|
225
|
+
createdAt: Date;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Store interface for email verification tokens.
|
|
229
|
+
* Implement this to use database-backed storage.
|
|
230
|
+
*/
|
|
231
|
+
interface EmailVerificationTokenStore {
|
|
232
|
+
/**
|
|
233
|
+
* Store a new verification token.
|
|
234
|
+
*/
|
|
235
|
+
store(token: EmailVerificationToken): Promise<void>;
|
|
236
|
+
/**
|
|
237
|
+
* Find a token by its opaque token ID.
|
|
238
|
+
*/
|
|
239
|
+
findByTokenId(tokenId: string): Promise<EmailVerificationToken | null>;
|
|
240
|
+
/**
|
|
241
|
+
* Delete a token by its opaque token ID.
|
|
242
|
+
*/
|
|
243
|
+
delete(tokenId: string): Promise<void>;
|
|
244
|
+
/**
|
|
245
|
+
* Delete all tokens for a given email.
|
|
246
|
+
*/
|
|
247
|
+
deleteForEmail(email: string): Promise<void>;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* In-memory store for testing purposes.
|
|
251
|
+
* Do NOT use in production - tokens will be lost on restart.
|
|
252
|
+
*/
|
|
253
|
+
declare class MemoryEmailVerificationStore implements EmailVerificationTokenStore {
|
|
254
|
+
private tokens;
|
|
255
|
+
store(token: EmailVerificationToken): Promise<void>;
|
|
256
|
+
findByTokenId(tokenId: string): Promise<EmailVerificationToken | null>;
|
|
257
|
+
delete(tokenId: string): Promise<void>;
|
|
258
|
+
deleteForEmail(email: string): Promise<void>;
|
|
259
|
+
/**
|
|
260
|
+
* Clear all tokens (useful for testing).
|
|
261
|
+
*/
|
|
262
|
+
clear(): void;
|
|
263
|
+
/**
|
|
264
|
+
* Get the count of stored tokens (useful for testing).
|
|
265
|
+
*/
|
|
266
|
+
get size(): number;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Configuration options for email verification.
|
|
270
|
+
*/
|
|
271
|
+
interface EmailVerificationConfig {
|
|
272
|
+
/**
|
|
273
|
+
* Token expiration time in milliseconds.
|
|
274
|
+
* @default 86400000 (24 hours)
|
|
275
|
+
*/
|
|
276
|
+
expiresIn?: number;
|
|
277
|
+
/**
|
|
278
|
+
* Token byte length (before hex encoding).
|
|
279
|
+
* @default 32
|
|
280
|
+
*/
|
|
281
|
+
tokenLength?: number;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Result of creating an email verification token.
|
|
285
|
+
*/
|
|
286
|
+
interface EmailVerificationTokenResult {
|
|
287
|
+
/**
|
|
288
|
+
* The raw token to send to the user via email.
|
|
289
|
+
* This is NOT stored - only the hash is stored.
|
|
290
|
+
*/
|
|
291
|
+
token: string;
|
|
292
|
+
/**
|
|
293
|
+
* When the token expires.
|
|
294
|
+
*/
|
|
295
|
+
expiresAt: Date;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Create a new email verification token.
|
|
299
|
+
*
|
|
300
|
+
* @param email - The email address to verify
|
|
301
|
+
* @param store - Token store implementation
|
|
302
|
+
* @param config - Optional configuration
|
|
303
|
+
* @returns The raw token to send via email
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* ```ts
|
|
307
|
+
* const { token, expiresAt } = await createEmailVerificationToken(
|
|
308
|
+
* user.email,
|
|
309
|
+
* verificationStore
|
|
310
|
+
* )
|
|
311
|
+
*
|
|
312
|
+
* // Send email with verification link
|
|
313
|
+
* await sendEmail({
|
|
314
|
+
* to: user.email,
|
|
315
|
+
* subject: 'Verify your email',
|
|
316
|
+
* html: `<a href="${buildVerificationUrl(baseUrl, token)}">Verify Email</a>`,
|
|
317
|
+
* })
|
|
318
|
+
* ```
|
|
319
|
+
*/
|
|
320
|
+
declare function createEmailVerificationToken(email: string, store: EmailVerificationTokenStore, config?: EmailVerificationConfig): Promise<EmailVerificationTokenResult>;
|
|
321
|
+
/**
|
|
322
|
+
* Verify an email verification token.
|
|
323
|
+
*
|
|
324
|
+
* @param token - The raw token from the verification link
|
|
325
|
+
* @param store - Token store implementation
|
|
326
|
+
* @param config - Optional configuration (not currently used, reserved for future)
|
|
327
|
+
* @returns The email address if valid, null if invalid or expired
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```ts
|
|
331
|
+
* const email = await verifyEmailToken(token, verificationStore)
|
|
332
|
+
*
|
|
333
|
+
* if (!email) {
|
|
334
|
+
* return ctx.json({ error: 'Invalid or expired token' }, 400)
|
|
335
|
+
* }
|
|
336
|
+
*
|
|
337
|
+
* // Mark user as verified
|
|
338
|
+
* await User.update({ email }, { emailVerifiedAt: new Date() })
|
|
339
|
+
* ```
|
|
340
|
+
*/
|
|
341
|
+
declare function verifyEmailToken(token: string, store: EmailVerificationTokenStore, _config?: EmailVerificationConfig): Promise<string | null>;
|
|
342
|
+
/**
|
|
343
|
+
* Complete email verification by consuming the token.
|
|
344
|
+
*
|
|
345
|
+
* @param token - The raw token from the verification link
|
|
346
|
+
* @param store - Token store implementation
|
|
347
|
+
* @param markVerified - Function to mark the user as verified
|
|
348
|
+
* @returns The result of markVerified if successful, null if token invalid
|
|
349
|
+
*
|
|
350
|
+
* @example
|
|
351
|
+
* ```ts
|
|
352
|
+
* const result = await completeEmailVerification(
|
|
353
|
+
* token,
|
|
354
|
+
* verificationStore,
|
|
355
|
+
* async (email) => {
|
|
356
|
+
* await User.update({ email }, { emailVerifiedAt: new Date() })
|
|
357
|
+
* return User.findByEmail(email)
|
|
358
|
+
* }
|
|
359
|
+
* )
|
|
360
|
+
*
|
|
361
|
+
* if (!result) {
|
|
362
|
+
* return ctx.json({ error: 'Invalid or expired token' }, 400)
|
|
363
|
+
* }
|
|
364
|
+
*
|
|
365
|
+
* return ctx.redirect('/dashboard')
|
|
366
|
+
* ```
|
|
367
|
+
*/
|
|
368
|
+
declare function completeEmailVerification<T>(token: string, store: EmailVerificationTokenStore, markVerified: (email: string) => Promise<T>): Promise<T | null>;
|
|
369
|
+
/**
|
|
370
|
+
* Build a verification URL.
|
|
371
|
+
*/
|
|
372
|
+
declare const buildVerificationUrl: typeof buildTokenUrl;
|
|
373
|
+
/**
|
|
374
|
+
* Parse a verification URL to extract token and email.
|
|
375
|
+
*/
|
|
376
|
+
declare const parseVerificationUrl: typeof parseTokenUrl;
|
|
377
|
+
/**
|
|
378
|
+
* Check if a user's email is verified.
|
|
379
|
+
* Helper function for use with User models.
|
|
380
|
+
*
|
|
381
|
+
* @param user - User object with emailVerifiedAt field
|
|
382
|
+
* @returns true if verified, false otherwise
|
|
383
|
+
*
|
|
384
|
+
* @example
|
|
385
|
+
* ```ts
|
|
386
|
+
* if (!isEmailVerified(user)) {
|
|
387
|
+
* return ctx.redirect('/verify-email')
|
|
388
|
+
* }
|
|
389
|
+
* ```
|
|
390
|
+
*/
|
|
391
|
+
declare function isEmailVerified(user: {
|
|
392
|
+
emailVerifiedAt?: Date | null;
|
|
393
|
+
} | null): boolean;
|
|
394
|
+
/**
|
|
395
|
+
* Middleware factory to require verified email.
|
|
396
|
+
*
|
|
397
|
+
* @param options - Configuration options
|
|
398
|
+
* @returns Middleware function
|
|
399
|
+
*
|
|
400
|
+
* @example
|
|
401
|
+
* ```ts
|
|
402
|
+
* router.get('/dashboard', [DashboardController, 'index'],
|
|
403
|
+
* requireAuthenticated(),
|
|
404
|
+
* requireVerifiedEmail({ redirectTo: '/verify-email' })
|
|
405
|
+
* )
|
|
406
|
+
* ```
|
|
407
|
+
*/
|
|
408
|
+
declare function requireVerifiedEmail(options?: {
|
|
409
|
+
redirectTo?: string;
|
|
410
|
+
getUser?: (ctx: unknown) => Promise<{
|
|
411
|
+
emailVerifiedAt?: Date | null;
|
|
412
|
+
} | null>;
|
|
413
|
+
}): (ctx: {
|
|
414
|
+
get: (key: string) => unknown;
|
|
415
|
+
redirect: (url: string) => Response;
|
|
416
|
+
}, next: () => Promise<void>) => Promise<Response | undefined>;
|
|
417
|
+
|
|
418
|
+
export { AuthCredentials, Authenticatable, AuthenticatableModel, type EmailVerificationConfig, type EmailVerificationToken, type EmailVerificationTokenResult, type EmailVerificationTokenStore, Guard, MemoryEmailVerificationStore, MemoryPasswordResetStore, NodeHasher, PasswordHasher, type PasswordResetConfig, type PasswordResetTokenResult, type PasswordResetTokenStore, ScryptHasher, SessionGuard, UserProvider, buildPasswordResetUrl, buildTokenUrl, buildVerificationUrl, completeEmailVerification, completePasswordReset, createEmailVerificationToken, createPasswordResetToken, generateId, generateToken, hashToken, isEmailVerified, parsePasswordResetUrl, parseTokenUrl, parseVerificationUrl, requireVerifiedEmail, secureCompare, secureStringCompare, verifyEmailToken, verifyPasswordResetToken };
|