1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[34247],{58429:(e,t,r)=>{var i=r(82737),o=r(90114),a=r(98009),s=r(19890),n=r(55071),c=r(36099),d=r(47366),l=r(67642),p=r(66631),u=r(93834),f=(r(144),r(42099),r(38295));r(84597),r(45708);var m=r(50380),h=r(23994),w=r(95832),g=r(13236),k=r(40284),y=r(3736),b=r(18792);r(12319);var A=r(36677);r(11810),r(74980);var T=r(11534);function x(e){return"-"===e||"^"===e||"$"===e||"+"===e||"."===e||"("===e||")"===e||"|"===e||"["===e||"]"===e||"{"===e||"}"===e||"*"===e||"?"===e||"\\"===e?`\\${e}`:e}function U(e,t){if("string"!=typeof t)throw TypeError(`Sample must be a string, but ${typeof t} given`);return e.test(t)}function E(e,t){if("string"!=typeof e&&!Array.isArray(e))throw TypeError(`The first argument must be a single pattern string or an array of patterns, but ${typeof e} given`);if(("string"==typeof t||"boolean"==typeof t)&&(t={separator:t}),2==arguments.length&&!(void 0===t||"object"==typeof t&&null!==t&&!Array.isArray(t)))throw TypeError(`The second argument must be an options object or a string/boolean separator, but ${typeof t} given`);if("\\"===(t=t||{}).separator)throw Error("\\ is not a valid separator because it is used for escaping. Try setting the separator to `true` instead");let r=function e(t,r=!0){if(Array.isArray(t)){let i=t.map(t=>`^${e(t,r)}$`);return`(?:${i.join("|")})`}let i="",o="",a=".";!0===r?(i="/",o="[/\\\\]",a="[^/\\\\]"):r&&((o=function(e){let t="";for(let r=0;r<e.length;r++)t+=x(e[r]);return t}(i=r)).length>1?(o=`(?:${o})`,a=`((?!${o}).)`):a=`[^${o}]`);let s=r?`${o}+?`:"",n=r?`${o}*?`:"",c=r?t.split(i):[t],d="";for(let e=0;e<c.length;e++){let t=c[e],i=c[e+1],o="";if(t||!(e>0)){if(r&&(o=e===c.length-1?n:"**"!==i?s:""),r&&"**"===t){o&&(d+=0===e?"":o,d+=`(?:${a}*?${o})*?`);continue}for(let e=0;e<t.length;e++){let r=t[e];"\\"===r?e<t.length-1&&(d+=x(t[e+1]),e++):"?"===r?d+=a:"*"===r?d+=`${a}*?`:d+=x(r)}d+=o}}return d}(e,t.separator),i=RegExp(`^${r}$`,t.flags),o=U.bind(null,i);return o.options=t,o.pattern=e,o.regexp=i,o}r(40196),(0,a.c)(async e=>{if(e.request?.method!=="POST"||!e.request)return;let{body:t,query:r,context:i}=e,o=e.headers?.get("origin")||e.headers?.get("referer")||"",a=t?.callbackURL||r?.callbackURL,n=t?.redirectTo,c=t?.errorCallbackURL,d=t?.newUserCallbackURL,l=Array.isArray(i.options.trustedOrigins)?i.trustedOrigins:[...i.trustedOrigins,...await i.options.trustedOrigins?.(e.request)||[]],p=e.headers?.has("cookie"),u=(t,r)=>{if(t&&!l.some(e=>((e,t)=>{if(e.startsWith("/"))return!1;if(t.includes("*"))return t.includes("://")?E(t)((0,h.g)(e)||e):E(t)((0,h.b)(e));let r=(0,h.c)(e);return"http:"!==r&&"https:"!==r&&r?e.startsWith(t):t===(0,h.g)(e)})(t,e)||t?.startsWith("/")&&"origin"!==r&&/^\/(?!\/|\\|%2f|%5c)[\w\-.\+/@]*(?:\?[\w\-.\+/=&%@]*)?$/.test(t)))throw e.context.logger.error(`Invalid ${r}: ${t}`),e.context.logger.info(`If it's a valid URL, please add ${t} to trustedOrigins in your auth config 2`,`Current list of trustedOrigins: ${l}`),new s.LG("FORBIDDEN",{message:`Invalid ${r}`})};p&&!e.context.options.advanced?.disableCSRFCheck&&u(o,"origin"),a&&u(a,"callbackURL"),n&&u(n,"redirectURL"),c&&u(c,"errorCallbackURL"),d&&u(d,"newUserCallbackURL")});let R=e=>(0,a.c)(async t=>{if(!t.request)return;let{context:r}=t,i=e(t),o=Array.isArray(r.options.trustedOrigins)?r.trustedOrigins:[...r.trustedOrigins,...await r.options.trustedOrigins?.(t.request)||[]],a=(e,r)=>{if(e&&!o.some(t=>((e,t)=>{if(e.startsWith("/"))return!1;if(t.includes("*"))return t.includes("://")?E(t)((0,h.g)(e)||e):E(t)((0,h.b)(e));let r=(0,h.c)(e);return"http:"!==r&&"https:"!==r&&r?e.startsWith(t):t===(0,h.g)(e)})(e,t)||e?.startsWith("/")&&"origin"!==r&&/^\/(?!\/|\\|%2f|%5c)[\w\-.\+/@]*(?:\?[\w\-.\+/=&%@]*)?$/.test(e)))throw t.context.logger.error(`Invalid ${r}: ${e}`),t.context.logger.info(`If it's a valid URL, please add ${e} to trustedOrigins in your auth config 3`,`Current list of trustedOrigins: ${o}`),new s.LG("FORBIDDEN",{message:`Invalid ${r}`})};for(let e of Array.isArray(i)?i:[i])a(e,"callbackURL")});async function I(e,t,r,i=3600){return await (0,l.FA)({email:t.toLowerCase(),updateTo:r},e,i)}async function L(e,t){if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new s.LG("BAD_REQUEST",{message:"Verification email isn't enabled"});let r=await I(e.context.secret,t.email,void 0,e.context.options.emailVerification?.expires
3In),i=`${e.context.baseURL}/verify-email?token=${r}&callbackURL=${e.body.callbackURL||"/"}`;await e.context.options.emailVerification.sendVerificationEmail({user:t,url:i,token:r},e.request)}(0,a.a)("/send-verification-email",{method:"POST",body:i.Ik({email:i.Rp().meta({description:"The email to send the verification email to"}),callbackURL:i.Yj().meta({description:"The URL to use for email verification callback"}).optional()}),metadata:{openapi:{description:"Send a verification email to the user",requestBody:{content:{"application/json":{schema:{type:"object",properties:{email:{type:"string",description:"The email to send the verification email to",example:"[email protected]"},callbackURL:{type:"string",description:"The URL to use for email verification callback",example:"https://example.com/callback",nullable:!0}},required:["email"]}}}},responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean",description:"Indicates if the email was sent successfully",example:!0}}}}}},400:{description:"Bad Request",content:{"application/json":{schema:{type:"object",properties:{message:{type:"string",description:"Error message",example:"Verification email isn't enabled"}}}}}}}}}},async e=>{if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new s.LG("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:t}=e.body,r=await (0,a.g)(e);if(!r){let r=await e.context.internalAdapter.findUserByEmail(t);return r&&await L(e,r.user),e.json({status:!0})}if(r?.user.emailVerified)throw new s.LG("BAD_REQUEST",{message:"You can only send a verification email to an unverified email"});if(r?.user.email!==t)throw new s.LG("BAD_REQUEST",{message:"You can only send a verification email to your own email"});return await L(e,r.user),e.json({status:!0})}),(0,a.a)("/verify-email",{method:"GET",query:i.Ik({token:i.Yj().meta({description:"The token to verify the email"}),callbackURL:i.Yj().meta({description:"The URL to redirect to after email verification"}).optional()}),use:[R(e=>e.query.callbackURL)],metadata:{openapi:{description:"Verify the email of the user",parameters:[{name:"token",in:"query",description:"The token to verify the email",required:!0,schema:{type:"string"}},{name:"callbackURL",in:"query",description:"The URL to redirect to after email verification",required:!1,schema:{type:"string"}}],responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{user:{type:"object",properties:{id:{type:"string",description:"User ID"},email:{type:"string",description:"User email"},name:{type:"string",description:"User name"},image:{type:"string",description:"User image URL"},emailVerified:{type:"boolean",description:"Indicates if the user email is verified"},createdAt:{type:"string",description:"User creation date"},updatedAt:{type:"string",description:"User update date"}},required:["id","email","name","image","emailVerified","createdAt","updatedAt"]},status:{type:"boolean",description:"Indicates if the email was verified successfully"}},required:["user","status"]}}}}}}}},async e=>{let t;function r(t){if(e.query.callbackURL){if(e.query.callbackURL.includes("?"))throw e.redirect(`${e.query.callbackURL}&error=${t}`);throw e.redirect(`${e.query.callbackURL}?error=${t}`)}throw new s.LG("UNAUTHORIZED",{message:t})}let{token:o}=e.query;try{t=await (0,u.V)(o,new TextEncoder().encode(e.context.secret),{algorithms:["HS256"]})}catch(e){if(e instanceof g.n)return r("token_expired");return r("invalid_token")}let n=i.Ik({email:i.Yj().email(),updateTo:i.Yj().optional()}).parse(t.payload),c=await e.context.internalAdapter.findUserByEmail(n.email);if(!c)return r("user_not_found");if(n.updateTo){let t=await (0,a.g)(e);if(!t||t.user.email!==n.email){if(e.query.callbackURL)throw e.redirect(`${e.query.callbackURL}?error=unauthorized`);return r("unauthorized")}let i=await e.context.internalAdapter.updateUserByEmail(n.email,{email:n.updateTo,emailVerified:!1},e),o=await I(e.context.secret,n.updateTo);if(await e.context.options.emailVerification?.sendVerificationEmail?.({user:i,url:`${e.context.baseURL}/verify-email?token=${o}&callbackURL=${e.query.callbackURL||"/"}`,token:o},e.request),await (0,w.s)(e,{session:t.session,user:{...t.user,email:n.updateTo,emailVerified:!1}}),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({status:!0,user:{id:i.id,email:i.email,name:i.name,image:i.image,emailVerified:i.emailVerified,createdAt:i.createdAt,updatedAt:i.updatedAt}})}e.context.options.emailVerification?.onEmailVerification&&await e.context.options.emailVerification.onEmailVerification(c.user,e.request);
3let d=await e.context.internalAdapter.updateUserByEmail(n.email,{emailVerified:!0},e);if(e.context.options.emailVerification?.afterEmailVerification&&await e.context.options.emailVerification.afterEmailVerification(d,e.request),e.context.options.emailVerification?.autoSignInAfterVerification){let t=await (0,a.g)(e);if(t&&t.user.email===n.email)await (0,w.s)(e,{session:t.session,user:{...t.user,emailVerified:!0}});else{let t=await e.context.internalAdapter.createSession(c.user.id,e);if(!t)throw new s.LG("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});await (0,w.s)(e,{session:t,user:{...c.user,emailVerified:!0}})}}if(e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({status:!0,user:null})});let v={isAction:!1};async function _(e,t){let r=e.body?.callbackURL||e.context.options.baseURL;if(!r)throw new s.LG("BAD_REQUEST",{message:"callbackURL is required"});let i=(0,m.g)(128),o=(0,m.g)(32),a=JSON.stringify({callbackURL:r,codeVerifier:i,errorURL:e.body?.errorCallbackURL,newUserURL:e.body?.newUserCallbackURL,link:t,expiresAt:Date.now()+6e5,requestSignUp:e.body?.requestSignUp}),n=new Date;n.setMinutes(n.getMinutes()+10);let c=await e.context.internalAdapter.createVerificationValue({value:a,identifier:o,expiresAt:n},e);if(!c)throw e.context.logger.error("Unable to create verification. Make sure the database adapter is properly working and there is a verification table in the database"),new s.LG("INTERNAL_SERVER_ERROR",{message:"Unable to create verification"});return{state:c.identifier,codeVerifier:i}}async function S(e){let t=e.query.state||e.body.state,r=await e.context.internalAdapter.findVerificationValue(t);if(!r){e.context.logger.error("State Mismatch. Verification not found",{state:t});let r=e.context.options.onAPIError?.errorURL||`${e.context.baseURL}/error`;throw e.redirect(`${r}?error=please_restart_the_process`)}let a=i.Ik({callbackURL:i.Yj(),codeVerifier:i.Yj(),errorURL:i.Yj().optional(),newUserURL:i.Yj().optional(),expiresAt:i.ai(),link:i.Ik({email:i.Yj(),userId:o.Yj()}).optional(),requestSignUp:i.zM().optional()}).parse(JSON.parse(r.value));if(a.errorURL||(a.errorURL=`${e.context.baseURL}/error`),a.expiresAt<Date.now()){await e.context.internalAdapter.deleteVerificationValue(r.id);let t=e.context.options.onAPIError?.errorURL||`${e.context.baseURL}/error`;throw e.redirect(`${t}?error=please_restart_the_process`)}return await e.context.internalAdapter.deleteVerificationValue(r.id),a}function O(e,t){return t.options.account?.encryptOAuthTokens&&e?(0,l.vX)({key:t.secret,data:e}):e}async function D(e,{userInfo:t,account:r,callbackURL:i,disableSignUp:o,overrideUserInfo:a}){let n=await e.context.internalAdapter.findOAuthUser(t.email.toLowerCase(),r.accountId,r.providerId).catch(t=>{k.a.error("Better auth was unable to query your database.\nError: ",t);let r=e.context.options.onAPIError?.errorURL||`${e.context.baseURL}/error`;throw e.redirect(`${r}?error=internal_server_error`)}),c=n?.user,d=!c;if(n){let i=n.accounts.find(e=>e.providerId===r.providerId&&e.accountId===r.accountId);if(i){if(e.context.options.account?.updateAccountOnSignIn!==!1){let t=Object.fromEntries(Object.entries({idToken:r.idToken,accessToken:await O(r.accessToken,e.context),refreshToken:await O(r.refreshToken,e.context),accessTokenExpiresAt:r.accessTokenExpiresAt,refreshTokenExpiresAt:r.refreshTokenExpiresAt,scope:r.scope}).filter(([e,t])=>void 0!==t));Object.keys(t).length>0&&await e.context.internalAdapter.updateAccount(i.id,t,e)}
3}else{let i=e.context.options.account?.accountLinking?.trustedProviders;if(!i?.includes(r.providerId)&&!t.emailVerified||e.context.options.account?.accountLinking?.enabled===!1)return A.b&&k.a.warn(`User already exist but account isn't linked to ${r.providerId}. To read more about how account linking works in Better Auth see https://www.better-auth.com/docs/concepts/users-accounts#account-linking.`),{error:"account not linked",data:null};try{await e.context.internalAdapter.linkAccount({providerId:r.providerId,accountId:t.id.toString(),userId:n.user.id,accessToken:await O(r.accessToken,e.context),refreshToken:await O(r.refreshToken,e.context),idToken:r.idToken,accessTokenExpiresAt:r.accessTokenExpiresAt,refreshTokenExpiresAt:r.refreshTokenExpiresAt,scope:r.scope},e)}catch(e){return k.a.error("Unable to link account",e),{error:"unable to link account",data:null}}}if(a){let{id:r,...i}=t;await e.context.internalAdapter.updateUser(n.user.id,{...i,email:t.email.toLowerCase(),emailVerified:t.email.toLowerCase()===n.user.email&&n.user.emailVerified||t.emailVerified})}}else{if(o)return{error:"signup disabled",data:null,isRegister:!1};try{let{id:o,...a}=t;if(c=await e.context.internalAdapter.createOAuthUser({...a,email:t.email.toLowerCase()},{accessToken:await O(r.accessToken,e.context),refreshToken:await O(r.refreshToken,e.context),idToken:r.idToken,accessTokenExpiresAt:r.accessTokenExpiresAt,refreshTokenExpiresAt:r.refreshTokenExpiresAt,scope:r.scope,providerId:r.providerId,accountId:t.id.toString()},e).then(e=>e?.user),!t.emailVerified&&c&&e.context.options.emailVerification?.sendOnSignUp){let t=await I(e.context.secret,c.email,void 0,e.context.options.emailVerification?.expiresIn),r=`${e.context.baseURL}/verify-email?token=${t}&callbackURL=${i}`;await e.context.options.emailVerification?.sendVerificationEmail?.({user:c,url:r,token:t},e.request)}}catch(e){if(k.a.error(e),e instanceof s.LG)return{error:e.message,data:null,isRegister:!1};return{error:"unable to create user",data:null,isRegister:!1}}}if(!c)return{error:"unable to create user",data:null,isRegister:!1};let l=await e.context.internalAdapter.createSession(c.id,e);return l?{data:{session:l,user:c},error:null,isRegister:d}:{error:"unable to create session",data:null,isRegister:!1}}let j=i.k5(["apple","atlassian","cognito","discord","facebook","figma","github","microsoft","google","huggingface","slack","spotify","twitch","twitter","dropbox","kick","linear","linkedin","gitlab","tiktok","reddit","roblox","salesforce","vk","zoom","notion","kakao","naver","line","paypal"]).or(i.Yj());(0,a.a)("/sign-in/social",{method:"POST",body:i.Ik({callbackURL:i.Yj().meta({description:"Callback URL to redirect to after the user has signed in"}).optional(),newUserCallbackURL:i.Yj().optional(),errorCallbackURL:i.Yj().meta({description:"Callback URL to redirect to if an error happens"}).optional(),provider:j,disableRedirect:i.zM().meta({description:"Disable automatic redirection to the provider. Useful for handling the redirection yourself"}).optional(),idToken:i.lq(i.Ik({token:i.Yj().meta({description:"ID token from the provider"}),nonce:i.Yj().meta({description:"Nonce used to generate the token"}).optional(),accessToken:i.Yj().meta({description:"Access token from the provider"}).optional(),refreshToken:i.Yj().meta({description:"Refresh token from the provider"}).optional(),expiresAt:i.ai().meta({description:"Expiry date of the token"}).optional()})),scopes:i.YO(i.Yj()).meta({description:"Array of scopes to request from the provider. This will override the default scopes passed."}).optional(),requestSignUp:i.zM().meta({description:"Explicitly request sign-up. Useful when disableImplicitSignUp is true for this provider"}).optional(),loginHint:i.Yj().meta({description:"The login hint to use for the authorization code request"}).optional()}),metadata:{openapi:{description:"Sign in with a social provider",operationId:"socialSignIn",responses:{200:{description:"Success - Returns either session details or redirect URL",content:{"application/json":{schema:{type:"object",description:"Session response when idToken is provided",properties:{redirect:{type:"boolean",enum:[!1]},token:{type:"string",description:"Session token",url:{type:"null",nullable:!0},user:{type:"object",properties:{id:{type:"string"},email:{type:"string"},name:{type:"string",nullable:!0},image:{type:"string",nullable:!0},emailVerified:{type:"boolean"},createdAt:{type:"string",format:"date-time"},updatedAt:{type:"string",format:"date-time"}},required:["id","email","emailVerified","createdAt","updatedAt"]}}},required:["redirect","token","user"]}}}}}}}},async e=>{let t=e.context.socialProviders.find(t=>
3t.id===e.body.provider);if(!t)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new s.LG("NOT_FOUND",{message:a.B.PROVIDER_NOT_FOUND});if(e.body.idToken){if(!t.verifyIdToken)throw e.context.logger.error("Provider does not support id token verification",{provider:e.body.provider}),new s.LG("NOT_FOUND",{message:a.B.ID_TOKEN_NOT_SUPPORTED});let{token:r,nonce:i}=e.body.idToken;if(!await t.verifyIdToken(r,i))throw e.context.logger.error("Invalid id token",{provider:e.body.provider}),new s.LG("UNAUTHORIZED",{message:a.B.INVALID_TOKEN});let o=await t.getUserInfo({idToken:r,accessToken:e.body.idToken.accessToken,refreshToken:e.body.idToken.refreshToken});if(!o||!o?.user)throw e.context.logger.error("Failed to get user info",{provider:e.body.provider}),new s.LG("UNAUTHORIZED",{message:a.B.FAILED_TO_GET_USER_INFO});if(!o.user.email)throw e.context.logger.error("User email not found",{provider:e.body.provider}),new s.LG("UNAUTHORIZED",{message:a.B.USER_EMAIL_NOT_FOUND});let n=await D(e,{userInfo:{...o.user,email:o.user.email,id:String(o.user.id),name:o.user.name||"",image:o.user.image,emailVerified:o.user.emailVerified||!1},account:{providerId:t.id,accountId:String(o.user.id),accessToken:e.body.idToken.accessToken},callbackURL:e.body.callbackURL,disableSignUp:t.disableImplicitSignUp&&!e.body.requestSignUp||t.disableSignUp});if(n.error)throw new s.LG("UNAUTHORIZED",{message:n.error});return await (0,w.s)(e,n.data),e.json({redirect:!1,token:n.data.session.token,url:void 0,user:{id:n.data.user.id,email:n.data.user.email,name:n.data.user.name,image:n.data.user.image,emailVerified:n.data.user.emailVerified,createdAt:n.data.user.createdAt,updatedAt:n.data.user.updatedAt}})}let{codeVerifier:r,state:i}=await _(e),o=await t.createAuthorizationURL({state:i,codeVerifier:r,redirectURI:`${e.context.baseURL}/callback/${t.id}`,scopes:e.body.scopes,loginHint:e.body.loginHint});return e.json({url:o.toString(),redirect:!e.body.disableRedirect})}),(0,a.a)("/sign-in/email",{method:"POST",body:i.Ik({email:i.Yj().meta({description:"Email of the user"}),password:i.Yj().meta({description:"Password of the user"}),callbackURL:i.Yj().meta({description:"Callback URL to use as a redirect for email verification"}).optional(),rememberMe:i.zM().meta({description:"If this is false, the session will not be remembered. Default is `true`."}).default(!0).optional()}),metadata:{openapi:{description:"Sign in with email and password",responses:{200:{description:"Success - Returns either session details or redirect URL",content:{"application/json":{schema:{type:"object",description:"Session response when idToken is provided",properties:{redirect:{type:"boolean",enum:[!1]},token:{type:"string",description:"Session token"},url:{type:"null",nullable:!0},user:{type:"object",properties:{id:{type:"string"},email:{type:"string"},name:{type:"string",nullable:!0},image:{type:"string",nullable:!0},emailVerified:{type:"boolean"},createdAt:{type:"string",format:"date-time"},updatedAt:{type:"string",format:"date-time"}},required:["id","email","emailVerified","createdAt","updatedAt"]}},required:["redirect","token","user"]}}}}}}}},async e=>{if(!e.context.options?.emailAndPassword?.enabled)throw e.context.logger.error("Email and password is not enabled. Make sure to enable it in the options on you `auth.ts` file. Check `https://better-auth.com/docs/authentication/email-password` for more!"),new s.LG("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:t,password:r}=e.body;if(!i.Yj().email().safeParse(t).success)throw new s.LG("BAD_REQUEST",{message:a.B.INVALID_EMAIL});let o=await e.context.internalAdapter.findUserByEmail(t,{includeAccounts:!0});if(!o)throw await e.context.password.hash(r),e.context.logger.error("User not found",{email:t}),new s.LG("UNAUTHORIZED",{message:a.B.INVALID_EMAIL_OR_PASSWORD});let n=o.accounts.find(e=>"credential"===e.providerId);if(!n)throw e.context.logger.error("Credential account not found",{email:t}),new s.LG("UNAUTHORIZED",{message:a.B.INVALID_EMAIL_OR_PASSWORD});let c=n?.password;if(!c)throw e.context.logger.error("Password not found",{email:t}),new s.LG("UNAUTHORIZED",{message:a.B.INVALID_EMAIL_OR_PASSWORD});if(!await e.context.password.verify({hash:c,password:r}))throw e.context.logger.error("Invalid password"),new s.LG("UNAUTHORIZED",{message:a.B.INVALID_EMAIL_OR_PASSWORD});if(e.context.options?.emailAndPassword?.requireEmailVerification&&!o.user.emailVerified){if(!e.context.options?.emailVerification?.sendVerificationEmail)throw new s.LG("FORBIDDEN",{message:a.B.EMAIL_NOT_VERIFIED});if(e.context.options?.emailVerification?.sendOnSignIn){let t=await I(e.context.secret,o.user.email,void 0,e.context.options.emailVerification?.expires
3In),r=`${e.context.baseURL}/verify-email?token=${t}&callbackURL=${e.body.callbackURL||"/"}`;await e.context.options.emailVerification.sendVerificationEmail({user:o.user,url:r,token:t},e.request)}throw new s.LG("FORBIDDEN",{message:a.B.EMAIL_NOT_VERIFIED})}let d=await e.context.internalAdapter.createSession(o.user.id,e,!1===e.body.rememberMe);if(!d)throw e.context.logger.error("Failed to create session"),new s.LG("UNAUTHORIZED",{message:a.B.FAILED_TO_CREATE_SESSION});return await (0,w.s)(e,{session:d,user:o.user},!1===e.body.rememberMe),e.json({redirect:!!e.body.callbackURL,token:d.token,url:e.body.callbackURL,user:{id:o.user.id,email:o.user.email,name:o.user.name,image:o.user.image,emailVerified:o.user.emailVerified,createdAt:o.user.createdAt,updatedAt:o.user.updatedAt}})});let V=i.Ik({code:i.Yj().optional(),error:i.Yj().optional(),device_id:i.Yj().optional(),error_description:i.Yj().optional(),state:i.Yj().optional(),user:i.Yj().optional()});function N(e,t,r){let i=t?new URL(t,e.baseURL):new URL(`${e.baseURL}/error`);return r&&Object.entries(r).forEach(([e,t])=>i.searchParams.set(e,t)),i.href}(0,a.a)("/callback/:id",{method:["GET","POST"],body:V.optional(),query:V.optional(),metadata:v},async e=>{let t,r,i,o=e.context.options.onAPIError?.errorURL||`${e.context.baseURL}/error`;try{if("GET"===e.method)t=V.parse(e.query);else if("POST"===e.method)t=V.parse(e.body);else throw Error("Unsupported method")}catch(t){throw e.context.logger.error("INVALID_CALLBACK_REQUEST",t),e.redirect(`${o}?error=invalid_callback_request`)}let{code:a,error:s,state:n,error_description:c,device_id:d}=t;if(s)throw e.redirect(`${o}?error=${s}&error_description=${c}`);if(!n)throw e.context.logger.error("State not found",s),e.redirect(`${o}?error=state_not_found`);let{codeVerifier:l,callbackURL:p,link:u,errorURL:f,newUserURL:m,requestSignUp:h}=await S(e);function g(t){let r=f||o;throw r=r.includes("?")?`${r}&error=${t}`:`${r}?error=${t}`,e.redirect(r)}if(!a)throw e.context.logger.error("Code not found"),g("no_code");let k=e.context.socialProviders.find(t=>t.id===e.params.id);if(!k)throw e.context.logger.error("Oauth provider with id",e.params.id,"not found"),g("oauth_provider_not_found");try{r=await k.validateAuthorizationCode({code:a,codeVerifier:l,deviceId:d,redirectURI:`${e.context.baseURL}/callback/${k.id}`})}catch(t){throw e.context.logger.error("",t),g("invalid_code")}let b=await k.getUserInfo({...r,user:e.body?.user?(0,y.s)(e.body.user):void 0}).then(e=>e?.user);if(!b)return e.context.logger.error("Unable to get user info"),g("unable_to_get_user_info");if(!p)throw e.context.logger.error("No callback URL found"),g("no_callback_url");if(u){let t,i=e.context.options.account?.accountLinking?.trustedProviders;if(!i?.includes(k.id)&&!b.emailVerified||e.context.options.account?.accountLinking?.enabled===!1)return e.context.logger.error("Unable to link account - untrusted provider"),g("unable_to_link_account");if(b.email!==u.email&&e.context.options.account?.accountLinking?.allowDifferentEmails!==!0)return g("email_doesn't_match");let o=await e.context.internalAdapter.findAccount(String(b.id));if(o){if(o.userId.toString()!==u.userId.toString())return g("account_already_linked_to_different_user");let t=Object.fromEntries(Object.entries({accessToken:await O(r.accessToken,e.context),refreshToken:await O(r.refreshToken,e.context),idToken:r.idToken,accessTokenExpiresAt:r.accessTokenExpiresAt,refreshTokenExpiresAt:r.refreshTokenExpiresAt,scope:r.scopes?.join(",")}).filter(([e,t])=>void 0!==t));await e.context.internalAdapter.updateAccount(o.id,t)}else if(!await e.context.internalAdapter.createAccount({userId:u.userId,providerId:k.id,accountId:String(b.id),...r,accessToken:await O(r.accessToken,e.context),refreshToken:await O(r.refreshToken,e.context),scope:r.scopes?.join(",")},e))return g("unable_to_link_account");try{t=p.toString()}catch{t=p}throw e.redirect(t)}if(!b.email)return e.context.logger.error("Provider did not return email. This could be due to misconfiguration in the provider settings."),g("email_not_found");let A=await D(e,{userInfo:{...b,id:String(b.id),email:b.email,name:b.name||b.email},account:{providerId:k.id,accountId:String(b.id),...r,scope:r.scopes?.join(",")},callbackURL:p,disableSignUp:k.disableImplicitSignUp&&!h||k.options?.disableSignUp,overrideUserInfo:k.options?.overrideUserInfoOnSignIn});if(A.error)return e.context.logger.error(A.error.split(" ").join("_")),g(A.error.split(" ").join("_"));let{session:T,user:x}=A.data;await (0,w.s)(e,{session:T,user:x});try{i=(A.isRegister&&m||p).toString()}catch{i=A.isRegister&&m||p}throw e.redirect(i)}),(0,a.a)("/sign-out",{method:"POST",requireHeaders:!0,metadata:{openapi:{description:"Sign out the current user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"}}}}}}}}}},async e=>{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);
3if(!t)throw(0,w.d)(e),new s.LG("BAD_REQUEST",{message:a.B.FAILED_TO_GET_SESSION});return await e.context.internalAdapter.deleteSession(t),(0,w.d)(e),e.json({success:!0})}),(0,a.a)("/request-password-reset",{method:"POST",body:i.Ik({email:i.Rp().meta({description:"The email address of the user to send a password reset email to"}),redirectTo:i.Yj().meta({description:"The URL to redirect the user to reset their password. If the token isn't valid or expired, it'll be redirected with a query parameter `?error=INVALID_TOKEN`. If the token is valid, it'll be redirected with a query parameter `?token=VALID_TOKEN"}).optional()}),metadata:{openapi:{description:"Send a password reset email to the user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean"},message:{type:"string"}}}}}}}}}},async e=>{if(!e.context.options.emailAndPassword?.sendResetPassword)throw e.context.logger.error("Reset password isn't enabled.Please pass an emailAndPassword.sendResetPassword function in your auth config!"),new s.LG("BAD_REQUEST",{message:"Reset password isn't enabled"});let{email:t,redirectTo:r}=e.body,i=await e.context.internalAdapter.findUserByEmail(t,{includeAccounts:!0});if(!i)return e.context.logger.error("Reset Password: User not found",{email:t}),e.json({status:!0,message:"If this email exists in our system, check your email for the reset link"});let o=(0,n.g)(e.context.options.emailAndPassword.resetPasswordTokenExpiresIn||3600,"sec"),a=(0,b.g)(24);await e.context.internalAdapter.createVerificationValue({value:i.user.id,identifier:`reset-password:${a}`,expiresAt:o},e);let c=r?encodeURIComponent(r):"",d=`${e.context.baseURL}/reset-password/${a}?callbackURL=${c}`;return await e.context.options.emailAndPassword.sendResetPassword({user:i.user,url:d,token:a},e.request),e.json({status:!0})}),(0,a.a)("/forget-password",{method:"POST",body:i.Ik({email:i.Yj().email().meta({description:"The email address of the user to send a password reset email to"}),redirectTo:i.Yj().meta({description:"The URL to redirect the user to reset their password. If the token isn't valid or expired, it'll be redirected with a query parameter `?error=INVALID_TOKEN`. If the token is valid, it'll be redirected with a query parameter `?token=VALID_TOKEN"}).optional()}),metadata:{openapi:{description:"Send a password reset email to the user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean"},message:{type:"string"}}}}}}}}}},async e=>{if(!e.context.options.emailAndPassword?.sendResetPassword)throw e.context.logger.error("Reset password isn't enabled.Please pass an emailAndPassword.sendResetPassword function in your auth config!"),new s.LG("BAD_REQUEST",{message:"Reset password isn't enabled"});let{email:t,redirectTo:r}=e.body,i=await e.context.internalAdapter.findUserByEmail(t,{includeAccounts:!0});if(!i)return e.context.logger.error("Reset Password: User not found",{email:t}),e.json({status:!0,message:"If this email exists in our system, check your email for the reset link"});let o=(0,n.g)(e.context.options.emailAndPassword.resetPasswordTokenExpiresIn||3600,"sec"),a=(0,b.g)(24);await e.context.internalAdapter.createVerificationValue({value:i.user.id,identifier:`reset-password:${a}`,expiresAt:o},e);let c=r?encodeURIComponent(r):"",d=`${e.context.baseURL}/reset-password/${a}?callbackURL=${c}`;return await e.context.options.emailAndPassword.sendResetPassword({user:i.user,url:d,token:a},e.request),e.json({status:!0})}),(0,a.a)("/reset-password/:token",{method:"GET",query:i.Ik({callbackURL:i.Yj().meta({description:"The URL to redirect the user to reset their password"})}),use:[R(e=>e.query.callbackURL)],metadata:{openapi:{description:"Redirects the user to the callback URL with the token",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{token:{type:"string"}}}}}}}}}},async e=>{let{token:t}=e.params,{callbackURL:r}=e.query;if(!t||!r)throw e.redirect(N(e.context,r,{error:"INVALID_TOKEN"}));
3let i=await e.context.internalAdapter.findVerificationValue(`reset-password:${t}`);if(!i||i.expiresAt<new Date)throw e.redirect(N(e.context,r,{error:"INVALID_TOKEN"}));throw e.redirect(function(e,t,r){let i=new URL(t,e.baseURL);return r&&Object.entries(r).forEach(([e,t])=>i.searchParams.set(e,t)),i.href}(e.context,r,{token:t}))}),(0,a.a)("/reset-password",{method:"POST",query:i.Ik({token:i.Yj().optional()}).optional(),body:i.Ik({newPassword:i.Yj().meta({description:"The new password to set"}),token:i.Yj().meta({description:"The token to reset the password"}).optional()}),metadata:{openapi:{description:"Reset the password for a user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean"}}}}}}}}}},async e=>{let t=e.body.token||e.query?.token;if(!t)throw new s.LG("BAD_REQUEST",{message:a.B.INVALID_TOKEN});let{newPassword:r}=e.body,i=e.context.password?.config.minPasswordLength,o=e.context.password?.config.maxPasswordLength;if(r.length<i)throw new s.LG
3("BAD_REQUEST",{message:a.B.PASSWORD_TOO_SHORT});if(r.length>o)throw new s.LG("BAD_REQUEST",{message:a.B.PASSWORD_TOO_LONG});let n=`reset-password:${t}`,c=await e.context.internalAdapter.findVerificationValue(n);if(!c||c.expiresAt<new Date)throw new s.LG("BAD_REQUEST",{message:a.B.INVALID_TOKEN});let d=c.value,l=await e.context.password.hash(r);if((await e.context.internalAdapter.findAccounts(d)).find(e=>"credential"===e.providerId)?await e.context.internalAdapter.updatePassword(d,l,e):await e.context.internalAdapter.createAccount({userId:d,providerId:"credential",password:l,accountId:d},e),await e.context.internalAdapter.deleteVerificationValue(c.id),e.context.options.emailAndPassword?.onPasswordReset){let t=await e.context.internalAdapter.findUserById(d);t&&await e.context.options.emailAndPassword.onPasswordReset({user:t},e.request)}return e.context.options.emailAndPassword?.revokeSessionsOnPasswordReset&&await e.context.internalAdapter.deleteSessions(d),e.json({status:!0})}),(0,a.a)("/change-password",{method:"POST",body:i.Ik({newPassword:i.Yj().meta({description:"The new password to set"}),currentPassword:i.Yj().meta({description:"The current password is required"}),revokeOtherSessions:i.zM().meta({description:"Must be a boolean value"}).optional()}),use:[a.s],metadata:{openapi:{description:"Change the password of the user",responses:{200:{description:"Password successfully changed",content:{"application/json":{schema:{type:"object",properties:{token:{type:"string",nullable:!0,description:"New session token if other sessions were revoked"},user:{type:"object",properties:{id:{type:"string",description:"The unique identifier of the user"},email:{type:"string",format:"email",description:"The email address of the user"},name:{type:"string",description:"The name of the user"},image:{type:"string",format:"uri",nullable:!0,description:"The profile image URL of the user"},emailVerified:{type:"boolean",description:"Whether the email has been verified"},createdAt:{type:"string",format:"date-time",description:"When the user was created"},updatedAt:{type:"string",format:"date-time",description:"When the user was last updated"}},required:["id","email","name","emailVerified","createdAt","updatedAt"]}},required:["user"]}}}}}}}},async e=>{let{newPassword:t,currentPassword:r,revokeOtherSessions:i}=e.body,o=e.context.session,n=e.context.password.config.minPasswordLength;if(t.length<n)throw e.context.logger.error("Password is too short"),new s.LG("BAD_REQUEST",{message:a.B.PASSWORD_TOO_SHORT});let c=e.context.password.config.maxPasswordLength;if(t.length>c)throw e.context.logger.error("Password is too long"),new s.LG("BAD_REQUEST",{message:a.B.PASSWORD_TOO_LONG});let d=(await e.context.internalAdapter.findAccounts(o.user.id)).find(e=>"credential"===e.providerId&&e.password);if(!d||!d.password)throw new s.LG("BAD_REQUEST",{message:a.B.CREDENTIAL_ACCOUNT_NOT_FOUND});let l=await e.context.password.hash(t);if(!await e.context.password.verify({hash:d.password,password:r}))throw new s.LG("BAD_REQUEST",{message:a.B.INVALID_PASSWORD});await e.context.internalAdapter.updateAccount(d.id,{password:l});let p=null;if(i){await e.context.internalAdapter.deleteSessions(o.user.id);let t=await e.context.internalAdapter.createSession(o.user.id,e);if(!t)throw new s.LG("INTERNAL_SERVER_ERROR",{message:a.B.FAILED_TO_GET_SESSION});await (0,w.s)(e,{session:t,user:o.user}),p=t.token}return e.json({token:p,user:{id:o.user.id,email:o.user.email,name:o.user.name,image:o.user.image,emailVerified:o.user.emailVerified,createdAt:o.user.createdAt,updatedAt:o.user.updatedAt}})}),(0,a.a)("/set-password",{method:"POST",body:i.Ik({newPassword:i.Yj().meta({description:"The new password to set is required"})}),metadata:{SERVER_ONLY:!0},use:[a.s]},async e=>{let{newPassword:t}=e.body,r=e.context.session,i=e.context.password.config.minPasswordLength;if(t.length<i)throw e.context.logger.error("Password is too short"),new s.LG("BAD_REQUEST",{message:a.B.PASSWORD_TOO_SHORT});let o=e.context.password.config.maxPasswordLength;if(t.length>o)throw e.context.logger.error("Password is too long"),new s.LG("BAD_REQUEST",{message:a.B.PASSWORD_TOO_LONG});
3let n=(await e.context.internalAdapter.findAccounts(r.user.id)).find(e=>"credential"===e.providerId&&e.password),c=await e.context.password.hash(t);if(!n)return await e.context.internalAdapter.linkAccount({userId:r.user.id,providerId:"credential",accountId:r.user.id,password:c},e),e.json({status:!0});throw new s.LG("BAD_REQUEST",{message:"user already has a password"})}),(0,a.a)("/delete-user",{method:"POST",use:[a.s],body:i.Ik({callbackURL:i.Yj().meta({description:"The callback URL to redirect to after the user is deleted"}).optional(),password:i.Yj().meta({description:"The password of the user is required to delete the user"}).optional(),token:i.Yj().meta({description:"The token to delete the user is required"}).optional()}),metadata:{openapi:{description:"Delete the user",responses:{200:{description:"User deletion processed successfully",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",description:"Indicates if the operation was successful"},message:{type:"string",enum:["User deleted","Verification email sent"],description:"Status message of the deletion process"}},required:["success","message"]}}}}}}}},async e=>{if(!e.context.options.user?.deleteUser?.enabled)throw e.context.logger.error("Delete user is disabled. Enable it in the options",{session:e.context.session}),new s.LG("NOT_FOUND");let t=e.context.session;if(e.body.password){let r=(await e.context.internalAdapter.findAccounts(t.user.id)).find(e=>"credential"===e.providerId&&e.password);if(!r||!r.password)throw new s.LG("BAD_REQUEST",{message:a.B.CREDENTIAL_ACCOUNT_NOT_FOUND});if(!await e.context.password.verify({hash:r.password,password:e.body.password}))throw new s.LG("BAD_REQUEST",{message:a.B.INVALID_PASSWORD})}if(e.body.token)return await P({...e,query:{token:e.body.token}}),e.json({success:!0,message:"User deleted"});if(e.context.options.user.deleteUser?.sendDeleteAccountVerification){let r=(0,m.g)(32,"0-9","a-z");await e.context.internalAdapter.createVerificationValue({value:t.user.id,identifier:`delete-account-${r}`,expiresAt:new Date(Date.now()+1e3*(e.context.options.user.deleteUser?.deleteTokenExpiresIn||86400))},e);let i=`${e.context.baseURL}/delete-user/callback?token=${r}&callbackURL=${e.body.callbackURL||"/"}`;return await e.context.options.user.deleteUser.sendDeleteAccountVerification({user:t.user,url:i,token:r},e.request),e.json({success:!0,message:"Verification email sent"})}if(!e.body.password&&0!==e.context.sessionConfig.freshAge){let r=new Date(t.session.createdAt).getTime(),i=1e3*e.context.sessionConfig.freshAge;if(Date.now()-r>1e3*i)throw new s.LG("BAD_REQUEST",{message:a.B.SESSION_EXPIRED})}let r=e.context.options.user.deleteUser?.beforeDelete;r&&await r(t.user,e.request),await e.context.internalAdapter.deleteUser(t.user.id),await e.context.internalAdapter.deleteSessions(t.user.id),await e.context.internalAdapter.deleteAccounts(t.user.id),(0,w.d)(e);let i=e.context.options.user.deleteUser?.afterDelete;return i&&await i(t.user,e.request),e.json({success:!0,message:"User deleted"})});let P=(0,a.a)("/delete-user/callback",{method:"GET",query:i.Ik({token:i.Yj().meta({description:"The token to verify the deletion request"}),callbackURL:i.Yj().meta({description:"The URL to redirect to after deletion"}).optional()}),use:[R(e=>e.query.callbackURL)],metadata:{openapi:{description:"Callback to complete user deletion with verification token",responses:{200:{description:"User successfully deleted",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",description:"Indicates if the deletion was successful"},message:{type:"string",enum:["User deleted"],description:"Confirmation message"}},required:["success","message"]}}}}}}}},async e=>{if(!e.context.options.user?.deleteUser?.enabled)throw e.context.logger.error("Delete user is disabled. Enable it in the options"),new s.LG("NOT_FOUND");let t=await (0,a.g)(e);if(!t)throw new s.LG("NOT_FOUND",{message:a.B.FAILED_TO_GET_USER_INFO});let r=await e.context.internalAdapter.findVerificationValue(`delete-account-${e.query.token}`);if(!r||r.expiresAt<new Date||r.value!==t.user.id)throw new s.LG("NOT_FOUND",{message:a.B.INVALID_TOKEN});let i=e.context.options.user.deleteUser?.beforeDelete;
3i&&await i(t.user,e.request),await e.context.internalAdapter.deleteUser(t.user.id),await e.context.internalAdapter.deleteSessions(t.user.id),await e.context.internalAdapter.deleteAccounts(t.user.id),await e.context.internalAdapter.deleteVerificationValue(r.id),(0,w.d)(e);let o=e.context.options.user.deleteUser?.afterDelete;if(o&&await o(t.user,e.request),e.query.callbackURL)throw e.redirect(e.query.callbackURL||"/");return e.json({success:!0,message:"User deleted"})});(0,a.a)("/change-email",{method:"POST",body:i.Ik({newEmail:i.Rp().meta({description:"The new email address to set must be a valid email address"}),callbackURL:i.Yj().meta({description:"The URL to redirect to after email verification"}).optional()}),use:[a.s],metadata:{openapi:{responses:{200:{description:"Email change request processed successfully",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean",description:"Indicates if the request was successful"},message:{type:"string",enum:["Email updated","Verification email sent"],description:"Status message of the email change process",nullable:!0}},required:["status"]}}}},422:{description:"Unprocessable Entity. Email already exists",content:{"application/json":{schema:{type:"object",properties:{message:{type:"string"}}}}}}}}}},async e=>{if(!e.context.options.user?.changeEmail?.enabled)throw e.context.logger.error("Change email is disabled."),new s.LG("BAD_REQUEST",{message:"Change email is disabled"});let t=e.body.newEmail.toLowerCase();if(t===e.context.session.user.email)throw e.context.logger.error("Email is the same"),new s.LG("BAD_REQUEST",{message:"Email is the same"});if(await e.context.internalAdapter.findUserByEmail(t))throw e.context.logger.error("Email already exists"),new s.LG("BAD_REQUEST",{message:"Couldn't update your email"});if(!0!==e.context.session.user.emailVerified){if(await e.context.internalAdapter.findUserByEmail(t))throw new s.LG("UNPROCESSABLE_ENTITY",{message:a.B.USER_ALREADY_EXISTS});if(await e.context.internalAdapter.updateUserByEmail(e.context.session.user.email,{email:t},e),await (0,w.s)(e,{session:e.context.session.session,user:{...e.context.session.user,email:t}}),e.context.options.emailVerification?.sendVerificationEmail){let r=await I(e.context.secret,t,void 0,e.context.options.emailVerification?.expiresIn),i=`${e.context.baseURL}/verify-email?token=${r}&callbackURL=${e.body.callbackURL||"/"}`;await e.context.options.emailVerification.sendVerificationEmail({user:{...e.context.session.user,email:t},url:i,token:r},e.request)}return e.json({status:!0})}if(!e.context.options.user.changeEmail.sendChangeEmailVerification)throw e.context.logger.error("Verification email isn't enabled."),new s.LG("BAD_REQUEST",{message:"Verification email isn't enabled"});let r=await I(e.context.secret,e.context.session.user.email,t,e.context.options.emailVerification?.expiresIn),i=`${e.context.baseURL}/verify-email?token=${r}&callbackURL=${e.body.callbackURL||"/"}`;return await e.context.options.user.changeEmail.sendChangeEmailVerification({user:e.context.session.user,newEmail:t,url:i,token:r},e.request),e.json({status:!0})}),(0,a.a)("/error",{method:"GET",metadata:{...v,openapi:{description:"Displays an error page",responses:{200:{description:"Success",content:{"text/html":{schema:{type:"string",description:"The HTML content of the error page"}}}}}}}},async e=>new Response(((e="Unknown")=>`<!DOCTYPE html> 4<html lang="en"> 5<head> 6 <meta charset="UTF-8"> 7 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 8 <title>Authentication Error</title> 9 <style> 10 :root { 11 --bg-color: #f8f9fa; 12 --text-color: #212529; 13 --accent-color: #000000; 14 --error-color: #dc3545; 15 --border-color: #e9ecef; 16 } 17 body { 18 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; 19 background-color: var(--bg-color); 20 color: var(--text-color); 21 display: flex; 22 justify-content: center; 23 align-items: center; 24 height: 100vh; 25 margin: 0; 26 line-height: 1.5; 27 } 28 .error-container { 29 background-color: #ffffff; 30 border-radius: 12px; 31 box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); 32 padding: 2.5rem; 33 text-align: center; 34 max-width: 90%; 35 width: 400px; 36 } 37 h1 { 38 color: var(--error-color); 39 font-size: 1.75rem; 40 margin-bottom: 1rem; 41 font-weight: 600; 42 } 43 p { 44 margin-bottom: 1.5rem; 45 color: #495057; 46 } 47 .btn { 48 background-color: var(--accent-color); 49 color: #ffffff; 50 text-decoration: none; 51 padding: 0.75rem 1.5rem; 52 border-radius: 6px; 53 transition: all 0.3s ease; 54 display: inline-block; 55 font-weight: 500; 56 border: 2px solid var(--accent-color); 57 } 58 .btn:hover { 59 background-color: #131721; 60 } 61 .error-code { 62 font-size: 0.875rem; 63 color: #6c757d; 64 margin-top: 1.5rem; 65 padding-top: 1.5rem; 66 border-top: 1px solid var(--border-color); 67 } 68 .icon { 69 font-size: 3rem; 70 margin-bottom: 1rem; 71 } 72 </style> 73</head> 74<body> 75 <div class="error-container"> 76 <div class="icon">\u26A0\uFE0F</div> 77 <h1>Better Auth Error</h1> 78 <p>We encountered an issue while processing your request. Please try again or c
78ontact the application owner if the problem persists.</p> 79 <a href="/" id="returnLink" class="btn">Return to Application</a> 80 <div class="error-code">Error Code: <span id="errorCode">${e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}</span></div> 81 </div> 82</body> 83</html>`)(new URL(e.request?.url||"").searchParams.get("error")||"Unknown"),{headers:{"Content-Type":"text/html"}})),(0,a.a)("/ok",{method:"GET",metadata:{...v,openapi:{description:"Check if the API is working",responses:{200:{description:"API is working",content:{"application/json":{schema:{type:"object",properties:{ok:{type:"boolean",description:"Indicates if the API is working"}},required:["ok"]}}}}}}}},async e=>e.json({ok:!0})),(0,a.a)("/list-accounts",{method:"GET",use:[a.s],metadata:{openapi:{description:"List all accounts linked to the user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"array",items:{type:"object",properties:{id:{type:"string"},providerId:{type:"string"},createdAt:{type:"string",format:"date-time"},updatedAt:{type:"string",format:"date-time"},accountId:{type:"string"},scopes:{type:"array",items:{type:"string"}}},required:["id","providerId","createdAt","updatedAt","accountId","scopes"]}}}}}}}}},async e=>{let t=e.context.session,r=await e.context.internalAdapter.findAccounts(t.user.id);return e.json(r.map(e=>({id:e.id,providerId:e.providerId,createdAt:e.createdAt,updatedAt:e.updatedAt,accountId:e.accountId,scopes:e.scope?.split(",")||[]})))}),(0,a.a)("/link-social",{method:"POST",requireHeaders:!0,body:i.Ik({callbackURL:i.Yj().meta({description:"The URL to redirect to after the user has signed in"}).optional(),provider:j,idToken:i.Ik({token:i.Yj(),nonce:i.Yj().optional(),accessToken:i.Yj().optional(),refreshToken:i.Yj().optional(),scopes:i.YO(i.Yj()).optional()}).optional(),requestSignUp:i.zM().optional(),scopes:i.YO(i.Yj()).meta({description:"Additional scopes to request from the provider"}).optional(),errorCallbackURL:i.Yj().meta({description:"The URL to redirect to if there is an error during the link process"}).optional(),disableRedirect:i.zM().meta({description:"Disable automatic redirection to the provider. Useful for handling the redirection yourself"}).optional()}),use:[a.s],metadata:{openapi:{description:"Link a social account to the user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{url:{type:"string",description:"The authorization URL to redirect the user to"},redirect:{type:"boolean",description:"Indicates if the user should be redirected to the authorization URL"},status:{type:"boolean"}},required:["redirect"]}}}}}}}},async e=>{let t=e.context.session,r=e.context.socialProviders.find(t=>t.id===e.body.provider);if(!r)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new s.LG("NOT_FOUND",{message:a.B.PROVIDER_NOT_FOUND});if(e.body.idToken){if(!r.verifyIdToken)throw e.context.logger.error("Provider does not support id token verification",{provider:e.body.provider}),new s.LG("NOT_FOUND",{message:a.B.ID_TOKEN_NOT_SUPPORTED});let{token:i,nonce:o}=e.body.idToken;if(!await r.verifyIdToken(i,o))throw e.context.logger.error("Invalid id token",{provider:e.body.provider}),new s.LG("UNAUTHORIZED",{message:a.B.INVALID_TOKEN});let n=await r.getUserInfo({idToken:i,accessToken:e.body.idToken.accessToken,refreshToken:e.body.idToken.refreshToken});if(!n||!n?.user)throw e.context.logger.error("Failed to get user info",{provider:e.body.provider}),new s.LG("UNAUTHORIZED",{message:a.B.FAILED_TO_GET_USER_INFO});let c=String(n.user.id);if(!n.user.email)throw e.context.logger.error("User email not found",{provider:e.body.provider}),new s.LG("UNAUTHORIZED",{message:a.B.USER_EMAIL_NOT_FOUND});if((await e.context.internalAdapter.findAccounts(t.user.id)).find(e=>e.providerId===r.id&&e.accountId===c))return e.json({url:"",status:!0,redirect:!1});let d=e.context.options.account?.accountLinking?.trustedProviders;if(!d?.includes(r.id)&&!n.user.emailVerified||e.context.options.account?.accountLinking?.enabled===!1)throw new s.LG("UNAUTHORIZED",{message:"Account not linked - linking not allowed"});if(n.user.email!==t.user.email&&e.context.options.account?.accountLinking?.allowDifferentEmails!==!0)throw new s.LG("UNAUTHORIZED",{message:"Account not linked - different emails not allowed"});
83try{await e.context.internalAdapter.createAccount({userId:t.user.id,providerId:r.id,accountId:c,accessToken:e.body.idToken.accessToken,idToken:i,refreshToken:e.body.idToken.refreshToken,scope:e.body.idToken.scopes?.join(",")},e)}catch(e){throw new s.LG("EXPECTATION_FAILED",{message:"Account not linked - unable to create account"})}if(e.context.options.account?.accountLinking?.updateUserInfoOnLink===!0)try{await e.context.internalAdapter.updateUser(t.user.id,{name:n.user?.name,image:n.user?.image})}catch(e){console.warn("Could not update user - "+e.toString())}return e.json({url:"",status:!0,redirect:!1})}let i=await _(e,{userId:t.user.id,email:t.user.email}),o=await r.createAuthorizationURL({state:i.state,codeVerifier:i.codeVerifier,redirectURI:`${e.context.baseURL}/callback/${r.id}`,scopes:e.body.scopes});return e.json({url:o.toString(),redirect:!e.body.disableRedirect})}),(0,a.a)("/unlink-account",{method:"POST",body:i.Ik({providerId:i.Yj(),accountId:i.Yj().optional()}),use:[a.f],metadata:{openapi:{description:"Unlink an account",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean"}}}}}}}}}},async e=>{let{providerId:t,accountId:r}=e.body,i=await e.context.internalAdapter.findAccounts(e.context.session.user.id);if(1===i.length&&!e.context.options.account?.accountLinking?.allowUnlinkingAll)throw new s.LG("BAD_REQUEST",{message:a.B.FAILED_TO_UNLINK_LAST_ACCOUNT});let o=i.find(e=>r?e.accountId===r&&e.providerId===t:e.providerId===t);if(!o)throw new s.LG("BAD_REQUEST",{message:a.B.ACCOUNT_NOT_FOUND});return await e.context.internalAdapter.deleteAccount(o.id),e.json({status:!0})});let q=(0,a.a)("/get-access-token",{method:"POST",body:i.Ik({providerId:i.Yj().meta({description:"The provider ID for the OAuth provider"}),accountId:i.Yj().meta({description:"The account ID associated with the refresh token"}).optional(),userId:i.Yj().meta({description:"The user ID associated with the account"}).optional()}),metadata:{openapi:{description:"Get a valid access token, doing a refresh if needed",responses:{200:{description:"A Valid access token",content:{"application/json":{schema:{type:"object",properties:{tokenType:{type:"string"},idToken:{type:"string"},accessToken:{type:"string"},refreshToken:{type:"string"},accessTokenExpiresAt:{type:"string",format:"date-time"},refreshTokenExpiresAt:{type:"string",format:"date-time"}}}}}},400:{description:"Invalid refresh token or provider configuration"}}}}},async e=>{let{providerId:t,accountId:r,userId:i}=e.body,o=e.request,n=await (0,a.g)(e);if(o&&!n)throw e.error("UNAUTHORIZED");let c=n?.user?.id||i;if(!c)throw new s.LG("BAD_REQUEST",{message:"Either userId or session is required"});if(!e.context.socialProviders.find(e=>e.id===t))throw new s.LG("BAD_REQUEST",{message:`Provider ${t} is not supported.`});let d=(await e.context.internalAdapter.findAccounts(c)).find(e=>r?e.id===r&&e.providerId===t:e.providerId===t);if(!d)throw new s.LG("BAD_REQUEST",{message:"Account not found"});let p=e.context.socialProviders.find(e=>e.id===t);if(!p)throw new s.LG("BAD_REQUEST",{message:`Provider ${t} not found.`});try{let t=null,r=d.accessTokenExpiresAt&&new Date(d.accessTokenExpiresAt).getTime()-Date.now()<5e3;d.refreshToken&&r&&p.refreshAccessToken&&(t=await p.refreshAccessToken(d.refreshToken),await e.context.internalAdapter.updateAccount(d.id,{accessToken:await O(t.accessToken,e.context),accessTokenExpiresAt:t.accessTokenExpiresAt,refreshToken:await O(t.refreshToken,e.context),refreshTokenExpiresAt:t.refreshTokenExpiresAt}));let i={accessToken:await function(e,t){return e&&t.options.account?.encryptOAuthTokens?(0,l.zp)({key:t.secret,data:e}):e}(t?.accessToken??d.accessToken??"",e.context),accessTokenExpiresAt:t?.accessTokenExpiresAt??d.accessTokenExpiresAt??void 0,scopes:d.scope?.split(",")??[],idToken:t?.idToken??d.idToken??void 0};return e.json(i)}catch(e){throw new s.LG("BAD_REQUEST",{message:"Failed to get a valid access token",cause:e})}});(0,a.a)("/refresh-token",{method:"POST",body:i.Ik({providerId:i.Yj().meta({description:"The provider ID for the OAuth provider"}),accountId:i.Yj().meta({description:"The account ID associated with the refresh token"}).optional(),userId:i.Yj().meta({description:"The user ID associated with the account"}).optional()}),metadata:{openapi:{description:"Refresh the access token using a refresh token",responses:{200:{description:"Access token refreshed successfully",content:{"application/json":{schema:{type:"object",properties:{tokenType:{type:"string"},idToken:{type:"string"},accessToken:{type:"string"},refreshToken:{type:"string"},accessTokenExpiresAt:{type:"string",format:"date-time"},refreshTokenExpiresAt:{type:"string",format:"date-time"}}}}}},400:{description:"Invalid refresh token or provider configuration"}}}}},async e=>{let{providerId:t,accountId:r,userId:i}=e.body,o=e.request,n=await (0,a.g)(e);if(o&&!n)throw e.error("UNAUTHORIZED");let c=n?.user?.id||i;if(!c)throw new s.LG("BAD_REQUEST",{message:"Either userId or session is required"});
83let d=(await e.context.internalAdapter.findAccounts(c)).find(e=>r?e.id===r&&e.providerId===t:e.providerId===t);if(!d)throw new s.LG("BAD_REQUEST",{message:"Account not found"});let l=e.context.socialProviders.find(e=>e.id===t);if(!l)throw new s.LG("BAD_REQUEST",{message:`Provider ${t} not found.`});if(!l.refreshAccessToken)throw new s.LG("BAD_REQUEST",{message:`Provider ${t} does not support token refreshing.`});try{let t=await l.refreshAccessToken(d.refreshToken);return await e.context.internalAdapter.updateAccount(d.id,{accessToken:await O(t.accessToken,e.context),refreshToken:await O(t.refreshToken,e.context),accessTokenExpiresAt:t.accessTokenExpiresAt,refreshTokenExpiresAt:t.refreshTokenExpiresAt}),e.json(t)}catch(e){throw new s.LG("BAD_REQUEST",{message:"Failed to refresh access token",cause:e})}}),(0,a.a)("/account-info",{method:"POST",use:[a.s],metadata:{openapi:{description:"Get the account info provided by the provider",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{user:{type:"object",properties:{id:{type:"string"},name:{type:"string"},email:{type:"string"},image:{type:"string"},emailVerified:{type:"boolean"}},required:["id","emailVerified"]},data:{type:"object",properties:{},additionalProperties:!0}},required:["user","data"],additionalProperties:!1}}}}}}},body:i.Ik({accountId:i.Yj().meta({description:"The provider given account id for which to get the account info"})})},async e=>{let t=await e.context.internalAdapter.findAccount(e.body.accountId);if(!t||t.userId!==e.context.session.user.id)throw new s.LG("BAD_REQUEST",{message:"Account not found"});let r=e.context.socialProviders.find(e=>e.id===t.providerId);if(!r)throw new s.LG("INTERNAL_SERVER_ERROR",{message:`Provider account provider is ${t.providerId} but it is not configured`});let i=await q({...e,body:{accountId:t.id,providerId:t.providerId},returnHeaders:!1});if(!i.accessToken)throw new s.LG("BAD_REQUEST",{message:"Access token not found"});let o=await r.getUserInfo({...i,accessToken:i.accessToken});return e.json(o)}),(0,T.zG)((e,t,r)=>{if(Array.isArray(e[t])&&Array.isArray(r))return e[t]=r,!0})}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.