@draftlab/auth 0.15.1 → 0.16.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 (272) hide show
  1. package/dist/esm/allow.js +26 -0
  2. package/dist/esm/client.js +254 -0
  3. package/dist/esm/core.js +597 -0
  4. package/dist/esm/css.d.js +0 -0
  5. package/dist/esm/error.js +88 -0
  6. package/dist/esm/index.js +5 -0
  7. package/dist/esm/keys.js +126 -0
  8. package/dist/esm/mutex.js +53 -0
  9. package/dist/esm/pkce.js +87 -0
  10. package/dist/esm/provider/apple.js +15 -0
  11. package/dist/esm/provider/code.js +62 -0
  12. package/dist/esm/provider/discord.js +15 -0
  13. package/dist/esm/provider/facebook.js +15 -0
  14. package/dist/esm/provider/github.js +15 -0
  15. package/dist/esm/provider/gitlab.js +15 -0
  16. package/dist/esm/provider/google.js +16 -0
  17. package/dist/esm/provider/linkedin.js +15 -0
  18. package/dist/esm/provider/magiclink.js +83 -0
  19. package/dist/esm/provider/microsoft.js +15 -0
  20. package/dist/esm/provider/oauth2.js +130 -0
  21. package/dist/esm/provider/password.js +331 -0
  22. package/dist/esm/provider/provider.js +18 -0
  23. package/dist/esm/provider/reddit.js +15 -0
  24. package/dist/esm/provider/slack.js +15 -0
  25. package/dist/esm/provider/spotify.js +15 -0
  26. package/dist/esm/provider/twitch.js +15 -0
  27. package/dist/esm/provider/vercel.js +17 -0
  28. package/dist/esm/random.js +40 -0
  29. package/dist/esm/revocation.js +27 -0
  30. package/dist/esm/storage/memory.js +110 -0
  31. package/dist/esm/storage/storage.js +56 -0
  32. package/dist/esm/storage/turso.js +93 -0
  33. package/dist/esm/storage/unstorage.js +78 -0
  34. package/dist/esm/subject.js +7 -0
  35. package/dist/esm/themes/theme.js +115 -0
  36. package/dist/esm/toolkit/client.js +119 -0
  37. package/dist/esm/toolkit/index.js +25 -0
  38. package/dist/esm/toolkit/providers/facebook.js +11 -0
  39. package/dist/esm/toolkit/providers/github.js +11 -0
  40. package/dist/esm/toolkit/providers/google.js +11 -0
  41. package/dist/esm/toolkit/providers/strategy.js +0 -0
  42. package/dist/esm/toolkit/storage.js +81 -0
  43. package/dist/esm/toolkit/utils.js +18 -0
  44. package/dist/esm/types.js +0 -0
  45. package/dist/esm/ui/base.js +478 -0
  46. package/dist/esm/ui/code.js +186 -0
  47. package/dist/esm/ui/form.js +46 -0
  48. package/dist/esm/ui/icon.js +242 -0
  49. package/dist/esm/ui/magiclink.js +158 -0
  50. package/dist/esm/ui/password.js +435 -0
  51. package/dist/esm/ui/select.js +102 -0
  52. package/dist/esm/util.js +59 -0
  53. package/dist/{allow.d.mts → types/allow.d.ts} +9 -11
  54. package/dist/types/allow.d.ts.map +1 -0
  55. package/dist/types/client.d.ts +462 -0
  56. package/dist/types/client.d.ts.map +1 -0
  57. package/dist/types/core.d.ts +113 -0
  58. package/dist/types/core.d.ts.map +1 -0
  59. package/dist/{error.d.mts → types/error.d.ts} +95 -97
  60. package/dist/types/error.d.ts.map +1 -0
  61. package/dist/types/index.d.ts +2 -0
  62. package/dist/types/index.d.ts.map +1 -0
  63. package/dist/{keys.d.mts → types/keys.d.ts} +20 -23
  64. package/dist/types/keys.d.ts.map +1 -0
  65. package/dist/types/mutex.d.ts +42 -0
  66. package/dist/types/mutex.d.ts.map +1 -0
  67. package/dist/{pkce.d.mts → types/pkce.d.ts} +10 -11
  68. package/dist/types/pkce.d.ts.map +1 -0
  69. package/dist/types/provider/apple.d.ts +197 -0
  70. package/dist/types/provider/apple.d.ts.map +1 -0
  71. package/dist/types/provider/code.d.ts +288 -0
  72. package/dist/types/provider/code.d.ts.map +1 -0
  73. package/dist/types/provider/discord.d.ts +206 -0
  74. package/dist/types/provider/discord.d.ts.map +1 -0
  75. package/dist/types/provider/facebook.d.ts +200 -0
  76. package/dist/types/provider/facebook.d.ts.map +1 -0
  77. package/dist/types/provider/github.d.ts +220 -0
  78. package/dist/types/provider/github.d.ts.map +1 -0
  79. package/dist/types/provider/gitlab.d.ts +180 -0
  80. package/dist/types/provider/gitlab.d.ts.map +1 -0
  81. package/dist/types/provider/google.d.ts +158 -0
  82. package/dist/types/provider/google.d.ts.map +1 -0
  83. package/dist/types/provider/linkedin.d.ts +190 -0
  84. package/dist/types/provider/linkedin.d.ts.map +1 -0
  85. package/dist/types/provider/magiclink.d.ts +141 -0
  86. package/dist/types/provider/magiclink.d.ts.map +1 -0
  87. package/dist/types/provider/microsoft.d.ts +247 -0
  88. package/dist/types/provider/microsoft.d.ts.map +1 -0
  89. package/dist/types/provider/oauth2.d.ts +229 -0
  90. package/dist/types/provider/oauth2.d.ts.map +1 -0
  91. package/dist/types/provider/password.d.ts +408 -0
  92. package/dist/types/provider/password.d.ts.map +1 -0
  93. package/dist/types/provider/provider.d.ts +226 -0
  94. package/dist/types/provider/provider.d.ts.map +1 -0
  95. package/dist/types/provider/reddit.d.ts +159 -0
  96. package/dist/types/provider/reddit.d.ts.map +1 -0
  97. package/dist/types/provider/slack.d.ts +171 -0
  98. package/dist/types/provider/slack.d.ts.map +1 -0
  99. package/dist/types/provider/spotify.d.ts +168 -0
  100. package/dist/types/provider/spotify.d.ts.map +1 -0
  101. package/dist/types/provider/twitch.d.ts +163 -0
  102. package/dist/types/provider/twitch.d.ts.map +1 -0
  103. package/dist/types/provider/vercel.d.ts +294 -0
  104. package/dist/types/provider/vercel.d.ts.map +1 -0
  105. package/dist/{random.d.mts → types/random.d.ts} +4 -6
  106. package/dist/types/random.d.ts.map +1 -0
  107. package/dist/types/revocation.d.ts +76 -0
  108. package/dist/types/revocation.d.ts.map +1 -0
  109. package/dist/{storage/memory.d.mts → types/storage/memory.d.ts} +17 -20
  110. package/dist/types/storage/memory.d.ts.map +1 -0
  111. package/dist/types/storage/storage.d.ts +177 -0
  112. package/dist/types/storage/storage.d.ts.map +1 -0
  113. package/dist/{storage/turso.d.mts → types/storage/turso.d.ts} +4 -7
  114. package/dist/types/storage/turso.d.ts.map +1 -0
  115. package/dist/{storage/unstorage.d.mts → types/storage/unstorage.d.ts} +12 -10
  116. package/dist/types/storage/unstorage.d.ts.map +1 -0
  117. package/dist/types/subject.d.ts +115 -0
  118. package/dist/types/subject.d.ts.map +1 -0
  119. package/dist/types/themes/theme.d.ts +207 -0
  120. package/dist/types/themes/theme.d.ts.map +1 -0
  121. package/dist/types/toolkit/client.d.ts +235 -0
  122. package/dist/types/toolkit/client.d.ts.map +1 -0
  123. package/dist/types/toolkit/index.d.ts +45 -0
  124. package/dist/types/toolkit/index.d.ts.map +1 -0
  125. package/dist/types/toolkit/providers/facebook.d.ts +8 -0
  126. package/dist/types/toolkit/providers/facebook.d.ts.map +1 -0
  127. package/dist/types/toolkit/providers/github.d.ts +8 -0
  128. package/dist/types/toolkit/providers/github.d.ts.map +1 -0
  129. package/dist/types/toolkit/providers/google.d.ts +8 -0
  130. package/dist/types/toolkit/providers/google.d.ts.map +1 -0
  131. package/dist/types/toolkit/providers/strategy.d.ts +38 -0
  132. package/dist/types/toolkit/providers/strategy.d.ts.map +1 -0
  133. package/dist/{toolkit/storage.d.mts → types/toolkit/storage.d.ts} +37 -39
  134. package/dist/types/toolkit/storage.d.ts.map +1 -0
  135. package/dist/{toolkit/utils.d.mts → types/toolkit/utils.d.ts} +2 -4
  136. package/dist/types/toolkit/utils.d.ts.map +1 -0
  137. package/dist/types/types.d.ts +92 -0
  138. package/dist/types/types.d.ts.map +1 -0
  139. package/dist/types/ui/base.d.ts +18 -0
  140. package/dist/types/ui/base.d.ts.map +1 -0
  141. package/dist/types/ui/code.d.ts +43 -0
  142. package/dist/types/ui/code.d.ts.map +1 -0
  143. package/dist/types/ui/form.d.ts +24 -0
  144. package/dist/types/ui/form.d.ts.map +1 -0
  145. package/dist/types/ui/icon.d.ts +60 -0
  146. package/dist/types/ui/icon.d.ts.map +1 -0
  147. package/dist/types/ui/magiclink.d.ts +41 -0
  148. package/dist/types/ui/magiclink.d.ts.map +1 -0
  149. package/dist/types/ui/password.d.ts +43 -0
  150. package/dist/types/ui/password.d.ts.map +1 -0
  151. package/dist/types/ui/select.d.ts +33 -0
  152. package/dist/types/ui/select.d.ts.map +1 -0
  153. package/dist/{util.d.mts → types/util.d.ts} +11 -12
  154. package/dist/types/util.d.ts.map +1 -0
  155. package/package.json +10 -16
  156. package/dist/adapters/node.d.mts +0 -17
  157. package/dist/adapters/node.mjs +0 -69
  158. package/dist/allow.mjs +0 -63
  159. package/dist/client.d.mts +0 -462
  160. package/dist/client.mjs +0 -284
  161. package/dist/core.d.mts +0 -109
  162. package/dist/core.mjs +0 -595
  163. package/dist/error.mjs +0 -237
  164. package/dist/index.d.mts +0 -2
  165. package/dist/index.mjs +0 -3
  166. package/dist/keys.mjs +0 -146
  167. package/dist/mutex.d.mts +0 -44
  168. package/dist/mutex.mjs +0 -110
  169. package/dist/pkce.mjs +0 -157
  170. package/dist/provider/apple.d.mts +0 -110
  171. package/dist/provider/apple.mjs +0 -164
  172. package/dist/provider/code.d.mts +0 -218
  173. package/dist/provider/code.mjs +0 -246
  174. package/dist/provider/discord.d.mts +0 -145
  175. package/dist/provider/discord.mjs +0 -156
  176. package/dist/provider/facebook.d.mts +0 -141
  177. package/dist/provider/facebook.mjs +0 -150
  178. package/dist/provider/github.d.mts +0 -139
  179. package/dist/provider/github.mjs +0 -169
  180. package/dist/provider/gitlab.d.mts +0 -105
  181. package/dist/provider/gitlab.mjs +0 -147
  182. package/dist/provider/google.d.mts +0 -111
  183. package/dist/provider/google.mjs +0 -109
  184. package/dist/provider/linkedin.d.mts +0 -131
  185. package/dist/provider/linkedin.mjs +0 -142
  186. package/dist/provider/magiclink.d.mts +0 -79
  187. package/dist/provider/magiclink.mjs +0 -143
  188. package/dist/provider/microsoft.d.mts +0 -177
  189. package/dist/provider/microsoft.mjs +0 -177
  190. package/dist/provider/oauth2.d.mts +0 -175
  191. package/dist/provider/oauth2.mjs +0 -222
  192. package/dist/provider/passkey.d.mts +0 -103
  193. package/dist/provider/passkey.mjs +0 -320
  194. package/dist/provider/password.d.mts +0 -384
  195. package/dist/provider/password.mjs +0 -363
  196. package/dist/provider/provider.d.mts +0 -225
  197. package/dist/provider/provider.mjs +0 -44
  198. package/dist/provider/reddit.d.mts +0 -106
  199. package/dist/provider/reddit.mjs +0 -127
  200. package/dist/provider/slack.d.mts +0 -113
  201. package/dist/provider/slack.mjs +0 -138
  202. package/dist/provider/spotify.d.mts +0 -112
  203. package/dist/provider/spotify.mjs +0 -135
  204. package/dist/provider/totp.d.mts +0 -111
  205. package/dist/provider/totp.mjs +0 -191
  206. package/dist/provider/twitch.d.mts +0 -107
  207. package/dist/provider/twitch.mjs +0 -131
  208. package/dist/provider/vercel.d.mts +0 -176
  209. package/dist/provider/vercel.mjs +0 -230
  210. package/dist/random.mjs +0 -86
  211. package/dist/revocation.d.mts +0 -54
  212. package/dist/revocation.mjs +0 -63
  213. package/dist/router/context.d.mts +0 -21
  214. package/dist/router/context.mjs +0 -193
  215. package/dist/router/cookies.d.mts +0 -8
  216. package/dist/router/cookies.mjs +0 -13
  217. package/dist/router/index.d.mts +0 -21
  218. package/dist/router/index.mjs +0 -107
  219. package/dist/router/matcher.d.mts +0 -15
  220. package/dist/router/matcher.mjs +0 -76
  221. package/dist/router/middleware/cors.d.mts +0 -15
  222. package/dist/router/middleware/cors.mjs +0 -114
  223. package/dist/router/safe-request.d.mts +0 -52
  224. package/dist/router/safe-request.mjs +0 -160
  225. package/dist/router/types.d.mts +0 -67
  226. package/dist/router/types.mjs +0 -1
  227. package/dist/router/variables.d.mts +0 -12
  228. package/dist/router/variables.mjs +0 -20
  229. package/dist/storage/memory.mjs +0 -125
  230. package/dist/storage/storage.d.mts +0 -179
  231. package/dist/storage/storage.mjs +0 -104
  232. package/dist/storage/turso.mjs +0 -117
  233. package/dist/storage/unstorage.mjs +0 -103
  234. package/dist/subject.d.mts +0 -61
  235. package/dist/subject.mjs +0 -36
  236. package/dist/themes/theme.d.mts +0 -209
  237. package/dist/themes/theme.mjs +0 -120
  238. package/dist/toolkit/client.d.mts +0 -168
  239. package/dist/toolkit/client.mjs +0 -209
  240. package/dist/toolkit/index.d.mts +0 -9
  241. package/dist/toolkit/index.mjs +0 -9
  242. package/dist/toolkit/providers/facebook.d.mts +0 -11
  243. package/dist/toolkit/providers/facebook.mjs +0 -16
  244. package/dist/toolkit/providers/github.d.mts +0 -11
  245. package/dist/toolkit/providers/github.mjs +0 -16
  246. package/dist/toolkit/providers/google.d.mts +0 -11
  247. package/dist/toolkit/providers/google.mjs +0 -20
  248. package/dist/toolkit/providers/strategy.d.mts +0 -40
  249. package/dist/toolkit/providers/strategy.mjs +0 -1
  250. package/dist/toolkit/storage.mjs +0 -157
  251. package/dist/toolkit/utils.mjs +0 -30
  252. package/dist/types.d.mts +0 -94
  253. package/dist/types.mjs +0 -1
  254. package/dist/ui/base.d.mts +0 -29
  255. package/dist/ui/base.mjs +0 -407
  256. package/dist/ui/code.d.mts +0 -42
  257. package/dist/ui/code.mjs +0 -173
  258. package/dist/ui/form.d.mts +0 -31
  259. package/dist/ui/form.mjs +0 -49
  260. package/dist/ui/icon.d.mts +0 -57
  261. package/dist/ui/icon.mjs +0 -247
  262. package/dist/ui/magiclink.d.mts +0 -40
  263. package/dist/ui/magiclink.mjs +0 -152
  264. package/dist/ui/passkey.d.mts +0 -26
  265. package/dist/ui/passkey.mjs +0 -323
  266. package/dist/ui/password.d.mts +0 -41
  267. package/dist/ui/password.mjs +0 -402
  268. package/dist/ui/select.d.mts +0 -33
  269. package/dist/ui/select.mjs +0 -98
  270. package/dist/ui/totp.d.mts +0 -33
  271. package/dist/ui/totp.mjs +0 -270
  272. package/dist/util.mjs +0 -128
package/package.json CHANGED
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "name": "@draftlab/auth",
3
- "version": "0.15.1",
3
+ "version": "0.16.0",
4
4
  "type": "module",
5
5
  "description": "Core implementation for @draftlab/auth",
6
6
  "author": "Matheus Pergoli",
7
- "main": "dist/index.mjs",
8
- "typings": "dist/index.d.mts",
7
+ "main": "dist/esm/index.js",
8
+ "typings": "dist/types/index.d.ts",
9
9
  "files": [
10
10
  "dist"
11
11
  ],
12
12
  "exports": {
13
13
  ".": {
14
- "import": "./dist/index.mjs",
15
- "types": "./dist/index.d.mts"
14
+ "import": "./dist/esm/index.js",
15
+ "types": "./dist/types/index.d.ts"
16
16
  },
17
17
  "./*": {
18
- "import": "./dist/*.mjs",
19
- "types": "./dist/*.d.mts"
18
+ "import": "./dist/esm/*.js",
19
+ "types": "./dist/types/*.d.ts"
20
20
  }
21
21
  },
22
22
  "sideEffects": false,
@@ -37,14 +37,12 @@
37
37
  ],
38
38
  "license": "MIT",
39
39
  "devDependencies": {
40
- "@types/node": "^25.0.9",
41
- "@types/qrcode": "^1.5.6",
42
- "tsdown": "0.20.0-beta.3",
43
40
  "typescript": "^5.9.3",
44
41
  "@draftlab/tsconfig": "0.1.0"
45
42
  },
46
43
  "peerDependencies": {
47
44
  "@libsql/client": "^0.15.0",
45
+ "hono": "^4.0.0",
48
46
  "unstorage": "^1.0.0"
49
47
  },
50
48
  "peerDependenciesMeta": {
@@ -56,13 +54,9 @@
56
54
  }
57
55
  },
58
56
  "dependencies": {
59
- "@simplewebauthn/server": "^13.2.2",
60
57
  "@standard-schema/spec": "^1.1.0",
61
58
  "jose": "^6.1.3",
62
- "otpauth": "^9.4.1",
63
- "preact": "^10.28.2",
64
- "preact-render-to-string": "^6.6.5",
65
- "qrcode": "^1.5.4"
59
+ "zod": "^4.3.6"
66
60
  },
67
61
  "engines": {
68
62
  "node": ">=18"
@@ -71,7 +65,7 @@
71
65
  "access": "public"
72
66
  },
73
67
  "scripts": {
74
- "build": "tsdown",
68
+ "build": "bun run scripts/build.ts",
75
69
  "typecheck": "tsc --noEmit --emitDeclarationOnly false",
76
70
  "clean": "rm -rf dist .turbo node_modules"
77
71
  }
@@ -1,17 +0,0 @@
1
- import { IncomingMessage, ServerResponse } from "node:http";
2
-
3
- //#region src/adapters/node.d.ts
4
- /**
5
- * Converts Node.js IncomingMessage to Web Standards Request
6
- */
7
- declare const nodeRequestAdapter: (req: IncomingMessage) => Request;
8
- /**
9
- * Writes Web Standards Response to Node.js ServerResponse
10
- */
11
- declare const nodeResponseAdapter: (response: Response, res: ServerResponse) => Promise<void>;
12
- /**
13
- * Creates a Node.js HTTP handler from a Web Standards fetch function
14
- */
15
- declare const createNodeHandler: (fetchHandler: (request: Request) => Promise<Response>) => ((req: IncomingMessage, res: ServerResponse) => void);
16
- //#endregion
17
- export { createNodeHandler, nodeRequestAdapter, nodeResponseAdapter };
@@ -1,69 +0,0 @@
1
- import { Readable } from "node:stream";
2
-
3
- //#region src/adapters/node.ts
4
- /**
5
- * Converts Node.js IncomingMessage to Web Standards Request
6
- */
7
- const nodeRequestAdapter = (req) => {
8
- const sanitizedHost = (req.headers.host || "localhost").split(",")[0]?.trim();
9
- const url = new URL(req.url || "/", `http://${sanitizedHost}`);
10
- const headers = new Headers();
11
- for (const [key, value] of Object.entries(req.headers)) if (value !== void 0) if (Array.isArray(value)) for (const v of value) headers.append(key, v);
12
- else headers.set(key, value);
13
- let body;
14
- if (req.method !== "GET" && req.method !== "HEAD") body = Readable.toWeb(req);
15
- return new Request(url.toString(), {
16
- method: req.method || "GET",
17
- headers,
18
- body,
19
- duplex: "half"
20
- });
21
- };
22
- /**
23
- * Writes Web Standards Response to Node.js ServerResponse
24
- */
25
- const nodeResponseAdapter = async (response, res) => {
26
- res.statusCode = response.status;
27
- res.statusMessage = response.statusText;
28
- response.headers.forEach((value, key) => {
29
- res.setHeader(key, value);
30
- });
31
- if (response.body) {
32
- const reader = response.body.getReader();
33
- try {
34
- while (true) {
35
- const { done, value } = await reader.read();
36
- if (done) break;
37
- if (!res.write(value)) await new Promise((resolve) => res.once("drain", resolve));
38
- }
39
- } finally {
40
- reader.releaseLock();
41
- }
42
- }
43
- res.end();
44
- };
45
- /**
46
- * Creates a Node.js HTTP handler from a Web Standards fetch function
47
- */
48
- const createNodeHandler = (fetchHandler) => {
49
- return (req, res) => {
50
- try {
51
- fetchHandler(nodeRequestAdapter(req)).then((response) => nodeResponseAdapter(response, res)).catch((error) => {
52
- console.error("Handler error:", error instanceof Error ? error.message : "Unknown error");
53
- if (!res.headersSent) {
54
- res.statusCode = 500;
55
- res.end("Internal Server Error");
56
- }
57
- });
58
- } catch (error) {
59
- console.error("Request adapter error:", error instanceof Error ? error.message : "Unknown error");
60
- if (!res.headersSent) {
61
- res.statusCode = 400;
62
- res.end("Bad Request");
63
- }
64
- }
65
- };
66
- };
67
-
68
- //#endregion
69
- export { createNodeHandler, nodeRequestAdapter, nodeResponseAdapter };
package/dist/allow.mjs DELETED
@@ -1,63 +0,0 @@
1
- import { isDomainMatch } from "./util.mjs";
2
-
3
- //#region src/allow.ts
4
- /**
5
- * Default authorization check that validates client requests based on redirect URI security.
6
- *
7
- * ## Security Policy
8
- * - **Localhost**: Always allowed (for development)
9
- * - **Same domain**: Redirect URI must match request origin at TLD+1 level
10
- * - **Cross-domain**: Rejected for security
11
- *
12
- * This prevents unauthorized applications from hijacking authorization codes by using
13
- * malicious redirect URIs that don't belong to the legitimate client application.
14
- *
15
- * @param input - Client request details including ID and redirect URI
16
- * @param req - The original HTTP request for domain comparison
17
- * @returns Promise resolving to true if the request should be allowed
18
- *
19
- * @example
20
- * ```ts
21
- * // Allowed: localhost development
22
- * await defaultAllowCheck({
23
- * clientID: "dev-app",
24
- * redirectURI: "http://localhost:3000/callback"
25
- * }, request) // → true
26
- *
27
- * // Allowed: same domain
28
- * // Request from: https://myapp.com
29
- * await defaultAllowCheck({
30
- * clientID: "web-app",
31
- * redirectURI: "https://auth.myapp.com/callback"
32
- * }, request) // → true
33
- *
34
- * // Rejected: different domain
35
- * // Request from: https://myapp.com
36
- * await defaultAllowCheck({
37
- * clientID: "malicious-app",
38
- * redirectURI: "https://evil.com/steal-codes"
39
- * }, request) // → false
40
- * ```
41
- */
42
- const defaultAllowCheck = (input, req) => {
43
- return Promise.resolve((() => {
44
- let redirectHostname;
45
- try {
46
- redirectHostname = new URL(input.redirectURI).hostname;
47
- } catch {
48
- return false;
49
- }
50
- if (redirectHostname === "localhost" || redirectHostname === "127.0.0.1") return true;
51
- let currentHostname;
52
- try {
53
- const forwardedHost = req.headers.get("x-forwarded-host");
54
- currentHostname = forwardedHost ? new URL(`https://${forwardedHost}`).hostname : new URL(req.url).hostname;
55
- } catch {
56
- return false;
57
- }
58
- return isDomainMatch(redirectHostname, currentHostname);
59
- })());
60
- };
61
-
62
- //#endregion
63
- export { defaultAllowCheck };
package/dist/client.d.mts DELETED
@@ -1,462 +0,0 @@
1
- import { InvalidAccessTokenError, InvalidAuthorizationCodeError, InvalidRefreshTokenError, InvalidSubjectError } from "./error.mjs";
2
- import { SubjectSchema } from "./subject.mjs";
3
- import { StandardSchemaV1 } from "@standard-schema/spec";
4
-
5
- //#region src/client.d.ts
6
- /**
7
- * Result type for operations that can succeed or fail.
8
- *
9
- * @template T - The success data type
10
- * @template E - The error type
11
- *
12
- * @example
13
- * ```ts
14
- * const result = await client.exchange(code, redirectUri)
15
- * if (result.success) {
16
- * // Access token available: result.data.access
17
- * } else {
18
- * // Handle error: result.error.message
19
- * }
20
- * ```
21
- */
22
- type Result<T, E = Error> = {
23
- success: true;
24
- data: T;
25
- } | {
26
- success: false;
27
- error: E;
28
- };
29
- interface FetchResponse {
30
- ok: boolean;
31
- text(): Promise<string>;
32
- json(): Promise<unknown>;
33
- }
34
- type FetchLike = (url: string, init?: RequestInit) => Promise<FetchResponse>;
35
- /**
36
- * Authorization server metadata from well-known endpoints.
37
- */
38
- interface WellKnown {
39
- /**
40
- * URI to the JWKS endpoint for token verification.
41
- */
42
- jwks_uri: string;
43
- /**
44
- * URI to the token endpoint for authorization code exchange.
45
- */
46
- token_endpoint: string;
47
- /**
48
- * URI to the authorization endpoint for starting flows.
49
- */
50
- authorization_endpoint: string;
51
- }
52
- /**
53
- * Tokens returned by the authorization server.
54
- */
55
- interface Tokens {
56
- /**
57
- * Access token for making authenticated API requests.
58
- */
59
- access: string;
60
- /**
61
- * Refresh token for obtaining new access tokens.
62
- */
63
- refresh: string;
64
- /**
65
- * Number of seconds until the access token expires.
66
- */
67
- expiresIn: number;
68
- }
69
- /**
70
- * Challenge data for PKCE flows.
71
- */
72
- type Challenge = {
73
- /**
74
- * State parameter for CSRF protection.
75
- */
76
- state: string;
77
- /**
78
- * PKCE code verifier for token exchange.
79
- */
80
- verifier?: string;
81
- };
82
- /**
83
- * Client configuration options.
84
- */
85
- interface ClientInput {
86
- /**
87
- * Client ID that identifies your application.
88
- *
89
- * @example
90
- * ```ts
91
- * {
92
- * clientID: "my-web-app"
93
- * }
94
- * ```
95
- */
96
- clientID: string;
97
- /**
98
- * Base URL of your Draft Auth server.
99
- *
100
- * @example
101
- * ```ts
102
- * {
103
- * issuer: "https://auth.myserver.com"
104
- * }
105
- * ```
106
- */
107
- issuer: string;
108
- /**
109
- * Optionally, override the internally used fetch function.
110
- *
111
- * @example
112
- * ```ts
113
- * {
114
- * fetch: customFetch
115
- * }
116
- * ```
117
- */
118
- fetch?: FetchLike;
119
- }
120
- /**
121
- * Options for starting an authorization flow.
122
- */
123
- interface AuthorizeOptions {
124
- /**
125
- * Enable PKCE flow for enhanced security.
126
- *
127
- * Recommended for single-page applications and mobile apps.
128
- *
129
- * @default false
130
- * @example
131
- * ```ts
132
- * {
133
- * pkce: true
134
- * }
135
- * ```
136
- */
137
- pkce?: boolean;
138
- /**
139
- * Specific authentication provider to use.
140
- *
141
- * If not specified, users see a provider selection screen
142
- * or are redirected to the single configured provider.
143
- *
144
- * @example
145
- * ```ts
146
- * {
147
- * provider: "google"
148
- * }
149
- * ```
150
- */
151
- provider?: string;
152
- }
153
- /**
154
- * Result of starting an authorization flow.
155
- */
156
- interface AuthorizeResult {
157
- /**
158
- * Challenge data needed for PKCE flows.
159
- *
160
- * Store this securely and use when exchanging the code.
161
- *
162
- * @example
163
- * ```ts
164
- * sessionStorage.setItem("challenge", JSON.stringify(challenge))
165
- * ```
166
- */
167
- challenge: Challenge;
168
- /**
169
- * Authorization URL to redirect the user to.
170
- *
171
- * @example
172
- * ```ts
173
- * window.location.href = url
174
- * ```
175
- */
176
- url: string;
177
- }
178
- /**
179
- * Options for token refresh operations.
180
- */
181
- interface RefreshOptions {
182
- /**
183
- * Current access token to check before refreshing.
184
- *
185
- * Helps avoid unnecessary refresh requests.
186
- *
187
- * @example
188
- * ```ts
189
- * {
190
- * access: currentAccessToken
191
- * }
192
- * ```
193
- */
194
- access?: string;
195
- }
196
- /**
197
- * Options for token verification.
198
- */
199
- interface VerifyOptions {
200
- /**
201
- * Refresh token for automatic refresh if access token is expired.
202
- *
203
- * If passed in, this will automatically refresh the access token if it has expired.
204
- *
205
- * @example
206
- * ```ts
207
- * {
208
- * refresh: refreshToken
209
- * }
210
- * ```
211
- */
212
- refresh?: string;
213
- /**
214
- * Expected issuer for validation.
215
- * @internal
216
- */
217
- issuer?: string;
218
- /**
219
- * Expected audience for validation.
220
- * Defaults to clientID for security. Override only if you know what you're doing.
221
- * @internal
222
- */
223
- audience?: string;
224
- /**
225
- * Custom fetch for HTTP requests.
226
- *
227
- * Optionally, override the internally used fetch function.
228
- */
229
- fetch?: FetchLike;
230
- }
231
- /**
232
- * Result of successful token verification.
233
- */
234
- interface VerifyResult<T extends SubjectSchema> {
235
- /**
236
- * New tokens if access token was refreshed during verification.
237
- */
238
- tokens?: Tokens;
239
- /**
240
- * Audience (client ID) the token was issued for.
241
- * @internal
242
- */
243
- aud: string;
244
- /**
245
- * Unique subject identifier.
246
- *
247
- * This is a stable, consistent identifier derived from the subject type and properties.
248
- * Format: `{type}:{hash}` (e.g., `user:30e16a2659c8bbb2`)
249
- */
250
- sub: string;
251
- /**
252
- * Decoded subject information from the access token.
253
- *
254
- * Contains user data that was encoded when the token was issued.
255
- */
256
- subject: { [K in keyof T]: {
257
- type: K;
258
- properties: StandardSchemaV1.InferOutput<T[K]>;
259
- } }[keyof T];
260
- }
261
- /**
262
- * Options for token revocation.
263
- */
264
- interface RevokeOptions {
265
- /**
266
- * Optional hint about the token type.
267
- * Can be "access_token" or "refresh_token".
268
- *
269
- * Helps the server optimize token lookup.
270
- *
271
- * @example
272
- * ```ts
273
- * {
274
- * tokenTypeHint: "refresh_token"
275
- * }
276
- * ```
277
- */
278
- tokenTypeHint?: "access_token" | "refresh_token";
279
- }
280
- /**
281
- * Draft Auth client with OAuth 2.0 operations.
282
- */
283
- interface Client {
284
- /**
285
- * Start an OAuth authorization flow.
286
- *
287
- * @param redirectURI - Where users will be sent after authorization
288
- * @param response - Response type ("code" or "token")
289
- * @param opts - Additional authorization options
290
- * @returns Authorization URL and challenge data
291
- *
292
- * @example Basic flow
293
- * ```ts
294
- * const result = await client.authorize(
295
- * "https://myapp.com/callback",
296
- * "code"
297
- * )
298
- * if (result.success) {
299
- * window.location.href = result.data.url
300
- * }
301
- * ```
302
- *
303
- * @example PKCE flow
304
- * ```ts
305
- * const result = await client.authorize(
306
- * "https://spa.example.com/callback",
307
- * "code",
308
- * { pkce: true, scopes: ["read", "write"] }
309
- * )
310
- * if (result.success) {
311
- * sessionStorage.setItem("challenge", JSON.stringify(result.data.challenge))
312
- * window.location.href = result.data.url
313
- * }
314
- * ```
315
- */
316
- authorize(redirectURI: string, response: "code" | "token", opts?: AuthorizeOptions): Promise<Result<AuthorizeResult>>;
317
- /**
318
- * Exchange authorization code for tokens.
319
- *
320
- * @param code - Authorization code from the callback
321
- * @param redirectURI - Same redirect URI used in authorization
322
- * @param verifier - PKCE code verifier (required for PKCE flows)
323
- * @returns Access tokens and metadata
324
- *
325
- * @example Basic exchange
326
- * ```ts
327
- * const urlParams = new URLSearchParams(window.location.search)
328
- * const code = urlParams.get('code')
329
- *
330
- * if (code) {
331
- * const result = await client.exchange(code, "https://myapp.com/callback")
332
- * if (result.success) {
333
- * const { access, refresh } = result.data
334
- * // Store tokens securely
335
- * }
336
- * }
337
- * ```
338
- *
339
- * @example PKCE exchange
340
- * ```ts
341
- * const challenge = JSON.parse(sessionStorage.getItem("challenge") || "{}")
342
- * const code = new URLSearchParams(window.location.search).get('code')
343
- *
344
- * if (code && challenge.verifier) {
345
- * const result = await client.exchange(
346
- * code,
347
- * "https://spa.example.com/callback",
348
- * challenge.verifier
349
- * )
350
- * if (result.success) {
351
- * sessionStorage.removeItem("challenge")
352
- * // Handle tokens
353
- * }
354
- * }
355
- * ```
356
- */
357
- exchange(code: string, redirectURI: string, verifier?: string): Promise<Result<Tokens, InvalidAuthorizationCodeError>>;
358
- /**
359
- * Refresh an access token using a refresh token.
360
- *
361
- * @param refresh - Refresh token to use
362
- * @param opts - Additional refresh options
363
- * @returns New tokens if refresh was needed
364
- *
365
- * @example Basic refresh
366
- * ```ts
367
- * const result = await client.refresh(storedRefreshToken)
368
- *
369
- * if (result.success && result.data.tokens) {
370
- * const { access, refresh: newRefresh } = result.data.tokens
371
- * updateStoredTokens(access, newRefresh)
372
- * } else if (result.success) {
373
- * // Token still valid
374
- * } else {
375
- * redirectToLogin()
376
- * }
377
- * ```
378
- */
379
- refresh(refresh: string, opts?: RefreshOptions): Promise<Result<{
380
- tokens?: Tokens;
381
- }, InvalidRefreshTokenError | InvalidAccessTokenError>>;
382
- /**
383
- * Verify and decode an access token.
384
- *
385
- * @param subjects - Subject schema used when creating the issuer
386
- * @param token - Access token to verify
387
- * @param options - Additional verification options
388
- * @returns Decoded token data and user information
389
- *
390
- * @example Basic verification
391
- * ```ts
392
- * const result = await client.verify(subjects, accessToken)
393
- *
394
- * if (result.success) {
395
- * const { subject, scopes } = result.data
396
- * // Access user ID: subject.properties.userID
397
- * // Access scopes: scopes?.join(', ')
398
- * }
399
- * ```
400
- *
401
- * @example With automatic refresh
402
- * ```ts
403
- * const result = await client.verify(subjects, accessToken, {
404
- * refresh: refreshToken
405
- * })
406
- *
407
- * if (result.success) {
408
- * if (result.data.tokens) {
409
- * // Tokens were refreshed
410
- * updateStoredTokens(result.data.tokens.access, result.data.tokens.refresh)
411
- * }
412
- * // Use verified subject data
413
- * const user = result.data.subject.properties
414
- * }
415
- * ```
416
- */
417
- verify<T extends SubjectSchema>(subjects: T, token: string, options?: VerifyOptions): Promise<Result<VerifyResult<T>, InvalidRefreshTokenError | InvalidAccessTokenError | InvalidSubjectError>>;
418
- /**
419
- * Revoke a token (access or refresh token).
420
- *
421
- * Once revoked, the token cannot be used to access resources or refresh.
422
- * Useful for implementing logout functionality.
423
- *
424
- * @param token - The token to revoke
425
- * @param opts - Additional revocation options
426
- * @returns Empty result on success
427
- *
428
- * @example Logout with refresh token revocation
429
- * ```ts
430
- * const result = await client.revoke(refreshToken, {
431
- * tokenTypeHint: "refresh_token"
432
- * })
433
- *
434
- * if (result.success) {
435
- * // Token revoked successfully, user is logged out
436
- * clearStoredTokens()
437
- * redirectToHome()
438
- * } else {
439
- * // Revocation failed, but still clear tokens on client
440
- * clearStoredTokens()
441
- * }
442
- * ```
443
- */
444
- revoke(token: string, opts?: RevokeOptions): Promise<Result<void>>;
445
- }
446
- /**
447
- * Create a Draft Auth client.
448
- *
449
- * @param input - Client configuration
450
- * @returns Configured client instance
451
- *
452
- * @example Basic setup
453
- * ```ts
454
- * const client = createClient({
455
- * clientID: "my-web-app",
456
- * issuer: "https://auth.mycompany.com"
457
- * })
458
- * ```
459
- */
460
- declare const createClient: (input: ClientInput) => Client;
461
- //#endregion
462
- export { AuthorizeOptions, AuthorizeResult, Challenge, Client, ClientInput, RefreshOptions, Result, RevokeOptions, Tokens, VerifyOptions, VerifyResult, WellKnown, createClient };