@opensyber/tokenforge 0.1.1 → 1.0.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 (142) hide show
  1. package/LICENSE.md +32 -0
  2. package/README.md +205 -47
  3. package/dist/adapters/astro.d.ts +55 -0
  4. package/dist/adapters/astro.d.ts.map +1 -0
  5. package/dist/adapters/astro.js +91 -0
  6. package/dist/adapters/astro.js.map +1 -0
  7. package/dist/adapters/express.d.ts +15 -0
  8. package/dist/adapters/express.d.ts.map +1 -1
  9. package/dist/adapters/express.js +27 -0
  10. package/dist/adapters/express.js.map +1 -1
  11. package/dist/adapters/fastify.d.ts +17 -0
  12. package/dist/adapters/fastify.d.ts.map +1 -1
  13. package/dist/adapters/fastify.js +27 -0
  14. package/dist/adapters/fastify.js.map +1 -1
  15. package/dist/adapters/hono.d.ts +8 -4
  16. package/dist/adapters/hono.d.ts.map +1 -1
  17. package/dist/adapters/hono.js +7 -4
  18. package/dist/adapters/hono.js.map +1 -1
  19. package/dist/adapters/index.d.ts +5 -3
  20. package/dist/adapters/index.d.ts.map +1 -1
  21. package/dist/adapters/index.js +5 -3
  22. package/dist/adapters/index.js.map +1 -1
  23. package/dist/adapters/nextjs.d.ts +16 -0
  24. package/dist/adapters/nextjs.d.ts.map +1 -1
  25. package/dist/adapters/nextjs.js +26 -0
  26. package/dist/adapters/nextjs.js.map +1 -1
  27. package/dist/adapters/sveltekit.d.ts +57 -0
  28. package/dist/adapters/sveltekit.d.ts.map +1 -0
  29. package/dist/adapters/sveltekit.js +88 -0
  30. package/dist/adapters/sveltekit.js.map +1 -0
  31. package/dist/client/action-signer.d.ts +53 -0
  32. package/dist/client/action-signer.d.ts.map +1 -0
  33. package/dist/client/action-signer.js +48 -0
  34. package/dist/client/action-signer.js.map +1 -0
  35. package/dist/client/binding.d.ts +24 -7
  36. package/dist/client/binding.d.ts.map +1 -1
  37. package/dist/client/binding.js +17 -6
  38. package/dist/client/binding.js.map +1 -1
  39. package/dist/client/index.d.ts +13 -0
  40. package/dist/client/index.d.ts.map +1 -1
  41. package/dist/client/index.js +27 -1
  42. package/dist/client/index.js.map +1 -1
  43. package/dist/client/signer.d.ts +17 -0
  44. package/dist/client/signer.d.ts.map +1 -1
  45. package/dist/client/signer.js +23 -0
  46. package/dist/client/signer.js.map +1 -1
  47. package/dist/client/webauthn.d.ts +45 -0
  48. package/dist/client/webauthn.d.ts.map +1 -0
  49. package/dist/client/webauthn.js +118 -0
  50. package/dist/client/webauthn.js.map +1 -0
  51. package/dist/server/action-verify.d.ts +56 -0
  52. package/dist/server/action-verify.d.ts.map +1 -0
  53. package/dist/server/action-verify.js +47 -0
  54. package/dist/server/action-verify.js.map +1 -0
  55. package/dist/server/aitm-heuristics.d.ts +57 -0
  56. package/dist/server/aitm-heuristics.d.ts.map +1 -0
  57. package/dist/server/aitm-heuristics.js +120 -0
  58. package/dist/server/aitm-heuristics.js.map +1 -0
  59. package/dist/server/bound-cookie.d.ts +39 -0
  60. package/dist/server/bound-cookie.d.ts.map +1 -0
  61. package/dist/server/bound-cookie.js +59 -0
  62. package/dist/server/bound-cookie.js.map +1 -0
  63. package/dist/server/cbor.d.ts +20 -0
  64. package/dist/server/cbor.d.ts.map +1 -0
  65. package/dist/server/cbor.js +110 -0
  66. package/dist/server/cbor.js.map +1 -0
  67. package/dist/server/dbsc-challenge.d.ts +51 -0
  68. package/dist/server/dbsc-challenge.d.ts.map +1 -0
  69. package/dist/server/dbsc-challenge.js +78 -0
  70. package/dist/server/dbsc-challenge.js.map +1 -0
  71. package/dist/server/index.d.ts +2 -4
  72. package/dist/server/index.d.ts.map +1 -1
  73. package/dist/server/index.js +6 -4
  74. package/dist/server/index.js.map +1 -1
  75. package/dist/server/jws-verify.d.ts +46 -0
  76. package/dist/server/jws-verify.d.ts.map +1 -0
  77. package/dist/server/jws-verify.js +64 -0
  78. package/dist/server/jws-verify.js.map +1 -0
  79. package/dist/server/middleware.d.ts +15 -0
  80. package/dist/server/middleware.d.ts.map +1 -1
  81. package/dist/server/middleware.js +27 -0
  82. package/dist/server/middleware.js.map +1 -1
  83. package/dist/server/oidc-verify.d.ts +56 -0
  84. package/dist/server/oidc-verify.d.ts.map +1 -0
  85. package/dist/server/oidc-verify.js +107 -0
  86. package/dist/server/oidc-verify.js.map +1 -0
  87. package/dist/server/policy.d.ts +47 -0
  88. package/dist/server/policy.d.ts.map +1 -0
  89. package/dist/server/policy.js +84 -0
  90. package/dist/server/policy.js.map +1 -0
  91. package/dist/server/step-up-policy.d.ts +36 -0
  92. package/dist/server/step-up-policy.d.ts.map +1 -0
  93. package/dist/server/step-up-policy.js +101 -0
  94. package/dist/server/step-up-policy.js.map +1 -0
  95. package/dist/server/trust-score-fixtures.d.ts +9 -0
  96. package/dist/server/trust-score-fixtures.d.ts.map +1 -0
  97. package/dist/server/trust-score-fixtures.js +23 -0
  98. package/dist/server/trust-score-fixtures.js.map +1 -0
  99. package/dist/server/webauthn-verify.d.ts +41 -0
  100. package/dist/server/webauthn-verify.d.ts.map +1 -0
  101. package/dist/server/webauthn-verify.js +175 -0
  102. package/dist/server/webauthn-verify.js.map +1 -0
  103. package/dist/server/webauthn-verify.test-helpers.d.ts +8 -0
  104. package/dist/server/webauthn-verify.test-helpers.d.ts.map +1 -0
  105. package/dist/server/webauthn-verify.test-helpers.js +39 -0
  106. package/dist/server/webauthn-verify.test-helpers.js.map +1 -0
  107. package/dist/server/webhooks.d.ts +42 -0
  108. package/dist/server/webhooks.d.ts.map +1 -0
  109. package/dist/server/webhooks.js +77 -0
  110. package/dist/server/webhooks.js.map +1 -0
  111. package/dist/shared/action-hash.d.ts +23 -0
  112. package/dist/shared/action-hash.d.ts.map +1 -0
  113. package/dist/shared/action-hash.js +35 -0
  114. package/dist/shared/action-hash.js.map +1 -0
  115. package/dist/shared/types.d.ts +2 -0
  116. package/dist/shared/types.d.ts.map +1 -1
  117. package/dist/shared/types.js.map +1 -1
  118. package/package.json +44 -16
  119. package/dist/server/binding.d.ts +0 -19
  120. package/dist/server/binding.d.ts.map +0 -1
  121. package/dist/server/binding.js +0 -87
  122. package/dist/server/binding.js.map +0 -1
  123. package/dist/server/step-up.d.ts +0 -19
  124. package/dist/server/step-up.d.ts.map +0 -1
  125. package/dist/server/step-up.js +0 -139
  126. package/dist/server/step-up.js.map +0 -1
  127. package/dist/server/storage/index.d.ts +0 -3
  128. package/dist/server/storage/index.d.ts.map +0 -1
  129. package/dist/server/storage/index.js +0 -2
  130. package/dist/server/storage/index.js.map +0 -1
  131. package/dist/server/storage/interface.d.ts +0 -61
  132. package/dist/server/storage/interface.d.ts.map +0 -1
  133. package/dist/server/storage/interface.js +0 -2
  134. package/dist/server/storage/interface.js.map +0 -1
  135. package/dist/server/storage/memory.d.ts +0 -40
  136. package/dist/server/storage/memory.d.ts.map +0 -1
  137. package/dist/server/storage/memory.js +0 -107
  138. package/dist/server/storage/memory.js.map +0 -1
  139. package/dist/server/totp.d.ts +0 -53
  140. package/dist/server/totp.d.ts.map +0 -1
  141. package/dist/server/totp.js +0 -114
  142. package/dist/server/totp.js.map +0 -1
@@ -1,114 +0,0 @@
1
- export const TOTP_MAX_ATTEMPTS = 5;
2
- export const TOTP_LOCKOUT_WINDOW_SECONDS = 300; // 5 min — matches the OWASP ASVS V6.2.6 guidance
3
- export class TotpLockedOutError extends Error {
4
- retryAfterSeconds;
5
- constructor(retryAfterSeconds) {
6
- super(`Too many failed TOTP attempts; locked out for ${retryAfterSeconds}s`);
7
- this.retryAfterSeconds = retryAfterSeconds;
8
- this.name = 'TotpLockedOutError';
9
- }
10
- }
11
- /**
12
- * TOTP verification (RFC 6238) using HMAC-SHA1.
13
- * Time step: 30 seconds, window: +/-1 step tolerance.
14
- *
15
- * Rate-limiting: when `options.rateLimiter` is provided, the user is
16
- * locked out for TOTP_LOCKOUT_WINDOW_SECONDS after TOTP_MAX_ATTEMPTS
17
- * failures. A TotpLockedOutError is thrown while locked so callers can
18
- * return a distinct 429 to the client instead of a generic "invalid
19
- * code". A successful verification resets the counter immediately.
20
- *
21
- * @param code - The 6-digit TOTP code from the user.
22
- * @param userId - User whose TOTP secret to look up.
23
- * @param options - Server options; must include `getTotpSecret` callback.
24
- * @returns True if the code is valid for the current or adjacent time window.
25
- * @throws TotpLockedOutError if the user is currently locked out.
26
- */
27
- export async function verifyTotp(code, userId, options) {
28
- if (!options.getTotpSecret)
29
- return false;
30
- const limiter = options.rateLimiter;
31
- if (limiter) {
32
- const attempts = await limiter.getFailedAttempts(userId);
33
- if (attempts >= TOTP_MAX_ATTEMPTS) {
34
- throw new TotpLockedOutError(TOTP_LOCKOUT_WINDOW_SECONDS);
35
- }
36
- }
37
- const secret = await options.getTotpSecret(userId);
38
- if (!secret) {
39
- if (limiter)
40
- await limiter.recordFailedAttempt(userId, TOTP_LOCKOUT_WINDOW_SECONDS);
41
- return false;
42
- }
43
- const now = Math.floor(Date.now() / 1000);
44
- const timeStep = 30;
45
- // Check current window and ±1 step for clock skew tolerance
46
- for (const offset of [-1, 0, 1]) {
47
- const counter = Math.floor((now + offset * timeStep) / timeStep);
48
- const expected = await generateTotp(secret, counter);
49
- if (timingSafeEqual(code, expected)) {
50
- if (limiter)
51
- await limiter.resetFailedAttempts(userId);
52
- return true;
53
- }
54
- }
55
- if (limiter)
56
- await limiter.recordFailedAttempt(userId, TOTP_LOCKOUT_WINDOW_SECONDS);
57
- return false;
58
- }
59
- /**
60
- * Generate a TOTP code for a given counter value.
61
- * Uses HMAC-SHA1 per RFC 4226, with 6-digit output.
62
- * @param secretBase32 - Base32-encoded shared secret.
63
- * @param counter - HMAC counter value (typically `floor(time / 30)`).
64
- * @returns A 6-digit zero-padded TOTP code.
65
- */
66
- export async function generateTotp(secretBase32, counter) {
67
- const keyBytes = base32Decode(secretBase32);
68
- const counterBytes = new ArrayBuffer(8);
69
- const view = new DataView(counterBytes);
70
- view.setBigUint64(0, BigInt(counter));
71
- const key = await crypto.subtle.importKey('raw', keyBytes.buffer, { name: 'HMAC', hash: 'SHA-1' }, false, ['sign']);
72
- const hmac = await crypto.subtle.sign('HMAC', key, counterBytes);
73
- const hmacArray = new Uint8Array(hmac);
74
- // Dynamic truncation (RFC 4226 section 5.3)
75
- const offset = hmacArray[hmacArray.length - 1] & 0x0f;
76
- const binary = ((hmacArray[offset] & 0x7f) << 24) |
77
- ((hmacArray[offset + 1] & 0xff) << 16) |
78
- ((hmacArray[offset + 2] & 0xff) << 8) |
79
- (hmacArray[offset + 3] & 0xff);
80
- return (binary % 1000000).toString().padStart(6, '0');
81
- }
82
- /** Decode a base32-encoded string (RFC 4648, no padding required) */
83
- function base32Decode(input) {
84
- const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
85
- const clean = input.replace(/[= ]/g, '').toUpperCase();
86
- const bits = [];
87
- for (const char of clean) {
88
- const val = alphabet.indexOf(char);
89
- if (val === -1)
90
- continue;
91
- for (let i = 4; i >= 0; i--) {
92
- bits.push((val >> i) & 1);
93
- }
94
- }
95
- const bytes = new Uint8Array(Math.floor(bits.length / 8));
96
- for (let i = 0; i < bytes.length; i++) {
97
- let byte = 0;
98
- for (let j = 0; j < 8; j++) {
99
- byte = (byte << 1) | (bits[i * 8 + j] ?? 0);
100
- }
101
- bytes[i] = byte;
102
- }
103
- return bytes;
104
- }
105
- /** Constant-time string comparison to prevent timing attacks */
106
- function timingSafeEqual(a, b) {
107
- const maxLen = Math.max(a.length, b.length);
108
- let result = a.length ^ b.length; // length mismatch contributes to failure
109
- for (let i = 0; i < maxLen; i++) {
110
- result |= (a.charCodeAt(i) || 0) ^ (b.charCodeAt(i) || 0);
111
- }
112
- return result === 0;
113
- }
114
- //# sourceMappingURL=totp.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"totp.js","sourceRoot":"","sources":["../../src/server/totp.ts"],"names":[],"mappings":"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"}