@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
@@ -0,0 +1,435 @@
1
+ // src/ui/password.tsx
2
+ import { run } from "../util";
3
+ import { Layout } from "./base";
4
+ import { FormAlert } from "./form";
5
+ import { jsxDEV, Fragment } from "hono/jsx/jsx-dev-runtime";
6
+ var DEFAULT_COPY = {
7
+ error_email_taken: "There is already an account with this email.",
8
+ error_invalid_code: "Code is incorrect.",
9
+ error_invalid_email: "Email is not valid.",
10
+ error_invalid_password: "Password is incorrect.",
11
+ error_password_mismatch: "Passwords do not match.",
12
+ register: "Register",
13
+ register_prompt: "Don't have an account?",
14
+ login_prompt: "Already have an account?",
15
+ login: "Login",
16
+ change_prompt: "Forgot password?",
17
+ code_resend: "Resend code",
18
+ code_return: "Back to",
19
+ input_email: "Email",
20
+ input_password: "Password",
21
+ input_code: "Code",
22
+ input_repeat: "Repeat password",
23
+ button_continue: "Continue",
24
+ logo: "A"
25
+ };
26
+ var PasswordUI = (options) => {
27
+ const copy = {
28
+ ...DEFAULT_COPY,
29
+ ...options.copy
30
+ };
31
+ const getErrorMessage = (error) => {
32
+ if (!error?.type)
33
+ return;
34
+ if (error.type === "validation_error" && "message" in error && error.message) {
35
+ return error.message;
36
+ }
37
+ const errorKey = `error_${error.type}`;
38
+ return copy[errorKey];
39
+ };
40
+ return {
41
+ validatePassword: options.validatePassword,
42
+ sendCode: options.sendCode,
43
+ login: async (_req, form, error) => {
44
+ const jsx = /* @__PURE__ */ jsxDEV(Layout, {
45
+ children: /* @__PURE__ */ jsxDEV("form", {
46
+ "data-component": "form",
47
+ method: "post",
48
+ children: [
49
+ /* @__PURE__ */ jsxDEV(FormAlert, {
50
+ message: getErrorMessage(error)
51
+ }, undefined, false, undefined, this),
52
+ /* @__PURE__ */ jsxDEV("input", {
53
+ type: "email",
54
+ name: "email",
55
+ placeholder: copy.input_email,
56
+ value: form?.get("email")?.toString() || "",
57
+ autoComplete: "email",
58
+ "data-component": "input",
59
+ required: true
60
+ }, undefined, false, undefined, this),
61
+ /* @__PURE__ */ jsxDEV("input", {
62
+ type: "password",
63
+ name: "password",
64
+ placeholder: copy.input_password,
65
+ autoComplete: "current-password",
66
+ "data-component": "input",
67
+ required: true
68
+ }, undefined, false, undefined, this),
69
+ /* @__PURE__ */ jsxDEV("button", {
70
+ "data-component": "button",
71
+ type: "submit",
72
+ children: copy.button_continue
73
+ }, undefined, false, undefined, this),
74
+ /* @__PURE__ */ jsxDEV("div", {
75
+ "data-component": "form-footer",
76
+ children: [
77
+ /* @__PURE__ */ jsxDEV("span", {
78
+ children: [
79
+ copy.register_prompt,
80
+ " ",
81
+ /* @__PURE__ */ jsxDEV("a", {
82
+ "data-component": "link",
83
+ href: "./register",
84
+ children: copy.register
85
+ }, undefined, false, undefined, this)
86
+ ]
87
+ }, undefined, true, undefined, this),
88
+ /* @__PURE__ */ jsxDEV("a", {
89
+ "data-component": "link",
90
+ href: "./change",
91
+ children: copy.change_prompt
92
+ }, undefined, false, undefined, this)
93
+ ]
94
+ }, undefined, true, undefined, this)
95
+ ]
96
+ }, undefined, true, undefined, this)
97
+ }, undefined, false, undefined, this);
98
+ return new Response(jsx.toString(), {
99
+ status: error ? 401 : 200,
100
+ headers: { "Content-Type": "text/html" }
101
+ });
102
+ },
103
+ register: async (_req, state, form, error) => {
104
+ const emailError = ["invalid_email", "email_taken"].includes(error?.type || "");
105
+ const passwordError = [
106
+ "invalid_password",
107
+ "password_mismatch",
108
+ "validation_error"
109
+ ].includes(error?.type || "");
110
+ const jsx = /* @__PURE__ */ jsxDEV(Layout, {
111
+ children: run(() => {
112
+ if (state.type === "start") {
113
+ return /* @__PURE__ */ jsxDEV("form", {
114
+ "data-component": "form",
115
+ method: "post",
116
+ children: [
117
+ /* @__PURE__ */ jsxDEV(FormAlert, {
118
+ message: getErrorMessage(error)
119
+ }, undefined, false, undefined, this),
120
+ /* @__PURE__ */ jsxDEV("input", {
121
+ name: "action",
122
+ type: "hidden",
123
+ value: "register"
124
+ }, undefined, false, undefined, this),
125
+ /* @__PURE__ */ jsxDEV("input", {
126
+ type: "email",
127
+ name: "email",
128
+ placeholder: copy.input_email,
129
+ value: emailError ? "" : form?.get("email")?.toString() || "",
130
+ autoComplete: "email",
131
+ "data-component": "input",
132
+ required: true
133
+ }, undefined, false, undefined, this),
134
+ /* @__PURE__ */ jsxDEV("input", {
135
+ type: "password",
136
+ name: "password",
137
+ placeholder: copy.input_password,
138
+ value: passwordError ? "" : form?.get("password")?.toString() || "",
139
+ autoComplete: "new-password",
140
+ "data-component": "input",
141
+ required: true
142
+ }, undefined, false, undefined, this),
143
+ /* @__PURE__ */ jsxDEV("input", {
144
+ type: "password",
145
+ name: "repeat",
146
+ placeholder: copy.input_repeat,
147
+ autoComplete: "new-password",
148
+ "data-component": "input",
149
+ required: true
150
+ }, undefined, false, undefined, this),
151
+ /* @__PURE__ */ jsxDEV("button", {
152
+ "data-component": "button",
153
+ type: "submit",
154
+ children: copy.button_continue
155
+ }, undefined, false, undefined, this),
156
+ /* @__PURE__ */ jsxDEV("div", {
157
+ "data-component": "form-footer",
158
+ children: /* @__PURE__ */ jsxDEV("span", {
159
+ children: [
160
+ copy.login_prompt,
161
+ " ",
162
+ /* @__PURE__ */ jsxDEV("a", {
163
+ "data-component": "link",
164
+ href: "./authorize",
165
+ children: copy.login
166
+ }, undefined, false, undefined, this)
167
+ ]
168
+ }, undefined, true, undefined, this)
169
+ }, undefined, false, undefined, this)
170
+ ]
171
+ }, undefined, true, undefined, this);
172
+ }
173
+ return /* @__PURE__ */ jsxDEV(Fragment, {
174
+ children: [
175
+ /* @__PURE__ */ jsxDEV("form", {
176
+ "data-component": "form",
177
+ method: "post",
178
+ children: [
179
+ /* @__PURE__ */ jsxDEV(FormAlert, {
180
+ message: getErrorMessage(error)
181
+ }, undefined, false, undefined, this),
182
+ /* @__PURE__ */ jsxDEV("input", {
183
+ name: "action",
184
+ type: "hidden",
185
+ value: "verify"
186
+ }, undefined, false, undefined, this),
187
+ /* @__PURE__ */ jsxDEV("input", {
188
+ type: "text",
189
+ name: "code",
190
+ placeholder: copy.input_code,
191
+ "aria-label": "6-digit verification code",
192
+ autoComplete: "one-time-code",
193
+ "data-component": "input",
194
+ inputMode: "numeric",
195
+ maxLength: 6,
196
+ minLength: 6,
197
+ pattern: "[0-9]{6}",
198
+ required: true
199
+ }, undefined, false, undefined, this),
200
+ /* @__PURE__ */ jsxDEV("button", {
201
+ "data-component": "button",
202
+ type: "submit",
203
+ children: copy.button_continue
204
+ }, undefined, false, undefined, this)
205
+ ]
206
+ }, undefined, true, undefined, this),
207
+ /* @__PURE__ */ jsxDEV("form", {
208
+ method: "post",
209
+ children: [
210
+ /* @__PURE__ */ jsxDEV("input", {
211
+ name: "action",
212
+ type: "hidden",
213
+ value: "register"
214
+ }, undefined, false, undefined, this),
215
+ /* @__PURE__ */ jsxDEV("input", {
216
+ name: "email",
217
+ type: "hidden",
218
+ value: state.email
219
+ }, undefined, false, undefined, this),
220
+ /* @__PURE__ */ jsxDEV("input", {
221
+ name: "password",
222
+ type: "hidden",
223
+ value: ""
224
+ }, undefined, false, undefined, this),
225
+ /* @__PURE__ */ jsxDEV("input", {
226
+ name: "repeat",
227
+ type: "hidden",
228
+ value: ""
229
+ }, undefined, false, undefined, this),
230
+ /* @__PURE__ */ jsxDEV("div", {
231
+ "data-component": "form-footer",
232
+ children: [
233
+ /* @__PURE__ */ jsxDEV("span", {
234
+ children: [
235
+ copy.code_return,
236
+ " ",
237
+ /* @__PURE__ */ jsxDEV("a", {
238
+ "data-component": "link",
239
+ href: "./authorize",
240
+ children: copy.login
241
+ }, undefined, false, undefined, this)
242
+ ]
243
+ }, undefined, true, undefined, this),
244
+ /* @__PURE__ */ jsxDEV("button", {
245
+ type: "submit",
246
+ "data-component": "link",
247
+ children: copy.code_resend
248
+ }, undefined, false, undefined, this)
249
+ ]
250
+ }, undefined, true, undefined, this)
251
+ ]
252
+ }, undefined, true, undefined, this)
253
+ ]
254
+ }, undefined, true, undefined, this);
255
+ })
256
+ }, undefined, false, undefined, this);
257
+ return new Response(jsx.toString(), {
258
+ headers: { "Content-Type": "text/html" }
259
+ });
260
+ },
261
+ change: async (_req, state, form, error) => {
262
+ const passwordError = [
263
+ "invalid_password",
264
+ "password_mismatch",
265
+ "validation_error"
266
+ ].includes(error?.type || "");
267
+ const jsx = /* @__PURE__ */ jsxDEV(Layout, {
268
+ children: run(() => {
269
+ if (state.type === "start") {
270
+ return /* @__PURE__ */ jsxDEV("form", {
271
+ "data-component": "form",
272
+ method: "post",
273
+ children: [
274
+ /* @__PURE__ */ jsxDEV(FormAlert, {
275
+ message: getErrorMessage(error)
276
+ }, undefined, false, undefined, this),
277
+ /* @__PURE__ */ jsxDEV("input", {
278
+ name: "action",
279
+ type: "hidden",
280
+ value: "code"
281
+ }, undefined, false, undefined, this),
282
+ /* @__PURE__ */ jsxDEV("input", {
283
+ type: "email",
284
+ name: "email",
285
+ placeholder: copy.input_email,
286
+ value: form?.get("email")?.toString() || "",
287
+ autoComplete: "email",
288
+ "data-component": "input",
289
+ required: true
290
+ }, undefined, false, undefined, this),
291
+ /* @__PURE__ */ jsxDEV("button", {
292
+ "data-component": "button",
293
+ type: "submit",
294
+ children: copy.button_continue
295
+ }, undefined, false, undefined, this),
296
+ /* @__PURE__ */ jsxDEV("div", {
297
+ "data-component": "form-footer",
298
+ children: /* @__PURE__ */ jsxDEV("span", {
299
+ children: [
300
+ copy.code_return,
301
+ " ",
302
+ /* @__PURE__ */ jsxDEV("a", {
303
+ "data-component": "link",
304
+ href: "./authorize",
305
+ children: copy.login
306
+ }, undefined, false, undefined, this)
307
+ ]
308
+ }, undefined, true, undefined, this)
309
+ }, undefined, false, undefined, this)
310
+ ]
311
+ }, undefined, true, undefined, this);
312
+ }
313
+ if (state.type === "code") {
314
+ return /* @__PURE__ */ jsxDEV(Fragment, {
315
+ children: [
316
+ /* @__PURE__ */ jsxDEV("form", {
317
+ "data-component": "form",
318
+ method: "post",
319
+ children: [
320
+ /* @__PURE__ */ jsxDEV(FormAlert, {
321
+ message: getErrorMessage(error)
322
+ }, undefined, false, undefined, this),
323
+ /* @__PURE__ */ jsxDEV("input", {
324
+ name: "action",
325
+ type: "hidden",
326
+ value: "verify"
327
+ }, undefined, false, undefined, this),
328
+ /* @__PURE__ */ jsxDEV("input", {
329
+ type: "text",
330
+ name: "code",
331
+ placeholder: copy.input_code,
332
+ "aria-label": "6-digit verification code",
333
+ autoComplete: "one-time-code",
334
+ inputMode: "numeric",
335
+ maxLength: 6,
336
+ minLength: 6,
337
+ "data-component": "input",
338
+ pattern: "[0-9]{6}",
339
+ required: true
340
+ }, undefined, false, undefined, this),
341
+ /* @__PURE__ */ jsxDEV("button", {
342
+ "data-component": "button",
343
+ type: "submit",
344
+ children: copy.button_continue
345
+ }, undefined, false, undefined, this)
346
+ ]
347
+ }, undefined, true, undefined, this),
348
+ /* @__PURE__ */ jsxDEV("form", {
349
+ method: "post",
350
+ children: [
351
+ /* @__PURE__ */ jsxDEV("input", {
352
+ name: "action",
353
+ type: "hidden",
354
+ value: "code"
355
+ }, undefined, false, undefined, this),
356
+ /* @__PURE__ */ jsxDEV("input", {
357
+ name: "email",
358
+ type: "hidden",
359
+ value: state.email
360
+ }, undefined, false, undefined, this),
361
+ /* @__PURE__ */ jsxDEV("div", {
362
+ "data-component": "form-footer",
363
+ children: [
364
+ /* @__PURE__ */ jsxDEV("span", {
365
+ children: [
366
+ copy.code_return,
367
+ " ",
368
+ /* @__PURE__ */ jsxDEV("a", {
369
+ "data-component": "link",
370
+ href: "./authorize",
371
+ children: copy.login
372
+ }, undefined, false, undefined, this)
373
+ ]
374
+ }, undefined, true, undefined, this),
375
+ /* @__PURE__ */ jsxDEV("button", {
376
+ type: "submit",
377
+ "data-component": "link",
378
+ children: copy.code_resend
379
+ }, undefined, false, undefined, this)
380
+ ]
381
+ }, undefined, true, undefined, this)
382
+ ]
383
+ }, undefined, true, undefined, this)
384
+ ]
385
+ }, undefined, true, undefined, this);
386
+ }
387
+ return /* @__PURE__ */ jsxDEV("form", {
388
+ "data-component": "form",
389
+ method: "post",
390
+ children: [
391
+ /* @__PURE__ */ jsxDEV(FormAlert, {
392
+ message: getErrorMessage(error)
393
+ }, undefined, false, undefined, this),
394
+ /* @__PURE__ */ jsxDEV("input", {
395
+ name: "action",
396
+ type: "hidden",
397
+ value: "update"
398
+ }, undefined, false, undefined, this),
399
+ /* @__PURE__ */ jsxDEV("input", {
400
+ type: "password",
401
+ name: "password",
402
+ placeholder: copy.input_password,
403
+ value: passwordError ? "" : form?.get("password")?.toString() || "",
404
+ autoComplete: "new-password",
405
+ "data-component": "input",
406
+ required: true
407
+ }, undefined, false, undefined, this),
408
+ /* @__PURE__ */ jsxDEV("input", {
409
+ type: "password",
410
+ name: "repeat",
411
+ placeholder: copy.input_repeat,
412
+ value: passwordError ? "" : form?.get("repeat")?.toString() || "",
413
+ autoComplete: "new-password",
414
+ "data-component": "input",
415
+ required: true
416
+ }, undefined, false, undefined, this),
417
+ /* @__PURE__ */ jsxDEV("button", {
418
+ "data-component": "button",
419
+ type: "submit",
420
+ children: copy.button_continue
421
+ }, undefined, false, undefined, this)
422
+ ]
423
+ }, undefined, true, undefined, this);
424
+ })
425
+ }, undefined, false, undefined, this);
426
+ return new Response(jsx.toString(), {
427
+ status: error ? 400 : 200,
428
+ headers: { "Content-Type": "text/html" }
429
+ });
430
+ }
431
+ };
432
+ };
433
+ export {
434
+ PasswordUI
435
+ };
@@ -0,0 +1,102 @@
1
+ // src/ui/select.tsx
2
+ import { Layout } from "./base";
3
+ import {
4
+ ICON_APPLE,
5
+ ICON_DISCORD,
6
+ ICON_EMAIL,
7
+ ICON_FACEBOOK,
8
+ ICON_GITHUB,
9
+ ICON_GITLAB,
10
+ ICON_GOOGLE,
11
+ ICON_LINKEDIN,
12
+ ICON_MICROSOFT,
13
+ ICON_REDDIT,
14
+ ICON_SLACK,
15
+ ICON_SPOTIFY,
16
+ ICON_TWITCH
17
+ } from "./icon";
18
+ import { jsxDEV } from "hono/jsx/jsx-dev-runtime";
19
+ var PROVIDER_ICONS = {
20
+ apple: ICON_APPLE,
21
+ code: ICON_EMAIL,
22
+ discord: ICON_DISCORD,
23
+ email: ICON_EMAIL,
24
+ facebook: ICON_FACEBOOK,
25
+ github: ICON_GITHUB,
26
+ gitlab: ICON_GITLAB,
27
+ google: ICON_GOOGLE,
28
+ linkedin: ICON_LINKEDIN,
29
+ magiclink: ICON_EMAIL,
30
+ microsoft: ICON_MICROSOFT,
31
+ password: ICON_EMAIL,
32
+ reddit: ICON_REDDIT,
33
+ slack: ICON_SLACK,
34
+ spotify: ICON_SPOTIFY,
35
+ twitch: ICON_TWITCH
36
+ };
37
+ var DEFAULT_DISPLAYS = {
38
+ apple: "Apple",
39
+ code: "Code",
40
+ discord: "Discord",
41
+ facebook: "Facebook",
42
+ github: "GitHub",
43
+ gitlab: "GitLab",
44
+ google: "Google",
45
+ linkedin: "LinkedIn",
46
+ microsoft: "Microsoft",
47
+ password: "Password",
48
+ reddit: "Reddit",
49
+ slack: "Slack",
50
+ spotify: "Spotify",
51
+ twitch: "Twitch"
52
+ };
53
+ var ProviderSelect = ({
54
+ providers,
55
+ config = {},
56
+ theme
57
+ }) => {
58
+ const buttonText = config.copy?.button_provider || "Continue with";
59
+ const displays = { ...DEFAULT_DISPLAYS, ...config.displays };
60
+ const visibleProviders = Object.entries(providers).filter(([key]) => !config.providers?.[key]?.hide);
61
+ return /* @__PURE__ */ jsxDEV(Layout, {
62
+ theme,
63
+ title: "Sign In",
64
+ children: /* @__PURE__ */ jsxDEV("div", {
65
+ "data-component": "form",
66
+ children: visibleProviders.map(([key, type]) => {
67
+ const displayName = config.providers?.[key]?.display || displays[type] || DEFAULT_DISPLAYS[type] || type;
68
+ const IconComponent = PROVIDER_ICONS[key] || PROVIDER_ICONS[type];
69
+ return /* @__PURE__ */ jsxDEV("a", {
70
+ href: `./${key}/authorize`,
71
+ "data-component": "button",
72
+ "data-color": "ghost",
73
+ "aria-label": `${buttonText} ${displayName}`,
74
+ children: [
75
+ IconComponent && /* @__PURE__ */ jsxDEV("i", {
76
+ "data-slot": "icon",
77
+ children: IconComponent()
78
+ }, undefined, false, undefined, this),
79
+ buttonText,
80
+ " ",
81
+ displayName
82
+ ]
83
+ }, key, true, undefined, this);
84
+ })
85
+ }, undefined, false, undefined, this)
86
+ }, undefined, false, undefined, this);
87
+ };
88
+ var Select = (props = {}) => {
89
+ return async (providers) => {
90
+ const jsx = /* @__PURE__ */ jsxDEV(ProviderSelect, {
91
+ providers,
92
+ config: props,
93
+ theme: props.theme
94
+ }, undefined, false, undefined, this);
95
+ return new Response(jsx.toString(), {
96
+ headers: { "Content-Type": "text/html" }
97
+ });
98
+ };
99
+ };
100
+ export {
101
+ Select
102
+ };
@@ -0,0 +1,59 @@
1
+ // src/util.ts
2
+ var getRelativeUrl = (c, path) => {
3
+ const result = new URL(path, c.req.url);
4
+ result.host = c.req.header("x-forwarded-host") || result.host;
5
+ result.protocol = c.req.header("x-forwarded-proto") || result.protocol;
6
+ result.port = c.req.header("x-forwarded-port") || result.port;
7
+ return result.toString();
8
+ };
9
+ var twoPartTlds = [
10
+ "co.uk",
11
+ "co.jp",
12
+ "co.kr",
13
+ "co.nz",
14
+ "co.za",
15
+ "co.in",
16
+ "com.au",
17
+ "com.br",
18
+ "com.cn",
19
+ "com.mx",
20
+ "com.tw",
21
+ "net.au",
22
+ "org.uk",
23
+ "ne.jp",
24
+ "ac.uk",
25
+ "gov.uk",
26
+ "edu.au",
27
+ "gov.au"
28
+ ];
29
+ var isDomainMatch = (a, b) => {
30
+ if (a === b) {
31
+ return true;
32
+ }
33
+ const partsA = a.split(".");
34
+ const partsB = b.split(".");
35
+ const hasTwoPartTld = twoPartTlds.some((tld) => a.endsWith(`.${tld}`) || b.endsWith(`.${tld}`));
36
+ const numParts = hasTwoPartTld ? -3 : -2;
37
+ const min = Math.min(partsA.length, partsB.length, numParts);
38
+ const tailA = partsA.slice(min).join(".");
39
+ const tailB = partsB.slice(min).join(".");
40
+ return tailA === tailB;
41
+ };
42
+ var lazy = (fn) => {
43
+ let value;
44
+ let hasValue = false;
45
+ return () => {
46
+ if (!hasValue) {
47
+ value = fn();
48
+ hasValue = true;
49
+ }
50
+ return value;
51
+ };
52
+ };
53
+ var run = (fn) => fn();
54
+ export {
55
+ run,
56
+ lazy,
57
+ isDomainMatch,
58
+ getRelativeUrl
59
+ };
@@ -1,4 +1,3 @@
1
- //#region src/allow.d.ts
2
1
  /**
3
2
  * Client authorization validation utilities.
4
3
  * Provides security checks to determine if OAuth authorization requests should be permitted
@@ -8,13 +7,13 @@
8
7
  * Input parameters for authorization allow checks.
9
8
  * Contains all necessary information to validate if a client request should be permitted.
10
9
  */
11
- interface AllowCheckInput {
12
- /** The client ID of the application requesting authorization */
13
- readonly clientID: string;
14
- /** The redirect URI where the user will be sent after authorization */
15
- readonly redirectURI: string;
16
- /** Optional audience parameter for the authorization request */
17
- readonly audience?: string;
10
+ export interface AllowCheckInput {
11
+ /** The client ID of the application requesting authorization */
12
+ readonly clientID: string;
13
+ /** The redirect URI where the user will be sent after authorization */
14
+ readonly redirectURI: string;
15
+ /** Optional audience parameter for the authorization request */
16
+ readonly audience?: string;
18
17
  }
19
18
  /**
20
19
  * Default authorization check that validates client requests based on redirect URI security.
@@ -54,6 +53,5 @@ interface AllowCheckInput {
54
53
  * }, request) // → false
55
54
  * ```
56
55
  */
57
- declare const defaultAllowCheck: (input: AllowCheckInput, req: Request) => Promise<boolean>;
58
- //#endregion
59
- export { AllowCheckInput, defaultAllowCheck };
56
+ export declare const defaultAllowCheck: (input: AllowCheckInput, req: Request) => Promise<boolean>;
57
+ //# sourceMappingURL=allow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"allow.d.ts","sourceRoot":"","sources":["../../src/allow.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,uEAAuE;IACvE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,eAAe,EAAE,KAAK,OAAO,KAAG,OAAO,CAAC,OAAO,CA+BvF,CAAA"}