@vonosan/auth 0.2.1

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 (61) hide show
  1. package/dist/__tests__/passkey.test.d.ts +11 -0
  2. package/dist/__tests__/passkey.test.d.ts.map +1 -0
  3. package/dist/__tests__/passkey.test.js +87 -0
  4. package/dist/__tests__/passkey.test.js.map +1 -0
  5. package/dist/composables/useAuth.d.ts +43 -0
  6. package/dist/composables/useAuth.d.ts.map +1 -0
  7. package/dist/composables/useAuth.js +133 -0
  8. package/dist/composables/useAuth.js.map +1 -0
  9. package/dist/composables/usePasskey.d.ts +72 -0
  10. package/dist/composables/usePasskey.d.ts.map +1 -0
  11. package/dist/composables/usePasskey.js +289 -0
  12. package/dist/composables/usePasskey.js.map +1 -0
  13. package/dist/index.d.ts +29 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +37 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/lib/jwt.d.ts +30 -0
  18. package/dist/lib/jwt.d.ts.map +1 -0
  19. package/dist/lib/jwt.js +43 -0
  20. package/dist/lib/jwt.js.map +1 -0
  21. package/dist/lib/otp.d.ts +23 -0
  22. package/dist/lib/otp.d.ts.map +1 -0
  23. package/dist/lib/otp.js +50 -0
  24. package/dist/lib/otp.js.map +1 -0
  25. package/dist/lib/passkey.d.ts +139 -0
  26. package/dist/lib/passkey.d.ts.map +1 -0
  27. package/dist/lib/passkey.js +401 -0
  28. package/dist/lib/passkey.js.map +1 -0
  29. package/dist/lib/password.d.ts +20 -0
  30. package/dist/lib/password.d.ts.map +1 -0
  31. package/dist/lib/password.js +77 -0
  32. package/dist/lib/password.js.map +1 -0
  33. package/dist/middleware/auth.middleware.d.ts +50 -0
  34. package/dist/middleware/auth.middleware.d.ts.map +1 -0
  35. package/dist/middleware/auth.middleware.js +194 -0
  36. package/dist/middleware/auth.middleware.js.map +1 -0
  37. package/dist/passkey-schema.d.ts +375 -0
  38. package/dist/passkey-schema.d.ts.map +1 -0
  39. package/dist/passkey-schema.js +63 -0
  40. package/dist/passkey-schema.js.map +1 -0
  41. package/dist/routes/auth.routes.d.ts +16 -0
  42. package/dist/routes/auth.routes.d.ts.map +1 -0
  43. package/dist/routes/auth.routes.js +81 -0
  44. package/dist/routes/auth.routes.js.map +1 -0
  45. package/dist/routes/passkey.routes.d.ts +16 -0
  46. package/dist/routes/passkey.routes.d.ts.map +1 -0
  47. package/dist/routes/passkey.routes.js +127 -0
  48. package/dist/routes/passkey.routes.js.map +1 -0
  49. package/dist/schema.d.ts +547 -0
  50. package/dist/schema.d.ts.map +1 -0
  51. package/dist/schema.js +81 -0
  52. package/dist/schema.js.map +1 -0
  53. package/dist/service/auth.service.d.ts +73 -0
  54. package/dist/service/auth.service.d.ts.map +1 -0
  55. package/dist/service/auth.service.js +249 -0
  56. package/dist/service/auth.service.js.map +1 -0
  57. package/dist/service/passkey.service.d.ts +65 -0
  58. package/dist/service/passkey.service.d.ts.map +1 -0
  59. package/dist/service/passkey.service.js +202 -0
  60. package/dist/service/passkey.service.js.map +1 -0
  61. package/package.json +49 -0
@@ -0,0 +1,401 @@
1
+ /**
2
+ * ──────────────────────────────────────────────────────────────────
3
+ * 🏢 Company Name: Bonifade Technologies
4
+ * 👨‍💻 Developer: Bowofade Oyerinde
5
+ * 🐙 GitHub: oyenet1
6
+ * 📅 Created Date: 2026-04-05
7
+ * 🔄 Updated Date: 2026-04-05
8
+ * ──────────────────────────────────────────────────────────────────
9
+ */
10
+ // ─── Challenge generation ─────────────────────────────────────────────────────
11
+ const CHALLENGE_TTL_MS = 5 * 60 * 1000; // 5 minutes
12
+ /**
13
+ * Generate a cryptographically random challenge for WebAuthn.
14
+ * Returns a base64url-encoded 32-byte random value.
15
+ */
16
+ export function generateChallenge() {
17
+ const bytes = crypto.getRandomValues(new Uint8Array(32));
18
+ return {
19
+ challenge: bufferToBase64url(bytes),
20
+ expiresAt: Date.now() + CHALLENGE_TTL_MS,
21
+ };
22
+ }
23
+ /**
24
+ * Build the PublicKeyCredentialCreationOptions for registration.
25
+ */
26
+ export function buildRegistrationOptions(opts) {
27
+ return {
28
+ rp: { id: opts.rpId, name: opts.rpName },
29
+ user: {
30
+ id: opts.userId,
31
+ name: opts.userName,
32
+ displayName: opts.userDisplayName,
33
+ },
34
+ challenge: opts.challenge,
35
+ pubKeyCredParams: [
36
+ { alg: -7, type: 'public-key' }, // ES256 (ECDSA P-256)
37
+ { alg: -257, type: 'public-key' }, // RS256 (RSA PKCS1)
38
+ ],
39
+ timeout: opts.timeout ?? 60000,
40
+ attestation: opts.attestation ?? 'none',
41
+ authenticatorSelection: opts.authenticatorSelection ?? {
42
+ residentKey: 'preferred',
43
+ userVerification: 'preferred',
44
+ },
45
+ excludeCredentials: [],
46
+ };
47
+ }
48
+ /**
49
+ * Build the PublicKeyCredentialRequestOptions for authentication.
50
+ */
51
+ export function buildAuthenticationOptions(opts) {
52
+ return {
53
+ rpId: opts.rpId,
54
+ challenge: opts.challenge,
55
+ timeout: opts.timeout ?? 60000,
56
+ userVerification: opts.userVerification ?? 'preferred',
57
+ allowCredentials: opts.allowCredentials ?? [],
58
+ };
59
+ }
60
+ // ─── Registration verification ───────────────────────────────────────────────
61
+ /**
62
+ * Verify a WebAuthn registration response.
63
+ *
64
+ * Validates:
65
+ * - clientDataJSON type, origin, and challenge
66
+ * - attestationObject format (none attestation)
67
+ * - Extracts public key, sign count, AAGUID, and device type
68
+ *
69
+ * @throws Error if verification fails
70
+ */
71
+ export async function verifyRegistration(response, expectedChallenge, expectedOrigin, expectedRpId) {
72
+ // 1. Decode and verify clientDataJSON
73
+ const clientData = decodeClientDataJSON(response.response.clientDataJSON);
74
+ if (clientData.type !== 'webauthn.create') {
75
+ throw new Error('Invalid clientData type for registration');
76
+ }
77
+ if (clientData.challenge !== expectedChallenge) {
78
+ throw new Error('Challenge mismatch');
79
+ }
80
+ if (clientData.origin !== expectedOrigin) {
81
+ throw new Error(`Origin mismatch: expected ${expectedOrigin}, got ${clientData.origin}`);
82
+ }
83
+ // 2. Decode attestationObject (CBOR — simplified for 'none' attestation)
84
+ const attestationBytes = base64urlToBuffer(response.response.attestationObject);
85
+ const attestation = decodeCBOR(attestationBytes);
86
+ if (!attestation || typeof attestation !== 'object') {
87
+ throw new Error('Failed to decode attestationObject');
88
+ }
89
+ const { fmt, authData } = attestation;
90
+ if (fmt !== 'none' && fmt !== 'packed') {
91
+ // For now we only support 'none' attestation (most common for passkeys)
92
+ // 'packed' is also common — we accept it but don't verify the attestation statement
93
+ }
94
+ // 3. Parse authenticatorData
95
+ const parsedAuthData = parseAuthenticatorData(authData);
96
+ // 4. Verify RP ID hash
97
+ const rpIdHash = await sha256(new TextEncoder().encode(expectedRpId));
98
+ if (!bufferEqual(parsedAuthData.rpIdHash, rpIdHash)) {
99
+ throw new Error('RP ID hash mismatch');
100
+ }
101
+ // 5. Check flags
102
+ const { flags } = parsedAuthData;
103
+ if (!(flags & 0x01))
104
+ throw new Error('User presence flag not set');
105
+ // 6. Extract credential data
106
+ if (!parsedAuthData.attestedCredentialData) {
107
+ throw new Error('No attested credential data in authenticatorData');
108
+ }
109
+ const { credentialId, publicKey, aaguid } = parsedAuthData.attestedCredentialData;
110
+ // 7. Determine device type from flags
111
+ const backedUp = !!(flags & 0x10);
112
+ const deviceType = !!(flags & 0x08) ? 'platform' : 'cross-platform';
113
+ return {
114
+ credentialId: bufferToBase64url(credentialId),
115
+ publicKey: bufferToBase64url(publicKey),
116
+ signCount: parsedAuthData.signCount,
117
+ aaguid: formatAaguid(aaguid),
118
+ deviceType,
119
+ backedUp,
120
+ transports: [],
121
+ };
122
+ }
123
+ // ─── Authentication verification ─────────────────────────────────────────────
124
+ /**
125
+ * Verify a WebAuthn authentication response.
126
+ *
127
+ * Validates:
128
+ * - clientDataJSON type, origin, and challenge
129
+ * - authenticatorData RP ID hash and flags
130
+ * - Signature over authenticatorData + clientDataHash using stored public key
131
+ * - Sign count (replay attack prevention)
132
+ *
133
+ * @throws Error if verification fails
134
+ */
135
+ export async function verifyAuthentication(response, expectedChallenge, expectedOrigin, expectedRpId, storedCredential) {
136
+ // 1. Verify clientDataJSON
137
+ const clientData = decodeClientDataJSON(response.response.clientDataJSON);
138
+ if (clientData.type !== 'webauthn.get') {
139
+ throw new Error('Invalid clientData type for authentication');
140
+ }
141
+ if (clientData.challenge !== expectedChallenge) {
142
+ throw new Error('Challenge mismatch');
143
+ }
144
+ if (clientData.origin !== expectedOrigin) {
145
+ throw new Error(`Origin mismatch: expected ${expectedOrigin}, got ${clientData.origin}`);
146
+ }
147
+ // 2. Parse authenticatorData
148
+ const authDataBytes = base64urlToBuffer(response.response.authenticatorData);
149
+ const parsedAuthData = parseAuthenticatorData(authDataBytes);
150
+ // 3. Verify RP ID hash
151
+ const rpIdHash = await sha256(new TextEncoder().encode(expectedRpId));
152
+ if (!bufferEqual(parsedAuthData.rpIdHash, rpIdHash)) {
153
+ throw new Error('RP ID hash mismatch');
154
+ }
155
+ // 4. Check user presence flag
156
+ if (!(parsedAuthData.flags & 0x01)) {
157
+ throw new Error('User presence flag not set');
158
+ }
159
+ const userVerified = !!(parsedAuthData.flags & 0x04);
160
+ // 5. Verify sign count (replay attack prevention)
161
+ if (parsedAuthData.signCount !== 0 &&
162
+ storedCredential.signCount !== 0 &&
163
+ parsedAuthData.signCount <= storedCredential.signCount) {
164
+ throw new Error(`Sign count mismatch — possible replay attack. ` +
165
+ `Stored: ${storedCredential.signCount}, received: ${parsedAuthData.signCount}`);
166
+ }
167
+ // 6. Verify signature
168
+ const clientDataHash = await sha256(base64urlToBuffer(response.response.clientDataJSON));
169
+ const signedData = concatBuffers(authDataBytes, clientDataHash);
170
+ const signature = base64urlToBuffer(response.response.signature);
171
+ const publicKeyBytes = base64urlToBuffer(storedCredential.publicKey);
172
+ const valid = await verifySignature(publicKeyBytes, signature, signedData);
173
+ if (!valid) {
174
+ throw new Error('Signature verification failed');
175
+ }
176
+ return {
177
+ credentialId: storedCredential.credentialId,
178
+ newSignCount: parsedAuthData.signCount,
179
+ userVerified,
180
+ };
181
+ }
182
+ // ─── Crypto helpers ───────────────────────────────────────────────────────────
183
+ async function sha256(data) {
184
+ const hash = await crypto.subtle.digest('SHA-256', data);
185
+ return new Uint8Array(hash);
186
+ }
187
+ async function verifySignature(publicKeyBytes, signature, data) {
188
+ try {
189
+ // Import COSE-encoded public key
190
+ // COSE key for ES256: kty=2 (EC), alg=-7, crv=1 (P-256), x, y
191
+ const coseKey = decodeCBOR(publicKeyBytes);
192
+ if (!coseKey)
193
+ return false;
194
+ const kty = coseKey[1];
195
+ const alg = coseKey[3];
196
+ if (kty === 2 && alg === -7) {
197
+ // EC P-256 (ES256)
198
+ const x = coseKey[-2];
199
+ const y = coseKey[-3];
200
+ const jwk = {
201
+ kty: 'EC',
202
+ crv: 'P-256',
203
+ x: bufferToBase64url(x),
204
+ y: bufferToBase64url(y),
205
+ };
206
+ const key = await crypto.subtle.importKey('jwk', jwk, { name: 'ECDSA', namedCurve: 'P-256' }, false, ['verify']);
207
+ // Convert DER signature to raw r||s format
208
+ const rawSig = derToRaw(signature);
209
+ return crypto.subtle.verify({ name: 'ECDSA', hash: 'SHA-256' }, key, rawSig, data);
210
+ }
211
+ if (kty === 3 && alg === -257) {
212
+ // RSA PKCS1 (RS256)
213
+ const n = coseKey[-1];
214
+ const e = coseKey[-2];
215
+ const jwk = {
216
+ kty: 'RSA',
217
+ alg: 'RS256',
218
+ n: bufferToBase64url(n),
219
+ e: bufferToBase64url(e),
220
+ };
221
+ const key = await crypto.subtle.importKey('jwk', jwk, { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' }, false, ['verify']);
222
+ return crypto.subtle.verify({ name: 'RSASSA-PKCS1-v1_5' }, key, signature, data);
223
+ }
224
+ return false;
225
+ }
226
+ catch {
227
+ return false;
228
+ }
229
+ }
230
+ // ─── Encoding helpers ─────────────────────────────────────────────────────────
231
+ export function bufferToBase64url(buffer) {
232
+ let binary = '';
233
+ for (let i = 0; i < buffer.length; i++) {
234
+ binary += String.fromCharCode(buffer[i]);
235
+ }
236
+ return btoa(binary)
237
+ .replace(/\+/g, '-')
238
+ .replace(/\//g, '_')
239
+ .replace(/=/g, '');
240
+ }
241
+ export function base64urlToBuffer(base64url) {
242
+ const base64 = base64url
243
+ .replace(/-/g, '+')
244
+ .replace(/_/g, '/')
245
+ .padEnd(base64url.length + ((4 - (base64url.length % 4)) % 4), '=');
246
+ const binary = atob(base64);
247
+ const bytes = new Uint8Array(binary.length);
248
+ for (let i = 0; i < binary.length; i++) {
249
+ bytes[i] = binary.charCodeAt(i);
250
+ }
251
+ return bytes;
252
+ }
253
+ function bufferEqual(a, b) {
254
+ // Constant-time comparison to prevent timing attacks on RP ID hash checks
255
+ if (a.length !== b.length)
256
+ return false;
257
+ let diff = 0;
258
+ for (let i = 0; i < a.length; i++) {
259
+ diff |= a[i] ^ b[i];
260
+ }
261
+ return diff === 0;
262
+ }
263
+ function concatBuffers(...buffers) {
264
+ const total = buffers.reduce((sum, b) => sum + b.length, 0);
265
+ const result = new Uint8Array(total);
266
+ let offset = 0;
267
+ for (const buf of buffers) {
268
+ result.set(buf, offset);
269
+ offset += buf.length;
270
+ }
271
+ return result;
272
+ }
273
+ // ─── CBOR decoder (minimal — handles WebAuthn subset) ────────────────────────
274
+ function decodeCBOR(data) {
275
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
276
+ const [value] = decodeCBORValue(view, 0);
277
+ return value;
278
+ }
279
+ function decodeCBORValue(view, offset) {
280
+ const byte = view.getUint8(offset);
281
+ const majorType = (byte >> 5) & 0x07;
282
+ const additionalInfo = byte & 0x1f;
283
+ offset++;
284
+ let length;
285
+ if (additionalInfo < 24) {
286
+ length = additionalInfo;
287
+ }
288
+ else if (additionalInfo === 24) {
289
+ length = view.getUint8(offset++);
290
+ }
291
+ else if (additionalInfo === 25) {
292
+ length = view.getUint16(offset);
293
+ offset += 2;
294
+ }
295
+ else if (additionalInfo === 26) {
296
+ length = view.getUint32(offset);
297
+ offset += 4;
298
+ }
299
+ else {
300
+ length = 0;
301
+ }
302
+ switch (majorType) {
303
+ case 0: return [length, offset]; // unsigned int
304
+ case 1: return [-(length + 1), offset]; // negative int
305
+ case 2: { // byte string
306
+ const bytes = new Uint8Array(view.buffer, view.byteOffset + offset, length);
307
+ return [bytes, offset + length];
308
+ }
309
+ case 3: { // text string
310
+ const bytes = new Uint8Array(view.buffer, view.byteOffset + offset, length);
311
+ return [new TextDecoder().decode(bytes), offset + length];
312
+ }
313
+ case 4: { // array
314
+ const arr = [];
315
+ for (let i = 0; i < length; i++) {
316
+ const [val, newOffset] = decodeCBORValue(view, offset);
317
+ arr.push(val);
318
+ offset = newOffset;
319
+ }
320
+ return [arr, offset];
321
+ }
322
+ case 5: { // map
323
+ const map = {};
324
+ for (let i = 0; i < length; i++) {
325
+ const [key, o1] = decodeCBORValue(view, offset);
326
+ const [val, o2] = decodeCBORValue(view, o1);
327
+ map[key] = val;
328
+ offset = o2;
329
+ }
330
+ return [map, offset];
331
+ }
332
+ default: return [null, offset];
333
+ }
334
+ }
335
+ function parseAuthenticatorData(data) {
336
+ let offset = 0;
337
+ const rpIdHash = data.slice(offset, offset + 32);
338
+ offset += 32;
339
+ const flags = data[offset++];
340
+ const signCount = new DataView(data.buffer, data.byteOffset + offset, 4).getUint32(0);
341
+ offset += 4;
342
+ let attestedCredentialData;
343
+ // AT flag (bit 6) indicates attested credential data is present
344
+ if (flags & 0x40) {
345
+ const aaguid = data.slice(offset, offset + 16);
346
+ offset += 16;
347
+ const credIdLen = new DataView(data.buffer, data.byteOffset + offset, 2).getUint16(0);
348
+ offset += 2;
349
+ const credentialId = data.slice(offset, offset + credIdLen);
350
+ offset += credIdLen;
351
+ // Remaining bytes are the COSE-encoded public key
352
+ const publicKey = data.slice(offset);
353
+ attestedCredentialData = { aaguid, credentialId, publicKey };
354
+ }
355
+ return { rpIdHash, flags, signCount, attestedCredentialData };
356
+ }
357
+ // ─── clientDataJSON decoder ───────────────────────────────────────────────────
358
+ function decodeClientDataJSON(base64url) {
359
+ const bytes = base64urlToBuffer(base64url);
360
+ const json = new TextDecoder().decode(bytes);
361
+ return JSON.parse(json);
362
+ }
363
+ // ─── DER → raw signature conversion ──────────────────────────────────────────
364
+ function derToRaw(der) {
365
+ // DER SEQUENCE { INTEGER r, INTEGER s } → raw 64-byte r||s
366
+ if (der[0] !== 0x30)
367
+ return der; // not DER, return as-is
368
+ let offset = 2;
369
+ if (der[1] & 0x80)
370
+ offset += der[1] & 0x7f;
371
+ // r
372
+ offset++; // 0x02
373
+ let rLen = der[offset++];
374
+ if (rLen & 0x80) {
375
+ rLen = der[offset++];
376
+ }
377
+ const rStart = offset + (der[offset] === 0x00 ? 1 : 0);
378
+ const rEnd = offset + rLen;
379
+ const r = der.slice(rStart, rEnd);
380
+ offset = rEnd;
381
+ // s
382
+ offset++; // 0x02
383
+ let sLen = der[offset++];
384
+ if (sLen & 0x80) {
385
+ sLen = der[offset++];
386
+ }
387
+ const sStart = offset + (der[offset] === 0x00 ? 1 : 0);
388
+ const sEnd = offset + sLen;
389
+ const s = der.slice(sStart, sEnd);
390
+ // Pad to 32 bytes each
391
+ const raw = new Uint8Array(64);
392
+ raw.set(r, 32 - r.length);
393
+ raw.set(s, 64 - s.length);
394
+ return raw;
395
+ }
396
+ // ─── AAGUID formatter ─────────────────────────────────────────────────────────
397
+ function formatAaguid(bytes) {
398
+ const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('');
399
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
400
+ }
401
+ //# sourceMappingURL=passkey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passkey.js","sourceRoot":"","sources":["../../src/lib/passkey.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * ──────────────────────────────────────────────────────────────────
3
+ * 🏢 Company Name: Bonifade Technologies
4
+ * 👨‍💻 Developer: Bowofade Oyerinde
5
+ * 🐙 GitHub: oyenet1
6
+ * 📅 Created Date: 2026-04-05
7
+ * 🔄 Updated Date: 2026-04-05
8
+ * ──────────────────────────────────────────────────────────────────
9
+ */
10
+ /**
11
+ * `hashPassword(password)` — derives a PBKDF2 hash from a plaintext password.
12
+ * Returns a `salt:hash` string safe to store in the database.
13
+ */
14
+ export declare function hashPassword(password: string): Promise<string>;
15
+ /**
16
+ * `verifyPassword(password, storedHash)` — timing-safe comparison.
17
+ * Returns true if the password matches the stored `salt:hash`.
18
+ */
19
+ export declare function verifyPassword(password: string, storedHash: string): Promise<boolean>;
20
+ //# sourceMappingURL=password.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/lib/password.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAiCH;;;GAGG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBpE;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC,CAkClB"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * ──────────────────────────────────────────────────────────────────
3
+ * 🏢 Company Name: Bonifade Technologies
4
+ * 👨‍💻 Developer: Bowofade Oyerinde
5
+ * 🐙 GitHub: oyenet1
6
+ * 📅 Created Date: 2026-04-05
7
+ * 🔄 Updated Date: 2026-04-05
8
+ * ──────────────────────────────────────────────────────────────────
9
+ */
10
+ /**
11
+ * Password hashing via PBKDF2 using the Web Crypto API.
12
+ *
13
+ * Compatible with Cloudflare Workers, Bun, Node.js (18+), and Deno.
14
+ * No native addons required.
15
+ *
16
+ * Format: `<hex-salt>:<hex-hash>`
17
+ */
18
+ const ITERATIONS = 100_000;
19
+ const KEY_LENGTH = 32; // bytes → 256-bit
20
+ const DIGEST = 'SHA-256';
21
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
22
+ function toHex(buffer) {
23
+ return Array.from(new Uint8Array(buffer))
24
+ .map((b) => b.toString(16).padStart(2, '0'))
25
+ .join('');
26
+ }
27
+ function fromHex(hex) {
28
+ const bytes = new Uint8Array(hex.length / 2);
29
+ for (let i = 0; i < hex.length; i += 2) {
30
+ bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
31
+ }
32
+ return bytes;
33
+ }
34
+ // ─── Public API ───────────────────────────────────────────────────────────────
35
+ /**
36
+ * `hashPassword(password)` — derives a PBKDF2 hash from a plaintext password.
37
+ * Returns a `salt:hash` string safe to store in the database.
38
+ */
39
+ export async function hashPassword(password) {
40
+ const saltBytes = crypto.getRandomValues(new Uint8Array(16));
41
+ const salt = toHex(saltBytes.buffer);
42
+ const keyMaterial = await crypto.subtle.importKey('raw', new TextEncoder().encode(password), 'PBKDF2', false, ['deriveBits']);
43
+ const hashBuffer = await crypto.subtle.deriveBits({
44
+ name: 'PBKDF2',
45
+ salt: saltBytes,
46
+ iterations: ITERATIONS,
47
+ hash: DIGEST,
48
+ }, keyMaterial, KEY_LENGTH * 8);
49
+ return `${salt}:${toHex(hashBuffer)}`;
50
+ }
51
+ /**
52
+ * `verifyPassword(password, storedHash)` — timing-safe comparison.
53
+ * Returns true if the password matches the stored `salt:hash`.
54
+ */
55
+ export async function verifyPassword(password, storedHash) {
56
+ const [saltHex, hashHex] = storedHash.split(':');
57
+ if (!saltHex || !hashHex)
58
+ return false;
59
+ const saltBytes = fromHex(saltHex);
60
+ const keyMaterial = await crypto.subtle.importKey('raw', new TextEncoder().encode(password), 'PBKDF2', false, ['deriveBits']);
61
+ const hashBuffer = await crypto.subtle.deriveBits({
62
+ name: 'PBKDF2',
63
+ salt: saltBytes,
64
+ iterations: ITERATIONS,
65
+ hash: DIGEST,
66
+ }, keyMaterial, KEY_LENGTH * 8);
67
+ const candidateHex = toHex(hashBuffer);
68
+ // Timing-safe comparison — compare byte-by-byte without short-circuiting
69
+ if (candidateHex.length !== hashHex.length)
70
+ return false;
71
+ let diff = 0;
72
+ for (let i = 0; i < candidateHex.length; i++) {
73
+ diff |= candidateHex.charCodeAt(i) ^ hashHex.charCodeAt(i);
74
+ }
75
+ return diff === 0;
76
+ }
77
+ //# sourceMappingURL=password.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password.js","sourceRoot":"","sources":["../../src/lib/password.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;GAOG;AAEH,MAAM,UAAU,GAAG,OAAO,CAAA;AAC1B,MAAM,UAAU,GAAG,EAAE,CAAA,CAAC,kBAAkB;AACxC,MAAM,MAAM,GAAG,SAAS,CAAA;AAExB,gFAAgF;AAEhF,SAAS,KAAK,CAAC,MAAmB;IAChC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SAC3C,IAAI,CAAC,EAAE,CAAC,CAAA;AACb,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IAClD,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,iFAAiF;AAEjF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,MAAM,SAAS,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAA;IAC5D,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IAEpC,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAC/C,KAAK,EACL,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAClC,QAAQ,EACR,KAAK,EACL,CAAC,YAAY,CAAC,CACf,CAAA;IAED,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,UAAU,CAC/C;QACE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,UAAU;QACtB,IAAI,EAAE,MAAM;KACb,EACD,WAAW,EACX,UAAU,GAAG,CAAC,CACf,CAAA;IAED,OAAO,GAAG,IAAI,IAAI,KAAK,CAAC,UAAU,CAAC,EAAE,CAAA;AACvC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAgB,EAChB,UAAkB;IAElB,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAChD,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAA;IAEtC,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAElC,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAC/C,KAAK,EACL,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAClC,QAAQ,EACR,KAAK,EACL,CAAC,YAAY,CAAC,CACf,CAAA;IAED,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,UAAU,CAC/C;QACE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,UAAU;QACtB,IAAI,EAAE,MAAM;KACb,EACD,WAAW,EACX,UAAU,GAAG,CAAC,CACf,CAAA;IAED,MAAM,YAAY,GAAG,KAAK,CAAC,UAAU,CAAC,CAAA;IAEtC,yEAAyE;IACzE,IAAI,YAAY,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IACxD,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,IAAI,IAAI,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;IAC5D,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,CAAA;AACnB,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * ──────────────────────────────────────────────────────────────────
3
+ * 🏢 Company Name: Bonifade Technologies
4
+ * 👨‍💻 Developer: Bowofade Oyerinde
5
+ * 🐙 GitHub: oyenet1
6
+ * 📅 Created Date: 2026-04-05
7
+ * 🔄 Updated Date: 2026-04-05
8
+ * ──────────────────────────────────────────────────────────────────
9
+ */
10
+ import type { AppVariables, AuthAccount } from 'vonosan/types';
11
+ type AuthVariables = AppVariables & {
12
+ account: AuthAccount;
13
+ };
14
+ /**
15
+ * `authMiddleware` — verifies the Bearer JWT, loads the account from DB,
16
+ * and sets `c.var.account`. Returns 401 on missing/invalid token.
17
+ */
18
+ export declare const authMiddleware: import("hono").MiddlewareHandler<{
19
+ Variables: AuthVariables;
20
+ }, string, {}>;
21
+ /**
22
+ * `optionalAuthMiddleware` — silently continues as guest on invalid/missing token.
23
+ * Does not set `c.var.account` if authentication fails.
24
+ */
25
+ export declare const optionalAuthMiddleware: import("hono").MiddlewareHandler<{
26
+ Variables: AppVariables;
27
+ }, string, {}>;
28
+ /**
29
+ * `isAdmin` — 403 if the authenticated user is not admin or superadmin.
30
+ * Must be used after `authMiddleware`.
31
+ */
32
+ export declare const isAdmin: import("hono").MiddlewareHandler<{
33
+ Variables: AuthVariables;
34
+ }, string, {}>;
35
+ /**
36
+ * `isSuperAdmin` — 403 if the authenticated user is not superadmin.
37
+ * Must be used after `authMiddleware`.
38
+ */
39
+ export declare const isSuperAdmin: import("hono").MiddlewareHandler<{
40
+ Variables: AuthVariables;
41
+ }, string, {}>;
42
+ /**
43
+ * `apiKeyOrJwtMiddleware` — accepts either a Bearer JWT or a `vono_*` API key.
44
+ * Sets `c.var.account` on success; returns 401 on failure.
45
+ */
46
+ export declare const apiKeyOrJwtMiddleware: import("hono").MiddlewareHandler<{
47
+ Variables: AuthVariables;
48
+ }, string, {}>;
49
+ export {};
50
+ //# sourceMappingURL=auth.middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAS9D,KAAK,aAAa,GAAG,YAAY,GAAG;IAAE,OAAO,EAAE,WAAW,CAAA;CAAE,CAAA;AAK5D;;;GAGG;AACH,eAAO,MAAM,cAAc;eAAiC,aAAa;cAwCxE,CAAA;AAID;;;GAGG;AACH,eAAO,MAAM,sBAAsB;eAAiC,YAAY;cAyC/E,CAAA;AAID;;;GAGG;AACH,eAAO,MAAM,OAAO;eAAiC,aAAa;cAShE,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY;eAAiC,aAAa;cAWtE,CAAA;AAID;;;GAGG;AACH,eAAO,MAAM,qBAAqB;eAAiC,aAAa;cAoF/E,CAAA"}