faire-auth 1.0.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 (221) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +34 -0
  3. package/dist/access-B5bBI4uT.mjs +39 -0
  4. package/dist/access-Crt-IJ2P.cjs +51 -0
  5. package/dist/adapter-factory-BXei1QRX.mjs +881 -0
  6. package/dist/adapter-factory-DT-_2aHJ.cjs +893 -0
  7. package/dist/adapters/drizzle-adapter/index.cjs +208 -0
  8. package/dist/adapters/drizzle-adapter/index.d.cts +48 -0
  9. package/dist/adapters/drizzle-adapter/index.d.mts +48 -0
  10. package/dist/adapters/drizzle-adapter/index.mjs +207 -0
  11. package/dist/adapters/index.cjs +23 -0
  12. package/dist/adapters/index.d.cts +157 -0
  13. package/dist/adapters/index.d.mts +157 -0
  14. package/dist/adapters/index.mjs +17 -0
  15. package/dist/adapters/kysely-adapter/index.cjs +11 -0
  16. package/dist/adapters/kysely-adapter/index.d.cts +52 -0
  17. package/dist/adapters/kysely-adapter/index.d.mts +52 -0
  18. package/dist/adapters/kysely-adapter/index.mjs +9 -0
  19. package/dist/adapters/memory-adapter/index.cjs +9 -0
  20. package/dist/adapters/memory-adapter/index.d.cts +15 -0
  21. package/dist/adapters/memory-adapter/index.d.mts +15 -0
  22. package/dist/adapters/memory-adapter/index.mjs +9 -0
  23. package/dist/adapters/mongodb-adapter/index.cjs +9 -0
  24. package/dist/adapters/mongodb-adapter/index.d.cts +4 -0
  25. package/dist/adapters/mongodb-adapter/index.d.mts +4 -0
  26. package/dist/adapters/mongodb-adapter/index.mjs +9 -0
  27. package/dist/adapters/prisma-adapter/index.cjs +156 -0
  28. package/dist/adapters/prisma-adapter/index.d.cts +35 -0
  29. package/dist/adapters/prisma-adapter/index.d.mts +35 -0
  30. package/dist/adapters/prisma-adapter/index.mjs +155 -0
  31. package/dist/adapters/test.cjs +797 -0
  32. package/dist/adapters/test.d.cts +82 -0
  33. package/dist/adapters/test.d.mts +82 -0
  34. package/dist/adapters/test.mjs +793 -0
  35. package/dist/api/index.cjs +20 -0
  36. package/dist/api/index.d.cts +3 -0
  37. package/dist/api/index.d.mts +3 -0
  38. package/dist/api/index.mjs +20 -0
  39. package/dist/api/middleware/index.cjs +16 -0
  40. package/dist/api/middleware/index.d.cts +16 -0
  41. package/dist/api/middleware/index.d.mts +16 -0
  42. package/dist/api/middleware/index.mjs +11 -0
  43. package/dist/api-Bm89BLgN.cjs +1899 -0
  44. package/dist/api-_B7qO28y.mjs +1892 -0
  45. package/dist/auth-Bo9PDt5j.cjs +739 -0
  46. package/dist/auth-Ds4AG4h4.mjs +709 -0
  47. package/dist/bearer-0SeEmaS4.mjs +54 -0
  48. package/dist/bearer-CHeREcGT.cjs +60 -0
  49. package/dist/bun-sqlite-dialect-CfkBo2v5.mjs +155 -0
  50. package/dist/bun-sqlite-dialect-wuaC2-gh.cjs +156 -0
  51. package/dist/chunk-Ceigfy4P.mjs +39 -0
  52. package/dist/chunk-oakRccI5.cjs +60 -0
  53. package/dist/client/index.cjs +22 -0
  54. package/dist/client/index.d.cts +8 -0
  55. package/dist/client/index.d.mts +8 -0
  56. package/dist/client/index.mjs +19 -0
  57. package/dist/client/lynx/index.cjs +79 -0
  58. package/dist/client/lynx/index.d.cts +156 -0
  59. package/dist/client/lynx/index.d.mts +156 -0
  60. package/dist/client/lynx/index.mjs +76 -0
  61. package/dist/client/plugins/index.cjs +11 -0
  62. package/dist/client/plugins/index.d.cts +17 -0
  63. package/dist/client/plugins/index.d.mts +17 -0
  64. package/dist/client/plugins/index.mjs +10 -0
  65. package/dist/client/react/index.cjs +79 -0
  66. package/dist/client/react/index.d.cts +156 -0
  67. package/dist/client/react/index.d.mts +156 -0
  68. package/dist/client/react/index.mjs +76 -0
  69. package/dist/client/solid/index.cjs +51 -0
  70. package/dist/client/solid/index.d.cts +90 -0
  71. package/dist/client/solid/index.d.mts +90 -0
  72. package/dist/client/solid/index.mjs +50 -0
  73. package/dist/client/svelte/index.cjs +28 -0
  74. package/dist/client/svelte/index.d.cts +110 -0
  75. package/dist/client/svelte/index.d.mts +110 -0
  76. package/dist/client/svelte/index.mjs +28 -0
  77. package/dist/client/vue/index.cjs +68 -0
  78. package/dist/client/vue/index.d.cts +123 -0
  79. package/dist/client/vue/index.d.mts +123 -0
  80. package/dist/client/vue/index.mjs +67 -0
  81. package/dist/cookies-B5xeA6i8.cjs +456 -0
  82. package/dist/cookies-Ch1JfQIz.mjs +367 -0
  83. package/dist/crypto/index.cjs +11 -0
  84. package/dist/crypto/index.d.cts +22 -0
  85. package/dist/crypto/index.d.mts +22 -0
  86. package/dist/crypto/index.mjs +5 -0
  87. package/dist/crypto-CcTxYH82.cjs +57 -0
  88. package/dist/crypto-CyQRFtkq.mjs +41 -0
  89. package/dist/db/index.cjs +40 -0
  90. package/dist/db/index.d.cts +4 -0
  91. package/dist/db/index.d.mts +4 -0
  92. package/dist/db/index.mjs +16 -0
  93. package/dist/db-BTKyYu-_.cjs +1180 -0
  94. package/dist/db-xiJtoDgz.mjs +1119 -0
  95. package/dist/defu-B0Svx_x4.cjs +34 -0
  96. package/dist/defu-SZkpHhbR.mjs +28 -0
  97. package/dist/email-verification-C-AsfJsb.cjs +247 -0
  98. package/dist/email-verification-CWhj2qfb.mjs +228 -0
  99. package/dist/hono-BEq1NYVX.cjs +526 -0
  100. package/dist/hono-Cdukwu5K.cjs +13 -0
  101. package/dist/hono-CoKYWnXA.mjs +7 -0
  102. package/dist/hono-Covz10jU.mjs +508 -0
  103. package/dist/hono-DOM31WQz.d.cts +18 -0
  104. package/dist/hono-DuE14mmj.d.mts +18 -0
  105. package/dist/index-B-WeOMzg.d.cts +13350 -0
  106. package/dist/index-B09P9p5_.d.cts +33 -0
  107. package/dist/index-B5_0QTLg.d.mts +3 -0
  108. package/dist/index-B7SKyR_a.d.cts +3 -0
  109. package/dist/index-BVHscLQl.d.cts +992 -0
  110. package/dist/index-C2-2QDyS.d.cts +35 -0
  111. package/dist/index-CTwrVluH.d.mts +41 -0
  112. package/dist/index-CWAqWfoZ.d.cts +27 -0
  113. package/dist/index-CYSShrFx.d.mts +27 -0
  114. package/dist/index-Qu-iJGNr.d.mts +992 -0
  115. package/dist/index-cs4Sh0En.d.cts +41 -0
  116. package/dist/index-jlessPI0.d.mts +13350 -0
  117. package/dist/index-ppgcFe12.d.mts +33 -0
  118. package/dist/index-to0RO38U.d.mts +35 -0
  119. package/dist/index.cjs +85 -0
  120. package/dist/index.d.cts +5 -0
  121. package/dist/index.d.mts +5 -0
  122. package/dist/index.mjs +27 -0
  123. package/dist/integrations/next-js.cjs +50 -0
  124. package/dist/integrations/next-js.d.cts +23 -0
  125. package/dist/integrations/next-js.d.mts +23 -0
  126. package/dist/integrations/next-js.mjs +49 -0
  127. package/dist/integrations/node.cjs +139 -0
  128. package/dist/integrations/node.d.cts +22 -0
  129. package/dist/integrations/node.d.mts +22 -0
  130. package/dist/integrations/node.mjs +134 -0
  131. package/dist/integrations/react-start.cjs +37 -0
  132. package/dist/integrations/react-start.d.cts +17 -0
  133. package/dist/integrations/react-start.d.mts +17 -0
  134. package/dist/integrations/react-start.mjs +37 -0
  135. package/dist/integrations/solid-start.cjs +14 -0
  136. package/dist/integrations/solid-start.d.cts +13 -0
  137. package/dist/integrations/solid-start.d.mts +13 -0
  138. package/dist/integrations/solid-start.mjs +13 -0
  139. package/dist/integrations/svelte-kit.cjs +52 -0
  140. package/dist/integrations/svelte-kit.d.cts +42 -0
  141. package/dist/integrations/svelte-kit.d.mts +42 -0
  142. package/dist/integrations/svelte-kit.mjs +49 -0
  143. package/dist/ip-B5SwXaMB.cjs +54 -0
  144. package/dist/ip-BjNYspCH.mjs +36 -0
  145. package/dist/json-B1v2qRTQ.mjs +24 -0
  146. package/dist/json-CcJ2HjGo.cjs +30 -0
  147. package/dist/kysely-adapter-Bxi7sPdG.cjs +288 -0
  148. package/dist/kysely-adapter-DRuoT_X8.mjs +270 -0
  149. package/dist/logged-CyGfp8_H.mjs +187 -0
  150. package/dist/logged-DQK3C64b.cjs +193 -0
  151. package/dist/memory-adapter-BlnDIAAX.cjs +154 -0
  152. package/dist/memory-adapter-Db3tsJTn.mjs +148 -0
  153. package/dist/middleware-CE6OhDkq.mjs +29 -0
  154. package/dist/middleware-CWvRH4EW.cjs +47 -0
  155. package/dist/mongodb-adapter-C_qGQED5.mjs +291 -0
  156. package/dist/mongodb-adapter-C_qfK87x.cjs +297 -0
  157. package/dist/node-sqlite-dialect-BfBzyOAg.mjs +155 -0
  158. package/dist/node-sqlite-dialect-mJWC8LWQ.cjs +156 -0
  159. package/dist/oauth2/index.cjs +25 -0
  160. package/dist/oauth2/index.d.cts +42 -0
  161. package/dist/oauth2/index.d.mts +42 -0
  162. package/dist/oauth2/index.mjs +16 -0
  163. package/dist/oauth2-B8M0lW9l.mjs +159 -0
  164. package/dist/oauth2-BLeOEi7Y.cjs +177 -0
  165. package/dist/origin-check-8Gajklvh.mjs +228 -0
  166. package/dist/origin-check-id9lTnqZ.cjs +246 -0
  167. package/dist/parser-CdncAl9i.cjs +83 -0
  168. package/dist/parser-CeAer-RM.mjs +71 -0
  169. package/dist/passkey-B6N20LSS.cjs +512 -0
  170. package/dist/passkey-DJsR_GX3.mjs +505 -0
  171. package/dist/plugins/access/index.cjs +4 -0
  172. package/dist/plugins/access/index.d.cts +2 -0
  173. package/dist/plugins/access/index.d.mts +2 -0
  174. package/dist/plugins/access/index.mjs +3 -0
  175. package/dist/plugins/bearer/index.cjs +7 -0
  176. package/dist/plugins/bearer/index.d.cts +4 -0
  177. package/dist/plugins/bearer/index.d.mts +4 -0
  178. package/dist/plugins/bearer/index.mjs +7 -0
  179. package/dist/plugins/index.cjs +49 -0
  180. package/dist/plugins/index.d.cts +9326 -0
  181. package/dist/plugins/index.d.mts +9326 -0
  182. package/dist/plugins/index.mjs +26 -0
  183. package/dist/plugins/passkey/index.cjs +15 -0
  184. package/dist/plugins/passkey/index.d.cts +4 -0
  185. package/dist/plugins/passkey/index.d.mts +4 -0
  186. package/dist/plugins/passkey/index.mjs +15 -0
  187. package/dist/plugins-C1lm2Wj3.cjs +5254 -0
  188. package/dist/plugins-Dai1QkRU.mjs +5199 -0
  189. package/dist/request-1NL_1lyJ.mjs +58 -0
  190. package/dist/request-CPNlp-DK.cjs +100 -0
  191. package/dist/schema-D-qjygfE.cjs +179 -0
  192. package/dist/schema-DTIwLLmf.mjs +125 -0
  193. package/dist/session-De9POJTW.cjs +641 -0
  194. package/dist/session-rH8ougDl.mjs +538 -0
  195. package/dist/social-providers/index.cjs +10 -0
  196. package/dist/social-providers/index.d.cts +2 -0
  197. package/dist/social-providers/index.d.mts +2 -0
  198. package/dist/social-providers/index.mjs +5 -0
  199. package/dist/social-providers-DcFNUT0S.cjs +13 -0
  200. package/dist/social-providers-DoYJhBe3.mjs +9 -0
  201. package/dist/state--f7fwIGh.cjs +99 -0
  202. package/dist/state-CqJfCIl9.mjs +86 -0
  203. package/dist/test-utils/index.cjs +27492 -0
  204. package/dist/test-utils/index.d.cts +4584 -0
  205. package/dist/test-utils/index.d.mts +4584 -0
  206. package/dist/test-utils/index.mjs +27490 -0
  207. package/dist/types/index.cjs +0 -0
  208. package/dist/types/index.d.cts +3 -0
  209. package/dist/types/index.d.mts +3 -0
  210. package/dist/types/index.mjs +1 -0
  211. package/dist/url-BoUuoIwZ.mjs +88 -0
  212. package/dist/url-D2yvKaM7.cjs +118 -0
  213. package/dist/utils/cookies.cjs +51 -0
  214. package/dist/utils/cookies.d.cts +179 -0
  215. package/dist/utils/cookies.d.mts +179 -0
  216. package/dist/utils/cookies.mjs +7 -0
  217. package/dist/utils-44aDDP8f.cjs +2 -0
  218. package/dist/utils-D4vZd1-9.mjs +4 -0
  219. package/dist/vanilla-Bu2PmFzE.cjs +30 -0
  220. package/dist/vanilla-TfHqeiC7.mjs +25 -0
  221. package/package.json +470 -0
@@ -0,0 +1,34 @@
1
+
2
+ //#region src/utils/defu.ts
3
+ const isPlainObject = (value) => {
4
+ if (value === null || typeof value !== "object") return false;
5
+ const prototype = Object.getPrototypeOf(value);
6
+ if (prototype !== null && prototype !== Object.prototype && Object.getPrototypeOf(prototype) !== null) return false;
7
+ if (Symbol.iterator in value) return false;
8
+ if (Symbol.toStringTag in value) return Object.prototype.toString.call(value) === "[object Module]";
9
+ return true;
10
+ };
11
+ const _defu = (baseObject, defaults, namespace = ".", merger) => {
12
+ if (!isPlainObject(defaults)) return _defu(baseObject, {}, namespace, merger);
13
+ const object = Object.assign({}, defaults);
14
+ for (const key in baseObject) {
15
+ if (key === "__proto__" || key === "constructor") continue;
16
+ const value = baseObject[key];
17
+ if (value === null || value === void 0) continue;
18
+ if (merger?.(object, key, value, namespace) != null) continue;
19
+ if (Array.isArray(value) && Array.isArray(object[key])) object[key] = [...value, ...object[key]];
20
+ else if (isPlainObject(value) && isPlainObject(object[key])) object[key] = _defu(value, object[key], (namespace ? `${namespace}.` : "") + key.toString(), merger);
21
+ else object[key] = value;
22
+ }
23
+ return object;
24
+ };
25
+ const createDefu = (merger) => (...arguments_) => arguments_.reduce((p, c) => _defu(p, c, "", merger), {});
26
+ const defu = createDefu();
27
+
28
+ //#endregion
29
+ Object.defineProperty(exports, 'defu', {
30
+ enumerable: true,
31
+ get: function () {
32
+ return defu;
33
+ }
34
+ });
@@ -0,0 +1,28 @@
1
+ //#region src/utils/defu.ts
2
+ const isPlainObject = (value) => {
3
+ if (value === null || typeof value !== "object") return false;
4
+ const prototype = Object.getPrototypeOf(value);
5
+ if (prototype !== null && prototype !== Object.prototype && Object.getPrototypeOf(prototype) !== null) return false;
6
+ if (Symbol.iterator in value) return false;
7
+ if (Symbol.toStringTag in value) return Object.prototype.toString.call(value) === "[object Module]";
8
+ return true;
9
+ };
10
+ const _defu = (baseObject, defaults, namespace = ".", merger) => {
11
+ if (!isPlainObject(defaults)) return _defu(baseObject, {}, namespace, merger);
12
+ const object = Object.assign({}, defaults);
13
+ for (const key in baseObject) {
14
+ if (key === "__proto__" || key === "constructor") continue;
15
+ const value = baseObject[key];
16
+ if (value === null || value === void 0) continue;
17
+ if (merger?.(object, key, value, namespace) != null) continue;
18
+ if (Array.isArray(value) && Array.isArray(object[key])) object[key] = [...value, ...object[key]];
19
+ else if (isPlainObject(value) && isPlainObject(object[key])) object[key] = _defu(value, object[key], (namespace ? `${namespace}.` : "") + key.toString(), merger);
20
+ else object[key] = value;
21
+ }
22
+ return object;
23
+ };
24
+ const createDefu = (merger) => (...arguments_) => arguments_.reduce((p, c) => _defu(p, c, "", merger), {});
25
+ const defu = createDefu();
26
+
27
+ //#endregion
28
+ export { defu as t };
@@ -0,0 +1,247 @@
1
+ const require_chunk = require('./chunk-oakRccI5.cjs');
2
+ const require_crypto = require('./crypto-CcTxYH82.cjs');
3
+ const require_cookies = require('./cookies-B5xeA6i8.cjs');
4
+ const require_middleware = require('./middleware-CWvRH4EW.cjs');
5
+ const require_session = require('./session-De9POJTW.cjs');
6
+ const require_origin_check = require('./origin-check-id9lTnqZ.cjs');
7
+ let __faire_auth_core_factory = require("@faire-auth/core/factory");
8
+ let __faire_auth_core_static = require("@faire-auth/core/static");
9
+ let __faire_auth_core_utils = require("@faire-auth/core/utils");
10
+ let zod = require("zod");
11
+ zod = require_chunk.__toESM(zod);
12
+ let jose = require("jose");
13
+ let jose_errors = require("jose/errors");
14
+
15
+ //#region src/api/schema/email-verification.ts
16
+ const sendVerificationEmailSchema = zod.object({
17
+ email: __faire_auth_core_factory.emailSchema.openapi({ description: "The email to send the verification email to" }),
18
+ callbackURL: (0, __faire_auth_core_factory.callbackURLSchema)(true).openapi({ description: "The URL to use for email verification callback" })
19
+ });
20
+ const verifyEmailQuerySchema = zod.object({
21
+ token: zod.string().openapi({ description: "The token to verify the email" }),
22
+ callbackURL: (0, __faire_auth_core_factory.callbackURLSchema)(true).openapi({ description: "The URL to redirect to after email verification" })
23
+ });
24
+ const verifyEmailTokenSchema = zod.object({
25
+ email: __faire_auth_core_factory.emailSchema,
26
+ updateTo: zod.string().optional()
27
+ });
28
+
29
+ //#endregion
30
+ //#region src/api/middleware/token-check.ts
31
+ const onError = async (ctx, error) => {
32
+ let code;
33
+ if (error === "missing_token") code = 400;
34
+ else code = 401;
35
+ const url = ctx.req.query("callbackURL");
36
+ if (url) {
37
+ if (url.includes("?")) return ctx.redirect(`${url}&error=${error}`, 302);
38
+ return ctx.redirect(`${url}?error=${error}`, 302);
39
+ }
40
+ return ctx.render({
41
+ success: __faire_auth_core_static.False,
42
+ code: error.toUpperCase(),
43
+ message: (0, __faire_auth_core_utils.capitalizeFirstLetter)(error.replaceAll("_", " "))
44
+ }, code);
45
+ };
46
+ const verifyToken = async (token, context) => {
47
+ let jwt;
48
+ try {
49
+ jwt = await (0, jose.jwtVerify)(token, new TextEncoder().encode(context.secret), { algorithms: ["HS256"] });
50
+ } catch (e) {
51
+ if (e instanceof jose_errors.JWTExpired) return "token_expired";
52
+ return "invalid_token";
53
+ }
54
+ return jwt;
55
+ };
56
+ /**
57
+ * Validates token against context secret.
58
+ * @template V - The context variables type.
59
+ * @param getValue - Function to get the token from the context.
60
+ * @returns The middleware function.
61
+ */
62
+ const tokenCheck = (getValue, schema) => require_middleware.createMiddleware()(async (ctx, next) => {
63
+ const token = await getValue(ctx);
64
+ if (!token) return onError(ctx, "missing_token");
65
+ const res$1 = await verifyToken(token, ctx.get("context"));
66
+ if (typeof res$1 === "string") return onError(ctx, res$1);
67
+ const dat = await schema.safeParseAsync(res$1.payload);
68
+ if (dat.success === false) return onError(ctx, "invalid_token");
69
+ ctx.set("token", dat.data);
70
+ return await next();
71
+ });
72
+
73
+ //#endregion
74
+ //#region src/api/routes/email-verification.ts
75
+ const createEmailVerificationToken = async (secret, email, updateTo, expiresIn = 3600) => {
76
+ return await (0, require_crypto.crypto_exports.signJWT)({
77
+ email: email.toLowerCase(),
78
+ updateTo
79
+ }, secret, expiresIn);
80
+ };
81
+ /**
82
+ * A function to send a verification email to the user
83
+ */
84
+ const sendVerificationEmailFn = async (ctx, user, callbackURL = encodeURIComponent("/"), options) => {
85
+ const context = ctx.get("context");
86
+ if (!options?.emailVerification?.sendVerificationEmail) {
87
+ context.logger.error("Verification email isn't enabled.");
88
+ return ctx.render({
89
+ success: __faire_auth_core_static.False,
90
+ message: "Verification email isn't enabled"
91
+ }, 400);
92
+ }
93
+ const token = await createEmailVerificationToken(context.secret, user.email, void 0, options.emailVerification.expiresIn);
94
+ const url = `${context.baseURL}/verify-email?token=${token}&callbackURL=${callbackURL}`;
95
+ await options.emailVerification.sendVerificationEmail({
96
+ user,
97
+ url,
98
+ token
99
+ }, ctx);
100
+ };
101
+ const sendVerificationEmailRoute = (0, __faire_auth_core_factory.createRoute)({
102
+ operationId: __faire_auth_core_static.Routes.SEND_VERIFICATION_EMAIL,
103
+ method: "post",
104
+ path: "/send-verification-email",
105
+ description: "Send a verification email to the user",
106
+ request: (0, __faire_auth_core_factory.req)().bdy(sendVerificationEmailSchema).bld(),
107
+ responses: (0, __faire_auth_core_factory.res)(__faire_auth_core_static.SCHEMAS[__faire_auth_core_static.Definitions.SUCCESS].default).err(400).zod().bld()
108
+ });
109
+ const sendVerificationEmail = require_session.createEndpoint(sendVerificationEmailRoute, (options) => async (ctx) => {
110
+ const context = ctx.get("context");
111
+ if (!options.emailVerification?.sendVerificationEmail) {
112
+ context.logger.error("Verification email isn't enabled.");
113
+ return ctx.render({
114
+ success: __faire_auth_core_static.False,
115
+ message: "Verification email isn't enabled"
116
+ }, 400);
117
+ }
118
+ const { email, callbackURL } = ctx.req.valid("json");
119
+ const session = await require_session.getSessionFromCtx(ctx);
120
+ if (session instanceof Response) {
121
+ const user = await context.internalAdapter.findUserByEmail(email);
122
+ if (!user) return ctx.render({ success: __faire_auth_core_static.True }, 200);
123
+ await sendVerificationEmailFn(ctx, user.user, callbackURL, options);
124
+ return ctx.render({ success: __faire_auth_core_static.True }, 200);
125
+ }
126
+ if (session.user.emailVerified) return ctx.render({
127
+ success: __faire_auth_core_static.False,
128
+ message: "You can only send a verification email to an unverified email"
129
+ }, 400);
130
+ if (session.user.email !== email) return ctx.render({
131
+ success: __faire_auth_core_static.False,
132
+ message: "You can only send a verification email to your own email"
133
+ }, 400);
134
+ await sendVerificationEmailFn(ctx, session.user, callbackURL, options);
135
+ return ctx.render({ success: __faire_auth_core_static.True }, 200);
136
+ });
137
+ const verifyEmailRoute = (0, __faire_auth_core_factory.createRoute)({
138
+ operationId: __faire_auth_core_static.Routes.VERIFY_EMAIL,
139
+ method: "get",
140
+ path: "/verify-email",
141
+ description: "Verify the email of the user",
142
+ middleware: [require_origin_check.originCheck((ctx) => ctx.req.query("callbackURL")), tokenCheck((ctx) => ctx.req.query("token"), verifyEmailTokenSchema)],
143
+ request: (0, __faire_auth_core_factory.req)().qry(verifyEmailQuerySchema).bld(),
144
+ responses: (0, __faire_auth_core_factory.res)(__faire_auth_core_static.SCHEMAS[__faire_auth_core_static.Definitions.TOKEN_USER].default).err(401, "Invalid or expired token").err(500).rdr("Redirect to callback URL").zod().bld()
145
+ });
146
+ const verifyEmail = require_session.createEndpoint(verifyEmailRoute, (options) => async (ctx) => {
147
+ const { callbackURL } = ctx.req.valid("query");
148
+ const context = ctx.get("context");
149
+ const parsed = ctx.get("token");
150
+ const redirectOnError = (error) => {
151
+ if (callbackURL) {
152
+ if (callbackURL.includes("?")) return ctx.redirect(`${callbackURL}&error=${error}`, 302);
153
+ return ctx.redirect(`${callbackURL}?error=${error}`, 302);
154
+ }
155
+ return ctx.render({
156
+ success: __faire_auth_core_static.False,
157
+ code: error.toUpperCase(),
158
+ message: (0, __faire_auth_core_utils.capitalizeFirstLetter)(error.replaceAll("_", " "))
159
+ }, 401);
160
+ };
161
+ const user = await context.internalAdapter.findUserByEmail(parsed.email);
162
+ if (!user) return redirectOnError("user_not_found");
163
+ if (parsed.updateTo) {
164
+ const session = await require_session.getSessionFromCtx(ctx);
165
+ if (session instanceof Response || session.user.email !== parsed.email) return redirectOnError("unauthorized");
166
+ const updatedUser$1 = await context.internalAdapter.updateUserByEmail(parsed.email, {
167
+ email: parsed.updateTo,
168
+ emailVerified: false
169
+ });
170
+ if (updatedUser$1 == null) return ctx.render({
171
+ success: __faire_auth_core_static.False,
172
+ message: "Failed to update user"
173
+ }, 500);
174
+ const newToken = await createEmailVerificationToken(context.secret, parsed.updateTo);
175
+ if (options.emailVerification?.sendVerificationEmail) await options.emailVerification.sendVerificationEmail({
176
+ user: updatedUser$1,
177
+ url: `${context.baseURL}/verify-email?token=${newToken}&callbackURL=${callbackURL ?? encodeURIComponent("/")}`,
178
+ token: newToken
179
+ }, ctx);
180
+ await require_cookies.setSessionCookie(ctx, options, {
181
+ session: session.session,
182
+ user: {
183
+ ...session.user,
184
+ email: parsed.updateTo,
185
+ emailVerified: false
186
+ }
187
+ });
188
+ if (callbackURL != null) return ctx.redirect(callbackURL, 302);
189
+ return ctx.render({
190
+ success: __faire_auth_core_static.True,
191
+ token: session.session.token,
192
+ user: updatedUser$1
193
+ }, 200);
194
+ }
195
+ if (options.emailVerification?.onEmailVerification) await options.emailVerification.onEmailVerification(user.user, ctx.req);
196
+ const updatedUser = await context.internalAdapter.updateUserByEmail(parsed.email, { emailVerified: true });
197
+ if (updatedUser == null) return ctx.render({
198
+ success: __faire_auth_core_static.False,
199
+ message: "Failed to update user"
200
+ }, 500);
201
+ if (options.emailVerification?.afterEmailVerification) await options.emailVerification.afterEmailVerification(updatedUser, ctx.req);
202
+ if (options.emailVerification?.autoSignInAfterVerification === true) {
203
+ const currentSession = await require_session.getSessionFromCtx(ctx);
204
+ if (currentSession instanceof Response || currentSession.user.email !== parsed.email) {
205
+ const session = await context.internalAdapter.createSession(user.user.id);
206
+ if (session == null) return ctx.render({
207
+ success: __faire_auth_core_static.False,
208
+ message: "Failed to create session"
209
+ }, 500);
210
+ await require_cookies.setSessionCookie(ctx, options, {
211
+ session,
212
+ user: {
213
+ ...user.user,
214
+ emailVerified: true
215
+ }
216
+ });
217
+ } else await require_cookies.setSessionCookie(ctx, options, {
218
+ session: currentSession.session,
219
+ user: {
220
+ ...currentSession.user,
221
+ emailVerified: true
222
+ }
223
+ });
224
+ }
225
+ if (callbackURL != null) return ctx.redirect(callbackURL, 302);
226
+ return ctx.render({ success: __faire_auth_core_static.False }, 200);
227
+ });
228
+
229
+ //#endregion
230
+ Object.defineProperty(exports, 'createEmailVerificationToken', {
231
+ enumerable: true,
232
+ get: function () {
233
+ return createEmailVerificationToken;
234
+ }
235
+ });
236
+ Object.defineProperty(exports, 'sendVerificationEmail', {
237
+ enumerable: true,
238
+ get: function () {
239
+ return sendVerificationEmail;
240
+ }
241
+ });
242
+ Object.defineProperty(exports, 'verifyEmail', {
243
+ enumerable: true,
244
+ get: function () {
245
+ return verifyEmail;
246
+ }
247
+ });
@@ -0,0 +1,228 @@
1
+ import { n as crypto_exports } from "./crypto-CyQRFtkq.mjs";
2
+ import { y as setSessionCookie } from "./cookies-Ch1JfQIz.mjs";
3
+ import { r as createMiddleware } from "./middleware-CE6OhDkq.mjs";
4
+ import { f as createEndpoint, r as getSessionFromCtx } from "./session-rH8ougDl.mjs";
5
+ import { n as originCheck } from "./origin-check-8Gajklvh.mjs";
6
+ import { callbackURLSchema, createRoute, emailSchema, req, res } from "@faire-auth/core/factory";
7
+ import { Definitions, False, Routes, SCHEMAS, True } from "@faire-auth/core/static";
8
+ import { capitalizeFirstLetter } from "@faire-auth/core/utils";
9
+ import * as z$1 from "zod";
10
+ import { jwtVerify } from "jose";
11
+ import { JWTExpired } from "jose/errors";
12
+
13
+ //#region src/api/schema/email-verification.ts
14
+ const sendVerificationEmailSchema = z$1.object({
15
+ email: emailSchema.openapi({ description: "The email to send the verification email to" }),
16
+ callbackURL: callbackURLSchema(true).openapi({ description: "The URL to use for email verification callback" })
17
+ });
18
+ const verifyEmailQuerySchema = z$1.object({
19
+ token: z$1.string().openapi({ description: "The token to verify the email" }),
20
+ callbackURL: callbackURLSchema(true).openapi({ description: "The URL to redirect to after email verification" })
21
+ });
22
+ const verifyEmailTokenSchema = z$1.object({
23
+ email: emailSchema,
24
+ updateTo: z$1.string().optional()
25
+ });
26
+
27
+ //#endregion
28
+ //#region src/api/middleware/token-check.ts
29
+ const onError = async (ctx, error) => {
30
+ let code;
31
+ if (error === "missing_token") code = 400;
32
+ else code = 401;
33
+ const url = ctx.req.query("callbackURL");
34
+ if (url) {
35
+ if (url.includes("?")) return ctx.redirect(`${url}&error=${error}`, 302);
36
+ return ctx.redirect(`${url}?error=${error}`, 302);
37
+ }
38
+ return ctx.render({
39
+ success: False,
40
+ code: error.toUpperCase(),
41
+ message: capitalizeFirstLetter(error.replaceAll("_", " "))
42
+ }, code);
43
+ };
44
+ const verifyToken = async (token, context) => {
45
+ let jwt;
46
+ try {
47
+ jwt = await jwtVerify(token, new TextEncoder().encode(context.secret), { algorithms: ["HS256"] });
48
+ } catch (e) {
49
+ if (e instanceof JWTExpired) return "token_expired";
50
+ return "invalid_token";
51
+ }
52
+ return jwt;
53
+ };
54
+ /**
55
+ * Validates token against context secret.
56
+ * @template V - The context variables type.
57
+ * @param getValue - Function to get the token from the context.
58
+ * @returns The middleware function.
59
+ */
60
+ const tokenCheck = (getValue, schema) => createMiddleware()(async (ctx, next) => {
61
+ const token = await getValue(ctx);
62
+ if (!token) return onError(ctx, "missing_token");
63
+ const res$1 = await verifyToken(token, ctx.get("context"));
64
+ if (typeof res$1 === "string") return onError(ctx, res$1);
65
+ const dat = await schema.safeParseAsync(res$1.payload);
66
+ if (dat.success === false) return onError(ctx, "invalid_token");
67
+ ctx.set("token", dat.data);
68
+ return await next();
69
+ });
70
+
71
+ //#endregion
72
+ //#region src/api/routes/email-verification.ts
73
+ const createEmailVerificationToken = async (secret, email, updateTo, expiresIn = 3600) => {
74
+ return await (0, crypto_exports.signJWT)({
75
+ email: email.toLowerCase(),
76
+ updateTo
77
+ }, secret, expiresIn);
78
+ };
79
+ /**
80
+ * A function to send a verification email to the user
81
+ */
82
+ const sendVerificationEmailFn = async (ctx, user, callbackURL = encodeURIComponent("/"), options) => {
83
+ const context = ctx.get("context");
84
+ if (!options?.emailVerification?.sendVerificationEmail) {
85
+ context.logger.error("Verification email isn't enabled.");
86
+ return ctx.render({
87
+ success: False,
88
+ message: "Verification email isn't enabled"
89
+ }, 400);
90
+ }
91
+ const token = await createEmailVerificationToken(context.secret, user.email, void 0, options.emailVerification.expiresIn);
92
+ const url = `${context.baseURL}/verify-email?token=${token}&callbackURL=${callbackURL}`;
93
+ await options.emailVerification.sendVerificationEmail({
94
+ user,
95
+ url,
96
+ token
97
+ }, ctx);
98
+ };
99
+ const sendVerificationEmailRoute = createRoute({
100
+ operationId: Routes.SEND_VERIFICATION_EMAIL,
101
+ method: "post",
102
+ path: "/send-verification-email",
103
+ description: "Send a verification email to the user",
104
+ request: req().bdy(sendVerificationEmailSchema).bld(),
105
+ responses: res(SCHEMAS[Definitions.SUCCESS].default).err(400).zod().bld()
106
+ });
107
+ const sendVerificationEmail = createEndpoint(sendVerificationEmailRoute, (options) => async (ctx) => {
108
+ const context = ctx.get("context");
109
+ if (!options.emailVerification?.sendVerificationEmail) {
110
+ context.logger.error("Verification email isn't enabled.");
111
+ return ctx.render({
112
+ success: False,
113
+ message: "Verification email isn't enabled"
114
+ }, 400);
115
+ }
116
+ const { email, callbackURL } = ctx.req.valid("json");
117
+ const session = await getSessionFromCtx(ctx);
118
+ if (session instanceof Response) {
119
+ const user = await context.internalAdapter.findUserByEmail(email);
120
+ if (!user) return ctx.render({ success: True }, 200);
121
+ await sendVerificationEmailFn(ctx, user.user, callbackURL, options);
122
+ return ctx.render({ success: True }, 200);
123
+ }
124
+ if (session.user.emailVerified) return ctx.render({
125
+ success: False,
126
+ message: "You can only send a verification email to an unverified email"
127
+ }, 400);
128
+ if (session.user.email !== email) return ctx.render({
129
+ success: False,
130
+ message: "You can only send a verification email to your own email"
131
+ }, 400);
132
+ await sendVerificationEmailFn(ctx, session.user, callbackURL, options);
133
+ return ctx.render({ success: True }, 200);
134
+ });
135
+ const verifyEmailRoute = createRoute({
136
+ operationId: Routes.VERIFY_EMAIL,
137
+ method: "get",
138
+ path: "/verify-email",
139
+ description: "Verify the email of the user",
140
+ middleware: [originCheck((ctx) => ctx.req.query("callbackURL")), tokenCheck((ctx) => ctx.req.query("token"), verifyEmailTokenSchema)],
141
+ request: req().qry(verifyEmailQuerySchema).bld(),
142
+ responses: res(SCHEMAS[Definitions.TOKEN_USER].default).err(401, "Invalid or expired token").err(500).rdr("Redirect to callback URL").zod().bld()
143
+ });
144
+ const verifyEmail = createEndpoint(verifyEmailRoute, (options) => async (ctx) => {
145
+ const { callbackURL } = ctx.req.valid("query");
146
+ const context = ctx.get("context");
147
+ const parsed = ctx.get("token");
148
+ const redirectOnError = (error) => {
149
+ if (callbackURL) {
150
+ if (callbackURL.includes("?")) return ctx.redirect(`${callbackURL}&error=${error}`, 302);
151
+ return ctx.redirect(`${callbackURL}?error=${error}`, 302);
152
+ }
153
+ return ctx.render({
154
+ success: False,
155
+ code: error.toUpperCase(),
156
+ message: capitalizeFirstLetter(error.replaceAll("_", " "))
157
+ }, 401);
158
+ };
159
+ const user = await context.internalAdapter.findUserByEmail(parsed.email);
160
+ if (!user) return redirectOnError("user_not_found");
161
+ if (parsed.updateTo) {
162
+ const session = await getSessionFromCtx(ctx);
163
+ if (session instanceof Response || session.user.email !== parsed.email) return redirectOnError("unauthorized");
164
+ const updatedUser$1 = await context.internalAdapter.updateUserByEmail(parsed.email, {
165
+ email: parsed.updateTo,
166
+ emailVerified: false
167
+ });
168
+ if (updatedUser$1 == null) return ctx.render({
169
+ success: False,
170
+ message: "Failed to update user"
171
+ }, 500);
172
+ const newToken = await createEmailVerificationToken(context.secret, parsed.updateTo);
173
+ if (options.emailVerification?.sendVerificationEmail) await options.emailVerification.sendVerificationEmail({
174
+ user: updatedUser$1,
175
+ url: `${context.baseURL}/verify-email?token=${newToken}&callbackURL=${callbackURL ?? encodeURIComponent("/")}`,
176
+ token: newToken
177
+ }, ctx);
178
+ await setSessionCookie(ctx, options, {
179
+ session: session.session,
180
+ user: {
181
+ ...session.user,
182
+ email: parsed.updateTo,
183
+ emailVerified: false
184
+ }
185
+ });
186
+ if (callbackURL != null) return ctx.redirect(callbackURL, 302);
187
+ return ctx.render({
188
+ success: True,
189
+ token: session.session.token,
190
+ user: updatedUser$1
191
+ }, 200);
192
+ }
193
+ if (options.emailVerification?.onEmailVerification) await options.emailVerification.onEmailVerification(user.user, ctx.req);
194
+ const updatedUser = await context.internalAdapter.updateUserByEmail(parsed.email, { emailVerified: true });
195
+ if (updatedUser == null) return ctx.render({
196
+ success: False,
197
+ message: "Failed to update user"
198
+ }, 500);
199
+ if (options.emailVerification?.afterEmailVerification) await options.emailVerification.afterEmailVerification(updatedUser, ctx.req);
200
+ if (options.emailVerification?.autoSignInAfterVerification === true) {
201
+ const currentSession = await getSessionFromCtx(ctx);
202
+ if (currentSession instanceof Response || currentSession.user.email !== parsed.email) {
203
+ const session = await context.internalAdapter.createSession(user.user.id);
204
+ if (session == null) return ctx.render({
205
+ success: False,
206
+ message: "Failed to create session"
207
+ }, 500);
208
+ await setSessionCookie(ctx, options, {
209
+ session,
210
+ user: {
211
+ ...user.user,
212
+ emailVerified: true
213
+ }
214
+ });
215
+ } else await setSessionCookie(ctx, options, {
216
+ session: currentSession.session,
217
+ user: {
218
+ ...currentSession.user,
219
+ emailVerified: true
220
+ }
221
+ });
222
+ }
223
+ if (callbackURL != null) return ctx.redirect(callbackURL, 302);
224
+ return ctx.render({ success: False }, 200);
225
+ });
226
+
227
+ //#endregion
228
+ export { sendVerificationEmail as n, verifyEmail as r, createEmailVerificationToken as t };