@alook/app 0.0.3 → 0.0.5
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.
- package/bundled/web/.open-next/.build/durable-objects/queue.js +5 -5
- package/bundled/web/.open-next/assets/BUILD_ID +1 -1
- package/bundled/web/.open-next/cache/{YGJyWNUCWhOqpFg-fDYKo → jsS4n9BW-F-LPiDHcvvEr}/_global-error.cache +1 -1
- package/bundled/web/.open-next/cache/{YGJyWNUCWhOqpFg-fDYKo → jsS4n9BW-F-LPiDHcvvEr}/_not-found.cache +1 -1
- package/bundled/web/.open-next/cache/{YGJyWNUCWhOqpFg-fDYKo → jsS4n9BW-F-LPiDHcvvEr}/sitemap.xml.cache +1 -1
- package/bundled/web/.open-next/cloudflare/cache-assets-manifest.sql +1 -1
- package/bundled/web/.open-next/cloudflare/init.js +1 -1
- package/bundled/web/.open-next/dynamodb-provider/dynamodb-cache.json +1 -1
- package/bundled/web/.open-next/middleware/handler.mjs +26 -26
- package/bundled/web/.open-next/server-functions/default/src/web/.next/BUILD_ID +1 -1
- package/bundled/web/.open-next/server-functions/default/src/web/.next/build-manifest.json +3 -3
- package/bundled/web/.open-next/server-functions/default/src/web/.next/prerender-manifest.json +3 -3
- package/bundled/web/.open-next/server-functions/default/src/web/.next/server/chunks/_0-6p0uy._.js +2 -2
- package/bundled/web/.open-next/server-functions/default/src/web/.next/server/chunks/_0ih-ceb._.js +2 -2
- package/bundled/web/.open-next/server-functions/default/src/web/.next/server/chunks/ssr/_0_k8iss._.js +2 -2
- package/bundled/web/.open-next/server-functions/default/src/web/.next/server/chunks/ssr/_11h6ii1._.js +2 -2
- package/bundled/web/.open-next/server-functions/default/src/web/.next/server/middleware-build-manifest.js +3 -3
- package/bundled/web/.open-next/server-functions/default/src/web/.next/server/middleware-manifest.json +5 -5
- package/bundled/web/.open-next/server-functions/default/src/web/.next/server/server-reference-manifest.js +1 -1
- package/bundled/web/.open-next/server-functions/default/src/web/.next/server/server-reference-manifest.json +1 -1
- package/bundled/web/.open-next/server-functions/default/src/web/handler.mjs +10 -10
- package/bundled/web/.open-next/server-functions/default/src/web/handler.mjs.meta.json +66 -66
- package/bundled/web/.open-next/server-functions/default/src/web/index.mjs +3 -3
- package/bundled/web/custom-worker.ts +2 -2
- package/dist/index.js +1 -0
- package/package.json +1 -1
- /package/bundled/web/.open-next/assets/_next/static/{YGJyWNUCWhOqpFg-fDYKo → jsS4n9BW-F-LPiDHcvvEr}/_buildManifest.js +0 -0
- /package/bundled/web/.open-next/assets/_next/static/{YGJyWNUCWhOqpFg-fDYKo → jsS4n9BW-F-LPiDHcvvEr}/_clientMiddlewareManifest.js +0 -0
- /package/bundled/web/.open-next/assets/_next/static/{YGJyWNUCWhOqpFg-fDYKo → jsS4n9BW-F-LPiDHcvvEr}/_ssgManifest.js +0 -0
- /package/bundled/web/.open-next/cache/{YGJyWNUCWhOqpFg-fDYKo → jsS4n9BW-F-LPiDHcvvEr}/robots.txt.cache +0 -0
package/bundled/web/.open-next/server-functions/default/src/web/.next/server/chunks/_0-6p0uy._.js
CHANGED
|
@@ -395,7 +395,7 @@ To resolve this, you can:
|
|
|
395
395
|
1. Use only one of the conflicting plugins
|
|
396
396
|
2. Configure the plugins to use different paths (if supported)
|
|
397
397
|
3. Ensure plugins use different HTTP methods for the same path
|
|
398
|
-
`)}}(t={...t,secret:i,baseURL:w?t.baseURL:A?new URL(A).origin:"",basePath:t.basePath||"/api/auth",plugins:s.concat(c)},l);let T=(0,h.getCookies)(t),R=(0,rT.getAuthTables)(t),I=(await Promise.all(Object.entries(t.socialProviders||{}).map(async([e,t])=>{let r="function"==typeof t?await t():t;if(null==r||!1===r.enabled)return null;r.clientId||l.warn(`Social provider ${e} is missing clientId or clientSecret`);let i=tP[e](r);return i.disableImplicitSignUp=r.disableImplicitSignUp,i}))).filter(e=>null!==e),v=({model:e,size:r})=>{if("function"==typeof t.advanced?.generateId)return t.advanced.generateId({model:e,size:r});let i=t?.advanced?.database?.generateId;return"function"==typeof i?i({model:e,size:r}):"uuid"===i?crypto.randomUUID():"serial"!==i&&!1!==i&&(0,t0.generateId)(r)},{publish:_}=await rK(t,{adapter:e.id,database:"function"==typeof t.database?"adapter":r(t.database)}),O=new Set(t.plugins.map(e=>e.id)),U=await (0,y.getTrustedOrigins)(t),P=await (0,y.getTrustedProviders)(t),C={appName:t.appName||"Better Auth",baseURL:A||"",version:(0,rk.getBetterAuthVersion)(),socialProviders:I,options:t,oauthConfig:{storeStateStrategy:t.account?.storeStateStrategy||(t.database?"database":"cookie"),skipStateCookieCheck:!!t.account?.skipStateCookieCheck},tables:R,trustedOrigins:U,trustedProviders:P,isTrustedOrigin(e,t){return this.trustedOrigins.some(r=>(0,u.matchesOriginPattern)(e,r,t))},sessionConfig:{updateAge:t.session?.updateAge!==void 0?t.session.updateAge:86400,expiresIn:t.session?.expiresIn||604800,freshAge:t.session?.freshAge===void 0?86400:t.session.freshAge,cookieRefreshCache:(o=t.session?.cookieCache?.refreshCache,n=t.session?.cookieCache?.maxAge||300,(t.database||t.secondaryStorage)&&o?(l.warn("[better-auth] `session.cookieCache.refreshCache` is enabled while `database` or `secondaryStorage` is configured. `refreshCache` is meant for stateless (DB-less) setups. Disabling `refreshCache` — remove it from your config to silence this warning."),!1):!1!==o&&void 0!==o&&(!0===o?{enabled:!0,updateAge:Math.floor(.2*n)}:{enabled:!0,updateAge:void 0!==o.updateAge?o.updateAge:Math.floor(.2*n)}))},secret:i,secretConfig:a,rateLimit:{...t.rateLimit,enabled:t.rateLimit?.enabled??tz.isProduction,window:t.rateLimit?.window||10,max:t.rateLimit?.max||100,storage:t.rateLimit?.storage||(t.secondaryStorage?"secondary-storage":"memory")},authCookies:T,logger:l,generateId:v,session:null,secondaryStorage:t.secondaryStorage,password:{hash:t.emailAndPassword?.password?.hash||f.hashPassword,verify:t.emailAndPassword?.password?.verify||f.verifyPassword,config:{minPasswordLength:t.emailAndPassword?.minPasswordLength||8,maxPasswordLength:t.emailAndPassword?.maxPasswordLength||128},checkPassword:g.checkPassword},setNewSession(e){this.newSession=e},newSession:null,adapter:e,internalAdapter:(0,m.createInternalAdapter)(e,{options:t,logger:l,hooks:t.databaseHooks?[{source:"user",hooks:t.databaseHooks}]:[],generateId:v}),createAuthCookie:(0,h.createCookieGetter)(t),async runMigrations(){throw new x.BetterAuthError("runMigrations will be set by the specific init implementation")},publishTelemetry:_,skipCSRFCheck:!!t.advanced?.disableCSRFCheck,skipOriginCheck:t.advanced?.disableOriginCheck!==void 0?t.advanced.disableOriginCheck:!!(0,tz.isTest)(),runInBackground:t.advanced?.backgroundTasks?.handler??(e=>{e.catch(()=>{})}),async runInBackgroundOrAwait(e){try{t.advanced?.backgroundTasks?.handler?e instanceof Promise&&t.advanced.backgroundTasks.handler(e.catch(e=>{l.error("Failed to run background task:",e)})):await e}catch(e){l.error("Failed to run background task:",e)}},getPlugin:e=>t.plugins.find(t=>t.id===e)??null,hasPlugin:e=>O.has(e)},D=(0,y.runPluginInit)(C);return(0,p.isPromise)(D)&&await D,C}var rF=e.i(439704);let rJ=async e=>{let t=await (0,c.getAdapter)(e),r=await rz(t,e,e=>(0,rF.getKyselyDatabaseType)(e)||"unknown");return r.runMigrations=async function(){if(!e.database||"updateMany"in e.database)throw new x.BetterAuthError("Database is not provided or it's an adapter. Migrations are only supported with a database instance.");let{runMigrations:t}=await (0,l.getMigrations)(e);await t()},r};e.s(["betterAuth",0,e=>((e,t)=>{let r=t(e),{api:i}=rS(r,e);return{handler:async t=>{let i,a=await r,o=a.options.basePath||"/api/auth";if((0,d.isDynamicBaseURLConfig)(e.baseURL))i=await (0,y.resolveRequestContext)(a,t,(0,y.resolveDynamicTrustedProxyHeaders)(a.options));else{if(i=a,!a.options.baseURL){let e=(0,d.getBaseURL)(void 0,o,t,void 0,a.options.advanced?.trustedProxyHeaders);if(e)a.baseURL=e,a.options.baseURL=(0,d.getOrigin)(a.baseURL)||void 0;else throw new x.BetterAuthError("Could not get base URL from request. Please provide a valid base URL.")}i.trustedOrigins=await (0,y.getTrustedOrigins)(a.options,t),i.trustedProviders=await (0,y.getTrustedProviders)(a.options,t)}let{handler:n}=((e,t)=>{let{api:r,middlewares:i}=rS(e,t),a=new URL(e.baseURL).pathname;return(0,rb.createRouter)(r,{routerContext:e,openapi:{disabled:!0},basePath:a,routerMiddleware:[{path:"/**",middleware:A.originCheckMiddleware},...i],allowedMediaTypes:["application/json"],skipTrailingSlashes:t.advanced?.skipTrailingSlashes??!1,async onRequest(t){let r=e.options.disabledPaths||[],i=(0,rE.normalizePathname)(t.url,a);if(r.includes(i))return new Response("Not Found",{status:404});let o=t;for(let t of e.options.plugins||[])if(t.onRequest){let r=await (0,rp.withSpan)(`onRequest ${t.id}`,{[rd.ATTR_HOOK_TYPE]:"onRequest",[rd.ATTR_CONTEXT]:`plugin:${t.id}`},()=>t.onRequest(o,e));if(r&&"response"in r)return r.response;r&&"request"in r&&(o=r.request)}let n=await (0,E.onRequestRateLimit)(o,e);return n||o},async onResponse(t,r){for(let i of(await (0,E.onResponseRateLimit)(r,e),e.options.plugins||[]))if(i.onResponse){let r=await (0,rp.withSpan)(`onResponse ${i.id}`,{[rd.ATTR_HOOK_TYPE]:"onResponse",[rd.ATTR_CONTEXT]:`plugin:${i.id}`,[ru.ATTR_HTTP_RESPONSE_STATUS_CODE]:t.status},()=>i.onResponse(t,e));if(r)return r.response}return t},onError(r){if((0,w.isAPIError)(r)&&"FOUND"===r.status)return;if(t.onAPIError?.throw)throw r;if(t.onAPIError?.onError)return void t.onAPIError.onError(r,e);let i=t.logger?.level,a="error"===i||"warn"===i||"debug"===i?eM.logger:void 0;if(t.logger?.disabled!==!0){if(r&&"object"==typeof r&&"message"in r&&"string"==typeof r.message&&(r.message.includes("no column")||r.message.includes("column")||r.message.includes("relation")||r.message.includes("table")||r.message.includes("does not exist")))return void e.logger?.error(r.message);(0,w.isAPIError)(r)?("INTERNAL_SERVER_ERROR"===r.status&&e.logger.error(r.status,r),a?.error(r.message)):e.logger?.error(r&&"object"==typeof r&&"name"in r?r.name:"",r)}}})})(i,e);return(0,t9.runWithAdapter)(i.adapter,()=>n(t))},api:i,options:e,$context:r,$ERROR_CODES:{...e.plugins?.reduce((e,t)=>t.$ERROR_CODES?{...e,...t.$ERROR_CODES}:e,{}),...v.BASE_ERROR_CODES}}})(e,rJ)],928976)},342573,e=>{"use strict";var t=e.i(928976),r=e.i(108761),i=e.i(760160),a=e.i(185599);let o=(0,e.i(332807).defineErrorCodes)({OTP_EXPIRED:"OTP expired",INVALID_OTP:"Invalid OTP",TOO_MANY_ATTEMPTS:"Too many attempts"});var n=e.i(280917);let s=async e=>{let t=e.context.returned;return t?t instanceof Response?200!==t.status?null:await t.clone().json():(0,n.isAPIError)(t)?null:t:null};var c=e.i(575779),l=e.i(618989);function d(e,t){return`${e}-otp-${t}`}let u=async e=>{let t=await (0,l.createHash)("SHA-256").digest(new TextEncoder().encode(e));return c.base64Url.encode(new Uint8Array(t),{padding:!1})};function p(e){let t=e.lastIndexOf(":");return -1===t?[e,""]:[e.slice(0,t),e.slice(t+1)]}var f=e.i(463617),h=e.i(277512);async function m(e,t,r){return"encrypted"===t.storeOTP?await (0,h.symmetricEncrypt)({key:e.context.secretConfig,data:r}):"hashed"===t.storeOTP?await u(r):"object"==typeof t.storeOTP&&"hash"in t.storeOTP?await t.storeOTP.hash(r):"object"==typeof t.storeOTP&&"encrypt"in t.storeOTP?await t.storeOTP.encrypt(r):r}async function y(e,t,r,i){return"encrypted"===t.storeOTP?(0,f.constantTimeEqual)(await (0,h.symmetricDecrypt)({key:e.context.secretConfig,data:r}),i):"hashed"===t.storeOTP?(0,f.constantTimeEqual)(await u(i),r):"object"==typeof t.storeOTP&&"hash"in t.storeOTP?(0,f.constantTimeEqual)(await t.storeOTP.hash(i),r):"object"==typeof t.storeOTP&&"decrypt"in t.storeOTP?(0,f.constantTimeEqual)(await t.storeOTP.decrypt(r),i):(0,f.constantTimeEqual)(i,r)}async function g(e,t,r){return"plain"===t.storeOTP||void 0===t.storeOTP?r:"encrypted"===t.storeOTP?await (0,h.symmetricDecrypt)({key:e.context.secretConfig,data:r}):"object"==typeof t.storeOTP&&"decrypt"in t.storeOTP?await t.storeOTP.decrypt(r):null}async function w(e,t,i){let a=await e.context.internalAdapter.findVerificationValue(i);if(!a||a.expiresAt<new Date)return null;let[o,n]=p(a.value),s=t.allowedAttempts||3;if(n&&parseInt(n)>=s)return null;let c=await g(e,t,o);return c?(await e.context.internalAdapter.updateVerificationByIdentifier(i,{expiresAt:(0,r.getDate)(t.expiresIn,"sec")}),c):null}var A=e.i(33573),E=e.i(22523),b=e.i(610914),S=e.i(290410),k=e.i(63162),T=e.i(702149),R=e.i(440277),I=e.i(807405);let x=["email-verification","sign-in","forget-password","change-email"];async function v(e,t,i,a){let o=d(a,i);if("reuse"===t.resendStrategy){let r=await w(e,t,o);if(r)return r}let n=t.generateOTP({email:i,type:a},e)||H(t),s=await m(e,t,n);return await e.context.internalAdapter.createVerificationValue({value:`${s}:0`,identifier:o,expiresAt:(0,r.getDate)(t.expiresIn,"sec")}).catch(async()=>{await e.context.internalAdapter.deleteVerificationByIdentifier(o),await e.context.internalAdapter.createVerificationValue({value:`${s}:0`,identifier:o,expiresAt:(0,r.getDate)(t.expiresIn,"sec")})}),n}let _=I.object({email:I.string({}).meta({description:"Email address to send the OTP"}),type:I.enum(x).meta({description:"Type of the OTP"})}),O=I.object({email:I.string({}).meta({description:"Email address to send the OTP"}),type:I.enum(x).meta({required:!0,description:"Type of the OTP"})}),U=I.object({email:I.string({}).meta({description:"Email address the OTP was sent to"}),type:I.enum(x).meta({required:!0,description:"Type of the OTP"})}),P=I.object({email:I.string().meta({description:"Email address the OTP was sent to"}),type:I.enum(x).meta({required:!0,description:"Type of the OTP"}),otp:I.string().meta({required:!0,description:"OTP to verify"})}),C=I.object({email:I.string({}).meta({description:"Email address to verify"}),otp:I.string().meta({required:!0,description:"OTP to verify"})}),D=I.object({email:I.string({}).meta({description:"Email address to sign in"}),otp:I.string().meta({required:!0,description:"OTP sent to the email"}),name:I.string().meta({description:'User display name. Only used if the user is registering for the first time. Eg: "my-name"'}).optional(),image:I.string().meta({description:"User profile image URL. Only used if the user is registering for the first time."}).optional()}).and(I.record(I.string(),I.any())),L=I.object({email:I.string().meta({description:"Email address to send the OTP"})}),N=I.object({email:I.string().meta({description:"Email address to send the OTP"})}),B=I.object({email:I.string().meta({description:"Email address to reset the password"}),otp:I.string().meta({description:"OTP sent to the email"}),password:I.string().meta({description:"New password"})}),j=I.object({newEmail:I.string().meta({description:"New email address to send the OTP"}),otp:I.string().optional().meta({description:"OTP sent to the current email. This is required if changeEmail.verifyCurrentEmail option is set to true"})}),$=I.object({newEmail:I.string().meta({description:"New email address to verify and change to"}),otp:I.string().meta({description:"OTP sent to the new email"})}),H=e=>(0,i.generateRandomString)(e.otpLength??6,"0-9");async function V(e,t,r,i){let a=await e.context.internalAdapter.findVerificationValue(r);if(!a)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);if(a.expiresAt<new Date)throw await e.context.internalAdapter.deleteVerificationByIdentifier(r),S.APIError.from("BAD_REQUEST",o.OTP_EXPIRED);let[n,s]=p(a.value),c=t?.allowedAttempts||3;if(s&&parseInt(s)>=c)throw await e.context.internalAdapter.deleteVerificationByIdentifier(r),S.APIError.from("FORBIDDEN",o.TOO_MANY_ATTEMPTS);if(await e.context.internalAdapter.deleteVerificationByIdentifier(r),!await y(e,t,n,i))throw await e.context.internalAdapter.createVerificationValue({value:`${n}:${parseInt(s||"0")+1}`,identifier:r,expiresAt:a.expiresAt}),S.APIError.from("BAD_REQUEST",o.INVALID_OTP)}let q=e=>(0,i.generateRandomString)(e.otpLength??6,"0-9");e.i(700598);var M=e.i(726527),W=e.i(704024);let K={"sign-in":"Your Alook sign-in code","email-verification":"Verify your Alook email","forget-password":"Reset your Alook password","change-email":"Confirm your new email address"},z={"sign-in":"Sign in to Alook","email-verification":"Verify your email","forget-password":"Reset your password","change-email":"Confirm email change"},F={"sign-in":"Enter this code to sign in to your account.","email-verification":"Enter this code to verify your email address.","forget-password":"Enter this code to reset your password.","change-email":"Enter this code to confirm your new email address."},J=(0,M.createLogger)({service:"auth"});function G(e,t){if(!e)return t;let r=Number.parseInt(e,10);return Number.isFinite(r)&&r>0?r:t}e.s(["createAuth",0,function(e){var i;let n,c,l,u=G(e.AUTH_OTP_RATE_LIMIT_MAX,5),f=G(e.AUTH_OTP_RATE_LIMIT_WINDOW_SEC,60),g=Math.max(60,f);return(0,t.betterAuth)({baseURL:e.BETTER_AUTH_URL,database:e.DB,secret:e.BETTER_AUTH_SECRET,session:{expiresIn:2592e3,updateAge:86400,cookieCache:{enabled:!0,maxAge:300}},emailAndPassword:{enabled:!1,requireEmailVerification:!1},socialProviders:{github:{clientId:e.GITHUB_CLIENT_ID,clientSecret:e.GITHUB_CLIENT_SECRET},google:{clientId:e.GOOGLE_CLIENT_ID,clientSecret:e.GOOGLE_CLIENT_SECRET}},rateLimit:{enabled:!0,customRules:{"/email-otp/send-verification-otp":{window:f,max:u}},customStorage:{get:async t=>{let r=await e.RATE_LIMIT_KV.get(t);return r?JSON.parse(r):void 0},set:async(t,r)=>{await e.RATE_LIMIT_KV.put(t,JSON.stringify(r),{expirationTtl:g})}}},plugins:[(n={expiresIn:300,generateOTP:()=>q(i),storeOTP:"plain",...i={async sendVerificationOTP({email:t,otp:r,type:i}){J.info("sending OTP email",{to:t,type:i});try{let a,o,n,s=JSON.stringify({to:t,subject:K[i],html:(o=z[i],n=F[i],`<!DOCTYPE html>
|
|
398
|
+
`)}}(t={...t,secret:i,baseURL:w?t.baseURL:A?new URL(A).origin:"",basePath:t.basePath||"/api/auth",plugins:s.concat(c)},l);let T=(0,h.getCookies)(t),R=(0,rT.getAuthTables)(t),I=(await Promise.all(Object.entries(t.socialProviders||{}).map(async([e,t])=>{let r="function"==typeof t?await t():t;if(null==r||!1===r.enabled)return null;r.clientId||l.warn(`Social provider ${e} is missing clientId or clientSecret`);let i=tP[e](r);return i.disableImplicitSignUp=r.disableImplicitSignUp,i}))).filter(e=>null!==e),v=({model:e,size:r})=>{if("function"==typeof t.advanced?.generateId)return t.advanced.generateId({model:e,size:r});let i=t?.advanced?.database?.generateId;return"function"==typeof i?i({model:e,size:r}):"uuid"===i?crypto.randomUUID():"serial"!==i&&!1!==i&&(0,t0.generateId)(r)},{publish:_}=await rK(t,{adapter:e.id,database:"function"==typeof t.database?"adapter":r(t.database)}),O=new Set(t.plugins.map(e=>e.id)),U=await (0,y.getTrustedOrigins)(t),P=await (0,y.getTrustedProviders)(t),C={appName:t.appName||"Better Auth",baseURL:A||"",version:(0,rk.getBetterAuthVersion)(),socialProviders:I,options:t,oauthConfig:{storeStateStrategy:t.account?.storeStateStrategy||(t.database?"database":"cookie"),skipStateCookieCheck:!!t.account?.skipStateCookieCheck},tables:R,trustedOrigins:U,trustedProviders:P,isTrustedOrigin(e,t){return this.trustedOrigins.some(r=>(0,u.matchesOriginPattern)(e,r,t))},sessionConfig:{updateAge:t.session?.updateAge!==void 0?t.session.updateAge:86400,expiresIn:t.session?.expiresIn||604800,freshAge:t.session?.freshAge===void 0?86400:t.session.freshAge,cookieRefreshCache:(o=t.session?.cookieCache?.refreshCache,n=t.session?.cookieCache?.maxAge||300,(t.database||t.secondaryStorage)&&o?(l.warn("[better-auth] `session.cookieCache.refreshCache` is enabled while `database` or `secondaryStorage` is configured. `refreshCache` is meant for stateless (DB-less) setups. Disabling `refreshCache` — remove it from your config to silence this warning."),!1):!1!==o&&void 0!==o&&(!0===o?{enabled:!0,updateAge:Math.floor(.2*n)}:{enabled:!0,updateAge:void 0!==o.updateAge?o.updateAge:Math.floor(.2*n)}))},secret:i,secretConfig:a,rateLimit:{...t.rateLimit,enabled:t.rateLimit?.enabled??tz.isProduction,window:t.rateLimit?.window||10,max:t.rateLimit?.max||100,storage:t.rateLimit?.storage||(t.secondaryStorage?"secondary-storage":"memory")},authCookies:T,logger:l,generateId:v,session:null,secondaryStorage:t.secondaryStorage,password:{hash:t.emailAndPassword?.password?.hash||f.hashPassword,verify:t.emailAndPassword?.password?.verify||f.verifyPassword,config:{minPasswordLength:t.emailAndPassword?.minPasswordLength||8,maxPasswordLength:t.emailAndPassword?.maxPasswordLength||128},checkPassword:g.checkPassword},setNewSession(e){this.newSession=e},newSession:null,adapter:e,internalAdapter:(0,m.createInternalAdapter)(e,{options:t,logger:l,hooks:t.databaseHooks?[{source:"user",hooks:t.databaseHooks}]:[],generateId:v}),createAuthCookie:(0,h.createCookieGetter)(t),async runMigrations(){throw new x.BetterAuthError("runMigrations will be set by the specific init implementation")},publishTelemetry:_,skipCSRFCheck:!!t.advanced?.disableCSRFCheck,skipOriginCheck:t.advanced?.disableOriginCheck!==void 0?t.advanced.disableOriginCheck:!!(0,tz.isTest)(),runInBackground:t.advanced?.backgroundTasks?.handler??(e=>{e.catch(()=>{})}),async runInBackgroundOrAwait(e){try{t.advanced?.backgroundTasks?.handler?e instanceof Promise&&t.advanced.backgroundTasks.handler(e.catch(e=>{l.error("Failed to run background task:",e)})):await e}catch(e){l.error("Failed to run background task:",e)}},getPlugin:e=>t.plugins.find(t=>t.id===e)??null,hasPlugin:e=>O.has(e)},D=(0,y.runPluginInit)(C);return(0,p.isPromise)(D)&&await D,C}var rF=e.i(439704);let rJ=async e=>{let t=await (0,c.getAdapter)(e),r=await rz(t,e,e=>(0,rF.getKyselyDatabaseType)(e)||"unknown");return r.runMigrations=async function(){if(!e.database||"updateMany"in e.database)throw new x.BetterAuthError("Database is not provided or it's an adapter. Migrations are only supported with a database instance.");let{runMigrations:t}=await (0,l.getMigrations)(e);await t()},r};e.s(["betterAuth",0,e=>((e,t)=>{let r=t(e),{api:i}=rS(r,e);return{handler:async t=>{let i,a=await r,o=a.options.basePath||"/api/auth";if((0,d.isDynamicBaseURLConfig)(e.baseURL))i=await (0,y.resolveRequestContext)(a,t,(0,y.resolveDynamicTrustedProxyHeaders)(a.options));else{if(i=a,!a.options.baseURL){let e=(0,d.getBaseURL)(void 0,o,t,void 0,a.options.advanced?.trustedProxyHeaders);if(e)a.baseURL=e,a.options.baseURL=(0,d.getOrigin)(a.baseURL)||void 0;else throw new x.BetterAuthError("Could not get base URL from request. Please provide a valid base URL.")}i.trustedOrigins=await (0,y.getTrustedOrigins)(a.options,t),i.trustedProviders=await (0,y.getTrustedProviders)(a.options,t)}let{handler:n}=((e,t)=>{let{api:r,middlewares:i}=rS(e,t),a=new URL(e.baseURL).pathname;return(0,rb.createRouter)(r,{routerContext:e,openapi:{disabled:!0},basePath:a,routerMiddleware:[{path:"/**",middleware:A.originCheckMiddleware},...i],allowedMediaTypes:["application/json"],skipTrailingSlashes:t.advanced?.skipTrailingSlashes??!1,async onRequest(t){let r=e.options.disabledPaths||[],i=(0,rE.normalizePathname)(t.url,a);if(r.includes(i))return new Response("Not Found",{status:404});let o=t;for(let t of e.options.plugins||[])if(t.onRequest){let r=await (0,rp.withSpan)(`onRequest ${t.id}`,{[rd.ATTR_HOOK_TYPE]:"onRequest",[rd.ATTR_CONTEXT]:`plugin:${t.id}`},()=>t.onRequest(o,e));if(r&&"response"in r)return r.response;r&&"request"in r&&(o=r.request)}let n=await (0,E.onRequestRateLimit)(o,e);return n||o},async onResponse(t,r){for(let i of(await (0,E.onResponseRateLimit)(r,e),e.options.plugins||[]))if(i.onResponse){let r=await (0,rp.withSpan)(`onResponse ${i.id}`,{[rd.ATTR_HOOK_TYPE]:"onResponse",[rd.ATTR_CONTEXT]:`plugin:${i.id}`,[ru.ATTR_HTTP_RESPONSE_STATUS_CODE]:t.status},()=>i.onResponse(t,e));if(r)return r.response}return t},onError(r){if((0,w.isAPIError)(r)&&"FOUND"===r.status)return;if(t.onAPIError?.throw)throw r;if(t.onAPIError?.onError)return void t.onAPIError.onError(r,e);let i=t.logger?.level,a="error"===i||"warn"===i||"debug"===i?eM.logger:void 0;if(t.logger?.disabled!==!0){if(r&&"object"==typeof r&&"message"in r&&"string"==typeof r.message&&(r.message.includes("no column")||r.message.includes("column")||r.message.includes("relation")||r.message.includes("table")||r.message.includes("does not exist")))return void e.logger?.error(r.message);(0,w.isAPIError)(r)?("INTERNAL_SERVER_ERROR"===r.status&&e.logger.error(r.status,r),a?.error(r.message)):e.logger?.error(r&&"object"==typeof r&&"name"in r?r.name:"",r)}}})})(i,e);return(0,t9.runWithAdapter)(i.adapter,()=>n(t))},api:i,options:e,$context:r,$ERROR_CODES:{...e.plugins?.reduce((e,t)=>t.$ERROR_CODES?{...e,...t.$ERROR_CODES}:e,{}),...v.BASE_ERROR_CODES}}})(e,rJ)],928976)},342573,e=>{"use strict";var t=e.i(928976),r=e.i(108761),i=e.i(760160),a=e.i(185599);let o=(0,e.i(332807).defineErrorCodes)({OTP_EXPIRED:"OTP expired",INVALID_OTP:"Invalid OTP",TOO_MANY_ATTEMPTS:"Too many attempts"});var n=e.i(280917);let s=async e=>{let t=e.context.returned;return t?t instanceof Response?200!==t.status?null:await t.clone().json():(0,n.isAPIError)(t)?null:t:null};var c=e.i(575779),l=e.i(618989);function d(e,t){return`${e}-otp-${t}`}let u=async e=>{let t=await (0,l.createHash)("SHA-256").digest(new TextEncoder().encode(e));return c.base64Url.encode(new Uint8Array(t),{padding:!1})};function p(e){let t=e.lastIndexOf(":");return -1===t?[e,""]:[e.slice(0,t),e.slice(t+1)]}var f=e.i(463617),h=e.i(277512);async function m(e,t,r){return"encrypted"===t.storeOTP?await (0,h.symmetricEncrypt)({key:e.context.secretConfig,data:r}):"hashed"===t.storeOTP?await u(r):"object"==typeof t.storeOTP&&"hash"in t.storeOTP?await t.storeOTP.hash(r):"object"==typeof t.storeOTP&&"encrypt"in t.storeOTP?await t.storeOTP.encrypt(r):r}async function y(e,t,r,i){return"encrypted"===t.storeOTP?(0,f.constantTimeEqual)(await (0,h.symmetricDecrypt)({key:e.context.secretConfig,data:r}),i):"hashed"===t.storeOTP?(0,f.constantTimeEqual)(await u(i),r):"object"==typeof t.storeOTP&&"hash"in t.storeOTP?(0,f.constantTimeEqual)(await t.storeOTP.hash(i),r):"object"==typeof t.storeOTP&&"decrypt"in t.storeOTP?(0,f.constantTimeEqual)(await t.storeOTP.decrypt(r),i):(0,f.constantTimeEqual)(i,r)}async function g(e,t,r){return"plain"===t.storeOTP||void 0===t.storeOTP?r:"encrypted"===t.storeOTP?await (0,h.symmetricDecrypt)({key:e.context.secretConfig,data:r}):"object"==typeof t.storeOTP&&"decrypt"in t.storeOTP?await t.storeOTP.decrypt(r):null}async function w(e,t,i){let a=await e.context.internalAdapter.findVerificationValue(i);if(!a||a.expiresAt<new Date)return null;let[o,n]=p(a.value),s=t.allowedAttempts||3;if(n&&parseInt(n)>=s)return null;let c=await g(e,t,o);return c?(await e.context.internalAdapter.updateVerificationByIdentifier(i,{expiresAt:(0,r.getDate)(t.expiresIn,"sec")}),c):null}var A=e.i(33573),E=e.i(22523),b=e.i(610914),S=e.i(290410),k=e.i(63162),T=e.i(702149),R=e.i(440277),I=e.i(807405);let x=["email-verification","sign-in","forget-password","change-email"];async function v(e,t,i,a){let o=d(a,i);if("reuse"===t.resendStrategy){let r=await w(e,t,o);if(r)return r}let n=t.generateOTP({email:i,type:a},e)||H(t),s=await m(e,t,n);return await e.context.internalAdapter.createVerificationValue({value:`${s}:0`,identifier:o,expiresAt:(0,r.getDate)(t.expiresIn,"sec")}).catch(async()=>{await e.context.internalAdapter.deleteVerificationByIdentifier(o),await e.context.internalAdapter.createVerificationValue({value:`${s}:0`,identifier:o,expiresAt:(0,r.getDate)(t.expiresIn,"sec")})}),n}let _=I.object({email:I.string({}).meta({description:"Email address to send the OTP"}),type:I.enum(x).meta({description:"Type of the OTP"})}),O=I.object({email:I.string({}).meta({description:"Email address to send the OTP"}),type:I.enum(x).meta({required:!0,description:"Type of the OTP"})}),U=I.object({email:I.string({}).meta({description:"Email address the OTP was sent to"}),type:I.enum(x).meta({required:!0,description:"Type of the OTP"})}),P=I.object({email:I.string().meta({description:"Email address the OTP was sent to"}),type:I.enum(x).meta({required:!0,description:"Type of the OTP"}),otp:I.string().meta({required:!0,description:"OTP to verify"})}),C=I.object({email:I.string({}).meta({description:"Email address to verify"}),otp:I.string().meta({required:!0,description:"OTP to verify"})}),D=I.object({email:I.string({}).meta({description:"Email address to sign in"}),otp:I.string().meta({required:!0,description:"OTP sent to the email"}),name:I.string().meta({description:'User display name. Only used if the user is registering for the first time. Eg: "my-name"'}).optional(),image:I.string().meta({description:"User profile image URL. Only used if the user is registering for the first time."}).optional()}).and(I.record(I.string(),I.any())),L=I.object({email:I.string().meta({description:"Email address to send the OTP"})}),N=I.object({email:I.string().meta({description:"Email address to send the OTP"})}),B=I.object({email:I.string().meta({description:"Email address to reset the password"}),otp:I.string().meta({description:"OTP sent to the email"}),password:I.string().meta({description:"New password"})}),j=I.object({newEmail:I.string().meta({description:"New email address to send the OTP"}),otp:I.string().optional().meta({description:"OTP sent to the current email. This is required if changeEmail.verifyCurrentEmail option is set to true"})}),$=I.object({newEmail:I.string().meta({description:"New email address to verify and change to"}),otp:I.string().meta({description:"OTP sent to the new email"})}),H=e=>(0,i.generateRandomString)(e.otpLength??6,"0-9");async function V(e,t,r,i){let a=await e.context.internalAdapter.findVerificationValue(r);if(!a)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);if(a.expiresAt<new Date)throw await e.context.internalAdapter.deleteVerificationByIdentifier(r),S.APIError.from("BAD_REQUEST",o.OTP_EXPIRED);let[n,s]=p(a.value),c=t?.allowedAttempts||3;if(s&&parseInt(s)>=c)throw await e.context.internalAdapter.deleteVerificationByIdentifier(r),S.APIError.from("FORBIDDEN",o.TOO_MANY_ATTEMPTS);if(await e.context.internalAdapter.deleteVerificationByIdentifier(r),!await y(e,t,n,i))throw await e.context.internalAdapter.createVerificationValue({value:`${n}:${parseInt(s||"0")+1}`,identifier:r,expiresAt:a.expiresAt}),S.APIError.from("BAD_REQUEST",o.INVALID_OTP)}let q=e=>(0,i.generateRandomString)(e.otpLength??6,"0-9");e.i(700598);var M=e.i(726527),W=e.i(704024);let K={"sign-in":"Your Alook sign-in code","email-verification":"Verify your Alook email","forget-password":"Reset your Alook password","change-email":"Confirm your new email address"},z={"sign-in":"Sign in to Alook","email-verification":"Verify your email","forget-password":"Reset your password","change-email":"Confirm email change"},F={"sign-in":"Enter this code to sign in to your account.","email-verification":"Enter this code to verify your email address.","forget-password":"Enter this code to reset your password.","change-email":"Enter this code to confirm your new email address."},J=(0,M.createLogger)({service:"auth"});function G(e,t){if(!e)return t;let r=Number.parseInt(e,10);return Number.isFinite(r)&&r>0?r:t}e.s(["createAuth",0,function(e){var i;let n,c,l,u=(e.NODE_ENV??"production")!=="development",f=G(e.AUTH_OTP_RATE_LIMIT_MAX,5),g=G(e.AUTH_OTP_RATE_LIMIT_WINDOW_SEC,60),w=Math.max(60,g);return(0,t.betterAuth)({baseURL:e.BETTER_AUTH_URL,database:e.DB,secret:e.BETTER_AUTH_SECRET,session:{expiresIn:2592e3,updateAge:86400,cookieCache:{enabled:!0,maxAge:300}},emailAndPassword:{enabled:!u,requireEmailVerification:!1},socialProviders:{github:{clientId:e.GITHUB_CLIENT_ID,clientSecret:e.GITHUB_CLIENT_SECRET},google:{clientId:e.GOOGLE_CLIENT_ID,clientSecret:e.GOOGLE_CLIENT_SECRET}},rateLimit:{enabled:u,customRules:{"/email-otp/send-verification-otp":{window:g,max:f}},customStorage:{get:async t=>{let r=await e.RATE_LIMIT_KV.get(t);return r?JSON.parse(r):void 0},set:async(t,r)=>{await e.RATE_LIMIT_KV.put(t,JSON.stringify(r),{expirationTtl:w})}}},plugins:u?[(n={expiresIn:300,generateOTP:()=>q(i),storeOTP:"plain",...i={async sendVerificationOTP({email:t,otp:r,type:i}){J.info("sending OTP email",{to:t,type:i});try{let a,o,n,s=JSON.stringify({to:t,subject:K[i],html:(o=z[i],n=F[i],`<!DOCTYPE html>
|
|
399
399
|
<html lang="en">
|
|
400
400
|
<head>
|
|
401
401
|
<meta charset="utf-8">
|
|
@@ -419,6 +419,6 @@ To resolve this, you can:
|
|
|
419
419
|
</td></tr>
|
|
420
420
|
</table>
|
|
421
421
|
</body>
|
|
422
|
-
</html>`)}),c={method:"POST",headers:{"Content-Type":"application/json"},body:s};try{a=await e.EMAIL_WORKER.fetch("http://internal/send/otp",c)}catch{a=await fetch(`${W.DEV_EMAIL_WORKER_URL}/send/otp`,c)}if(!a.ok){let e=await a.text();throw Error(`EMAIL_WORKER /send/otp failed: ${a.status} ${e}`)}J.info("OTP email sent",{to:t,type:i})}catch(e){throw J.error("OTP email failed",{to:t,type:i,err:e}),e}}}},c=(0,T.createAuthEndpoint)("/email-otp/send-verification-otp",{method:"POST",body:_,metadata:{openapi:{operationId:"sendEmailVerificationOTP",description:"Send a verification OTP to an email",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{if(!n?.sendVerificationOTP)throw e.context.logger.error("send email verification is not implemented"),S.APIError.fromStatus("BAD_REQUEST",{message:"send email verification is not implemented"});let t=e.body.email.toLowerCase();if(!I.email().safeParse(t).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);if("change-email"===e.body.type)throw e.context.logger.error("Use the /email-otp/request-email-change endpoint to send OTP for changing email"),S.APIError.fromStatus("BAD_REQUEST",{message:"Invalid OTP type"});let r=d(e.body.type,t),i=await v(e,n,t,e.body.type),a="sign-in"===e.body.type&&!n.disableSignUp;return await e.context.internalAdapter.findUserByEmail(t)||a?await e.context.runInBackgroundOrAwait(n.sendVerificationOTP({email:t,otp:i,type:e.body.type},e)):await e.context.internalAdapter.deleteVerificationByIdentifier(r),e.json({success:!0})}),{id:"email-otp",version:a.PACKAGE_VERSION,init(e){if(n.overrideDefaultEmailVerification)return{options:{emailVerification:{async sendVerificationEmail(t,r){await e.runInBackgroundOrAwait(c({context:e,request:r,body:{email:t.user.email,type:"email-verification"},ctx:e}))}}}}},endpoints:{sendVerificationOTP:c,createVerificationOTP:(0,T.createAuthEndpoint)({method:"POST",body:O,metadata:{openapi:{operationId:"createEmailVerificationOTP",description:"Create a verification OTP for an email",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"string"}}}}}}}},async e=>{let t=e.body.email.toLowerCase(),i=n.generateOTP({email:t,type:e.body.type},e)||H(n),a=await m(e,n,i);return await e.context.internalAdapter.createVerificationValue({value:`${a}:0`,identifier:d(e.body.type,t),expiresAt:(0,r.getDate)(n.expiresIn,"sec")}),i}),getVerificationOTP:(0,T.createAuthEndpoint)({method:"GET",query:U,metadata:{openapi:{operationId:"getEmailVerificationOTP",description:"Get a verification OTP for an email",responses:{200:{description:"OTP retrieved successfully or not found/expired",content:{"application/json":{schema:{type:"object",properties:{otp:{type:"string",nullable:!0,description:"The stored OTP, or null if not found or expired"}},required:["otp"]}}}}}}}},async e=>{let t=e.query.email.toLowerCase(),r=await e.context.internalAdapter.findVerificationValue(d(e.query.type,t));if(!r||r.expiresAt<new Date)return e.json({otp:null});if("hashed"===n.storeOTP||"object"==typeof n.storeOTP&&"hash"in n.storeOTP)throw S.APIError.fromStatus("BAD_REQUEST",{message:"OTP is hashed, cannot return the plain text OTP"});let[i,a]=p(r.value),o=i;return"encrypted"===n.storeOTP&&(o=await (0,h.symmetricDecrypt)({key:e.context.secretConfig,data:i})),"object"==typeof n.storeOTP&&"decrypt"in n.storeOTP&&(o=await n.storeOTP.decrypt(i)),e.json({otp:o})}),checkVerificationOTP:(0,T.createAuthEndpoint)("/email-otp/check-verification-otp",{method:"POST",body:P,metadata:{openapi:{operationId:"verifyEmailWithOTP",description:"Verify an email with an OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{let t=e.body.email.toLowerCase();if(!I.email().safeParse(t).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);if(!await e.context.internalAdapter.findUserByEmail(t))throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.USER_NOT_FOUND);let r=d(e.body.type,t),i=await e.context.internalAdapter.findVerificationValue(r);if(!i)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);if(i.expiresAt<new Date)throw await e.context.internalAdapter.deleteVerificationByIdentifier(r),S.APIError.from("BAD_REQUEST",o.OTP_EXPIRED);let[a,s]=p(i.value),c=n?.allowedAttempts||3;if(s&&parseInt(s)>=c)throw await e.context.internalAdapter.deleteVerificationByIdentifier(r),S.APIError.from("FORBIDDEN",o.TOO_MANY_ATTEMPTS);if(!await y(e,n,a,e.body.otp))throw await e.context.internalAdapter.updateVerificationByIdentifier(r,{value:`${a}:${parseInt(s||"0")+1}`}),S.APIError.from("BAD_REQUEST",o.INVALID_OTP);return e.json({success:!0})}),verifyEmailOTP:(0,T.createAuthEndpoint)("/email-otp/verify-email",{method:"POST",body:C,metadata:{openapi:{description:"Verify email with OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean",description:"Indicates if the verification was successful",enum:[!0]},token:{type:"string",nullable:!0,description:"Session token if autoSignInAfterVerification is enabled, otherwise null"},user:{$ref:"#/components/schemas/User"}},required:["status","token","user"]}}}}}}}},async e=>{let t=e.body.email.toLowerCase();if(!I.email().safeParse(t).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);await V(e,n,d("email-verification",t),e.body.otp);let r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.USER_NOT_FOUND);e.context.options.emailVerification?.beforeEmailVerification&&await e.context.options.emailVerification.beforeEmailVerification(r.user,e.request);let i=await e.context.internalAdapter.updateUser(r.user.id,{email:t,emailVerified:!0});if(await e.context.options.emailVerification?.afterEmailVerification?.(i,e.request),e.context.options.emailVerification?.autoSignInAfterVerification){let t=await e.context.internalAdapter.createSession(i.id);return await (0,E.setSessionCookie)(e,{session:t,user:i}),e.json({status:!0,token:t.token,user:(0,A.parseUserOutput)(e.context.options,i)})}let a=await (0,b.getSessionFromCtx)(e);if(a&&i.emailVerified){let t=await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret);await (0,E.setCookieCache)(e,{session:a.session,user:{...a.user,emailVerified:!0}},!!t)}return e.json({status:!0,token:null,user:(0,A.parseUserOutput)(e.context.options,i)})}),signInEmailOTP:(0,T.createAuthEndpoint)("/sign-in/email-otp",{method:"POST",body:D,metadata:{openapi:{operationId:"signInWithEmailOTP",description:"Sign in with email and OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{token:{type:"string",description:"Session token for the authenticated session"},user:{$ref:"#/components/schemas/User"}},required:["token","user"]}}}}}}}},async e=>{let{email:t,otp:r,name:i,image:a,...s}=e.body,c=t.toLowerCase();await V(e,n,d("sign-in",c),r);let l=await e.context.internalAdapter.findUserByEmail(c);if(!l){if(n.disableSignUp)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);let t=(0,A.parseUserInput)(e.context.options,s,"create"),r=await e.context.internalAdapter.createUser({...t,email:c,emailVerified:!0,name:i||"",image:a}),l=await e.context.internalAdapter.createSession(r.id);return await (0,E.setSessionCookie)(e,{session:l,user:r}),e.json({token:l.token,user:(0,A.parseUserOutput)(e.context.options,r)})}l.user.emailVerified||await e.context.internalAdapter.updateUser(l.user.id,{emailVerified:!0});let u=await e.context.internalAdapter.createSession(l.user.id);return await (0,E.setSessionCookie)(e,{session:u,user:l.user}),e.json({token:u.token,user:(0,A.parseUserOutput)(e.context.options,l.user)})}),requestPasswordResetEmailOTP:(0,T.createAuthEndpoint)("/email-otp/request-password-reset",{method:"POST",body:L,metadata:{openapi:{operationId:"requestPasswordResetWithEmailOTP",description:"Request password reset with email and OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",description:"Indicates if the OTP was sent successfully"}}}}}}}}}},async e=>{let t=e.body.email.toLowerCase(),r=d("forget-password",t),i=await v(e,n,t,"forget-password");return await e.context.internalAdapter.findUserByEmail(t)?await e.context.runInBackgroundOrAwait(n.sendVerificationOTP({email:t,otp:i,type:"forget-password"},e)):await e.context.internalAdapter.deleteVerificationByIdentifier(r),e.json({success:!0})}),forgetPasswordEmailOTP:(l=(0,R.deprecate)(()=>{},'The "/forget-password/email-otp" endpoint is deprecated. Please use "/email-otp/request-password-reset" instead. This endpoint will be removed in the next major version.'),(0,T.createAuthEndpoint)("/forget-password/email-otp",{method:"POST",body:N,metadata:{openapi:{operationId:"forgetPasswordWithEmailOTP",description:"Deprecated: Use /email-otp/request-password-reset instead.",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",description:"Indicates if the OTP was sent successfully"}}}}}}}}}},async e=>{l();let t=e.body.email.toLowerCase(),r=d("forget-password",t),i=await v(e,n,t,"forget-password");return await e.context.internalAdapter.findUserByEmail(t)?await e.context.runInBackgroundOrAwait(n.sendVerificationOTP({email:t,otp:i,type:"forget-password"},e)):await e.context.internalAdapter.deleteVerificationByIdentifier(r),e.json({success:!0})})),resetPasswordEmailOTP:(0,T.createAuthEndpoint)("/email-otp/reset-password",{method:"POST",body:B,metadata:{openapi:{operationId:"resetPasswordWithEmailOTP",description:"Reset password with email and OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{let t=e.body.email.toLowerCase();await V(e,n,d("forget-password",t),e.body.otp);let r=await e.context.internalAdapter.findUserByEmail(t,{includeAccounts:!0});if(!r)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.USER_NOT_FOUND);let i=e.context.password.config.minPasswordLength;if(e.body.password.length<i)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.PASSWORD_TOO_SHORT);let a=e.context.password.config.maxPasswordLength;if(e.body.password.length>a)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.PASSWORD_TOO_LONG);let o=await e.context.password.hash(e.body.password);return r.accounts?.find(e=>"credential"===e.providerId)?await e.context.internalAdapter.updatePassword(r.user.id,o):await e.context.internalAdapter.createAccount({userId:r.user.id,providerId:"credential",accountId:r.user.id,password:o}),e.context.options.emailAndPassword?.onPasswordReset&&await e.context.options.emailAndPassword.onPasswordReset({user:r.user},e.request),r.user.emailVerified||await e.context.internalAdapter.updateUser(r.user.id,{emailVerified:!0}),e.context.options.emailAndPassword?.revokeSessionsOnPasswordReset&&await e.context.internalAdapter.deleteSessions(r.user.id),e.json({success:!0})}),requestEmailChangeEmailOTP:(0,T.createAuthEndpoint)("/email-otp/request-email-change",{method:"POST",body:j,use:[b.sensitiveSessionMiddleware],metadata:{openapi:{operationId:"requestEmailChangeWithEmailOTP",description:"Request email change with verification OTP sent to the new email",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{if(!n.changeEmail?.enabled)throw e.context.logger.error("Change email with OTP is disabled."),S.APIError.fromStatus("BAD_REQUEST",{message:"Change email with OTP is disabled"});let t=e.context.session.user.email.toLowerCase(),i=e.body.newEmail.toLowerCase();if(!I.email().safeParse(i).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);if(i===t)throw e.context.logger.error("Email is the same"),S.APIError.fromStatus("BAD_REQUEST",{message:"Email is the same"});if(n.changeEmail?.verifyCurrentEmail){if(!e.body.otp)throw S.APIError.fromStatus("BAD_REQUEST",{message:"OTP is required to verify current email"});let r=await e.context.internalAdapter.findVerificationValue(d("email-verification",t));if(!r)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);let i=d("email-verification",t);if(r.expiresAt<new Date)throw await e.context.internalAdapter.deleteVerificationByIdentifier(i),S.APIError.from("BAD_REQUEST",o.OTP_EXPIRED);let[a,s]=p(r.value),c=n?.allowedAttempts||3;if(s&&parseInt(s)>=c)throw await e.context.internalAdapter.deleteVerificationByIdentifier(i),S.APIError.from("FORBIDDEN",o.TOO_MANY_ATTEMPTS);if(!await y(e,n,a,e.body.otp))throw await e.context.internalAdapter.updateVerificationByIdentifier(i,{value:`${a}:${parseInt(s||"0")+1}`}),S.APIError.from("BAD_REQUEST",o.INVALID_OTP);await e.context.internalAdapter.deleteVerificationByIdentifier(i)}else e.body.otp&&e.context.logger.warn("OTP provided but not required for verifying current email. If you want to require OTP verification for current email, please set the changeEmail.verifyCurrentEmail option to true in the configuration");let a=n.generateOTP({email:i,type:"change-email"},e)||H(n),s=await m(e,n,a);return(await e.context.internalAdapter.createVerificationValue({value:`${s}:0`,identifier:d("change-email",`${t}-${i}`),expiresAt:(0,r.getDate)(n.expiresIn,"sec")}),await e.context.internalAdapter.findUserByEmail(i))?await e.context.internalAdapter.deleteVerificationByIdentifier(d("change-email",`${t}-${i}`)):await e.context.runInBackgroundOrAwait(n.sendVerificationOTP({email:i,otp:a,type:"change-email"},e)),e.json({success:!0})}),changeEmailEmailOTP:(0,T.createAuthEndpoint)("/email-otp/change-email",{method:"POST",body:$,use:[b.sensitiveSessionMiddleware],metadata:{openapi:{operationId:"changeEmailWithEmailOTP",description:"Verify new email with OTP and change the email if verification is successful",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{if(!n.changeEmail?.enabled)throw e.context.logger.error("Change email with OTP is disabled."),S.APIError.fromStatus("BAD_REQUEST",{message:"Change email with OTP is disabled"});let t=e.context.session,r=t.user.email.toLowerCase(),i=e.body.newEmail.toLowerCase();if(!I.email().safeParse(i).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);if(i===r)throw e.context.logger.error("Email is the same"),S.APIError.fromStatus("BAD_REQUEST",{message:"Email is the same"});let a=await e.context.internalAdapter.findVerificationValue(d("change-email",`${r}-${i}`));if(!a)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);let s=d("change-email",`${r}-${i}`);if(a.expiresAt<new Date)throw await e.context.internalAdapter.deleteVerificationByIdentifier(s),S.APIError.from("BAD_REQUEST",o.OTP_EXPIRED);let[c,l]=p(a.value),u=n?.allowedAttempts||3;if(l&&parseInt(l)>=u)throw await e.context.internalAdapter.deleteVerificationByIdentifier(s),S.APIError.from("FORBIDDEN",o.TOO_MANY_ATTEMPTS);if(!await y(e,n,c,e.body.otp))throw await e.context.internalAdapter.updateVerificationByIdentifier(s,{value:`${c}:${parseInt(l||"0")+1}`}),S.APIError.from("BAD_REQUEST",o.INVALID_OTP);await e.context.internalAdapter.deleteVerificationByIdentifier(s);let f=await e.context.internalAdapter.findUserByEmail(r);if(!f)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.USER_NOT_FOUND);if(await e.context.internalAdapter.findUserByEmail(i))throw S.APIError.fromStatus("BAD_REQUEST",{message:"Email already in use"});e.context.options.emailVerification?.beforeEmailVerification&&await e.context.options.emailVerification.beforeEmailVerification(f.user,e.request);let h=await e.context.internalAdapter.updateUser(f.user.id,{email:i,emailVerified:!0});return e.context.options.emailVerification?.afterEmailVerification&&await e.context.options.emailVerification.afterEmailVerification(h,e.request),await (0,E.setSessionCookie)(e,{session:t.session,user:{...t.user,email:i,emailVerified:!0}}),e.json({success:!0})})},hooks:{after:[{matcher:e=>!!(e.path?.startsWith("/sign-up")&&n.sendVerificationOnSignUp&&!n.overrideDefaultEmailVerification),handler:(0,T.createAuthMiddleware)(async e=>{let t=(await s(e))?.user.email;if(t){let a=n.generateOTP({email:t,type:e.body.type},e)||q(n),o=await m(e,n,a);await e.context.internalAdapter.createVerificationValue({value:`${o}:0`,identifier:d("email-verification",t),expiresAt:(0,r.getDate)(n.expiresIn,"sec")}),await e.context.runInBackgroundOrAwait(i.sendVerificationOTP({email:t,otp:a,type:"email-verification"},e))}})}]},rateLimit:[{pathMatcher:e=>"/email-otp/send-verification-otp"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/check-verification-otp"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/verify-email"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/sign-in/email-otp"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/request-password-reset"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/reset-password"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/forget-password/email-otp"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/request-email-change"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/change-email"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3}],options:i,$ERROR_CODES:o})]})}],342573)}];
|
|
422
|
+
</html>`)}),c={method:"POST",headers:{"Content-Type":"application/json"},body:s};try{a=await e.EMAIL_WORKER.fetch("http://internal/send/otp",c)}catch{a=await fetch(`${W.DEV_EMAIL_WORKER_URL}/send/otp`,c)}if(!a.ok){let e=await a.text();throw Error(`EMAIL_WORKER /send/otp failed: ${a.status} ${e}`)}J.info("OTP email sent",{to:t,type:i})}catch(e){throw J.error("OTP email failed",{to:t,type:i,err:e}),e}}}},c=(0,T.createAuthEndpoint)("/email-otp/send-verification-otp",{method:"POST",body:_,metadata:{openapi:{operationId:"sendEmailVerificationOTP",description:"Send a verification OTP to an email",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{if(!n?.sendVerificationOTP)throw e.context.logger.error("send email verification is not implemented"),S.APIError.fromStatus("BAD_REQUEST",{message:"send email verification is not implemented"});let t=e.body.email.toLowerCase();if(!I.email().safeParse(t).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);if("change-email"===e.body.type)throw e.context.logger.error("Use the /email-otp/request-email-change endpoint to send OTP for changing email"),S.APIError.fromStatus("BAD_REQUEST",{message:"Invalid OTP type"});let r=d(e.body.type,t),i=await v(e,n,t,e.body.type),a="sign-in"===e.body.type&&!n.disableSignUp;return await e.context.internalAdapter.findUserByEmail(t)||a?await e.context.runInBackgroundOrAwait(n.sendVerificationOTP({email:t,otp:i,type:e.body.type},e)):await e.context.internalAdapter.deleteVerificationByIdentifier(r),e.json({success:!0})}),{id:"email-otp",version:a.PACKAGE_VERSION,init(e){if(n.overrideDefaultEmailVerification)return{options:{emailVerification:{async sendVerificationEmail(t,r){await e.runInBackgroundOrAwait(c({context:e,request:r,body:{email:t.user.email,type:"email-verification"},ctx:e}))}}}}},endpoints:{sendVerificationOTP:c,createVerificationOTP:(0,T.createAuthEndpoint)({method:"POST",body:O,metadata:{openapi:{operationId:"createEmailVerificationOTP",description:"Create a verification OTP for an email",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"string"}}}}}}}},async e=>{let t=e.body.email.toLowerCase(),i=n.generateOTP({email:t,type:e.body.type},e)||H(n),a=await m(e,n,i);return await e.context.internalAdapter.createVerificationValue({value:`${a}:0`,identifier:d(e.body.type,t),expiresAt:(0,r.getDate)(n.expiresIn,"sec")}),i}),getVerificationOTP:(0,T.createAuthEndpoint)({method:"GET",query:U,metadata:{openapi:{operationId:"getEmailVerificationOTP",description:"Get a verification OTP for an email",responses:{200:{description:"OTP retrieved successfully or not found/expired",content:{"application/json":{schema:{type:"object",properties:{otp:{type:"string",nullable:!0,description:"The stored OTP, or null if not found or expired"}},required:["otp"]}}}}}}}},async e=>{let t=e.query.email.toLowerCase(),r=await e.context.internalAdapter.findVerificationValue(d(e.query.type,t));if(!r||r.expiresAt<new Date)return e.json({otp:null});if("hashed"===n.storeOTP||"object"==typeof n.storeOTP&&"hash"in n.storeOTP)throw S.APIError.fromStatus("BAD_REQUEST",{message:"OTP is hashed, cannot return the plain text OTP"});let[i,a]=p(r.value),o=i;return"encrypted"===n.storeOTP&&(o=await (0,h.symmetricDecrypt)({key:e.context.secretConfig,data:i})),"object"==typeof n.storeOTP&&"decrypt"in n.storeOTP&&(o=await n.storeOTP.decrypt(i)),e.json({otp:o})}),checkVerificationOTP:(0,T.createAuthEndpoint)("/email-otp/check-verification-otp",{method:"POST",body:P,metadata:{openapi:{operationId:"verifyEmailWithOTP",description:"Verify an email with an OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{let t=e.body.email.toLowerCase();if(!I.email().safeParse(t).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);if(!await e.context.internalAdapter.findUserByEmail(t))throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.USER_NOT_FOUND);let r=d(e.body.type,t),i=await e.context.internalAdapter.findVerificationValue(r);if(!i)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);if(i.expiresAt<new Date)throw await e.context.internalAdapter.deleteVerificationByIdentifier(r),S.APIError.from("BAD_REQUEST",o.OTP_EXPIRED);let[a,s]=p(i.value),c=n?.allowedAttempts||3;if(s&&parseInt(s)>=c)throw await e.context.internalAdapter.deleteVerificationByIdentifier(r),S.APIError.from("FORBIDDEN",o.TOO_MANY_ATTEMPTS);if(!await y(e,n,a,e.body.otp))throw await e.context.internalAdapter.updateVerificationByIdentifier(r,{value:`${a}:${parseInt(s||"0")+1}`}),S.APIError.from("BAD_REQUEST",o.INVALID_OTP);return e.json({success:!0})}),verifyEmailOTP:(0,T.createAuthEndpoint)("/email-otp/verify-email",{method:"POST",body:C,metadata:{openapi:{description:"Verify email with OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean",description:"Indicates if the verification was successful",enum:[!0]},token:{type:"string",nullable:!0,description:"Session token if autoSignInAfterVerification is enabled, otherwise null"},user:{$ref:"#/components/schemas/User"}},required:["status","token","user"]}}}}}}}},async e=>{let t=e.body.email.toLowerCase();if(!I.email().safeParse(t).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);await V(e,n,d("email-verification",t),e.body.otp);let r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.USER_NOT_FOUND);e.context.options.emailVerification?.beforeEmailVerification&&await e.context.options.emailVerification.beforeEmailVerification(r.user,e.request);let i=await e.context.internalAdapter.updateUser(r.user.id,{email:t,emailVerified:!0});if(await e.context.options.emailVerification?.afterEmailVerification?.(i,e.request),e.context.options.emailVerification?.autoSignInAfterVerification){let t=await e.context.internalAdapter.createSession(i.id);return await (0,E.setSessionCookie)(e,{session:t,user:i}),e.json({status:!0,token:t.token,user:(0,A.parseUserOutput)(e.context.options,i)})}let a=await (0,b.getSessionFromCtx)(e);if(a&&i.emailVerified){let t=await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret);await (0,E.setCookieCache)(e,{session:a.session,user:{...a.user,emailVerified:!0}},!!t)}return e.json({status:!0,token:null,user:(0,A.parseUserOutput)(e.context.options,i)})}),signInEmailOTP:(0,T.createAuthEndpoint)("/sign-in/email-otp",{method:"POST",body:D,metadata:{openapi:{operationId:"signInWithEmailOTP",description:"Sign in with email and OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{token:{type:"string",description:"Session token for the authenticated session"},user:{$ref:"#/components/schemas/User"}},required:["token","user"]}}}}}}}},async e=>{let{email:t,otp:r,name:i,image:a,...s}=e.body,c=t.toLowerCase();await V(e,n,d("sign-in",c),r);let l=await e.context.internalAdapter.findUserByEmail(c);if(!l){if(n.disableSignUp)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);let t=(0,A.parseUserInput)(e.context.options,s,"create"),r=await e.context.internalAdapter.createUser({...t,email:c,emailVerified:!0,name:i||"",image:a}),l=await e.context.internalAdapter.createSession(r.id);return await (0,E.setSessionCookie)(e,{session:l,user:r}),e.json({token:l.token,user:(0,A.parseUserOutput)(e.context.options,r)})}l.user.emailVerified||await e.context.internalAdapter.updateUser(l.user.id,{emailVerified:!0});let u=await e.context.internalAdapter.createSession(l.user.id);return await (0,E.setSessionCookie)(e,{session:u,user:l.user}),e.json({token:u.token,user:(0,A.parseUserOutput)(e.context.options,l.user)})}),requestPasswordResetEmailOTP:(0,T.createAuthEndpoint)("/email-otp/request-password-reset",{method:"POST",body:L,metadata:{openapi:{operationId:"requestPasswordResetWithEmailOTP",description:"Request password reset with email and OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",description:"Indicates if the OTP was sent successfully"}}}}}}}}}},async e=>{let t=e.body.email.toLowerCase(),r=d("forget-password",t),i=await v(e,n,t,"forget-password");return await e.context.internalAdapter.findUserByEmail(t)?await e.context.runInBackgroundOrAwait(n.sendVerificationOTP({email:t,otp:i,type:"forget-password"},e)):await e.context.internalAdapter.deleteVerificationByIdentifier(r),e.json({success:!0})}),forgetPasswordEmailOTP:(l=(0,R.deprecate)(()=>{},'The "/forget-password/email-otp" endpoint is deprecated. Please use "/email-otp/request-password-reset" instead. This endpoint will be removed in the next major version.'),(0,T.createAuthEndpoint)("/forget-password/email-otp",{method:"POST",body:N,metadata:{openapi:{operationId:"forgetPasswordWithEmailOTP",description:"Deprecated: Use /email-otp/request-password-reset instead.",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",description:"Indicates if the OTP was sent successfully"}}}}}}}}}},async e=>{l();let t=e.body.email.toLowerCase(),r=d("forget-password",t),i=await v(e,n,t,"forget-password");return await e.context.internalAdapter.findUserByEmail(t)?await e.context.runInBackgroundOrAwait(n.sendVerificationOTP({email:t,otp:i,type:"forget-password"},e)):await e.context.internalAdapter.deleteVerificationByIdentifier(r),e.json({success:!0})})),resetPasswordEmailOTP:(0,T.createAuthEndpoint)("/email-otp/reset-password",{method:"POST",body:B,metadata:{openapi:{operationId:"resetPasswordWithEmailOTP",description:"Reset password with email and OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{let t=e.body.email.toLowerCase();await V(e,n,d("forget-password",t),e.body.otp);let r=await e.context.internalAdapter.findUserByEmail(t,{includeAccounts:!0});if(!r)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.USER_NOT_FOUND);let i=e.context.password.config.minPasswordLength;if(e.body.password.length<i)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.PASSWORD_TOO_SHORT);let a=e.context.password.config.maxPasswordLength;if(e.body.password.length>a)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.PASSWORD_TOO_LONG);let o=await e.context.password.hash(e.body.password);return r.accounts?.find(e=>"credential"===e.providerId)?await e.context.internalAdapter.updatePassword(r.user.id,o):await e.context.internalAdapter.createAccount({userId:r.user.id,providerId:"credential",accountId:r.user.id,password:o}),e.context.options.emailAndPassword?.onPasswordReset&&await e.context.options.emailAndPassword.onPasswordReset({user:r.user},e.request),r.user.emailVerified||await e.context.internalAdapter.updateUser(r.user.id,{emailVerified:!0}),e.context.options.emailAndPassword?.revokeSessionsOnPasswordReset&&await e.context.internalAdapter.deleteSessions(r.user.id),e.json({success:!0})}),requestEmailChangeEmailOTP:(0,T.createAuthEndpoint)("/email-otp/request-email-change",{method:"POST",body:j,use:[b.sensitiveSessionMiddleware],metadata:{openapi:{operationId:"requestEmailChangeWithEmailOTP",description:"Request email change with verification OTP sent to the new email",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{if(!n.changeEmail?.enabled)throw e.context.logger.error("Change email with OTP is disabled."),S.APIError.fromStatus("BAD_REQUEST",{message:"Change email with OTP is disabled"});let t=e.context.session.user.email.toLowerCase(),i=e.body.newEmail.toLowerCase();if(!I.email().safeParse(i).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);if(i===t)throw e.context.logger.error("Email is the same"),S.APIError.fromStatus("BAD_REQUEST",{message:"Email is the same"});if(n.changeEmail?.verifyCurrentEmail){if(!e.body.otp)throw S.APIError.fromStatus("BAD_REQUEST",{message:"OTP is required to verify current email"});let r=await e.context.internalAdapter.findVerificationValue(d("email-verification",t));if(!r)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);let i=d("email-verification",t);if(r.expiresAt<new Date)throw await e.context.internalAdapter.deleteVerificationByIdentifier(i),S.APIError.from("BAD_REQUEST",o.OTP_EXPIRED);let[a,s]=p(r.value),c=n?.allowedAttempts||3;if(s&&parseInt(s)>=c)throw await e.context.internalAdapter.deleteVerificationByIdentifier(i),S.APIError.from("FORBIDDEN",o.TOO_MANY_ATTEMPTS);if(!await y(e,n,a,e.body.otp))throw await e.context.internalAdapter.updateVerificationByIdentifier(i,{value:`${a}:${parseInt(s||"0")+1}`}),S.APIError.from("BAD_REQUEST",o.INVALID_OTP);await e.context.internalAdapter.deleteVerificationByIdentifier(i)}else e.body.otp&&e.context.logger.warn("OTP provided but not required for verifying current email. If you want to require OTP verification for current email, please set the changeEmail.verifyCurrentEmail option to true in the configuration");let a=n.generateOTP({email:i,type:"change-email"},e)||H(n),s=await m(e,n,a);return(await e.context.internalAdapter.createVerificationValue({value:`${s}:0`,identifier:d("change-email",`${t}-${i}`),expiresAt:(0,r.getDate)(n.expiresIn,"sec")}),await e.context.internalAdapter.findUserByEmail(i))?await e.context.internalAdapter.deleteVerificationByIdentifier(d("change-email",`${t}-${i}`)):await e.context.runInBackgroundOrAwait(n.sendVerificationOTP({email:i,otp:a,type:"change-email"},e)),e.json({success:!0})}),changeEmailEmailOTP:(0,T.createAuthEndpoint)("/email-otp/change-email",{method:"POST",body:$,use:[b.sensitiveSessionMiddleware],metadata:{openapi:{operationId:"changeEmailWithEmailOTP",description:"Verify new email with OTP and change the email if verification is successful",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{if(!n.changeEmail?.enabled)throw e.context.logger.error("Change email with OTP is disabled."),S.APIError.fromStatus("BAD_REQUEST",{message:"Change email with OTP is disabled"});let t=e.context.session,r=t.user.email.toLowerCase(),i=e.body.newEmail.toLowerCase();if(!I.email().safeParse(i).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);if(i===r)throw e.context.logger.error("Email is the same"),S.APIError.fromStatus("BAD_REQUEST",{message:"Email is the same"});let a=await e.context.internalAdapter.findVerificationValue(d("change-email",`${r}-${i}`));if(!a)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);let s=d("change-email",`${r}-${i}`);if(a.expiresAt<new Date)throw await e.context.internalAdapter.deleteVerificationByIdentifier(s),S.APIError.from("BAD_REQUEST",o.OTP_EXPIRED);let[c,l]=p(a.value),u=n?.allowedAttempts||3;if(l&&parseInt(l)>=u)throw await e.context.internalAdapter.deleteVerificationByIdentifier(s),S.APIError.from("FORBIDDEN",o.TOO_MANY_ATTEMPTS);if(!await y(e,n,c,e.body.otp))throw await e.context.internalAdapter.updateVerificationByIdentifier(s,{value:`${c}:${parseInt(l||"0")+1}`}),S.APIError.from("BAD_REQUEST",o.INVALID_OTP);await e.context.internalAdapter.deleteVerificationByIdentifier(s);let f=await e.context.internalAdapter.findUserByEmail(r);if(!f)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.USER_NOT_FOUND);if(await e.context.internalAdapter.findUserByEmail(i))throw S.APIError.fromStatus("BAD_REQUEST",{message:"Email already in use"});e.context.options.emailVerification?.beforeEmailVerification&&await e.context.options.emailVerification.beforeEmailVerification(f.user,e.request);let h=await e.context.internalAdapter.updateUser(f.user.id,{email:i,emailVerified:!0});return e.context.options.emailVerification?.afterEmailVerification&&await e.context.options.emailVerification.afterEmailVerification(h,e.request),await (0,E.setSessionCookie)(e,{session:t.session,user:{...t.user,email:i,emailVerified:!0}}),e.json({success:!0})})},hooks:{after:[{matcher:e=>!!(e.path?.startsWith("/sign-up")&&n.sendVerificationOnSignUp&&!n.overrideDefaultEmailVerification),handler:(0,T.createAuthMiddleware)(async e=>{let t=(await s(e))?.user.email;if(t){let a=n.generateOTP({email:t,type:e.body.type},e)||q(n),o=await m(e,n,a);await e.context.internalAdapter.createVerificationValue({value:`${o}:0`,identifier:d("email-verification",t),expiresAt:(0,r.getDate)(n.expiresIn,"sec")}),await e.context.runInBackgroundOrAwait(i.sendVerificationOTP({email:t,otp:a,type:"email-verification"},e))}})}]},rateLimit:[{pathMatcher:e=>"/email-otp/send-verification-otp"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/check-verification-otp"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/verify-email"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/sign-in/email-otp"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/request-password-reset"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/reset-password"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/forget-password/email-otp"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/request-email-change"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/change-email"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3}],options:i,$ERROR_CODES:o})]:[]})}],342573)}];
|
|
423
423
|
|
|
424
424
|
//# sourceMappingURL=_0-6p0uy._.js.map
|
package/bundled/web/.open-next/server-functions/default/src/web/.next/server/chunks/_0ih-ceb._.js
CHANGED
|
@@ -395,7 +395,7 @@ To resolve this, you can:
|
|
|
395
395
|
1. Use only one of the conflicting plugins
|
|
396
396
|
2. Configure the plugins to use different paths (if supported)
|
|
397
397
|
3. Ensure plugins use different HTTP methods for the same path
|
|
398
|
-
`)}}(t={...t,secret:i,baseURL:w?t.baseURL:A?new URL(A).origin:"",basePath:t.basePath||"/api/auth",plugins:s.concat(c)},l);let T=(0,h.getCookies)(t),R=(0,rT.getAuthTables)(t),I=(await Promise.all(Object.entries(t.socialProviders||{}).map(async([e,t])=>{let r="function"==typeof t?await t():t;if(null==r||!1===r.enabled)return null;r.clientId||l.warn(`Social provider ${e} is missing clientId or clientSecret`);let i=tP[e](r);return i.disableImplicitSignUp=r.disableImplicitSignUp,i}))).filter(e=>null!==e),v=({model:e,size:r})=>{if("function"==typeof t.advanced?.generateId)return t.advanced.generateId({model:e,size:r});let i=t?.advanced?.database?.generateId;return"function"==typeof i?i({model:e,size:r}):"uuid"===i?crypto.randomUUID():"serial"!==i&&!1!==i&&(0,t0.generateId)(r)},{publish:_}=await rK(t,{adapter:e.id,database:"function"==typeof t.database?"adapter":r(t.database)}),O=new Set(t.plugins.map(e=>e.id)),U=await (0,y.getTrustedOrigins)(t),P=await (0,y.getTrustedProviders)(t),C={appName:t.appName||"Better Auth",baseURL:A||"",version:(0,rk.getBetterAuthVersion)(),socialProviders:I,options:t,oauthConfig:{storeStateStrategy:t.account?.storeStateStrategy||(t.database?"database":"cookie"),skipStateCookieCheck:!!t.account?.skipStateCookieCheck},tables:R,trustedOrigins:U,trustedProviders:P,isTrustedOrigin(e,t){return this.trustedOrigins.some(r=>(0,u.matchesOriginPattern)(e,r,t))},sessionConfig:{updateAge:t.session?.updateAge!==void 0?t.session.updateAge:86400,expiresIn:t.session?.expiresIn||604800,freshAge:t.session?.freshAge===void 0?86400:t.session.freshAge,cookieRefreshCache:(o=t.session?.cookieCache?.refreshCache,n=t.session?.cookieCache?.maxAge||300,(t.database||t.secondaryStorage)&&o?(l.warn("[better-auth] `session.cookieCache.refreshCache` is enabled while `database` or `secondaryStorage` is configured. `refreshCache` is meant for stateless (DB-less) setups. Disabling `refreshCache` — remove it from your config to silence this warning."),!1):!1!==o&&void 0!==o&&(!0===o?{enabled:!0,updateAge:Math.floor(.2*n)}:{enabled:!0,updateAge:void 0!==o.updateAge?o.updateAge:Math.floor(.2*n)}))},secret:i,secretConfig:a,rateLimit:{...t.rateLimit,enabled:t.rateLimit?.enabled??tz.isProduction,window:t.rateLimit?.window||10,max:t.rateLimit?.max||100,storage:t.rateLimit?.storage||(t.secondaryStorage?"secondary-storage":"memory")},authCookies:T,logger:l,generateId:v,session:null,secondaryStorage:t.secondaryStorage,password:{hash:t.emailAndPassword?.password?.hash||f.hashPassword,verify:t.emailAndPassword?.password?.verify||f.verifyPassword,config:{minPasswordLength:t.emailAndPassword?.minPasswordLength||8,maxPasswordLength:t.emailAndPassword?.maxPasswordLength||128},checkPassword:g.checkPassword},setNewSession(e){this.newSession=e},newSession:null,adapter:e,internalAdapter:(0,m.createInternalAdapter)(e,{options:t,logger:l,hooks:t.databaseHooks?[{source:"user",hooks:t.databaseHooks}]:[],generateId:v}),createAuthCookie:(0,h.createCookieGetter)(t),async runMigrations(){throw new x.BetterAuthError("runMigrations will be set by the specific init implementation")},publishTelemetry:_,skipCSRFCheck:!!t.advanced?.disableCSRFCheck,skipOriginCheck:t.advanced?.disableOriginCheck!==void 0?t.advanced.disableOriginCheck:!!(0,tz.isTest)(),runInBackground:t.advanced?.backgroundTasks?.handler??(e=>{e.catch(()=>{})}),async runInBackgroundOrAwait(e){try{t.advanced?.backgroundTasks?.handler?e instanceof Promise&&t.advanced.backgroundTasks.handler(e.catch(e=>{l.error("Failed to run background task:",e)})):await e}catch(e){l.error("Failed to run background task:",e)}},getPlugin:e=>t.plugins.find(t=>t.id===e)??null,hasPlugin:e=>O.has(e)},D=(0,y.runPluginInit)(C);return(0,p.isPromise)(D)&&await D,C}var rF=e.i(439704);let rJ=async e=>{let t=await (0,c.getAdapter)(e),r=await rz(t,e,e=>(0,rF.getKyselyDatabaseType)(e)||"unknown");return r.runMigrations=async function(){if(!e.database||"updateMany"in e.database)throw new x.BetterAuthError("Database is not provided or it's an adapter. Migrations are only supported with a database instance.");let{runMigrations:t}=await (0,l.getMigrations)(e);await t()},r};e.s(["betterAuth",0,e=>((e,t)=>{let r=t(e),{api:i}=rS(r,e);return{handler:async t=>{let i,a=await r,o=a.options.basePath||"/api/auth";if((0,d.isDynamicBaseURLConfig)(e.baseURL))i=await (0,y.resolveRequestContext)(a,t,(0,y.resolveDynamicTrustedProxyHeaders)(a.options));else{if(i=a,!a.options.baseURL){let e=(0,d.getBaseURL)(void 0,o,t,void 0,a.options.advanced?.trustedProxyHeaders);if(e)a.baseURL=e,a.options.baseURL=(0,d.getOrigin)(a.baseURL)||void 0;else throw new x.BetterAuthError("Could not get base URL from request. Please provide a valid base URL.")}i.trustedOrigins=await (0,y.getTrustedOrigins)(a.options,t),i.trustedProviders=await (0,y.getTrustedProviders)(a.options,t)}let{handler:n}=((e,t)=>{let{api:r,middlewares:i}=rS(e,t),a=new URL(e.baseURL).pathname;return(0,rb.createRouter)(r,{routerContext:e,openapi:{disabled:!0},basePath:a,routerMiddleware:[{path:"/**",middleware:A.originCheckMiddleware},...i],allowedMediaTypes:["application/json"],skipTrailingSlashes:t.advanced?.skipTrailingSlashes??!1,async onRequest(t){let r=e.options.disabledPaths||[],i=(0,rE.normalizePathname)(t.url,a);if(r.includes(i))return new Response("Not Found",{status:404});let o=t;for(let t of e.options.plugins||[])if(t.onRequest){let r=await (0,rp.withSpan)(`onRequest ${t.id}`,{[rd.ATTR_HOOK_TYPE]:"onRequest",[rd.ATTR_CONTEXT]:`plugin:${t.id}`},()=>t.onRequest(o,e));if(r&&"response"in r)return r.response;r&&"request"in r&&(o=r.request)}let n=await (0,E.onRequestRateLimit)(o,e);return n||o},async onResponse(t,r){for(let i of(await (0,E.onResponseRateLimit)(r,e),e.options.plugins||[]))if(i.onResponse){let r=await (0,rp.withSpan)(`onResponse ${i.id}`,{[rd.ATTR_HOOK_TYPE]:"onResponse",[rd.ATTR_CONTEXT]:`plugin:${i.id}`,[ru.ATTR_HTTP_RESPONSE_STATUS_CODE]:t.status},()=>i.onResponse(t,e));if(r)return r.response}return t},onError(r){if((0,w.isAPIError)(r)&&"FOUND"===r.status)return;if(t.onAPIError?.throw)throw r;if(t.onAPIError?.onError)return void t.onAPIError.onError(r,e);let i=t.logger?.level,a="error"===i||"warn"===i||"debug"===i?eM.logger:void 0;if(t.logger?.disabled!==!0){if(r&&"object"==typeof r&&"message"in r&&"string"==typeof r.message&&(r.message.includes("no column")||r.message.includes("column")||r.message.includes("relation")||r.message.includes("table")||r.message.includes("does not exist")))return void e.logger?.error(r.message);(0,w.isAPIError)(r)?("INTERNAL_SERVER_ERROR"===r.status&&e.logger.error(r.status,r),a?.error(r.message)):e.logger?.error(r&&"object"==typeof r&&"name"in r?r.name:"",r)}}})})(i,e);return(0,t9.runWithAdapter)(i.adapter,()=>n(t))},api:i,options:e,$context:r,$ERROR_CODES:{...e.plugins?.reduce((e,t)=>t.$ERROR_CODES?{...e,...t.$ERROR_CODES}:e,{}),...v.BASE_ERROR_CODES}}})(e,rJ)],928976)},185599,e=>{"use strict";e.s(["PACKAGE_VERSION",0,"1.6.10"],185599)},342573,e=>{"use strict";var t=e.i(928976),r=e.i(108761),i=e.i(760160),a=e.i(185599);let o=(0,e.i(332807).defineErrorCodes)({OTP_EXPIRED:"OTP expired",INVALID_OTP:"Invalid OTP",TOO_MANY_ATTEMPTS:"Too many attempts"});var n=e.i(280917);let s=async e=>{let t=e.context.returned;return t?t instanceof Response?200!==t.status?null:await t.clone().json():(0,n.isAPIError)(t)?null:t:null};var c=e.i(575779),l=e.i(618989);function d(e,t){return`${e}-otp-${t}`}let u=async e=>{let t=await (0,l.createHash)("SHA-256").digest(new TextEncoder().encode(e));return c.base64Url.encode(new Uint8Array(t),{padding:!1})};function p(e){let t=e.lastIndexOf(":");return -1===t?[e,""]:[e.slice(0,t),e.slice(t+1)]}var f=e.i(463617),h=e.i(277512);async function m(e,t,r){return"encrypted"===t.storeOTP?await (0,h.symmetricEncrypt)({key:e.context.secretConfig,data:r}):"hashed"===t.storeOTP?await u(r):"object"==typeof t.storeOTP&&"hash"in t.storeOTP?await t.storeOTP.hash(r):"object"==typeof t.storeOTP&&"encrypt"in t.storeOTP?await t.storeOTP.encrypt(r):r}async function y(e,t,r,i){return"encrypted"===t.storeOTP?(0,f.constantTimeEqual)(await (0,h.symmetricDecrypt)({key:e.context.secretConfig,data:r}),i):"hashed"===t.storeOTP?(0,f.constantTimeEqual)(await u(i),r):"object"==typeof t.storeOTP&&"hash"in t.storeOTP?(0,f.constantTimeEqual)(await t.storeOTP.hash(i),r):"object"==typeof t.storeOTP&&"decrypt"in t.storeOTP?(0,f.constantTimeEqual)(await t.storeOTP.decrypt(r),i):(0,f.constantTimeEqual)(i,r)}async function g(e,t,r){return"plain"===t.storeOTP||void 0===t.storeOTP?r:"encrypted"===t.storeOTP?await (0,h.symmetricDecrypt)({key:e.context.secretConfig,data:r}):"object"==typeof t.storeOTP&&"decrypt"in t.storeOTP?await t.storeOTP.decrypt(r):null}async function w(e,t,i){let a=await e.context.internalAdapter.findVerificationValue(i);if(!a||a.expiresAt<new Date)return null;let[o,n]=p(a.value),s=t.allowedAttempts||3;if(n&&parseInt(n)>=s)return null;let c=await g(e,t,o);return c?(await e.context.internalAdapter.updateVerificationByIdentifier(i,{expiresAt:(0,r.getDate)(t.expiresIn,"sec")}),c):null}var A=e.i(33573),E=e.i(22523),b=e.i(610914),S=e.i(290410),k=e.i(63162),T=e.i(702149),R=e.i(440277),I=e.i(807405);let x=["email-verification","sign-in","forget-password","change-email"];async function v(e,t,i,a){let o=d(a,i);if("reuse"===t.resendStrategy){let r=await w(e,t,o);if(r)return r}let n=t.generateOTP({email:i,type:a},e)||H(t),s=await m(e,t,n);return await e.context.internalAdapter.createVerificationValue({value:`${s}:0`,identifier:o,expiresAt:(0,r.getDate)(t.expiresIn,"sec")}).catch(async()=>{await e.context.internalAdapter.deleteVerificationByIdentifier(o),await e.context.internalAdapter.createVerificationValue({value:`${s}:0`,identifier:o,expiresAt:(0,r.getDate)(t.expiresIn,"sec")})}),n}let _=I.object({email:I.string({}).meta({description:"Email address to send the OTP"}),type:I.enum(x).meta({description:"Type of the OTP"})}),O=I.object({email:I.string({}).meta({description:"Email address to send the OTP"}),type:I.enum(x).meta({required:!0,description:"Type of the OTP"})}),U=I.object({email:I.string({}).meta({description:"Email address the OTP was sent to"}),type:I.enum(x).meta({required:!0,description:"Type of the OTP"})}),P=I.object({email:I.string().meta({description:"Email address the OTP was sent to"}),type:I.enum(x).meta({required:!0,description:"Type of the OTP"}),otp:I.string().meta({required:!0,description:"OTP to verify"})}),C=I.object({email:I.string({}).meta({description:"Email address to verify"}),otp:I.string().meta({required:!0,description:"OTP to verify"})}),D=I.object({email:I.string({}).meta({description:"Email address to sign in"}),otp:I.string().meta({required:!0,description:"OTP sent to the email"}),name:I.string().meta({description:'User display name. Only used if the user is registering for the first time. Eg: "my-name"'}).optional(),image:I.string().meta({description:"User profile image URL. Only used if the user is registering for the first time."}).optional()}).and(I.record(I.string(),I.any())),L=I.object({email:I.string().meta({description:"Email address to send the OTP"})}),N=I.object({email:I.string().meta({description:"Email address to send the OTP"})}),B=I.object({email:I.string().meta({description:"Email address to reset the password"}),otp:I.string().meta({description:"OTP sent to the email"}),password:I.string().meta({description:"New password"})}),j=I.object({newEmail:I.string().meta({description:"New email address to send the OTP"}),otp:I.string().optional().meta({description:"OTP sent to the current email. This is required if changeEmail.verifyCurrentEmail option is set to true"})}),$=I.object({newEmail:I.string().meta({description:"New email address to verify and change to"}),otp:I.string().meta({description:"OTP sent to the new email"})}),H=e=>(0,i.generateRandomString)(e.otpLength??6,"0-9");async function V(e,t,r,i){let a=await e.context.internalAdapter.findVerificationValue(r);if(!a)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);if(a.expiresAt<new Date)throw await e.context.internalAdapter.deleteVerificationByIdentifier(r),S.APIError.from("BAD_REQUEST",o.OTP_EXPIRED);let[n,s]=p(a.value),c=t?.allowedAttempts||3;if(s&&parseInt(s)>=c)throw await e.context.internalAdapter.deleteVerificationByIdentifier(r),S.APIError.from("FORBIDDEN",o.TOO_MANY_ATTEMPTS);if(await e.context.internalAdapter.deleteVerificationByIdentifier(r),!await y(e,t,n,i))throw await e.context.internalAdapter.createVerificationValue({value:`${n}:${parseInt(s||"0")+1}`,identifier:r,expiresAt:a.expiresAt}),S.APIError.from("BAD_REQUEST",o.INVALID_OTP)}let q=e=>(0,i.generateRandomString)(e.otpLength??6,"0-9");e.i(700598);var M=e.i(726527),W=e.i(704024);let K={"sign-in":"Your Alook sign-in code","email-verification":"Verify your Alook email","forget-password":"Reset your Alook password","change-email":"Confirm your new email address"},z={"sign-in":"Sign in to Alook","email-verification":"Verify your email","forget-password":"Reset your password","change-email":"Confirm email change"},F={"sign-in":"Enter this code to sign in to your account.","email-verification":"Enter this code to verify your email address.","forget-password":"Enter this code to reset your password.","change-email":"Enter this code to confirm your new email address."},J=(0,M.createLogger)({service:"auth"});function G(e,t){if(!e)return t;let r=Number.parseInt(e,10);return Number.isFinite(r)&&r>0?r:t}e.s(["createAuth",0,function(e){var i;let n,c,l,u=G(e.AUTH_OTP_RATE_LIMIT_MAX,5),f=G(e.AUTH_OTP_RATE_LIMIT_WINDOW_SEC,60),g=Math.max(60,f);return(0,t.betterAuth)({baseURL:e.BETTER_AUTH_URL,database:e.DB,secret:e.BETTER_AUTH_SECRET,session:{expiresIn:2592e3,updateAge:86400,cookieCache:{enabled:!0,maxAge:300}},emailAndPassword:{enabled:!1,requireEmailVerification:!1},socialProviders:{github:{clientId:e.GITHUB_CLIENT_ID,clientSecret:e.GITHUB_CLIENT_SECRET},google:{clientId:e.GOOGLE_CLIENT_ID,clientSecret:e.GOOGLE_CLIENT_SECRET}},rateLimit:{enabled:!0,customRules:{"/email-otp/send-verification-otp":{window:f,max:u}},customStorage:{get:async t=>{let r=await e.RATE_LIMIT_KV.get(t);return r?JSON.parse(r):void 0},set:async(t,r)=>{await e.RATE_LIMIT_KV.put(t,JSON.stringify(r),{expirationTtl:g})}}},plugins:[(n={expiresIn:300,generateOTP:()=>q(i),storeOTP:"plain",...i={async sendVerificationOTP({email:t,otp:r,type:i}){J.info("sending OTP email",{to:t,type:i});try{let a,o,n,s=JSON.stringify({to:t,subject:K[i],html:(o=z[i],n=F[i],`<!DOCTYPE html>
|
|
398
|
+
`)}}(t={...t,secret:i,baseURL:w?t.baseURL:A?new URL(A).origin:"",basePath:t.basePath||"/api/auth",plugins:s.concat(c)},l);let T=(0,h.getCookies)(t),R=(0,rT.getAuthTables)(t),I=(await Promise.all(Object.entries(t.socialProviders||{}).map(async([e,t])=>{let r="function"==typeof t?await t():t;if(null==r||!1===r.enabled)return null;r.clientId||l.warn(`Social provider ${e} is missing clientId or clientSecret`);let i=tP[e](r);return i.disableImplicitSignUp=r.disableImplicitSignUp,i}))).filter(e=>null!==e),v=({model:e,size:r})=>{if("function"==typeof t.advanced?.generateId)return t.advanced.generateId({model:e,size:r});let i=t?.advanced?.database?.generateId;return"function"==typeof i?i({model:e,size:r}):"uuid"===i?crypto.randomUUID():"serial"!==i&&!1!==i&&(0,t0.generateId)(r)},{publish:_}=await rK(t,{adapter:e.id,database:"function"==typeof t.database?"adapter":r(t.database)}),O=new Set(t.plugins.map(e=>e.id)),U=await (0,y.getTrustedOrigins)(t),P=await (0,y.getTrustedProviders)(t),C={appName:t.appName||"Better Auth",baseURL:A||"",version:(0,rk.getBetterAuthVersion)(),socialProviders:I,options:t,oauthConfig:{storeStateStrategy:t.account?.storeStateStrategy||(t.database?"database":"cookie"),skipStateCookieCheck:!!t.account?.skipStateCookieCheck},tables:R,trustedOrigins:U,trustedProviders:P,isTrustedOrigin(e,t){return this.trustedOrigins.some(r=>(0,u.matchesOriginPattern)(e,r,t))},sessionConfig:{updateAge:t.session?.updateAge!==void 0?t.session.updateAge:86400,expiresIn:t.session?.expiresIn||604800,freshAge:t.session?.freshAge===void 0?86400:t.session.freshAge,cookieRefreshCache:(o=t.session?.cookieCache?.refreshCache,n=t.session?.cookieCache?.maxAge||300,(t.database||t.secondaryStorage)&&o?(l.warn("[better-auth] `session.cookieCache.refreshCache` is enabled while `database` or `secondaryStorage` is configured. `refreshCache` is meant for stateless (DB-less) setups. Disabling `refreshCache` — remove it from your config to silence this warning."),!1):!1!==o&&void 0!==o&&(!0===o?{enabled:!0,updateAge:Math.floor(.2*n)}:{enabled:!0,updateAge:void 0!==o.updateAge?o.updateAge:Math.floor(.2*n)}))},secret:i,secretConfig:a,rateLimit:{...t.rateLimit,enabled:t.rateLimit?.enabled??tz.isProduction,window:t.rateLimit?.window||10,max:t.rateLimit?.max||100,storage:t.rateLimit?.storage||(t.secondaryStorage?"secondary-storage":"memory")},authCookies:T,logger:l,generateId:v,session:null,secondaryStorage:t.secondaryStorage,password:{hash:t.emailAndPassword?.password?.hash||f.hashPassword,verify:t.emailAndPassword?.password?.verify||f.verifyPassword,config:{minPasswordLength:t.emailAndPassword?.minPasswordLength||8,maxPasswordLength:t.emailAndPassword?.maxPasswordLength||128},checkPassword:g.checkPassword},setNewSession(e){this.newSession=e},newSession:null,adapter:e,internalAdapter:(0,m.createInternalAdapter)(e,{options:t,logger:l,hooks:t.databaseHooks?[{source:"user",hooks:t.databaseHooks}]:[],generateId:v}),createAuthCookie:(0,h.createCookieGetter)(t),async runMigrations(){throw new x.BetterAuthError("runMigrations will be set by the specific init implementation")},publishTelemetry:_,skipCSRFCheck:!!t.advanced?.disableCSRFCheck,skipOriginCheck:t.advanced?.disableOriginCheck!==void 0?t.advanced.disableOriginCheck:!!(0,tz.isTest)(),runInBackground:t.advanced?.backgroundTasks?.handler??(e=>{e.catch(()=>{})}),async runInBackgroundOrAwait(e){try{t.advanced?.backgroundTasks?.handler?e instanceof Promise&&t.advanced.backgroundTasks.handler(e.catch(e=>{l.error("Failed to run background task:",e)})):await e}catch(e){l.error("Failed to run background task:",e)}},getPlugin:e=>t.plugins.find(t=>t.id===e)??null,hasPlugin:e=>O.has(e)},D=(0,y.runPluginInit)(C);return(0,p.isPromise)(D)&&await D,C}var rF=e.i(439704);let rJ=async e=>{let t=await (0,c.getAdapter)(e),r=await rz(t,e,e=>(0,rF.getKyselyDatabaseType)(e)||"unknown");return r.runMigrations=async function(){if(!e.database||"updateMany"in e.database)throw new x.BetterAuthError("Database is not provided or it's an adapter. Migrations are only supported with a database instance.");let{runMigrations:t}=await (0,l.getMigrations)(e);await t()},r};e.s(["betterAuth",0,e=>((e,t)=>{let r=t(e),{api:i}=rS(r,e);return{handler:async t=>{let i,a=await r,o=a.options.basePath||"/api/auth";if((0,d.isDynamicBaseURLConfig)(e.baseURL))i=await (0,y.resolveRequestContext)(a,t,(0,y.resolveDynamicTrustedProxyHeaders)(a.options));else{if(i=a,!a.options.baseURL){let e=(0,d.getBaseURL)(void 0,o,t,void 0,a.options.advanced?.trustedProxyHeaders);if(e)a.baseURL=e,a.options.baseURL=(0,d.getOrigin)(a.baseURL)||void 0;else throw new x.BetterAuthError("Could not get base URL from request. Please provide a valid base URL.")}i.trustedOrigins=await (0,y.getTrustedOrigins)(a.options,t),i.trustedProviders=await (0,y.getTrustedProviders)(a.options,t)}let{handler:n}=((e,t)=>{let{api:r,middlewares:i}=rS(e,t),a=new URL(e.baseURL).pathname;return(0,rb.createRouter)(r,{routerContext:e,openapi:{disabled:!0},basePath:a,routerMiddleware:[{path:"/**",middleware:A.originCheckMiddleware},...i],allowedMediaTypes:["application/json"],skipTrailingSlashes:t.advanced?.skipTrailingSlashes??!1,async onRequest(t){let r=e.options.disabledPaths||[],i=(0,rE.normalizePathname)(t.url,a);if(r.includes(i))return new Response("Not Found",{status:404});let o=t;for(let t of e.options.plugins||[])if(t.onRequest){let r=await (0,rp.withSpan)(`onRequest ${t.id}`,{[rd.ATTR_HOOK_TYPE]:"onRequest",[rd.ATTR_CONTEXT]:`plugin:${t.id}`},()=>t.onRequest(o,e));if(r&&"response"in r)return r.response;r&&"request"in r&&(o=r.request)}let n=await (0,E.onRequestRateLimit)(o,e);return n||o},async onResponse(t,r){for(let i of(await (0,E.onResponseRateLimit)(r,e),e.options.plugins||[]))if(i.onResponse){let r=await (0,rp.withSpan)(`onResponse ${i.id}`,{[rd.ATTR_HOOK_TYPE]:"onResponse",[rd.ATTR_CONTEXT]:`plugin:${i.id}`,[ru.ATTR_HTTP_RESPONSE_STATUS_CODE]:t.status},()=>i.onResponse(t,e));if(r)return r.response}return t},onError(r){if((0,w.isAPIError)(r)&&"FOUND"===r.status)return;if(t.onAPIError?.throw)throw r;if(t.onAPIError?.onError)return void t.onAPIError.onError(r,e);let i=t.logger?.level,a="error"===i||"warn"===i||"debug"===i?eM.logger:void 0;if(t.logger?.disabled!==!0){if(r&&"object"==typeof r&&"message"in r&&"string"==typeof r.message&&(r.message.includes("no column")||r.message.includes("column")||r.message.includes("relation")||r.message.includes("table")||r.message.includes("does not exist")))return void e.logger?.error(r.message);(0,w.isAPIError)(r)?("INTERNAL_SERVER_ERROR"===r.status&&e.logger.error(r.status,r),a?.error(r.message)):e.logger?.error(r&&"object"==typeof r&&"name"in r?r.name:"",r)}}})})(i,e);return(0,t9.runWithAdapter)(i.adapter,()=>n(t))},api:i,options:e,$context:r,$ERROR_CODES:{...e.plugins?.reduce((e,t)=>t.$ERROR_CODES?{...e,...t.$ERROR_CODES}:e,{}),...v.BASE_ERROR_CODES}}})(e,rJ)],928976)},185599,e=>{"use strict";e.s(["PACKAGE_VERSION",0,"1.6.10"],185599)},342573,e=>{"use strict";var t=e.i(928976),r=e.i(108761),i=e.i(760160),a=e.i(185599);let o=(0,e.i(332807).defineErrorCodes)({OTP_EXPIRED:"OTP expired",INVALID_OTP:"Invalid OTP",TOO_MANY_ATTEMPTS:"Too many attempts"});var n=e.i(280917);let s=async e=>{let t=e.context.returned;return t?t instanceof Response?200!==t.status?null:await t.clone().json():(0,n.isAPIError)(t)?null:t:null};var c=e.i(575779),l=e.i(618989);function d(e,t){return`${e}-otp-${t}`}let u=async e=>{let t=await (0,l.createHash)("SHA-256").digest(new TextEncoder().encode(e));return c.base64Url.encode(new Uint8Array(t),{padding:!1})};function p(e){let t=e.lastIndexOf(":");return -1===t?[e,""]:[e.slice(0,t),e.slice(t+1)]}var f=e.i(463617),h=e.i(277512);async function m(e,t,r){return"encrypted"===t.storeOTP?await (0,h.symmetricEncrypt)({key:e.context.secretConfig,data:r}):"hashed"===t.storeOTP?await u(r):"object"==typeof t.storeOTP&&"hash"in t.storeOTP?await t.storeOTP.hash(r):"object"==typeof t.storeOTP&&"encrypt"in t.storeOTP?await t.storeOTP.encrypt(r):r}async function y(e,t,r,i){return"encrypted"===t.storeOTP?(0,f.constantTimeEqual)(await (0,h.symmetricDecrypt)({key:e.context.secretConfig,data:r}),i):"hashed"===t.storeOTP?(0,f.constantTimeEqual)(await u(i),r):"object"==typeof t.storeOTP&&"hash"in t.storeOTP?(0,f.constantTimeEqual)(await t.storeOTP.hash(i),r):"object"==typeof t.storeOTP&&"decrypt"in t.storeOTP?(0,f.constantTimeEqual)(await t.storeOTP.decrypt(r),i):(0,f.constantTimeEqual)(i,r)}async function g(e,t,r){return"plain"===t.storeOTP||void 0===t.storeOTP?r:"encrypted"===t.storeOTP?await (0,h.symmetricDecrypt)({key:e.context.secretConfig,data:r}):"object"==typeof t.storeOTP&&"decrypt"in t.storeOTP?await t.storeOTP.decrypt(r):null}async function w(e,t,i){let a=await e.context.internalAdapter.findVerificationValue(i);if(!a||a.expiresAt<new Date)return null;let[o,n]=p(a.value),s=t.allowedAttempts||3;if(n&&parseInt(n)>=s)return null;let c=await g(e,t,o);return c?(await e.context.internalAdapter.updateVerificationByIdentifier(i,{expiresAt:(0,r.getDate)(t.expiresIn,"sec")}),c):null}var A=e.i(33573),E=e.i(22523),b=e.i(610914),S=e.i(290410),k=e.i(63162),T=e.i(702149),R=e.i(440277),I=e.i(807405);let x=["email-verification","sign-in","forget-password","change-email"];async function v(e,t,i,a){let o=d(a,i);if("reuse"===t.resendStrategy){let r=await w(e,t,o);if(r)return r}let n=t.generateOTP({email:i,type:a},e)||H(t),s=await m(e,t,n);return await e.context.internalAdapter.createVerificationValue({value:`${s}:0`,identifier:o,expiresAt:(0,r.getDate)(t.expiresIn,"sec")}).catch(async()=>{await e.context.internalAdapter.deleteVerificationByIdentifier(o),await e.context.internalAdapter.createVerificationValue({value:`${s}:0`,identifier:o,expiresAt:(0,r.getDate)(t.expiresIn,"sec")})}),n}let _=I.object({email:I.string({}).meta({description:"Email address to send the OTP"}),type:I.enum(x).meta({description:"Type of the OTP"})}),O=I.object({email:I.string({}).meta({description:"Email address to send the OTP"}),type:I.enum(x).meta({required:!0,description:"Type of the OTP"})}),U=I.object({email:I.string({}).meta({description:"Email address the OTP was sent to"}),type:I.enum(x).meta({required:!0,description:"Type of the OTP"})}),P=I.object({email:I.string().meta({description:"Email address the OTP was sent to"}),type:I.enum(x).meta({required:!0,description:"Type of the OTP"}),otp:I.string().meta({required:!0,description:"OTP to verify"})}),C=I.object({email:I.string({}).meta({description:"Email address to verify"}),otp:I.string().meta({required:!0,description:"OTP to verify"})}),D=I.object({email:I.string({}).meta({description:"Email address to sign in"}),otp:I.string().meta({required:!0,description:"OTP sent to the email"}),name:I.string().meta({description:'User display name. Only used if the user is registering for the first time. Eg: "my-name"'}).optional(),image:I.string().meta({description:"User profile image URL. Only used if the user is registering for the first time."}).optional()}).and(I.record(I.string(),I.any())),L=I.object({email:I.string().meta({description:"Email address to send the OTP"})}),N=I.object({email:I.string().meta({description:"Email address to send the OTP"})}),B=I.object({email:I.string().meta({description:"Email address to reset the password"}),otp:I.string().meta({description:"OTP sent to the email"}),password:I.string().meta({description:"New password"})}),j=I.object({newEmail:I.string().meta({description:"New email address to send the OTP"}),otp:I.string().optional().meta({description:"OTP sent to the current email. This is required if changeEmail.verifyCurrentEmail option is set to true"})}),$=I.object({newEmail:I.string().meta({description:"New email address to verify and change to"}),otp:I.string().meta({description:"OTP sent to the new email"})}),H=e=>(0,i.generateRandomString)(e.otpLength??6,"0-9");async function V(e,t,r,i){let a=await e.context.internalAdapter.findVerificationValue(r);if(!a)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);if(a.expiresAt<new Date)throw await e.context.internalAdapter.deleteVerificationByIdentifier(r),S.APIError.from("BAD_REQUEST",o.OTP_EXPIRED);let[n,s]=p(a.value),c=t?.allowedAttempts||3;if(s&&parseInt(s)>=c)throw await e.context.internalAdapter.deleteVerificationByIdentifier(r),S.APIError.from("FORBIDDEN",o.TOO_MANY_ATTEMPTS);if(await e.context.internalAdapter.deleteVerificationByIdentifier(r),!await y(e,t,n,i))throw await e.context.internalAdapter.createVerificationValue({value:`${n}:${parseInt(s||"0")+1}`,identifier:r,expiresAt:a.expiresAt}),S.APIError.from("BAD_REQUEST",o.INVALID_OTP)}let q=e=>(0,i.generateRandomString)(e.otpLength??6,"0-9");e.i(700598);var M=e.i(726527),W=e.i(704024);let K={"sign-in":"Your Alook sign-in code","email-verification":"Verify your Alook email","forget-password":"Reset your Alook password","change-email":"Confirm your new email address"},z={"sign-in":"Sign in to Alook","email-verification":"Verify your email","forget-password":"Reset your password","change-email":"Confirm email change"},F={"sign-in":"Enter this code to sign in to your account.","email-verification":"Enter this code to verify your email address.","forget-password":"Enter this code to reset your password.","change-email":"Enter this code to confirm your new email address."},J=(0,M.createLogger)({service:"auth"});function G(e,t){if(!e)return t;let r=Number.parseInt(e,10);return Number.isFinite(r)&&r>0?r:t}e.s(["createAuth",0,function(e){var i;let n,c,l,u=(e.NODE_ENV??"production")!=="development",f=G(e.AUTH_OTP_RATE_LIMIT_MAX,5),g=G(e.AUTH_OTP_RATE_LIMIT_WINDOW_SEC,60),w=Math.max(60,g);return(0,t.betterAuth)({baseURL:e.BETTER_AUTH_URL,database:e.DB,secret:e.BETTER_AUTH_SECRET,session:{expiresIn:2592e3,updateAge:86400,cookieCache:{enabled:!0,maxAge:300}},emailAndPassword:{enabled:!u,requireEmailVerification:!1},socialProviders:{github:{clientId:e.GITHUB_CLIENT_ID,clientSecret:e.GITHUB_CLIENT_SECRET},google:{clientId:e.GOOGLE_CLIENT_ID,clientSecret:e.GOOGLE_CLIENT_SECRET}},rateLimit:{enabled:u,customRules:{"/email-otp/send-verification-otp":{window:g,max:f}},customStorage:{get:async t=>{let r=await e.RATE_LIMIT_KV.get(t);return r?JSON.parse(r):void 0},set:async(t,r)=>{await e.RATE_LIMIT_KV.put(t,JSON.stringify(r),{expirationTtl:w})}}},plugins:u?[(n={expiresIn:300,generateOTP:()=>q(i),storeOTP:"plain",...i={async sendVerificationOTP({email:t,otp:r,type:i}){J.info("sending OTP email",{to:t,type:i});try{let a,o,n,s=JSON.stringify({to:t,subject:K[i],html:(o=z[i],n=F[i],`<!DOCTYPE html>
|
|
399
399
|
<html lang="en">
|
|
400
400
|
<head>
|
|
401
401
|
<meta charset="utf-8">
|
|
@@ -419,6 +419,6 @@ To resolve this, you can:
|
|
|
419
419
|
</td></tr>
|
|
420
420
|
</table>
|
|
421
421
|
</body>
|
|
422
|
-
</html>`)}),c={method:"POST",headers:{"Content-Type":"application/json"},body:s};try{a=await e.EMAIL_WORKER.fetch("http://internal/send/otp",c)}catch{a=await fetch(`${W.DEV_EMAIL_WORKER_URL}/send/otp`,c)}if(!a.ok){let e=await a.text();throw Error(`EMAIL_WORKER /send/otp failed: ${a.status} ${e}`)}J.info("OTP email sent",{to:t,type:i})}catch(e){throw J.error("OTP email failed",{to:t,type:i,err:e}),e}}}},c=(0,T.createAuthEndpoint)("/email-otp/send-verification-otp",{method:"POST",body:_,metadata:{openapi:{operationId:"sendEmailVerificationOTP",description:"Send a verification OTP to an email",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{if(!n?.sendVerificationOTP)throw e.context.logger.error("send email verification is not implemented"),S.APIError.fromStatus("BAD_REQUEST",{message:"send email verification is not implemented"});let t=e.body.email.toLowerCase();if(!I.email().safeParse(t).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);if("change-email"===e.body.type)throw e.context.logger.error("Use the /email-otp/request-email-change endpoint to send OTP for changing email"),S.APIError.fromStatus("BAD_REQUEST",{message:"Invalid OTP type"});let r=d(e.body.type,t),i=await v(e,n,t,e.body.type),a="sign-in"===e.body.type&&!n.disableSignUp;return await e.context.internalAdapter.findUserByEmail(t)||a?await e.context.runInBackgroundOrAwait(n.sendVerificationOTP({email:t,otp:i,type:e.body.type},e)):await e.context.internalAdapter.deleteVerificationByIdentifier(r),e.json({success:!0})}),{id:"email-otp",version:a.PACKAGE_VERSION,init(e){if(n.overrideDefaultEmailVerification)return{options:{emailVerification:{async sendVerificationEmail(t,r){await e.runInBackgroundOrAwait(c({context:e,request:r,body:{email:t.user.email,type:"email-verification"},ctx:e}))}}}}},endpoints:{sendVerificationOTP:c,createVerificationOTP:(0,T.createAuthEndpoint)({method:"POST",body:O,metadata:{openapi:{operationId:"createEmailVerificationOTP",description:"Create a verification OTP for an email",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"string"}}}}}}}},async e=>{let t=e.body.email.toLowerCase(),i=n.generateOTP({email:t,type:e.body.type},e)||H(n),a=await m(e,n,i);return await e.context.internalAdapter.createVerificationValue({value:`${a}:0`,identifier:d(e.body.type,t),expiresAt:(0,r.getDate)(n.expiresIn,"sec")}),i}),getVerificationOTP:(0,T.createAuthEndpoint)({method:"GET",query:U,metadata:{openapi:{operationId:"getEmailVerificationOTP",description:"Get a verification OTP for an email",responses:{200:{description:"OTP retrieved successfully or not found/expired",content:{"application/json":{schema:{type:"object",properties:{otp:{type:"string",nullable:!0,description:"The stored OTP, or null if not found or expired"}},required:["otp"]}}}}}}}},async e=>{let t=e.query.email.toLowerCase(),r=await e.context.internalAdapter.findVerificationValue(d(e.query.type,t));if(!r||r.expiresAt<new Date)return e.json({otp:null});if("hashed"===n.storeOTP||"object"==typeof n.storeOTP&&"hash"in n.storeOTP)throw S.APIError.fromStatus("BAD_REQUEST",{message:"OTP is hashed, cannot return the plain text OTP"});let[i,a]=p(r.value),o=i;return"encrypted"===n.storeOTP&&(o=await (0,h.symmetricDecrypt)({key:e.context.secretConfig,data:i})),"object"==typeof n.storeOTP&&"decrypt"in n.storeOTP&&(o=await n.storeOTP.decrypt(i)),e.json({otp:o})}),checkVerificationOTP:(0,T.createAuthEndpoint)("/email-otp/check-verification-otp",{method:"POST",body:P,metadata:{openapi:{operationId:"verifyEmailWithOTP",description:"Verify an email with an OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{let t=e.body.email.toLowerCase();if(!I.email().safeParse(t).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);if(!await e.context.internalAdapter.findUserByEmail(t))throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.USER_NOT_FOUND);let r=d(e.body.type,t),i=await e.context.internalAdapter.findVerificationValue(r);if(!i)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);if(i.expiresAt<new Date)throw await e.context.internalAdapter.deleteVerificationByIdentifier(r),S.APIError.from("BAD_REQUEST",o.OTP_EXPIRED);let[a,s]=p(i.value),c=n?.allowedAttempts||3;if(s&&parseInt(s)>=c)throw await e.context.internalAdapter.deleteVerificationByIdentifier(r),S.APIError.from("FORBIDDEN",o.TOO_MANY_ATTEMPTS);if(!await y(e,n,a,e.body.otp))throw await e.context.internalAdapter.updateVerificationByIdentifier(r,{value:`${a}:${parseInt(s||"0")+1}`}),S.APIError.from("BAD_REQUEST",o.INVALID_OTP);return e.json({success:!0})}),verifyEmailOTP:(0,T.createAuthEndpoint)("/email-otp/verify-email",{method:"POST",body:C,metadata:{openapi:{description:"Verify email with OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean",description:"Indicates if the verification was successful",enum:[!0]},token:{type:"string",nullable:!0,description:"Session token if autoSignInAfterVerification is enabled, otherwise null"},user:{$ref:"#/components/schemas/User"}},required:["status","token","user"]}}}}}}}},async e=>{let t=e.body.email.toLowerCase();if(!I.email().safeParse(t).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);await V(e,n,d("email-verification",t),e.body.otp);let r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.USER_NOT_FOUND);e.context.options.emailVerification?.beforeEmailVerification&&await e.context.options.emailVerification.beforeEmailVerification(r.user,e.request);let i=await e.context.internalAdapter.updateUser(r.user.id,{email:t,emailVerified:!0});if(await e.context.options.emailVerification?.afterEmailVerification?.(i,e.request),e.context.options.emailVerification?.autoSignInAfterVerification){let t=await e.context.internalAdapter.createSession(i.id);return await (0,E.setSessionCookie)(e,{session:t,user:i}),e.json({status:!0,token:t.token,user:(0,A.parseUserOutput)(e.context.options,i)})}let a=await (0,b.getSessionFromCtx)(e);if(a&&i.emailVerified){let t=await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret);await (0,E.setCookieCache)(e,{session:a.session,user:{...a.user,emailVerified:!0}},!!t)}return e.json({status:!0,token:null,user:(0,A.parseUserOutput)(e.context.options,i)})}),signInEmailOTP:(0,T.createAuthEndpoint)("/sign-in/email-otp",{method:"POST",body:D,metadata:{openapi:{operationId:"signInWithEmailOTP",description:"Sign in with email and OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{token:{type:"string",description:"Session token for the authenticated session"},user:{$ref:"#/components/schemas/User"}},required:["token","user"]}}}}}}}},async e=>{let{email:t,otp:r,name:i,image:a,...s}=e.body,c=t.toLowerCase();await V(e,n,d("sign-in",c),r);let l=await e.context.internalAdapter.findUserByEmail(c);if(!l){if(n.disableSignUp)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);let t=(0,A.parseUserInput)(e.context.options,s,"create"),r=await e.context.internalAdapter.createUser({...t,email:c,emailVerified:!0,name:i||"",image:a}),l=await e.context.internalAdapter.createSession(r.id);return await (0,E.setSessionCookie)(e,{session:l,user:r}),e.json({token:l.token,user:(0,A.parseUserOutput)(e.context.options,r)})}l.user.emailVerified||await e.context.internalAdapter.updateUser(l.user.id,{emailVerified:!0});let u=await e.context.internalAdapter.createSession(l.user.id);return await (0,E.setSessionCookie)(e,{session:u,user:l.user}),e.json({token:u.token,user:(0,A.parseUserOutput)(e.context.options,l.user)})}),requestPasswordResetEmailOTP:(0,T.createAuthEndpoint)("/email-otp/request-password-reset",{method:"POST",body:L,metadata:{openapi:{operationId:"requestPasswordResetWithEmailOTP",description:"Request password reset with email and OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",description:"Indicates if the OTP was sent successfully"}}}}}}}}}},async e=>{let t=e.body.email.toLowerCase(),r=d("forget-password",t),i=await v(e,n,t,"forget-password");return await e.context.internalAdapter.findUserByEmail(t)?await e.context.runInBackgroundOrAwait(n.sendVerificationOTP({email:t,otp:i,type:"forget-password"},e)):await e.context.internalAdapter.deleteVerificationByIdentifier(r),e.json({success:!0})}),forgetPasswordEmailOTP:(l=(0,R.deprecate)(()=>{},'The "/forget-password/email-otp" endpoint is deprecated. Please use "/email-otp/request-password-reset" instead. This endpoint will be removed in the next major version.'),(0,T.createAuthEndpoint)("/forget-password/email-otp",{method:"POST",body:N,metadata:{openapi:{operationId:"forgetPasswordWithEmailOTP",description:"Deprecated: Use /email-otp/request-password-reset instead.",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",description:"Indicates if the OTP was sent successfully"}}}}}}}}}},async e=>{l();let t=e.body.email.toLowerCase(),r=d("forget-password",t),i=await v(e,n,t,"forget-password");return await e.context.internalAdapter.findUserByEmail(t)?await e.context.runInBackgroundOrAwait(n.sendVerificationOTP({email:t,otp:i,type:"forget-password"},e)):await e.context.internalAdapter.deleteVerificationByIdentifier(r),e.json({success:!0})})),resetPasswordEmailOTP:(0,T.createAuthEndpoint)("/email-otp/reset-password",{method:"POST",body:B,metadata:{openapi:{operationId:"resetPasswordWithEmailOTP",description:"Reset password with email and OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{let t=e.body.email.toLowerCase();await V(e,n,d("forget-password",t),e.body.otp);let r=await e.context.internalAdapter.findUserByEmail(t,{includeAccounts:!0});if(!r)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.USER_NOT_FOUND);let i=e.context.password.config.minPasswordLength;if(e.body.password.length<i)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.PASSWORD_TOO_SHORT);let a=e.context.password.config.maxPasswordLength;if(e.body.password.length>a)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.PASSWORD_TOO_LONG);let o=await e.context.password.hash(e.body.password);return r.accounts?.find(e=>"credential"===e.providerId)?await e.context.internalAdapter.updatePassword(r.user.id,o):await e.context.internalAdapter.createAccount({userId:r.user.id,providerId:"credential",accountId:r.user.id,password:o}),e.context.options.emailAndPassword?.onPasswordReset&&await e.context.options.emailAndPassword.onPasswordReset({user:r.user},e.request),r.user.emailVerified||await e.context.internalAdapter.updateUser(r.user.id,{emailVerified:!0}),e.context.options.emailAndPassword?.revokeSessionsOnPasswordReset&&await e.context.internalAdapter.deleteSessions(r.user.id),e.json({success:!0})}),requestEmailChangeEmailOTP:(0,T.createAuthEndpoint)("/email-otp/request-email-change",{method:"POST",body:j,use:[b.sensitiveSessionMiddleware],metadata:{openapi:{operationId:"requestEmailChangeWithEmailOTP",description:"Request email change with verification OTP sent to the new email",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{if(!n.changeEmail?.enabled)throw e.context.logger.error("Change email with OTP is disabled."),S.APIError.fromStatus("BAD_REQUEST",{message:"Change email with OTP is disabled"});let t=e.context.session.user.email.toLowerCase(),i=e.body.newEmail.toLowerCase();if(!I.email().safeParse(i).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);if(i===t)throw e.context.logger.error("Email is the same"),S.APIError.fromStatus("BAD_REQUEST",{message:"Email is the same"});if(n.changeEmail?.verifyCurrentEmail){if(!e.body.otp)throw S.APIError.fromStatus("BAD_REQUEST",{message:"OTP is required to verify current email"});let r=await e.context.internalAdapter.findVerificationValue(d("email-verification",t));if(!r)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);let i=d("email-verification",t);if(r.expiresAt<new Date)throw await e.context.internalAdapter.deleteVerificationByIdentifier(i),S.APIError.from("BAD_REQUEST",o.OTP_EXPIRED);let[a,s]=p(r.value),c=n?.allowedAttempts||3;if(s&&parseInt(s)>=c)throw await e.context.internalAdapter.deleteVerificationByIdentifier(i),S.APIError.from("FORBIDDEN",o.TOO_MANY_ATTEMPTS);if(!await y(e,n,a,e.body.otp))throw await e.context.internalAdapter.updateVerificationByIdentifier(i,{value:`${a}:${parseInt(s||"0")+1}`}),S.APIError.from("BAD_REQUEST",o.INVALID_OTP);await e.context.internalAdapter.deleteVerificationByIdentifier(i)}else e.body.otp&&e.context.logger.warn("OTP provided but not required for verifying current email. If you want to require OTP verification for current email, please set the changeEmail.verifyCurrentEmail option to true in the configuration");let a=n.generateOTP({email:i,type:"change-email"},e)||H(n),s=await m(e,n,a);return(await e.context.internalAdapter.createVerificationValue({value:`${s}:0`,identifier:d("change-email",`${t}-${i}`),expiresAt:(0,r.getDate)(n.expiresIn,"sec")}),await e.context.internalAdapter.findUserByEmail(i))?await e.context.internalAdapter.deleteVerificationByIdentifier(d("change-email",`${t}-${i}`)):await e.context.runInBackgroundOrAwait(n.sendVerificationOTP({email:i,otp:a,type:"change-email"},e)),e.json({success:!0})}),changeEmailEmailOTP:(0,T.createAuthEndpoint)("/email-otp/change-email",{method:"POST",body:$,use:[b.sensitiveSessionMiddleware],metadata:{openapi:{operationId:"changeEmailWithEmailOTP",description:"Verify new email with OTP and change the email if verification is successful",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{if(!n.changeEmail?.enabled)throw e.context.logger.error("Change email with OTP is disabled."),S.APIError.fromStatus("BAD_REQUEST",{message:"Change email with OTP is disabled"});let t=e.context.session,r=t.user.email.toLowerCase(),i=e.body.newEmail.toLowerCase();if(!I.email().safeParse(i).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);if(i===r)throw e.context.logger.error("Email is the same"),S.APIError.fromStatus("BAD_REQUEST",{message:"Email is the same"});let a=await e.context.internalAdapter.findVerificationValue(d("change-email",`${r}-${i}`));if(!a)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);let s=d("change-email",`${r}-${i}`);if(a.expiresAt<new Date)throw await e.context.internalAdapter.deleteVerificationByIdentifier(s),S.APIError.from("BAD_REQUEST",o.OTP_EXPIRED);let[c,l]=p(a.value),u=n?.allowedAttempts||3;if(l&&parseInt(l)>=u)throw await e.context.internalAdapter.deleteVerificationByIdentifier(s),S.APIError.from("FORBIDDEN",o.TOO_MANY_ATTEMPTS);if(!await y(e,n,c,e.body.otp))throw await e.context.internalAdapter.updateVerificationByIdentifier(s,{value:`${c}:${parseInt(l||"0")+1}`}),S.APIError.from("BAD_REQUEST",o.INVALID_OTP);await e.context.internalAdapter.deleteVerificationByIdentifier(s);let f=await e.context.internalAdapter.findUserByEmail(r);if(!f)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.USER_NOT_FOUND);if(await e.context.internalAdapter.findUserByEmail(i))throw S.APIError.fromStatus("BAD_REQUEST",{message:"Email already in use"});e.context.options.emailVerification?.beforeEmailVerification&&await e.context.options.emailVerification.beforeEmailVerification(f.user,e.request);let h=await e.context.internalAdapter.updateUser(f.user.id,{email:i,emailVerified:!0});return e.context.options.emailVerification?.afterEmailVerification&&await e.context.options.emailVerification.afterEmailVerification(h,e.request),await (0,E.setSessionCookie)(e,{session:t.session,user:{...t.user,email:i,emailVerified:!0}}),e.json({success:!0})})},hooks:{after:[{matcher:e=>!!(e.path?.startsWith("/sign-up")&&n.sendVerificationOnSignUp&&!n.overrideDefaultEmailVerification),handler:(0,T.createAuthMiddleware)(async e=>{let t=(await s(e))?.user.email;if(t){let a=n.generateOTP({email:t,type:e.body.type},e)||q(n),o=await m(e,n,a);await e.context.internalAdapter.createVerificationValue({value:`${o}:0`,identifier:d("email-verification",t),expiresAt:(0,r.getDate)(n.expiresIn,"sec")}),await e.context.runInBackgroundOrAwait(i.sendVerificationOTP({email:t,otp:a,type:"email-verification"},e))}})}]},rateLimit:[{pathMatcher:e=>"/email-otp/send-verification-otp"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/check-verification-otp"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/verify-email"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/sign-in/email-otp"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/request-password-reset"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/reset-password"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/forget-password/email-otp"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/request-email-change"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/change-email"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3}],options:i,$ERROR_CODES:o})]})}],342573)}];
|
|
422
|
+
</html>`)}),c={method:"POST",headers:{"Content-Type":"application/json"},body:s};try{a=await e.EMAIL_WORKER.fetch("http://internal/send/otp",c)}catch{a=await fetch(`${W.DEV_EMAIL_WORKER_URL}/send/otp`,c)}if(!a.ok){let e=await a.text();throw Error(`EMAIL_WORKER /send/otp failed: ${a.status} ${e}`)}J.info("OTP email sent",{to:t,type:i})}catch(e){throw J.error("OTP email failed",{to:t,type:i,err:e}),e}}}},c=(0,T.createAuthEndpoint)("/email-otp/send-verification-otp",{method:"POST",body:_,metadata:{openapi:{operationId:"sendEmailVerificationOTP",description:"Send a verification OTP to an email",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{if(!n?.sendVerificationOTP)throw e.context.logger.error("send email verification is not implemented"),S.APIError.fromStatus("BAD_REQUEST",{message:"send email verification is not implemented"});let t=e.body.email.toLowerCase();if(!I.email().safeParse(t).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);if("change-email"===e.body.type)throw e.context.logger.error("Use the /email-otp/request-email-change endpoint to send OTP for changing email"),S.APIError.fromStatus("BAD_REQUEST",{message:"Invalid OTP type"});let r=d(e.body.type,t),i=await v(e,n,t,e.body.type),a="sign-in"===e.body.type&&!n.disableSignUp;return await e.context.internalAdapter.findUserByEmail(t)||a?await e.context.runInBackgroundOrAwait(n.sendVerificationOTP({email:t,otp:i,type:e.body.type},e)):await e.context.internalAdapter.deleteVerificationByIdentifier(r),e.json({success:!0})}),{id:"email-otp",version:a.PACKAGE_VERSION,init(e){if(n.overrideDefaultEmailVerification)return{options:{emailVerification:{async sendVerificationEmail(t,r){await e.runInBackgroundOrAwait(c({context:e,request:r,body:{email:t.user.email,type:"email-verification"},ctx:e}))}}}}},endpoints:{sendVerificationOTP:c,createVerificationOTP:(0,T.createAuthEndpoint)({method:"POST",body:O,metadata:{openapi:{operationId:"createEmailVerificationOTP",description:"Create a verification OTP for an email",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"string"}}}}}}}},async e=>{let t=e.body.email.toLowerCase(),i=n.generateOTP({email:t,type:e.body.type},e)||H(n),a=await m(e,n,i);return await e.context.internalAdapter.createVerificationValue({value:`${a}:0`,identifier:d(e.body.type,t),expiresAt:(0,r.getDate)(n.expiresIn,"sec")}),i}),getVerificationOTP:(0,T.createAuthEndpoint)({method:"GET",query:U,metadata:{openapi:{operationId:"getEmailVerificationOTP",description:"Get a verification OTP for an email",responses:{200:{description:"OTP retrieved successfully or not found/expired",content:{"application/json":{schema:{type:"object",properties:{otp:{type:"string",nullable:!0,description:"The stored OTP, or null if not found or expired"}},required:["otp"]}}}}}}}},async e=>{let t=e.query.email.toLowerCase(),r=await e.context.internalAdapter.findVerificationValue(d(e.query.type,t));if(!r||r.expiresAt<new Date)return e.json({otp:null});if("hashed"===n.storeOTP||"object"==typeof n.storeOTP&&"hash"in n.storeOTP)throw S.APIError.fromStatus("BAD_REQUEST",{message:"OTP is hashed, cannot return the plain text OTP"});let[i,a]=p(r.value),o=i;return"encrypted"===n.storeOTP&&(o=await (0,h.symmetricDecrypt)({key:e.context.secretConfig,data:i})),"object"==typeof n.storeOTP&&"decrypt"in n.storeOTP&&(o=await n.storeOTP.decrypt(i)),e.json({otp:o})}),checkVerificationOTP:(0,T.createAuthEndpoint)("/email-otp/check-verification-otp",{method:"POST",body:P,metadata:{openapi:{operationId:"verifyEmailWithOTP",description:"Verify an email with an OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{let t=e.body.email.toLowerCase();if(!I.email().safeParse(t).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);if(!await e.context.internalAdapter.findUserByEmail(t))throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.USER_NOT_FOUND);let r=d(e.body.type,t),i=await e.context.internalAdapter.findVerificationValue(r);if(!i)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);if(i.expiresAt<new Date)throw await e.context.internalAdapter.deleteVerificationByIdentifier(r),S.APIError.from("BAD_REQUEST",o.OTP_EXPIRED);let[a,s]=p(i.value),c=n?.allowedAttempts||3;if(s&&parseInt(s)>=c)throw await e.context.internalAdapter.deleteVerificationByIdentifier(r),S.APIError.from("FORBIDDEN",o.TOO_MANY_ATTEMPTS);if(!await y(e,n,a,e.body.otp))throw await e.context.internalAdapter.updateVerificationByIdentifier(r,{value:`${a}:${parseInt(s||"0")+1}`}),S.APIError.from("BAD_REQUEST",o.INVALID_OTP);return e.json({success:!0})}),verifyEmailOTP:(0,T.createAuthEndpoint)("/email-otp/verify-email",{method:"POST",body:C,metadata:{openapi:{description:"Verify email with OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean",description:"Indicates if the verification was successful",enum:[!0]},token:{type:"string",nullable:!0,description:"Session token if autoSignInAfterVerification is enabled, otherwise null"},user:{$ref:"#/components/schemas/User"}},required:["status","token","user"]}}}}}}}},async e=>{let t=e.body.email.toLowerCase();if(!I.email().safeParse(t).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);await V(e,n,d("email-verification",t),e.body.otp);let r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.USER_NOT_FOUND);e.context.options.emailVerification?.beforeEmailVerification&&await e.context.options.emailVerification.beforeEmailVerification(r.user,e.request);let i=await e.context.internalAdapter.updateUser(r.user.id,{email:t,emailVerified:!0});if(await e.context.options.emailVerification?.afterEmailVerification?.(i,e.request),e.context.options.emailVerification?.autoSignInAfterVerification){let t=await e.context.internalAdapter.createSession(i.id);return await (0,E.setSessionCookie)(e,{session:t,user:i}),e.json({status:!0,token:t.token,user:(0,A.parseUserOutput)(e.context.options,i)})}let a=await (0,b.getSessionFromCtx)(e);if(a&&i.emailVerified){let t=await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret);await (0,E.setCookieCache)(e,{session:a.session,user:{...a.user,emailVerified:!0}},!!t)}return e.json({status:!0,token:null,user:(0,A.parseUserOutput)(e.context.options,i)})}),signInEmailOTP:(0,T.createAuthEndpoint)("/sign-in/email-otp",{method:"POST",body:D,metadata:{openapi:{operationId:"signInWithEmailOTP",description:"Sign in with email and OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{token:{type:"string",description:"Session token for the authenticated session"},user:{$ref:"#/components/schemas/User"}},required:["token","user"]}}}}}}}},async e=>{let{email:t,otp:r,name:i,image:a,...s}=e.body,c=t.toLowerCase();await V(e,n,d("sign-in",c),r);let l=await e.context.internalAdapter.findUserByEmail(c);if(!l){if(n.disableSignUp)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);let t=(0,A.parseUserInput)(e.context.options,s,"create"),r=await e.context.internalAdapter.createUser({...t,email:c,emailVerified:!0,name:i||"",image:a}),l=await e.context.internalAdapter.createSession(r.id);return await (0,E.setSessionCookie)(e,{session:l,user:r}),e.json({token:l.token,user:(0,A.parseUserOutput)(e.context.options,r)})}l.user.emailVerified||await e.context.internalAdapter.updateUser(l.user.id,{emailVerified:!0});let u=await e.context.internalAdapter.createSession(l.user.id);return await (0,E.setSessionCookie)(e,{session:u,user:l.user}),e.json({token:u.token,user:(0,A.parseUserOutput)(e.context.options,l.user)})}),requestPasswordResetEmailOTP:(0,T.createAuthEndpoint)("/email-otp/request-password-reset",{method:"POST",body:L,metadata:{openapi:{operationId:"requestPasswordResetWithEmailOTP",description:"Request password reset with email and OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",description:"Indicates if the OTP was sent successfully"}}}}}}}}}},async e=>{let t=e.body.email.toLowerCase(),r=d("forget-password",t),i=await v(e,n,t,"forget-password");return await e.context.internalAdapter.findUserByEmail(t)?await e.context.runInBackgroundOrAwait(n.sendVerificationOTP({email:t,otp:i,type:"forget-password"},e)):await e.context.internalAdapter.deleteVerificationByIdentifier(r),e.json({success:!0})}),forgetPasswordEmailOTP:(l=(0,R.deprecate)(()=>{},'The "/forget-password/email-otp" endpoint is deprecated. Please use "/email-otp/request-password-reset" instead. This endpoint will be removed in the next major version.'),(0,T.createAuthEndpoint)("/forget-password/email-otp",{method:"POST",body:N,metadata:{openapi:{operationId:"forgetPasswordWithEmailOTP",description:"Deprecated: Use /email-otp/request-password-reset instead.",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",description:"Indicates if the OTP was sent successfully"}}}}}}}}}},async e=>{l();let t=e.body.email.toLowerCase(),r=d("forget-password",t),i=await v(e,n,t,"forget-password");return await e.context.internalAdapter.findUserByEmail(t)?await e.context.runInBackgroundOrAwait(n.sendVerificationOTP({email:t,otp:i,type:"forget-password"},e)):await e.context.internalAdapter.deleteVerificationByIdentifier(r),e.json({success:!0})})),resetPasswordEmailOTP:(0,T.createAuthEndpoint)("/email-otp/reset-password",{method:"POST",body:B,metadata:{openapi:{operationId:"resetPasswordWithEmailOTP",description:"Reset password with email and OTP",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{let t=e.body.email.toLowerCase();await V(e,n,d("forget-password",t),e.body.otp);let r=await e.context.internalAdapter.findUserByEmail(t,{includeAccounts:!0});if(!r)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.USER_NOT_FOUND);let i=e.context.password.config.minPasswordLength;if(e.body.password.length<i)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.PASSWORD_TOO_SHORT);let a=e.context.password.config.maxPasswordLength;if(e.body.password.length>a)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.PASSWORD_TOO_LONG);let o=await e.context.password.hash(e.body.password);return r.accounts?.find(e=>"credential"===e.providerId)?await e.context.internalAdapter.updatePassword(r.user.id,o):await e.context.internalAdapter.createAccount({userId:r.user.id,providerId:"credential",accountId:r.user.id,password:o}),e.context.options.emailAndPassword?.onPasswordReset&&await e.context.options.emailAndPassword.onPasswordReset({user:r.user},e.request),r.user.emailVerified||await e.context.internalAdapter.updateUser(r.user.id,{emailVerified:!0}),e.context.options.emailAndPassword?.revokeSessionsOnPasswordReset&&await e.context.internalAdapter.deleteSessions(r.user.id),e.json({success:!0})}),requestEmailChangeEmailOTP:(0,T.createAuthEndpoint)("/email-otp/request-email-change",{method:"POST",body:j,use:[b.sensitiveSessionMiddleware],metadata:{openapi:{operationId:"requestEmailChangeWithEmailOTP",description:"Request email change with verification OTP sent to the new email",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{if(!n.changeEmail?.enabled)throw e.context.logger.error("Change email with OTP is disabled."),S.APIError.fromStatus("BAD_REQUEST",{message:"Change email with OTP is disabled"});let t=e.context.session.user.email.toLowerCase(),i=e.body.newEmail.toLowerCase();if(!I.email().safeParse(i).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);if(i===t)throw e.context.logger.error("Email is the same"),S.APIError.fromStatus("BAD_REQUEST",{message:"Email is the same"});if(n.changeEmail?.verifyCurrentEmail){if(!e.body.otp)throw S.APIError.fromStatus("BAD_REQUEST",{message:"OTP is required to verify current email"});let r=await e.context.internalAdapter.findVerificationValue(d("email-verification",t));if(!r)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);let i=d("email-verification",t);if(r.expiresAt<new Date)throw await e.context.internalAdapter.deleteVerificationByIdentifier(i),S.APIError.from("BAD_REQUEST",o.OTP_EXPIRED);let[a,s]=p(r.value),c=n?.allowedAttempts||3;if(s&&parseInt(s)>=c)throw await e.context.internalAdapter.deleteVerificationByIdentifier(i),S.APIError.from("FORBIDDEN",o.TOO_MANY_ATTEMPTS);if(!await y(e,n,a,e.body.otp))throw await e.context.internalAdapter.updateVerificationByIdentifier(i,{value:`${a}:${parseInt(s||"0")+1}`}),S.APIError.from("BAD_REQUEST",o.INVALID_OTP);await e.context.internalAdapter.deleteVerificationByIdentifier(i)}else e.body.otp&&e.context.logger.warn("OTP provided but not required for verifying current email. If you want to require OTP verification for current email, please set the changeEmail.verifyCurrentEmail option to true in the configuration");let a=n.generateOTP({email:i,type:"change-email"},e)||H(n),s=await m(e,n,a);return(await e.context.internalAdapter.createVerificationValue({value:`${s}:0`,identifier:d("change-email",`${t}-${i}`),expiresAt:(0,r.getDate)(n.expiresIn,"sec")}),await e.context.internalAdapter.findUserByEmail(i))?await e.context.internalAdapter.deleteVerificationByIdentifier(d("change-email",`${t}-${i}`)):await e.context.runInBackgroundOrAwait(n.sendVerificationOTP({email:i,otp:a,type:"change-email"},e)),e.json({success:!0})}),changeEmailEmailOTP:(0,T.createAuthEndpoint)("/email-otp/change-email",{method:"POST",body:$,use:[b.sensitiveSessionMiddleware],metadata:{openapi:{operationId:"changeEmailWithEmailOTP",description:"Verify new email with OTP and change the email if verification is successful",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{if(!n.changeEmail?.enabled)throw e.context.logger.error("Change email with OTP is disabled."),S.APIError.fromStatus("BAD_REQUEST",{message:"Change email with OTP is disabled"});let t=e.context.session,r=t.user.email.toLowerCase(),i=e.body.newEmail.toLowerCase();if(!I.email().safeParse(i).success)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.INVALID_EMAIL);if(i===r)throw e.context.logger.error("Email is the same"),S.APIError.fromStatus("BAD_REQUEST",{message:"Email is the same"});let a=await e.context.internalAdapter.findVerificationValue(d("change-email",`${r}-${i}`));if(!a)throw S.APIError.from("BAD_REQUEST",o.INVALID_OTP);let s=d("change-email",`${r}-${i}`);if(a.expiresAt<new Date)throw await e.context.internalAdapter.deleteVerificationByIdentifier(s),S.APIError.from("BAD_REQUEST",o.OTP_EXPIRED);let[c,l]=p(a.value),u=n?.allowedAttempts||3;if(l&&parseInt(l)>=u)throw await e.context.internalAdapter.deleteVerificationByIdentifier(s),S.APIError.from("FORBIDDEN",o.TOO_MANY_ATTEMPTS);if(!await y(e,n,c,e.body.otp))throw await e.context.internalAdapter.updateVerificationByIdentifier(s,{value:`${c}:${parseInt(l||"0")+1}`}),S.APIError.from("BAD_REQUEST",o.INVALID_OTP);await e.context.internalAdapter.deleteVerificationByIdentifier(s);let f=await e.context.internalAdapter.findUserByEmail(r);if(!f)throw S.APIError.from("BAD_REQUEST",k.BASE_ERROR_CODES.USER_NOT_FOUND);if(await e.context.internalAdapter.findUserByEmail(i))throw S.APIError.fromStatus("BAD_REQUEST",{message:"Email already in use"});e.context.options.emailVerification?.beforeEmailVerification&&await e.context.options.emailVerification.beforeEmailVerification(f.user,e.request);let h=await e.context.internalAdapter.updateUser(f.user.id,{email:i,emailVerified:!0});return e.context.options.emailVerification?.afterEmailVerification&&await e.context.options.emailVerification.afterEmailVerification(h,e.request),await (0,E.setSessionCookie)(e,{session:t.session,user:{...t.user,email:i,emailVerified:!0}}),e.json({success:!0})})},hooks:{after:[{matcher:e=>!!(e.path?.startsWith("/sign-up")&&n.sendVerificationOnSignUp&&!n.overrideDefaultEmailVerification),handler:(0,T.createAuthMiddleware)(async e=>{let t=(await s(e))?.user.email;if(t){let a=n.generateOTP({email:t,type:e.body.type},e)||q(n),o=await m(e,n,a);await e.context.internalAdapter.createVerificationValue({value:`${o}:0`,identifier:d("email-verification",t),expiresAt:(0,r.getDate)(n.expiresIn,"sec")}),await e.context.runInBackgroundOrAwait(i.sendVerificationOTP({email:t,otp:a,type:"email-verification"},e))}})}]},rateLimit:[{pathMatcher:e=>"/email-otp/send-verification-otp"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/check-verification-otp"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/verify-email"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/sign-in/email-otp"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/request-password-reset"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/reset-password"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/forget-password/email-otp"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/request-email-change"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3},{pathMatcher:e=>"/email-otp/change-email"===e,window:n.rateLimit?.window||60,max:n.rateLimit?.max||3}],options:i,$ERROR_CODES:o})]:[]})}],342573)}];
|
|
423
423
|
|
|
424
424
|
//# sourceMappingURL=_0ih-ceb._.js.map
|