@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
@@ -1,402 +0,0 @@
1
- import { run } from "../util.mjs";
2
- import { Layout, renderToHTML } from "./base.mjs";
3
- import { FormAlert } from "./form.mjs";
4
- import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
5
-
6
- //#region src/ui/password.tsx
7
- /**
8
- * Default copy text for password authentication UI
9
- */
10
- const DEFAULT_COPY = {
11
- error_email_taken: "There is already an account with this email.",
12
- error_invalid_code: "Code is incorrect.",
13
- error_invalid_email: "Email is not valid.",
14
- error_invalid_password: "Password is incorrect.",
15
- error_password_mismatch: "Passwords do not match.",
16
- register: "Register",
17
- register_prompt: "Don't have an account?",
18
- login_prompt: "Already have an account?",
19
- login: "Login",
20
- change_prompt: "Forgot password?",
21
- code_resend: "Resend code",
22
- code_return: "Back to",
23
- input_email: "Email",
24
- input_password: "Password",
25
- input_code: "Code",
26
- input_repeat: "Repeat password",
27
- button_continue: "Continue",
28
- logo: "A"
29
- };
30
- /**
31
- * Creates a complete UI configuration for password-based authentication
32
- */
33
- const PasswordUI = (options) => {
34
- const copy = {
35
- ...DEFAULT_COPY,
36
- ...options.copy
37
- };
38
- /**
39
- * Gets the appropriate error message for display
40
- */
41
- const getErrorMessage = (error) => {
42
- if (!error?.type) return void 0;
43
- if (error.type === "validation_error" && "message" in error && error.message) return error.message;
44
- return copy[`error_${error.type}`];
45
- };
46
- /**
47
- * Renders the login form with email and password inputs
48
- */
49
- const renderLogin = (form, error) => /* @__PURE__ */ jsx(Layout, { children: /* @__PURE__ */ jsxs("form", {
50
- "data-component": "form",
51
- method: "post",
52
- children: [
53
- /* @__PURE__ */ jsx(FormAlert, { message: getErrorMessage(error) }),
54
- /* @__PURE__ */ jsx("input", {
55
- type: "email",
56
- name: "email",
57
- placeholder: copy.input_email,
58
- value: form?.get("email")?.toString() || "",
59
- autoComplete: "email",
60
- "data-component": "input",
61
- required: true
62
- }),
63
- /* @__PURE__ */ jsx("input", {
64
- type: "password",
65
- name: "password",
66
- placeholder: copy.input_password,
67
- autoComplete: "current-password",
68
- "data-component": "input",
69
- required: true
70
- }),
71
- /* @__PURE__ */ jsx("button", {
72
- "data-component": "button",
73
- type: "submit",
74
- children: copy.button_continue
75
- }),
76
- /* @__PURE__ */ jsxs("div", {
77
- "data-component": "form-footer",
78
- children: [/* @__PURE__ */ jsxs("span", { children: [
79
- copy.register_prompt,
80
- " ",
81
- /* @__PURE__ */ jsx("a", {
82
- "data-component": "link",
83
- href: "./register",
84
- children: copy.register
85
- })
86
- ] }), /* @__PURE__ */ jsx("a", {
87
- "data-component": "link",
88
- href: "./change",
89
- children: copy.change_prompt
90
- })]
91
- })
92
- ]
93
- }) });
94
- /**
95
- * Renders the registration form based on current state
96
- */
97
- const renderRegister = (state, form, error) => {
98
- const emailError = ["invalid_email", "email_taken"].includes(error?.type || "");
99
- const passwordError = [
100
- "invalid_password",
101
- "password_mismatch",
102
- "validation_error"
103
- ].includes(error?.type || "");
104
- return /* @__PURE__ */ jsx(Layout, { children: run(() => {
105
- if (state.type === "start") return /* @__PURE__ */ jsxs("form", {
106
- "data-component": "form",
107
- method: "post",
108
- children: [
109
- /* @__PURE__ */ jsx(FormAlert, { message: getErrorMessage(error) }),
110
- /* @__PURE__ */ jsx("input", {
111
- name: "action",
112
- type: "hidden",
113
- value: "register"
114
- }),
115
- /* @__PURE__ */ jsx("input", {
116
- type: "email",
117
- name: "email",
118
- placeholder: copy.input_email,
119
- value: emailError ? "" : form?.get("email")?.toString() || "",
120
- autoComplete: "email",
121
- "data-component": "input",
122
- required: true
123
- }),
124
- /* @__PURE__ */ jsx("input", {
125
- type: "password",
126
- name: "password",
127
- placeholder: copy.input_password,
128
- value: passwordError ? "" : form?.get("password")?.toString() || "",
129
- autoComplete: "new-password",
130
- "data-component": "input",
131
- required: true
132
- }),
133
- /* @__PURE__ */ jsx("input", {
134
- type: "password",
135
- name: "repeat",
136
- placeholder: copy.input_repeat,
137
- autoComplete: "new-password",
138
- "data-component": "input",
139
- required: true
140
- }),
141
- /* @__PURE__ */ jsx("button", {
142
- "data-component": "button",
143
- type: "submit",
144
- children: copy.button_continue
145
- }),
146
- /* @__PURE__ */ jsx("div", {
147
- "data-component": "form-footer",
148
- children: /* @__PURE__ */ jsxs("span", { children: [
149
- copy.login_prompt,
150
- " ",
151
- /* @__PURE__ */ jsx("a", {
152
- "data-component": "link",
153
- href: "./authorize",
154
- children: copy.login
155
- })
156
- ] })
157
- })
158
- ]
159
- });
160
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("form", {
161
- "data-component": "form",
162
- method: "post",
163
- children: [
164
- /* @__PURE__ */ jsx(FormAlert, { message: getErrorMessage(error) }),
165
- /* @__PURE__ */ jsx("input", {
166
- name: "action",
167
- type: "hidden",
168
- value: "verify"
169
- }),
170
- /* @__PURE__ */ jsx("input", {
171
- type: "text",
172
- name: "code",
173
- placeholder: copy.input_code,
174
- "aria-label": "6-digit verification code",
175
- autoComplete: "one-time-code",
176
- "data-component": "input",
177
- inputMode: "numeric",
178
- maxLength: 6,
179
- minLength: 6,
180
- pattern: "[0-9]{6}",
181
- required: true
182
- }),
183
- /* @__PURE__ */ jsx("button", {
184
- "data-component": "button",
185
- type: "submit",
186
- children: copy.button_continue
187
- })
188
- ]
189
- }), /* @__PURE__ */ jsxs("form", {
190
- method: "post",
191
- children: [
192
- /* @__PURE__ */ jsx("input", {
193
- name: "action",
194
- type: "hidden",
195
- value: "register"
196
- }),
197
- /* @__PURE__ */ jsx("input", {
198
- name: "email",
199
- type: "hidden",
200
- value: state.email
201
- }),
202
- /* @__PURE__ */ jsx("input", {
203
- name: "password",
204
- type: "hidden",
205
- value: ""
206
- }),
207
- /* @__PURE__ */ jsx("input", {
208
- name: "repeat",
209
- type: "hidden",
210
- value: ""
211
- }),
212
- /* @__PURE__ */ jsxs("div", {
213
- "data-component": "form-footer",
214
- children: [/* @__PURE__ */ jsxs("span", { children: [
215
- copy.code_return,
216
- " ",
217
- /* @__PURE__ */ jsx("a", {
218
- "data-component": "link",
219
- href: "./authorize",
220
- children: copy.login
221
- })
222
- ] }), /* @__PURE__ */ jsx("button", {
223
- type: "submit",
224
- "data-component": "link",
225
- children: copy.code_resend
226
- })]
227
- })
228
- ]
229
- })] });
230
- }) });
231
- };
232
- /**
233
- * Renders the password change form based on current state
234
- */
235
- const renderChange = (state, form, error) => {
236
- const passwordError = [
237
- "invalid_password",
238
- "password_mismatch",
239
- "validation_error"
240
- ].includes(error?.type || "");
241
- return /* @__PURE__ */ jsx(Layout, { children: run(() => {
242
- if (state.type === "start") return /* @__PURE__ */ jsxs("form", {
243
- "data-component": "form",
244
- method: "post",
245
- children: [
246
- /* @__PURE__ */ jsx(FormAlert, { message: getErrorMessage(error) }),
247
- /* @__PURE__ */ jsx("input", {
248
- name: "action",
249
- type: "hidden",
250
- value: "code"
251
- }),
252
- /* @__PURE__ */ jsx("input", {
253
- type: "email",
254
- name: "email",
255
- placeholder: copy.input_email,
256
- value: form?.get("email")?.toString() || "",
257
- autoComplete: "email",
258
- "data-component": "input",
259
- required: true
260
- }),
261
- /* @__PURE__ */ jsx("button", {
262
- "data-component": "button",
263
- type: "submit",
264
- children: copy.button_continue
265
- }),
266
- /* @__PURE__ */ jsx("div", {
267
- "data-component": "form-footer",
268
- children: /* @__PURE__ */ jsxs("span", { children: [
269
- copy.code_return,
270
- " ",
271
- /* @__PURE__ */ jsx("a", {
272
- "data-component": "link",
273
- href: "./authorize",
274
- children: copy.login
275
- })
276
- ] })
277
- })
278
- ]
279
- });
280
- if (state.type === "code") return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("form", {
281
- "data-component": "form",
282
- method: "post",
283
- children: [
284
- /* @__PURE__ */ jsx(FormAlert, { message: getErrorMessage(error) }),
285
- /* @__PURE__ */ jsx("input", {
286
- name: "action",
287
- type: "hidden",
288
- value: "verify"
289
- }),
290
- /* @__PURE__ */ jsx("input", {
291
- type: "text",
292
- name: "code",
293
- placeholder: copy.input_code,
294
- "aria-label": "6-digit verification code",
295
- autoComplete: "one-time-code",
296
- inputMode: "numeric",
297
- maxLength: 6,
298
- minLength: 6,
299
- "data-component": "input",
300
- pattern: "[0-9]{6}",
301
- required: true
302
- }),
303
- /* @__PURE__ */ jsx("button", {
304
- "data-component": "button",
305
- type: "submit",
306
- children: copy.button_continue
307
- })
308
- ]
309
- }), /* @__PURE__ */ jsxs("form", {
310
- method: "post",
311
- children: [
312
- /* @__PURE__ */ jsx("input", {
313
- name: "action",
314
- type: "hidden",
315
- value: "code"
316
- }),
317
- /* @__PURE__ */ jsx("input", {
318
- name: "email",
319
- type: "hidden",
320
- value: state.email
321
- }),
322
- /* @__PURE__ */ jsxs("div", {
323
- "data-component": "form-footer",
324
- children: [/* @__PURE__ */ jsxs("span", { children: [
325
- copy.code_return,
326
- " ",
327
- /* @__PURE__ */ jsx("a", {
328
- "data-component": "link",
329
- href: "./authorize",
330
- children: copy.login
331
- })
332
- ] }), /* @__PURE__ */ jsx("button", {
333
- type: "submit",
334
- "data-component": "link",
335
- children: copy.code_resend
336
- })]
337
- })
338
- ]
339
- })] });
340
- return /* @__PURE__ */ jsxs("form", {
341
- "data-component": "form",
342
- method: "post",
343
- children: [
344
- /* @__PURE__ */ jsx(FormAlert, { message: getErrorMessage(error) }),
345
- /* @__PURE__ */ jsx("input", {
346
- name: "action",
347
- type: "hidden",
348
- value: "update"
349
- }),
350
- /* @__PURE__ */ jsx("input", {
351
- type: "password",
352
- name: "password",
353
- placeholder: copy.input_password,
354
- value: passwordError ? "" : form?.get("password")?.toString() || "",
355
- autoComplete: "new-password",
356
- "data-component": "input",
357
- required: true
358
- }),
359
- /* @__PURE__ */ jsx("input", {
360
- type: "password",
361
- name: "repeat",
362
- placeholder: copy.input_repeat,
363
- value: passwordError ? "" : form?.get("repeat")?.toString() || "",
364
- autoComplete: "new-password",
365
- "data-component": "input",
366
- required: true
367
- }),
368
- /* @__PURE__ */ jsx("button", {
369
- "data-component": "button",
370
- type: "submit",
371
- children: copy.button_continue
372
- })
373
- ]
374
- });
375
- }) });
376
- };
377
- return {
378
- validatePassword: options.validatePassword,
379
- sendCode: options.sendCode,
380
- login: async (_req, form, error) => {
381
- const html = renderToHTML(renderLogin(form, error));
382
- return new Response(html, {
383
- status: error ? 401 : 200,
384
- headers: { "Content-Type": "text/html" }
385
- });
386
- },
387
- register: async (_req, state, form, error) => {
388
- const html = renderToHTML(renderRegister(state, form, error));
389
- return new Response(html, { headers: { "Content-Type": "text/html" } });
390
- },
391
- change: async (_req, state, form, error) => {
392
- const html = renderToHTML(renderChange(state, form, error));
393
- return new Response(html, {
394
- status: error ? 400 : 200,
395
- headers: { "Content-Type": "text/html" }
396
- });
397
- }
398
- };
399
- };
400
-
401
- //#endregion
402
- export { PasswordUI };
@@ -1,34 +0,0 @@
1
- import { Theme } from "../themes/theme.mjs";
2
-
3
- //#region src/ui/select.d.ts
4
-
5
- /**
6
- * Provider configuration for the select UI
7
- */
8
- interface ProviderConfig {
9
- /** Whether to hide the provider from the select UI */
10
- hide?: boolean;
11
- /** Custom display name for this provider */
12
- display?: string;
13
- }
14
- /**
15
- * Props for the Select component
16
- */
17
- interface SelectProps {
18
- /** Provider-specific configurations */
19
- providers?: Record<string, ProviderConfig>;
20
- /** Custom copy text overrides */
21
- copy?: {
22
- button_provider?: string;
23
- };
24
- /** Global display name overrides for provider types */
25
- displays?: Record<string, string>;
26
- /** Theme configuration */
27
- theme?: Theme;
28
- }
29
- /**
30
- * Creates a provider selection UI
31
- */
32
- declare const Select: (props?: SelectProps) => (providers: Record<string, string>) => Promise<Response>;
33
- //#endregion
34
- export { ProviderConfig, Select, SelectProps };
@@ -1,98 +0,0 @@
1
- import { Layout, renderToHTML } from "./base.mjs";
2
- import { ICON_APPLE, ICON_DISCORD, ICON_EMAIL, ICON_FACEBOOK, ICON_GITHUB, ICON_GITLAB, ICON_GOOGLE, ICON_LINKEDIN, ICON_MICROSOFT, ICON_REDDIT, ICON_SLACK, ICON_SPOTIFY, ICON_TWITCH } from "./icon.mjs";
3
- import { jsx, jsxs } from "preact/jsx-runtime";
4
-
5
- //#region src/ui/select.tsx
6
- /**
7
- * Icon components for providers
8
- */
9
- const PROVIDER_ICONS = {
10
- apple: ICON_APPLE,
11
- discord: ICON_DISCORD,
12
- email: ICON_EMAIL,
13
- facebook: ICON_FACEBOOK,
14
- github: ICON_GITHUB,
15
- gitlab: ICON_GITLAB,
16
- google: ICON_GOOGLE,
17
- linkedin: ICON_LINKEDIN,
18
- magiclink: ICON_EMAIL,
19
- microsoft: ICON_MICROSOFT,
20
- password: ICON_EMAIL,
21
- reddit: ICON_REDDIT,
22
- slack: ICON_SLACK,
23
- spotify: ICON_SPOTIFY,
24
- twitch: ICON_TWITCH
25
- };
26
- /**
27
- * Default display names for provider types
28
- */
29
- const DEFAULT_DISPLAYS = {
30
- apple: "Apple",
31
- code: "Code",
32
- discord: "Discord",
33
- facebook: "Facebook",
34
- github: "GitHub",
35
- gitlab: "GitLab",
36
- google: "Google",
37
- linkedin: "LinkedIn",
38
- microsoft: "Microsoft",
39
- passkey: "Passkey",
40
- password: "Password",
41
- reddit: "Reddit",
42
- slack: "Slack",
43
- spotify: "Spotify",
44
- twitch: "Twitch"
45
- };
46
- /**
47
- * Main provider selection component
48
- */
49
- const ProviderSelect = ({ providers, config = {}, theme }) => {
50
- const buttonText = config.copy?.button_provider || "Continue with";
51
- const displays = {
52
- ...DEFAULT_DISPLAYS,
53
- ...config.displays
54
- };
55
- const visibleProviders = Object.entries(providers).filter(([key]) => !config.providers?.[key]?.hide);
56
- return /* @__PURE__ */ jsx(Layout, {
57
- theme,
58
- title: "Sign In",
59
- children: /* @__PURE__ */ jsx("div", {
60
- "data-component": "form",
61
- children: visibleProviders.map(([key, type]) => {
62
- const displayName = config.providers?.[key]?.display || displays[type] || DEFAULT_DISPLAYS[type] || type;
63
- const IconComponent = PROVIDER_ICONS[key] || PROVIDER_ICONS[type];
64
- return /* @__PURE__ */ jsxs("a", {
65
- href: `./${key}/authorize`,
66
- "data-component": "button",
67
- "data-color": "ghost",
68
- "aria-label": `${buttonText} ${displayName}`,
69
- children: [
70
- IconComponent && /* @__PURE__ */ jsx("i", {
71
- "data-slot": "icon",
72
- children: /* @__PURE__ */ jsx(IconComponent, {})
73
- }),
74
- buttonText,
75
- " ",
76
- displayName
77
- ]
78
- }, key);
79
- })
80
- })
81
- });
82
- };
83
- /**
84
- * Creates a provider selection UI
85
- */
86
- const Select = (props = {}) => {
87
- return async (providers) => {
88
- const html = renderToHTML(/* @__PURE__ */ jsx(ProviderSelect, {
89
- providers,
90
- config: props,
91
- theme: props.theme
92
- }));
93
- return new Response(html, { headers: { "Content-Type": "text/html" } });
94
- };
95
- };
96
-
97
- //#endregion
98
- export { Select };
@@ -1,34 +0,0 @@
1
- import { TOTPProviderConfig } from "../provider/totp.mjs";
2
-
3
- //#region src/ui/totp.d.ts
4
-
5
- /**
6
- * Strongly typed copy text configuration for TOTP UI
7
- */
8
- interface TOTPUICopy {
9
- readonly setup_manual_entry: string;
10
- readonly setup_backup_codes_title: string;
11
- readonly setup_backup_codes_description: string;
12
- readonly button_continue: string;
13
- readonly link_use_recovery: string;
14
- readonly link_back_to_totp: string;
15
- readonly input_token: string;
16
- readonly input_recovery_code: string;
17
- }
18
- /**
19
- * Configuration options for TOTP UI
20
- */
21
- interface TOTPUIOptions {
22
- /** Custom copy text overrides */
23
- readonly copy?: Partial<TOTPUICopy>;
24
- /** QR code image size in pixels */
25
- readonly qrSize?: number;
26
- /** Whether to show manual secret entry option */
27
- readonly showManualEntry?: boolean;
28
- }
29
- /**
30
- * Creates a complete UI configuration for TOTP authentication
31
- */
32
- declare const TOTPUI: (options?: TOTPUIOptions) => Omit<TOTPProviderConfig, "issuer">;
33
- //#endregion
34
- export { TOTPUI };