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