peta-auth 0.1.1 → 0.1.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.
- package/README.md +29 -1
- package/dist/index.d.mts +15 -1
- package/dist/index.mjs +26 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -226,6 +226,33 @@ if (!validateCsrf(session, body._csrf)) {
|
|
|
226
226
|
|
|
227
227
|
---
|
|
228
228
|
|
|
229
|
+
## Password Reset
|
|
230
|
+
|
|
231
|
+
Helpers for forgot/reset password flows using short-lived JWTs.
|
|
232
|
+
|
|
233
|
+
```ts
|
|
234
|
+
import { createPasswordResetToken, verifyPasswordResetToken, resetPassword } from 'peta-auth'
|
|
235
|
+
|
|
236
|
+
// Generate a token (e.g., in a "forgot password" endpoint)
|
|
237
|
+
const token = await createPasswordResetToken(user.email, {
|
|
238
|
+
password: process.env.SECRET!,
|
|
239
|
+
exp: 3600, // optional, default 1 hour
|
|
240
|
+
})
|
|
241
|
+
// → email token as a link: https://example.com/reset?token=${token}
|
|
242
|
+
|
|
243
|
+
// Verify a token (e.g., in a "reset password" endpoint)
|
|
244
|
+
const payload = await verifyPasswordResetToken(token, process.env.SECRET!)
|
|
245
|
+
if (!payload) throw new Error('Invalid or expired token')
|
|
246
|
+
// payload.userId → the email passed to createPasswordResetToken
|
|
247
|
+
|
|
248
|
+
// Combined: verify token + hash new password
|
|
249
|
+
const result = await resetPassword(token, newPassword, process.env.SECRET!)
|
|
250
|
+
if (!result) throw new Error('Invalid or expired token')
|
|
251
|
+
users.set(result.userId, { ...user, hash: result.hash })
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
229
256
|
## Low-level
|
|
230
257
|
|
|
231
258
|
```ts
|
|
@@ -300,6 +327,7 @@ bun run examples/hono-guard.ts # Hono — requireSession guard
|
|
|
300
327
|
bun run examples/elysia-basic.ts # Elysia — session CRUD, views counter
|
|
301
328
|
bun run examples/elysia-guard.ts # Elysia — requireSession guard
|
|
302
329
|
bun run examples/password-auth.ts # Hono — signup + login with bcrypt
|
|
330
|
+
bun run examples/password-reset.ts # Hono — forgot/reset password flow
|
|
303
331
|
bun run examples/jwt-basic.ts # JWT sign + verify + tamper detection
|
|
304
332
|
bun run examples/csrf-basic.ts # Hono — CSRF token form example
|
|
305
333
|
bun run examples/oauth-github.ts # Hono — GitHub OAuth
|
|
@@ -326,7 +354,7 @@ Session data is serialized, encrypted with AES-256-CBC, integrity-protected with
|
|
|
326
354
|
## Scripts
|
|
327
355
|
|
|
328
356
|
```bash
|
|
329
|
-
bun test #
|
|
357
|
+
bun test # 65 tests across 12 files
|
|
330
358
|
bun run build # tsdown → dist/ (21 files, 30 kB)
|
|
331
359
|
bun run prepublish # build + publish
|
|
332
360
|
```
|
package/dist/index.d.mts
CHANGED
|
@@ -10,4 +10,18 @@ interface HashOptions {
|
|
|
10
10
|
declare function hashPassword(password: string, options?: HashOptions): Promise<string>;
|
|
11
11
|
declare function verifyPassword(hash: string, password: string): Promise<boolean>;
|
|
12
12
|
//#endregion
|
|
13
|
-
|
|
13
|
+
//#region src/reset-password.d.ts
|
|
14
|
+
interface PasswordResetOptions {
|
|
15
|
+
password: Password;
|
|
16
|
+
exp?: number;
|
|
17
|
+
}
|
|
18
|
+
declare function createPasswordResetToken(userId: string, options: PasswordResetOptions): Promise<string>;
|
|
19
|
+
declare function verifyPasswordResetToken(token: string, password: Password): Promise<{
|
|
20
|
+
userId: string;
|
|
21
|
+
} | null>;
|
|
22
|
+
declare function resetPassword(token: string, newPassword: string, password: Password): Promise<{
|
|
23
|
+
userId: string;
|
|
24
|
+
hash: string;
|
|
25
|
+
} | null>;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { type CSRFOptions, type IronSession, type JWTOptions, type Password, type PasswordResetOptions, type SessionAdapter, type SessionOptions, createPasswordResetToken, createSessionFromAdapter, generateCsrf, hashPassword, resetPassword, sealData, signJWT, unsealData, validateCsrf, verifyJWT, verifyPassword, verifyPasswordResetToken };
|
package/dist/index.mjs
CHANGED
|
@@ -10,4 +10,29 @@ async function verifyPassword(hash, password) {
|
|
|
10
10
|
return compareSync(password, hash);
|
|
11
11
|
}
|
|
12
12
|
//#endregion
|
|
13
|
-
|
|
13
|
+
//#region src/reset-password.ts
|
|
14
|
+
const DEFAULT_EXPIRY = 3600;
|
|
15
|
+
async function createPasswordResetToken(userId, options) {
|
|
16
|
+
return signJWT({
|
|
17
|
+
userId,
|
|
18
|
+
purpose: "password-reset"
|
|
19
|
+
}, {
|
|
20
|
+
password: options.password,
|
|
21
|
+
exp: options.exp ?? DEFAULT_EXPIRY
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
async function verifyPasswordResetToken(token, password) {
|
|
25
|
+
const payload = await verifyJWT(token, { password });
|
|
26
|
+
if (!payload || payload.purpose !== "password-reset") return null;
|
|
27
|
+
return { userId: payload.userId };
|
|
28
|
+
}
|
|
29
|
+
async function resetPassword(token, newPassword, password) {
|
|
30
|
+
const payload = await verifyPasswordResetToken(token, password);
|
|
31
|
+
if (!payload) return null;
|
|
32
|
+
return {
|
|
33
|
+
userId: payload.userId,
|
|
34
|
+
hash: await hashPassword(newPassword)
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { createPasswordResetToken, createSessionFromAdapter, generateCsrf, hashPassword, resetPassword, sealData, signJWT, unsealData, validateCsrf, verifyJWT, verifyPassword, verifyPasswordResetToken };
|