@access-dlsu/leapify 0.260507.4 → 0.260524.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 (139) hide show
  1. package/dist/app.d.ts.map +1 -1
  2. package/dist/auth/auth.d.ts.map +1 -1
  3. package/dist/auth/middleware.d.ts.map +1 -1
  4. package/dist/chunk-64MMUYMK.cjs +167 -0
  5. package/dist/chunk-64MMUYMK.cjs.map +1 -0
  6. package/dist/chunk-AKCERDGP.js +161 -0
  7. package/dist/chunk-AKCERDGP.js.map +1 -0
  8. package/dist/client/auth.d.ts +1 -13
  9. package/dist/client/auth.d.ts.map +1 -1
  10. package/dist/client/index.cjs +55 -841
  11. package/dist/client/index.cjs.map +1 -1
  12. package/dist/client/index.d.ts +3 -8
  13. package/dist/client/index.d.ts.map +1 -1
  14. package/dist/client/index.js +53 -839
  15. package/dist/client/index.js.map +1 -1
  16. package/dist/client/turnstile.d.ts +25 -0
  17. package/dist/client/turnstile.d.ts.map +1 -0
  18. package/dist/client/types.d.ts +2 -15
  19. package/dist/client/types.d.ts.map +1 -1
  20. package/dist/db/migrate.d.ts.map +1 -1
  21. package/dist/db/schema/classes.d.ts +0 -19
  22. package/dist/db/schema/classes.d.ts.map +1 -1
  23. package/dist/db/schema/site-config.d.ts +0 -83
  24. package/dist/db/schema/site-config.d.ts.map +1 -1
  25. package/dist/index.cjs +687 -38309
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.ts +3 -5
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +541 -38156
  30. package/dist/index.js.map +1 -1
  31. package/dist/lib/middleware/cors.d.ts.map +1 -1
  32. package/dist/lib/middleware/rate-limit.d.ts.map +1 -1
  33. package/dist/lib/middleware/referer-guard.d.ts.map +1 -1
  34. package/dist/lib/middleware/turnstile-challenge.cjs +29 -0
  35. package/dist/lib/middleware/turnstile-challenge.cjs.map +1 -0
  36. package/dist/lib/middleware/turnstile-challenge.d.ts +45 -0
  37. package/dist/lib/middleware/turnstile-challenge.d.ts.map +1 -0
  38. package/dist/lib/middleware/turnstile-challenge.js +4 -0
  39. package/dist/lib/middleware/turnstile-challenge.js.map +1 -0
  40. package/dist/queues/jobs.d.ts +0 -5
  41. package/dist/queues/jobs.d.ts.map +1 -1
  42. package/dist/routes/classes.d.ts.map +1 -1
  43. package/dist/routes/faqs.d.ts.map +1 -1
  44. package/dist/routes/site-config.d.ts.map +1 -1
  45. package/dist/routes/themes.d.ts.map +1 -1
  46. package/dist/routes/uploads.d.ts.map +1 -1
  47. package/dist/types.d.ts +5 -26
  48. package/dist/types.d.ts.map +1 -1
  49. package/dist/worker-handler.d.ts +1 -0
  50. package/dist/worker-handler.d.ts.map +1 -1
  51. package/dist/worker.js +704 -64338
  52. package/dist/worker.js.map +1 -1
  53. package/package.json +155 -153
  54. package/dist/bun-sqlite-dialect-na--YwnN-NIYANHVJ.cjs +0 -162
  55. package/dist/bun-sqlite-dialect-na--YwnN-NIYANHVJ.cjs.map +0 -1
  56. package/dist/bun-sqlite-dialect-na--YwnN-XVQNOKSL.js +0 -160
  57. package/dist/bun-sqlite-dialect-na--YwnN-XVQNOKSL.js.map +0 -1
  58. package/dist/chunk-4DPT2KQR.cjs +0 -467
  59. package/dist/chunk-4DPT2KQR.cjs.map +0 -1
  60. package/dist/chunk-5JKLV7IE.cjs +0 -2962
  61. package/dist/chunk-5JKLV7IE.cjs.map +0 -1
  62. package/dist/chunk-5OQD5ALM.cjs +0 -76
  63. package/dist/chunk-5OQD5ALM.cjs.map +0 -1
  64. package/dist/chunk-6MMWL46O.cjs +0 -7170
  65. package/dist/chunk-6MMWL46O.cjs.map +0 -1
  66. package/dist/chunk-BFMJDSDI.cjs +0 -2297
  67. package/dist/chunk-BFMJDSDI.cjs.map +0 -1
  68. package/dist/chunk-EGRHWZRV.js +0 -3
  69. package/dist/chunk-EGRHWZRV.js.map +0 -1
  70. package/dist/chunk-EMMSS5I5.cjs +0 -37
  71. package/dist/chunk-EMMSS5I5.cjs.map +0 -1
  72. package/dist/chunk-FUCJEA2S.js +0 -6196
  73. package/dist/chunk-FUCJEA2S.js.map +0 -1
  74. package/dist/chunk-G3PMV62Z.js +0 -33
  75. package/dist/chunk-G3PMV62Z.js.map +0 -1
  76. package/dist/chunk-GNRL67OU.js +0 -2949
  77. package/dist/chunk-GNRL67OU.js.map +0 -1
  78. package/dist/chunk-HHNEB7YR.js +0 -8
  79. package/dist/chunk-HHNEB7YR.js.map +0 -1
  80. package/dist/chunk-IQEWVHLM.js +0 -889
  81. package/dist/chunk-IQEWVHLM.js.map +0 -1
  82. package/dist/chunk-JIZPYG6H.js +0 -72
  83. package/dist/chunk-JIZPYG6H.js.map +0 -1
  84. package/dist/chunk-JPVIXCF5.cjs +0 -10
  85. package/dist/chunk-JPVIXCF5.cjs.map +0 -1
  86. package/dist/chunk-JQSZJWBN.cjs +0 -3075
  87. package/dist/chunk-JQSZJWBN.cjs.map +0 -1
  88. package/dist/chunk-LJ5BSSYE.js +0 -2286
  89. package/dist/chunk-LJ5BSSYE.js.map +0 -1
  90. package/dist/chunk-MCOLCTFX.js +0 -213
  91. package/dist/chunk-MCOLCTFX.js.map +0 -1
  92. package/dist/chunk-MKWVLWVJ.cjs +0 -219
  93. package/dist/chunk-MKWVLWVJ.cjs.map +0 -1
  94. package/dist/chunk-MNEW2V4T.js +0 -447
  95. package/dist/chunk-MNEW2V4T.js.map +0 -1
  96. package/dist/chunk-MY37YE52.js +0 -3034
  97. package/dist/chunk-MY37YE52.js.map +0 -1
  98. package/dist/chunk-NKIQRCOM.cjs +0 -4
  99. package/dist/chunk-NKIQRCOM.cjs.map +0 -1
  100. package/dist/chunk-OK6RVPEH.cjs +0 -6200
  101. package/dist/chunk-OK6RVPEH.cjs.map +0 -1
  102. package/dist/chunk-RFP2X2FA.cjs +0 -903
  103. package/dist/chunk-RFP2X2FA.cjs.map +0 -1
  104. package/dist/chunk-XJSWMHDL.js +0 -7142
  105. package/dist/chunk-XJSWMHDL.js.map +0 -1
  106. package/dist/client/pow.d.ts +0 -28
  107. package/dist/client/pow.d.ts.map +0 -1
  108. package/dist/cron/lifecycle-check.d.ts +0 -10
  109. package/dist/cron/lifecycle-check.d.ts.map +0 -1
  110. package/dist/d1-sqlite-dialect-C2B7YsIT-6TVV7EJ5.js +0 -122
  111. package/dist/d1-sqlite-dialect-C2B7YsIT-6TVV7EJ5.js.map +0 -1
  112. package/dist/d1-sqlite-dialect-C2B7YsIT-PE74FLHQ.cjs +0 -124
  113. package/dist/d1-sqlite-dialect-C2B7YsIT-PE74FLHQ.cjs.map +0 -1
  114. package/dist/dist-DZHA5VYX.cjs +0 -260
  115. package/dist/dist-DZHA5VYX.cjs.map +0 -1
  116. package/dist/dist-RRQUBLLO.js +0 -258
  117. package/dist/dist-RRQUBLLO.js.map +0 -1
  118. package/dist/kysely-adapter-C76KJVG7.js +0 -10
  119. package/dist/kysely-adapter-C76KJVG7.js.map +0 -1
  120. package/dist/kysely-adapter-TGY4UUP5.cjs +0 -27
  121. package/dist/kysely-adapter-TGY4UUP5.cjs.map +0 -1
  122. package/dist/lib/middleware/pow-challenge.cjs +0 -29
  123. package/dist/lib/middleware/pow-challenge.cjs.map +0 -1
  124. package/dist/lib/middleware/pow-challenge.d.ts +0 -58
  125. package/dist/lib/middleware/pow-challenge.d.ts.map +0 -1
  126. package/dist/lib/middleware/pow-challenge.js +0 -4
  127. package/dist/lib/middleware/pow-challenge.js.map +0 -1
  128. package/dist/node-sqlite-dialect-B3H37T3R.cjs +0 -162
  129. package/dist/node-sqlite-dialect-B3H37T3R.cjs.map +0 -1
  130. package/dist/node-sqlite-dialect-GDP7ZE54.js +0 -160
  131. package/dist/node-sqlite-dialect-GDP7ZE54.js.map +0 -1
  132. package/dist/routes/contentful-sync.d.ts +0 -4
  133. package/dist/routes/contentful-sync.d.ts.map +0 -1
  134. package/dist/services/contentful-management.d.ts +0 -38
  135. package/dist/services/contentful-management.d.ts.map +0 -1
  136. package/dist/services/contentful.d.ts +0 -97
  137. package/dist/services/contentful.d.ts.map +0 -1
  138. package/dist/services/snapshot.d.ts +0 -95
  139. package/dist/services/snapshot.d.ts.map +0 -1
package/dist/app.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAuBzC,MAAM,WAAW,iBAAiB;IAChC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,wBAAgB,SAAS,CAAC,OAAO,GAAE,iBAAsB,GAAG,IAAI,CAAC,UAAU,CAAC,CA4F3E"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAqBzC,MAAM,WAAW,iBAAiB;IAChC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,wBAAgB,SAAS,CAAC,OAAO,GAAE,iBAAsB,GAAG,IAAI,CAAC,UAAU,CAAC,CAkF3E"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/auth/auth.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAI/C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAoCrC;;;mBAGG;;;;;;;;;;;;;;;;;;;;gBAWH;;;;;;;mBAOG;;;;;;;;;;;;;GAiCZ;AAED,MAAM,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAA"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/auth/auth.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAI/C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAoCrC;;;mBAGG;;;;;;;;;;;;;;;;;;;;gBAWH;;;;;;;mBAOG;;;;;;;;;;;;;GA2CZ;AAED,MAAM,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/auth/middleware.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAM1C,OAAO,QAAQ,MAAM,CAAC;IACpB,UAAU,kBAAkB;QAC1B,IAAI,EAAE,WAAW,CAAA;KAClB;CACF;AA4DD,eAAO,MAAM,cAAc;cAAgC,eAAe;wBAsDzE,CAAA;AAID,eAAO,MAAM,sBAAsB;cACvB,eAAe;wBAUzB,CAAA;AAIF,eAAO,MAAM,eAAe;cAAgC,eAAe;wBAQ1E,CAAA;AAID,eAAO,MAAM,kBAAkB;cACnB,eAAe;wBAOzB,CAAA"}
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/auth/middleware.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAM1C,OAAO,QAAQ,MAAM,CAAC;IACpB,UAAU,kBAAkB;QAC1B,IAAI,EAAE,WAAW,CAAA;KAClB;CACF;AAkED,eAAO,MAAM,cAAc;cAAgC,eAAe;wBAsDzE,CAAA;AAID,eAAO,MAAM,sBAAsB;cACvB,eAAe;wBAUzB,CAAA;AAIF,eAAO,MAAM,eAAe;cAAgC,eAAe;wBAQ1E,CAAA;AAID,eAAO,MAAM,kBAAkB;cACnB,eAAe;wBAOzB,CAAA"}
@@ -0,0 +1,167 @@
1
+ 'use strict';
2
+
3
+ var factory = require('hono/factory');
4
+
5
+ // src/lib/middleware/turnstile-challenge.ts
6
+ var TURNSTILE_PATH = "/.well-known/leapify/turnstile";
7
+ var TURNSTILE_VERIFY_PATH = `${TURNSTILE_PATH}/verify`;
8
+ var TURNSTILE_COOKIE_NAME = "leapify-turnstile";
9
+ var VERIFY_URL = "https://challenges.cloudflare.com/turnstile/v0/siteverify";
10
+ var COOKIE_MAX_AGE_SEC = 86400;
11
+ var EXEMPT_PATHS = [
12
+ "/health",
13
+ "/internal",
14
+ "/api/auth",
15
+ "/api/uploads/images",
16
+ "/api/classes",
17
+ "/api/faqs",
18
+ "/api/config",
19
+ TURNSTILE_VERIFY_PATH
20
+ ];
21
+ function base64urlEncode(bytes) {
22
+ let binary = "";
23
+ for (const byte of bytes) {
24
+ binary += String.fromCharCode(byte);
25
+ }
26
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
27
+ }
28
+ function base64urlDecode(str) {
29
+ const padded = str.replace(/-/g, "+").replace(/_/g, "/");
30
+ const binary = atob(padded);
31
+ const bytes = new Uint8Array(new ArrayBuffer(binary.length));
32
+ for (let i = 0; i < binary.length; i++) {
33
+ bytes[i] = binary.charCodeAt(i);
34
+ }
35
+ return bytes;
36
+ }
37
+ async function importHmacKey(secret) {
38
+ return crypto.subtle.importKey(
39
+ "raw",
40
+ new TextEncoder().encode(secret),
41
+ { name: "HMAC", hash: "SHA-256" },
42
+ false,
43
+ ["sign", "verify"]
44
+ );
45
+ }
46
+ async function signCookie(secret, ip) {
47
+ const ts = Date.now();
48
+ const nonce = base64urlEncode(crypto.getRandomValues(new Uint8Array(8)));
49
+ const payload = `${ip}:${ts}:${nonce}`;
50
+ const key = await importHmacKey(secret);
51
+ const sig = await crypto.subtle.sign(
52
+ "HMAC",
53
+ key,
54
+ new TextEncoder().encode(payload)
55
+ );
56
+ const sigB64 = base64urlEncode(new Uint8Array(sig));
57
+ return `${base64urlEncode(new TextEncoder().encode(payload))}.${sigB64}`;
58
+ }
59
+ async function validateCookie(secret, cookie, ip) {
60
+ try {
61
+ const [payloadB64, sigB64] = cookie.split(".");
62
+ if (!payloadB64 || !sigB64) return false;
63
+ const payloadBytes = base64urlDecode(payloadB64);
64
+ const sigBytes = base64urlDecode(sigB64);
65
+ const key = await importHmacKey(secret);
66
+ const valid = await crypto.subtle.verify(
67
+ "HMAC",
68
+ key,
69
+ sigBytes,
70
+ payloadBytes
71
+ );
72
+ if (!valid) return false;
73
+ const payload = new TextDecoder().decode(payloadBytes);
74
+ const [cookieIp, tsStr] = payload.split(":");
75
+ if (cookieIp !== ip) return false;
76
+ const ts = parseInt(tsStr, 10);
77
+ if (isNaN(ts) || Date.now() - ts > COOKIE_MAX_AGE_SEC * 1e3) return false;
78
+ return true;
79
+ } catch {
80
+ return false;
81
+ }
82
+ }
83
+ function getClientIp(c) {
84
+ return c.req.header("CF-Connecting-IP") ?? c.req.header("X-Real-IP") ?? c.req.header("X-Forwarded-For")?.split(",")[0]?.trim() ?? "unknown";
85
+ }
86
+ function isExempt(path) {
87
+ const normalized = path.toLowerCase().replace(/\/$/, "");
88
+ return EXEMPT_PATHS.some((p) => {
89
+ const ep = p.toLowerCase().replace(/\/$/, "");
90
+ return normalized === ep || normalized.startsWith(ep + "/");
91
+ });
92
+ }
93
+ function setCookieHeader(c, token) {
94
+ const isSecure = c.req.raw.url.startsWith("https") || c.req.header("x-forwarded-proto") === "https";
95
+ c.header(
96
+ "Set-Cookie",
97
+ `${TURNSTILE_COOKIE_NAME}=${token}; Path=/; Max-Age=${COOKIE_MAX_AGE_SEC}; ${isSecure ? "Secure; " : ""}HttpOnly; SameSite=Lax`
98
+ );
99
+ }
100
+ async function handleTurnstileVerify(c) {
101
+ const body = await c.req.json();
102
+ const { token } = body;
103
+ if (!token) {
104
+ return c.json(
105
+ { error: { code: "VALIDATION_ERROR", message: "Missing Turnstile token" } },
106
+ 422
107
+ );
108
+ }
109
+ const secret = c.env.TURNSTILE_SECRET_KEY;
110
+ if (!secret) {
111
+ return c.json(
112
+ { error: { code: "CONFIG_ERROR", message: "Turnstile not configured" } },
113
+ 500
114
+ );
115
+ }
116
+ const ip = getClientIp(c);
117
+ const formData = new URLSearchParams();
118
+ formData.append("secret", secret);
119
+ formData.append("response", token);
120
+ if (ip !== "unknown") {
121
+ formData.append("remoteip", ip);
122
+ }
123
+ const res = await fetch(VERIFY_URL, {
124
+ method: "POST",
125
+ body: formData
126
+ });
127
+ const outcome = await res.json();
128
+ if (!outcome.success) {
129
+ return c.json(
130
+ { error: { code: "TURNSTILE_FAILED", message: "Turnstile verification failed", details: outcome["error-codes"] } },
131
+ 403
132
+ );
133
+ }
134
+ const cookieToken = await signCookie(secret, ip);
135
+ setCookieHeader(c, cookieToken);
136
+ return c.json({ success: true });
137
+ }
138
+ function createTurnstileMiddleware() {
139
+ return factory.createMiddleware(async (c, next) => {
140
+ if (isExempt(c.req.path)) return next();
141
+ if (c.req.method === "OPTIONS") return next();
142
+ if (c.req.header("Authorization")) return next();
143
+ const secret = c.env.TURNSTILE_SECRET_KEY;
144
+ if (!secret) return next();
145
+ const cookieHeader = c.req.header("Cookie") ?? "";
146
+ const cookieMatch = cookieHeader.match(
147
+ new RegExp(`${TURNSTILE_COOKIE_NAME}=([^;]+)`)
148
+ );
149
+ if (cookieMatch) {
150
+ const ip = getClientIp(c);
151
+ const valid = await validateCookie(secret, cookieMatch[1], ip);
152
+ if (valid) return next();
153
+ }
154
+ return c.json(
155
+ { error: { code: "TURNSTILE_REQUIRED", message: "Turnstile verification required" } },
156
+ 401
157
+ );
158
+ });
159
+ }
160
+
161
+ exports.TURNSTILE_COOKIE_NAME = TURNSTILE_COOKIE_NAME;
162
+ exports.TURNSTILE_PATH = TURNSTILE_PATH;
163
+ exports.TURNSTILE_VERIFY_PATH = TURNSTILE_VERIFY_PATH;
164
+ exports.createTurnstileMiddleware = createTurnstileMiddleware;
165
+ exports.handleTurnstileVerify = handleTurnstileVerify;
166
+ //# sourceMappingURL=chunk-64MMUYMK.cjs.map
167
+ //# sourceMappingURL=chunk-64MMUYMK.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/middleware/turnstile-challenge.ts"],"names":["createMiddleware"],"mappings":"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","file":"chunk-64MMUYMK.cjs","sourcesContent":["import { createMiddleware } from 'hono/factory'\nimport type { Context } from 'hono'\nimport type { LeapifyBindings } from '../../types'\n\nexport const TURNSTILE_PATH = '/.well-known/leapify/turnstile'\n\nexport const TURNSTILE_VERIFY_PATH = `${TURNSTILE_PATH}/verify`\n\nexport const TURNSTILE_COOKIE_NAME = 'leapify-turnstile'\n\nconst VERIFY_URL = 'https://challenges.cloudflare.com/turnstile/v0/siteverify'\n\nconst COOKIE_MAX_AGE_SEC = 86400\n\nconst EXEMPT_PATHS = [\n \"/health\",\n \"/internal\",\n \"/api/auth\",\n \"/api/uploads/images\",\n \"/api/classes\",\n \"/api/faqs\",\n \"/api/config\",\n TURNSTILE_VERIFY_PATH,\n];\n\nfunction base64urlEncode(bytes: Uint8Array): string {\n let binary = ''\n for (const byte of bytes) {\n binary += String.fromCharCode(byte)\n }\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\nfunction base64urlDecode(str: string): Uint8Array<ArrayBuffer> {\n const padded = str.replace(/-/g, '+').replace(/_/g, '/')\n const binary = atob(padded)\n const bytes = new Uint8Array(new ArrayBuffer(binary.length))\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n return bytes\n}\n\nasync function importHmacKey(secret: string): Promise<CryptoKey> {\n return crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign', 'verify']\n )\n}\n\nasync function signCookie(secret: string, ip: string): Promise<string> {\n const ts = Date.now()\n const nonce = base64urlEncode(crypto.getRandomValues(new Uint8Array(8)))\n const payload = `${ip}:${ts}:${nonce}`\n const key = await importHmacKey(secret)\n const sig = await crypto.subtle.sign(\n 'HMAC',\n key,\n new TextEncoder().encode(payload)\n )\n const sigB64 = base64urlEncode(new Uint8Array(sig))\n return `${base64urlEncode(new TextEncoder().encode(payload))}.${sigB64}`\n}\n\nasync function validateCookie(\n secret: string,\n cookie: string,\n ip: string\n): Promise<boolean> {\n try {\n const [payloadB64, sigB64] = cookie.split('.')\n if (!payloadB64 || !sigB64) return false\n\n const payloadBytes = base64urlDecode(payloadB64)\n const sigBytes = base64urlDecode(sigB64)\n\n const key = await importHmacKey(secret)\n const valid = await crypto.subtle.verify(\n 'HMAC',\n key,\n sigBytes,\n payloadBytes\n )\n if (!valid) return false\n\n const payload = new TextDecoder().decode(payloadBytes)\n const [cookieIp, tsStr] = payload.split(':')\n\n if (cookieIp !== ip) return false\n\n const ts = parseInt(tsStr, 10)\n if (isNaN(ts) || Date.now() - ts > COOKIE_MAX_AGE_SEC * 1000) return false\n\n return true\n } catch {\n return false\n }\n}\n\nfunction getClientIp(c: Context<{ Bindings: LeapifyBindings }>): string {\n return (\n c.req.header('CF-Connecting-IP') ??\n c.req.header('X-Real-IP') ??\n c.req.header('X-Forwarded-For')?.split(',')[0]?.trim() ??\n 'unknown'\n )\n}\n\nfunction isExempt(path: string): boolean {\n const normalized = path.toLowerCase().replace(/\\/$/, '')\n return EXEMPT_PATHS.some((p) => {\n const ep = p.toLowerCase().replace(/\\/$/, '')\n return normalized === ep || normalized.startsWith(ep + '/')\n })\n}\n\nfunction setCookieHeader(c: Context<{ Bindings: LeapifyBindings }>, token: string): void {\n const isSecure = c.req.raw.url.startsWith(\"https\") || c.req.header(\"x-forwarded-proto\") === \"https\";\n c.header(\n \"Set-Cookie\",\n `${TURNSTILE_COOKIE_NAME}=${token}; Path=/; Max-Age=${COOKIE_MAX_AGE_SEC}; ${\n isSecure ? \"Secure; \" : \"\"\n }HttpOnly; SameSite=Lax`,\n );\n}\n\n/**\n * POST /.well-known/leapify/turnstile/verify\n *\n * Validates a Turnstile token and issues a signed cookie on success.\n */\nexport async function handleTurnstileVerify(\n c: Context<{ Bindings: LeapifyBindings }>\n) {\n const body = await c.req.json<{ token?: string }>()\n const { token } = body\n\n if (!token) {\n return c.json(\n { error: { code: 'VALIDATION_ERROR', message: 'Missing Turnstile token' } },\n 422\n )\n }\n\n const secret = c.env.TURNSTILE_SECRET_KEY\n if (!secret) {\n return c.json(\n { error: { code: 'CONFIG_ERROR', message: 'Turnstile not configured' } },\n 500\n )\n }\n\n const ip = getClientIp(c)\n const formData = new URLSearchParams()\n formData.append('secret', secret)\n formData.append('response', token)\n if (ip !== 'unknown') {\n formData.append('remoteip', ip)\n }\n\n const res = await fetch(VERIFY_URL, {\n method: 'POST',\n body: formData,\n })\n const outcome = await res.json() as { success: boolean; 'error-codes'?: string[] }\n\n if (!outcome.success) {\n return c.json(\n { error: { code: 'TURNSTILE_FAILED', message: 'Turnstile verification failed', details: outcome['error-codes'] } },\n 403\n )\n }\n\n const cookieToken = await signCookie(secret, ip)\n setCookieHeader(c, cookieToken)\n\n return c.json({ success: true })\n}\n\n/**\n * Turnstile challenge middleware.\n *\n * Requires a valid Turnstile-signed cookie on all non-exempt requests.\n * The client must first solve a Turnstile challenge and POST the token\n * to the verify endpoint to obtain the cookie.\n *\n * Exempt paths: /health, /internal, /api/auth, /api/uploads/images,\n * and the verify endpoint itself.\n */\nexport function createTurnstileMiddleware() {\n return createMiddleware<{ Bindings: LeapifyBindings }>(async (c, next) => {\n if (isExempt(c.req.path)) return next()\n\n if (c.req.method === 'OPTIONS') return next()\n\n // Skip challenge for authenticated requests (Bearer token present)\n // The auth middleware will handle session validation instead.\n if (c.req.header('Authorization')) return next()\n\n const secret = c.env.TURNSTILE_SECRET_KEY\n if (!secret) return next()\n\n const cookieHeader = c.req.header('Cookie') ?? ''\n const cookieMatch = cookieHeader.match(\n new RegExp(`${TURNSTILE_COOKIE_NAME}=([^;]+)`)\n )\n if (cookieMatch) {\n const ip = getClientIp(c)\n const valid = await validateCookie(secret, cookieMatch[1], ip)\n if (valid) return next()\n }\n\n return c.json(\n { error: { code: 'TURNSTILE_REQUIRED', message: 'Turnstile verification required' } },\n 401\n )\n })\n}\n"]}
@@ -0,0 +1,161 @@
1
+ import { createMiddleware } from 'hono/factory';
2
+
3
+ // src/lib/middleware/turnstile-challenge.ts
4
+ var TURNSTILE_PATH = "/.well-known/leapify/turnstile";
5
+ var TURNSTILE_VERIFY_PATH = `${TURNSTILE_PATH}/verify`;
6
+ var TURNSTILE_COOKIE_NAME = "leapify-turnstile";
7
+ var VERIFY_URL = "https://challenges.cloudflare.com/turnstile/v0/siteverify";
8
+ var COOKIE_MAX_AGE_SEC = 86400;
9
+ var EXEMPT_PATHS = [
10
+ "/health",
11
+ "/internal",
12
+ "/api/auth",
13
+ "/api/uploads/images",
14
+ "/api/classes",
15
+ "/api/faqs",
16
+ "/api/config",
17
+ TURNSTILE_VERIFY_PATH
18
+ ];
19
+ function base64urlEncode(bytes) {
20
+ let binary = "";
21
+ for (const byte of bytes) {
22
+ binary += String.fromCharCode(byte);
23
+ }
24
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
25
+ }
26
+ function base64urlDecode(str) {
27
+ const padded = str.replace(/-/g, "+").replace(/_/g, "/");
28
+ const binary = atob(padded);
29
+ const bytes = new Uint8Array(new ArrayBuffer(binary.length));
30
+ for (let i = 0; i < binary.length; i++) {
31
+ bytes[i] = binary.charCodeAt(i);
32
+ }
33
+ return bytes;
34
+ }
35
+ async function importHmacKey(secret) {
36
+ return crypto.subtle.importKey(
37
+ "raw",
38
+ new TextEncoder().encode(secret),
39
+ { name: "HMAC", hash: "SHA-256" },
40
+ false,
41
+ ["sign", "verify"]
42
+ );
43
+ }
44
+ async function signCookie(secret, ip) {
45
+ const ts = Date.now();
46
+ const nonce = base64urlEncode(crypto.getRandomValues(new Uint8Array(8)));
47
+ const payload = `${ip}:${ts}:${nonce}`;
48
+ const key = await importHmacKey(secret);
49
+ const sig = await crypto.subtle.sign(
50
+ "HMAC",
51
+ key,
52
+ new TextEncoder().encode(payload)
53
+ );
54
+ const sigB64 = base64urlEncode(new Uint8Array(sig));
55
+ return `${base64urlEncode(new TextEncoder().encode(payload))}.${sigB64}`;
56
+ }
57
+ async function validateCookie(secret, cookie, ip) {
58
+ try {
59
+ const [payloadB64, sigB64] = cookie.split(".");
60
+ if (!payloadB64 || !sigB64) return false;
61
+ const payloadBytes = base64urlDecode(payloadB64);
62
+ const sigBytes = base64urlDecode(sigB64);
63
+ const key = await importHmacKey(secret);
64
+ const valid = await crypto.subtle.verify(
65
+ "HMAC",
66
+ key,
67
+ sigBytes,
68
+ payloadBytes
69
+ );
70
+ if (!valid) return false;
71
+ const payload = new TextDecoder().decode(payloadBytes);
72
+ const [cookieIp, tsStr] = payload.split(":");
73
+ if (cookieIp !== ip) return false;
74
+ const ts = parseInt(tsStr, 10);
75
+ if (isNaN(ts) || Date.now() - ts > COOKIE_MAX_AGE_SEC * 1e3) return false;
76
+ return true;
77
+ } catch {
78
+ return false;
79
+ }
80
+ }
81
+ function getClientIp(c) {
82
+ return c.req.header("CF-Connecting-IP") ?? c.req.header("X-Real-IP") ?? c.req.header("X-Forwarded-For")?.split(",")[0]?.trim() ?? "unknown";
83
+ }
84
+ function isExempt(path) {
85
+ const normalized = path.toLowerCase().replace(/\/$/, "");
86
+ return EXEMPT_PATHS.some((p) => {
87
+ const ep = p.toLowerCase().replace(/\/$/, "");
88
+ return normalized === ep || normalized.startsWith(ep + "/");
89
+ });
90
+ }
91
+ function setCookieHeader(c, token) {
92
+ const isSecure = c.req.raw.url.startsWith("https") || c.req.header("x-forwarded-proto") === "https";
93
+ c.header(
94
+ "Set-Cookie",
95
+ `${TURNSTILE_COOKIE_NAME}=${token}; Path=/; Max-Age=${COOKIE_MAX_AGE_SEC}; ${isSecure ? "Secure; " : ""}HttpOnly; SameSite=Lax`
96
+ );
97
+ }
98
+ async function handleTurnstileVerify(c) {
99
+ const body = await c.req.json();
100
+ const { token } = body;
101
+ if (!token) {
102
+ return c.json(
103
+ { error: { code: "VALIDATION_ERROR", message: "Missing Turnstile token" } },
104
+ 422
105
+ );
106
+ }
107
+ const secret = c.env.TURNSTILE_SECRET_KEY;
108
+ if (!secret) {
109
+ return c.json(
110
+ { error: { code: "CONFIG_ERROR", message: "Turnstile not configured" } },
111
+ 500
112
+ );
113
+ }
114
+ const ip = getClientIp(c);
115
+ const formData = new URLSearchParams();
116
+ formData.append("secret", secret);
117
+ formData.append("response", token);
118
+ if (ip !== "unknown") {
119
+ formData.append("remoteip", ip);
120
+ }
121
+ const res = await fetch(VERIFY_URL, {
122
+ method: "POST",
123
+ body: formData
124
+ });
125
+ const outcome = await res.json();
126
+ if (!outcome.success) {
127
+ return c.json(
128
+ { error: { code: "TURNSTILE_FAILED", message: "Turnstile verification failed", details: outcome["error-codes"] } },
129
+ 403
130
+ );
131
+ }
132
+ const cookieToken = await signCookie(secret, ip);
133
+ setCookieHeader(c, cookieToken);
134
+ return c.json({ success: true });
135
+ }
136
+ function createTurnstileMiddleware() {
137
+ return createMiddleware(async (c, next) => {
138
+ if (isExempt(c.req.path)) return next();
139
+ if (c.req.method === "OPTIONS") return next();
140
+ if (c.req.header("Authorization")) return next();
141
+ const secret = c.env.TURNSTILE_SECRET_KEY;
142
+ if (!secret) return next();
143
+ const cookieHeader = c.req.header("Cookie") ?? "";
144
+ const cookieMatch = cookieHeader.match(
145
+ new RegExp(`${TURNSTILE_COOKIE_NAME}=([^;]+)`)
146
+ );
147
+ if (cookieMatch) {
148
+ const ip = getClientIp(c);
149
+ const valid = await validateCookie(secret, cookieMatch[1], ip);
150
+ if (valid) return next();
151
+ }
152
+ return c.json(
153
+ { error: { code: "TURNSTILE_REQUIRED", message: "Turnstile verification required" } },
154
+ 401
155
+ );
156
+ });
157
+ }
158
+
159
+ export { TURNSTILE_COOKIE_NAME, TURNSTILE_PATH, TURNSTILE_VERIFY_PATH, createTurnstileMiddleware, handleTurnstileVerify };
160
+ //# sourceMappingURL=chunk-AKCERDGP.js.map
161
+ //# sourceMappingURL=chunk-AKCERDGP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/middleware/turnstile-challenge.ts"],"names":[],"mappings":"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","file":"chunk-AKCERDGP.js","sourcesContent":["import { createMiddleware } from 'hono/factory'\nimport type { Context } from 'hono'\nimport type { LeapifyBindings } from '../../types'\n\nexport const TURNSTILE_PATH = '/.well-known/leapify/turnstile'\n\nexport const TURNSTILE_VERIFY_PATH = `${TURNSTILE_PATH}/verify`\n\nexport const TURNSTILE_COOKIE_NAME = 'leapify-turnstile'\n\nconst VERIFY_URL = 'https://challenges.cloudflare.com/turnstile/v0/siteverify'\n\nconst COOKIE_MAX_AGE_SEC = 86400\n\nconst EXEMPT_PATHS = [\n \"/health\",\n \"/internal\",\n \"/api/auth\",\n \"/api/uploads/images\",\n \"/api/classes\",\n \"/api/faqs\",\n \"/api/config\",\n TURNSTILE_VERIFY_PATH,\n];\n\nfunction base64urlEncode(bytes: Uint8Array): string {\n let binary = ''\n for (const byte of bytes) {\n binary += String.fromCharCode(byte)\n }\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\nfunction base64urlDecode(str: string): Uint8Array<ArrayBuffer> {\n const padded = str.replace(/-/g, '+').replace(/_/g, '/')\n const binary = atob(padded)\n const bytes = new Uint8Array(new ArrayBuffer(binary.length))\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n return bytes\n}\n\nasync function importHmacKey(secret: string): Promise<CryptoKey> {\n return crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign', 'verify']\n )\n}\n\nasync function signCookie(secret: string, ip: string): Promise<string> {\n const ts = Date.now()\n const nonce = base64urlEncode(crypto.getRandomValues(new Uint8Array(8)))\n const payload = `${ip}:${ts}:${nonce}`\n const key = await importHmacKey(secret)\n const sig = await crypto.subtle.sign(\n 'HMAC',\n key,\n new TextEncoder().encode(payload)\n )\n const sigB64 = base64urlEncode(new Uint8Array(sig))\n return `${base64urlEncode(new TextEncoder().encode(payload))}.${sigB64}`\n}\n\nasync function validateCookie(\n secret: string,\n cookie: string,\n ip: string\n): Promise<boolean> {\n try {\n const [payloadB64, sigB64] = cookie.split('.')\n if (!payloadB64 || !sigB64) return false\n\n const payloadBytes = base64urlDecode(payloadB64)\n const sigBytes = base64urlDecode(sigB64)\n\n const key = await importHmacKey(secret)\n const valid = await crypto.subtle.verify(\n 'HMAC',\n key,\n sigBytes,\n payloadBytes\n )\n if (!valid) return false\n\n const payload = new TextDecoder().decode(payloadBytes)\n const [cookieIp, tsStr] = payload.split(':')\n\n if (cookieIp !== ip) return false\n\n const ts = parseInt(tsStr, 10)\n if (isNaN(ts) || Date.now() - ts > COOKIE_MAX_AGE_SEC * 1000) return false\n\n return true\n } catch {\n return false\n }\n}\n\nfunction getClientIp(c: Context<{ Bindings: LeapifyBindings }>): string {\n return (\n c.req.header('CF-Connecting-IP') ??\n c.req.header('X-Real-IP') ??\n c.req.header('X-Forwarded-For')?.split(',')[0]?.trim() ??\n 'unknown'\n )\n}\n\nfunction isExempt(path: string): boolean {\n const normalized = path.toLowerCase().replace(/\\/$/, '')\n return EXEMPT_PATHS.some((p) => {\n const ep = p.toLowerCase().replace(/\\/$/, '')\n return normalized === ep || normalized.startsWith(ep + '/')\n })\n}\n\nfunction setCookieHeader(c: Context<{ Bindings: LeapifyBindings }>, token: string): void {\n const isSecure = c.req.raw.url.startsWith(\"https\") || c.req.header(\"x-forwarded-proto\") === \"https\";\n c.header(\n \"Set-Cookie\",\n `${TURNSTILE_COOKIE_NAME}=${token}; Path=/; Max-Age=${COOKIE_MAX_AGE_SEC}; ${\n isSecure ? \"Secure; \" : \"\"\n }HttpOnly; SameSite=Lax`,\n );\n}\n\n/**\n * POST /.well-known/leapify/turnstile/verify\n *\n * Validates a Turnstile token and issues a signed cookie on success.\n */\nexport async function handleTurnstileVerify(\n c: Context<{ Bindings: LeapifyBindings }>\n) {\n const body = await c.req.json<{ token?: string }>()\n const { token } = body\n\n if (!token) {\n return c.json(\n { error: { code: 'VALIDATION_ERROR', message: 'Missing Turnstile token' } },\n 422\n )\n }\n\n const secret = c.env.TURNSTILE_SECRET_KEY\n if (!secret) {\n return c.json(\n { error: { code: 'CONFIG_ERROR', message: 'Turnstile not configured' } },\n 500\n )\n }\n\n const ip = getClientIp(c)\n const formData = new URLSearchParams()\n formData.append('secret', secret)\n formData.append('response', token)\n if (ip !== 'unknown') {\n formData.append('remoteip', ip)\n }\n\n const res = await fetch(VERIFY_URL, {\n method: 'POST',\n body: formData,\n })\n const outcome = await res.json() as { success: boolean; 'error-codes'?: string[] }\n\n if (!outcome.success) {\n return c.json(\n { error: { code: 'TURNSTILE_FAILED', message: 'Turnstile verification failed', details: outcome['error-codes'] } },\n 403\n )\n }\n\n const cookieToken = await signCookie(secret, ip)\n setCookieHeader(c, cookieToken)\n\n return c.json({ success: true })\n}\n\n/**\n * Turnstile challenge middleware.\n *\n * Requires a valid Turnstile-signed cookie on all non-exempt requests.\n * The client must first solve a Turnstile challenge and POST the token\n * to the verify endpoint to obtain the cookie.\n *\n * Exempt paths: /health, /internal, /api/auth, /api/uploads/images,\n * and the verify endpoint itself.\n */\nexport function createTurnstileMiddleware() {\n return createMiddleware<{ Bindings: LeapifyBindings }>(async (c, next) => {\n if (isExempt(c.req.path)) return next()\n\n if (c.req.method === 'OPTIONS') return next()\n\n // Skip challenge for authenticated requests (Bearer token present)\n // The auth middleware will handle session validation instead.\n if (c.req.header('Authorization')) return next()\n\n const secret = c.env.TURNSTILE_SECRET_KEY\n if (!secret) return next()\n\n const cookieHeader = c.req.header('Cookie') ?? ''\n const cookieMatch = cookieHeader.match(\n new RegExp(`${TURNSTILE_COOKIE_NAME}=([^;]+)`)\n )\n if (cookieMatch) {\n const ip = getClientIp(c)\n const valid = await validateCookie(secret, cookieMatch[1], ip)\n if (valid) return next()\n }\n\n return c.json(\n { error: { code: 'TURNSTILE_REQUIRED', message: 'Turnstile verification required' } },\n 401\n )\n })\n}\n"]}
@@ -709,19 +709,7 @@ export declare function createLeapifyAuthClient(baseUrl: string): {
709
709
  referrerPolicy?: ReferrerPolicy | undefined;
710
710
  signal?: (AbortSignal | null) | undefined;
711
711
  window?: null | undefined;
712
- onRetry
713
- /**
714
- * Get the current bearer token from storage, or null for guests.
715
- * Pass this to `createLeapifyClient` as the `getToken` option.
716
- *
717
- * @example
718
- * import { createLeapifyClient } from 'leapify/client'
719
- * import { createLeapifyAuthClient, getLeapifyToken } from 'leapify/client'
720
- *
721
- * const authClient = createLeapifyAuthClient(API_URL)
722
- * const api = createLeapifyClient(API_URL, () => getLeapifyToken(authClient))
723
- */
724
- ?: ((response: import("@better-fetch/fetch").ResponseContext) => Promise<void> | void) | undefined;
712
+ onRetry?: ((response: import("@better-fetch/fetch").ResponseContext) => Promise<void> | void) | undefined;
725
713
  hookOptions?: {
726
714
  cloneResponse?: boolean;
727
715
  } | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/client/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BA0BtD,CAAC;iBAAe,CAAC;;;;;;;;;;;;;;;;;;;;gBA+BA,CAAC;aAAwC,CAAC;mBAEjC,CAAC;eAAiC,CAAC;;;;;iBAWvD,CAAC;iBAEM,CAAC;;YACE,CAAA;gBAAuC,CAAC;gBACpC,CAAC;sBAEhB,CAAD;cAAwC,CAAC;cAGzB,CAAC;;QAItB;;;;;;;;;;WAUG;QACH,CAZC;mBAG+B,CAAC;yBAAuB,CAAC;;eAGzC,CAAC;;;aACiD,CAAC;YAEnD,CAAC;;;;;;;;;;;;YAgBmB,CAAC;aAAgB,CAAC;cAC9C,CAAA;cAAiB,CAAC;;aAES,CAAC;oBAIL,CAAC;cAAgC,CAAC;mBAAkG,CAAC;yBAA0E,CAAC;qBAAwC,CAAC;;;uBAAkF,CAAC;+GAAuL,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAnGliB;AAED,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAA;AAE1E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,iBAAiB,EAC7B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,iBAAiB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAWf;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAEnC,UAAU,CAAC,EAAE,iBAAiB,GAC7B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAKxB;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,UAAU,EAAE,iBAAiB;;;;;;;;;;;;;GAM1D"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/client/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BA0BA,CAAC;iBACnD,CAAC;;;;;;;;;;;;;;;;;;;;gBAgCwB,CAAA;aAE3B,CAAA;mBAC+B,CAAC;eAAiC,CAAC;;;;;iBAWvC,CAAA;iBAAoC,CAAA;;YAE9D,CAAH;gBACsB,CAAC;gBAItB,CADF;sBAAwC,CAAC;cAKf,CAAC;cACnB,CAAA;eAA+B,CAAC;mBAI9B,CAAC;yBAAuB,CAAC;;eAClC,CAAD;;;aAEgD,CAAC;YAChD,CAAC;;;;;;;;;;;;YAiBuB,CAAC;aAAgB,CAAC;cAE/B,CAAC;cAED,CAAC;;aAA8F,CAAC;oBAAiE,CAAC;cAAgC,CAAC;mBAAkG,CAAC;yBAA0E,CAAC;qBAAwC,CAAC;;;uBAAkF,CAAC;+GAAuL,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAnGhrB;AAED,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAA;AAE1E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,iBAAiB,EAC7B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,iBAAiB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAWf;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAEnC,UAAU,CAAC,EAAE,iBAAiB,GAC7B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAKxB;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,UAAU,EAAE,iBAAiB;;;;;;;;;;;;;GAM1D"}