better-auth 1.0.21 → 1.0.22-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/adapters/prisma.d.cts +1 -1
  2. package/dist/adapters/prisma.d.ts +1 -1
  3. package/dist/api.cjs +1 -1
  4. package/dist/api.js +1 -1
  5. package/dist/client/plugins.d.cts +1 -1
  6. package/dist/client/plugins.d.ts +1 -1
  7. package/dist/{index-Dt4lZbQi.d.ts → index-Dd3_WG87.d.ts} +105 -103
  8. package/dist/{index-CgaJXZ9u.d.cts → index-Dp04oxSM.d.cts} +105 -103
  9. package/dist/index.cjs +2 -2
  10. package/dist/index.js +2 -2
  11. package/dist/plugin/custom-session.cjs +4 -4
  12. package/dist/plugin/custom-session.js +2 -2
  13. package/dist/plugins/admin.cjs +1 -1
  14. package/dist/plugins/admin.js +1 -1
  15. package/dist/plugins/anonymous.cjs +1 -1
  16. package/dist/plugins/anonymous.js +1 -1
  17. package/dist/plugins/bearer.cjs +1 -1
  18. package/dist/plugins/bearer.js +1 -1
  19. package/dist/plugins/email-otp.cjs +1 -1
  20. package/dist/plugins/email-otp.js +1 -1
  21. package/dist/plugins/generic-oauth.cjs +1 -1
  22. package/dist/plugins/generic-oauth.js +1 -1
  23. package/dist/plugins/jwt.cjs +2 -2
  24. package/dist/plugins/jwt.js +2 -2
  25. package/dist/plugins/multi-session.cjs +1 -1
  26. package/dist/plugins/multi-session.js +1 -1
  27. package/dist/plugins/one-tap.cjs +1 -1
  28. package/dist/plugins/one-tap.js +1 -1
  29. package/dist/plugins/open-api.cjs +1 -1
  30. package/dist/plugins/open-api.js +1 -1
  31. package/dist/plugins/organization.cjs +4 -4
  32. package/dist/plugins/organization.d.cts +1 -1
  33. package/dist/plugins/organization.d.ts +1 -1
  34. package/dist/plugins/organization.js +2 -2
  35. package/dist/plugins/passkey.cjs +1 -1
  36. package/dist/plugins/passkey.js +1 -1
  37. package/dist/plugins/phone-number.cjs +1 -1
  38. package/dist/plugins/phone-number.js +1 -1
  39. package/dist/plugins/two-factor.cjs +1 -1
  40. package/dist/plugins/two-factor.js +1 -1
  41. package/dist/plugins/username.cjs +1 -1
  42. package/dist/plugins/username.js +1 -1
  43. package/dist/plugins.cjs +3 -3
  44. package/dist/plugins.d.cts +1 -1
  45. package/dist/plugins.d.ts +1 -1
  46. package/dist/plugins.js +4 -4
  47. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import{z}from"zod";var le={jwks:{fields:{publicKey:{type:"string",required:!0},privateKey:{type:"string",required:!0},createdAt:{type:"date",required:!0}}}},vr=z.object({id:z.string(),publicKey:z.string(),privateKey:z.string(),createdAt:z.date()});var oe=e=>({getAllKeys:async()=>await e.findMany({model:"jwks"}),getLatestKey:async()=>(await e.findMany({model:"jwks",sortBy:{field:"createdAt",direction:"desc"},limit:1}))[0],createJwk:async t=>await e.create({model:"jwks",data:{...t,createdAt:new Date}})});import{exportJWK as Xe,generateKeyPair as Ur,importJWK as _r,SignJWT as Tr}from"jose";import{APIError as ec,createRouter as tc,getCookie as rc,getSignedCookie as oc,setCookie as ic,setSignedCookie as nc}from"better-call";import{APIError as st}from"better-call";import{createEndpointCreator as et,createMiddleware as ue,createMiddlewareCreator as tt}from"better-call";var me=ue(async()=>({})),q=tt({use:[me,ue(async()=>({}))]}),m=et({use:[me]});function ie(e){return e==="-"||e==="^"||e==="$"||e==="+"||e==="."||e==="("||e===")"||e==="|"||e==="["||e==="]"||e==="{"||e==="}"||e==="*"||e==="?"||e==="\\"?`\\${e}`:e}function rt(e){let t="";for(let r=0;r<e.length;r++)t+=ie(e[r]);return t}function fe(e,t=!0){if(Array.isArray(e))return`(?:${e.map(p=>`^${fe(p,t)}$`).join("|")})`;let r="",o="",i=".";t===!0?(r="/",o="[/\\\\]",i="[^/\\\\]"):t&&(r=t,o=rt(r),o.length>1?(o=`(?:${o})`,i=`((?!${o}).)`):i=`[^${o}]`);let n=t?`${o}+?`:"",s=t?`${o}*?`:"",c=t?e.split(r):[e],a="";for(let d=0;d<c.length;d++){let p=c[d],f=c[d+1],A="";if(!(!p&&d>0)){if(t&&(d===c.length-1?A=s:f!=="**"?A=n:A=""),t&&p==="**"){A&&(a+=d===0?"":A,a+=`(?:${i}*?${A})*?`);continue}for(let g=0;g<p.length;g++){let w=p[g];w==="\\"?g<p.length-1&&(a+=ie(p[g+1]),g++):w==="?"?a+=i:w==="*"?a+=`${i}*?`:a+=ie(w)}a+=A}}return a}function ot(e,t){if(typeof t!="string")throw new TypeError(`Sample must be a string, but ${typeof t} given`);return e.test(t)}function ne(e,t){if(typeof e!="string"&&!Array.isArray(e))throw new TypeError(`The first argument must be a single pattern string or an array of patterns, but ${typeof e} given`);if((typeof t=="string"||typeof t=="boolean")&&(t={separator:t}),arguments.length===2&&!(typeof t>"u"||typeof t=="object"&&t!==null&&!Array.isArray(t)))throw new TypeError(`The second argument must be an options object or a string/boolean separator, but ${typeof t} given`);if(t=t||{},t.separator==="\\")throw new Error("\\ is not a valid separator because it is used for escaping. Try setting the separator to `true` instead");let r=fe(e,t.separator),o=new RegExp(`^${r}$`,t.flags),i=ot.bind(null,o);return i.options=t,i.pattern=e,i.regexp=o,i}var J=Object.create(null),M=e=>globalThis.process?.env||globalThis.Deno?.env.toObject()||globalThis.__env__||(e?J:globalThis),ge=new Proxy(J,{get(e,t){return M()[t]??J[t]},has(e,t){let r=M();return t in r||t in J},set(e,t,r){let o=M(!0);return o[t]=r,!0},deleteProperty(e,t){if(!t)return!1;let r=M(!0);return delete r[t],!0},ownKeys(){let e=M(!0);return Object.keys(e)}});function it(e){return e?e!=="false":!1}var se=typeof process<"u"&&process.env&&process.env.NODE_ENV||"";var ae=se==="dev"||se==="development",nt=se==="test"||it(ge.TEST);var j=class extends Error{constructor(t,r){super(t),this.name="BetterAuthError",this.message=t,this.cause=r,this.stack=""}};function he(e){try{return new URL(e).origin}catch{return null}}function we(e){return e.includes("://")?new URL(e).host:e}var at=q(async e=>{if(e.request?.method!=="POST")return;let{body:t,query:r,context:o}=e,i=e.headers?.get("origin")||e.headers?.get("referer")||"",n=t?.callbackURL||r?.callbackURL,s=t?.redirectTo,c=r?.currentURL,a=t?.errorCallbackURL,d=t?.newUserCallbackURL,p=o.trustedOrigins,f=e.headers?.has("cookie"),A=(w,E)=>w.startsWith("/")?!1:E.includes("*")?ne(E)(we(w)):w.startsWith(E),g=(w,E)=>{if(!w)return;if(!p.some(te=>A(w,te)||w?.startsWith("/")&&E!=="origin"&&!w.includes(":")))throw e.context.logger.error(`Invalid ${E}: ${w}`),e.context.logger.info(`If it's a valid URL, please add ${w} to trustedOrigins in your auth config
2
- `,`Current list of trustedOrigins: ${p}`),new st("FORBIDDEN",{message:`Invalid ${E}`})};f&&!e.context.options.advanced?.disableCSRFCheck&&g(i,"origin"),n&&g(n,"callbackURL"),s&&g(s,"redirectURL"),c&&g(c,"currentURL"),a&&g(a,"errorCallbackURL"),d&&g(s,"newUserCallbackURL")});import{APIError as R}from"better-call";import{z as b}from"zod";import{TimeSpan as eo}from"oslo";import{base64url as lt}from"oslo/encoding";import{HMAC as ye,sha256 as Kr}from"oslo/crypto";async function dt({value:e,secret:t}){return new ye("SHA-256").sign(new TextEncoder().encode(t),new TextEncoder().encode(e)).then(o=>Buffer.from(o).toString("base64"))}function pt({value:e,signature:t,secret:r}){return new ye("SHA-256").verify(new TextEncoder().encode(r),Buffer.from(t,"base64"),new TextEncoder().encode(e))}var W={sign:dt,verify:pt};var N=(e,t="ms")=>new Date(Date.now()+(t==="sec"?e*1e3:e));async function T(e,t,r,o){let i=e.context.authCookies.sessionToken.options,n=r?void 0:e.context.sessionConfig.expiresIn;if(await e.setSignedCookie(e.context.authCookies.sessionToken.name,t.session.token,e.context.secret,{...i,maxAge:n,...o}),r&&await e.setSignedCookie(e.context.authCookies.dontRememberToken.name,"true",e.context.secret,e.context.authCookies.dontRememberToken.options),e.context.options.session?.cookieCache?.enabled){let c=lt.encode(new TextEncoder().encode(JSON.stringify({session:t,expiresAt:N(e.context.authCookies.sessionData.options.maxAge||60,"sec").getTime(),signature:await W.sign({value:JSON.stringify(t),secret:e.context.secret})})),{includePadding:!1});if(c.length>4093)throw new j("Session data is too large to store in the cookie. Please disable session cookie caching or reduce the size of the session data");e.setCookie(e.context.authCookies.sessionData.name,c,e.context.authCookies.sessionData.options)}e.context.setNewSession(t),e.context.options.secondaryStorage&&await e.context.secondaryStorage?.set(t.session.token,JSON.stringify({user:t.user,session:t.session}),Math.floor((new Date(t.session.expiresAt).getTime()-Date.now())/1e3))}function I(e){e.setCookie(e.context.authCookies.sessionToken.name,"",{...e.context.authCookies.sessionToken.options,maxAge:0}),e.setCookie(e.context.authCookies.sessionData.name,"",{...e.context.authCookies.sessionData.options,maxAge:0}),e.setCookie(e.context.authCookies.dontRememberToken.name,"",{...e.context.authCookies.dontRememberToken.options,maxAge:0})}import{betterFetch as wt}from"@better-fetch/fetch";import{APIError as yt}from"better-call";import{decodeProtectedHeader as bt,importJWK as At,jwtVerify as kt}from"jose";import{parseJWT as Rt}from"oslo/jwt";import{sha256 as ut}from"oslo/crypto";import{base64url as mt}from"oslo/encoding";async function be(e){let t=await ut(new TextEncoder().encode(e));return mt.encode(new Uint8Array(t),{includePadding:!1})}function Z(e){return{tokenType:e.token_type,accessToken:e.access_token,refreshToken:e.refresh_token,accessTokenExpiresAt:e.expires_in?N(e.expires_in,"sec"):void 0,scopes:e?.scope?typeof e.scope=="string"?e.scope.split(" "):e.scope:[],idToken:e.id_token}}async function y({id:e,options:t,authorizationEndpoint:r,state:o,codeVerifier:i,scopes:n,claims:s,redirectURI:c,duration:a}){let d=new URL(r);if(d.searchParams.set("response_type","code"),d.searchParams.set("client_id",t.clientId),d.searchParams.set("state",o),d.searchParams.set("scope",n.join(" ")),d.searchParams.set("redirect_uri",t.redirectURI||c),i){let p=await be(i);d.searchParams.set("code_challenge_method","S256"),d.searchParams.set("code_challenge",p)}if(s){let p=s.reduce((f,A)=>(f[A]=null,f),{});d.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...p}}))}return a&&d.searchParams.set("duration",a),d}import{betterFetch as ft}from"@better-fetch/fetch";async function h({code:e,codeVerifier:t,redirectURI:r,options:o,tokenEndpoint:i,authentication:n}){let s=new URLSearchParams,c={"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"};if(s.set("grant_type","authorization_code"),s.set("code",e),t&&s.set("code_verifier",t),s.set("redirect_uri",r),n==="basic"){let f=btoa(`${o.clientId}:${o.clientSecret}`);c.authorization=`Basic ${f}`}else s.set("client_id",o.clientId),s.set("client_secret",o.clientSecret);let{data:a,error:d}=await ft(i,{method:"POST",body:s,headers:c});if(d)throw d;return Z(a)}import{generateCodeVerifier as gt,generateState as ht}from"oslo/oauth2";import{z as L}from"zod";import{APIError as Ae}from"better-call";async function Q(e,t){let r=e.body?.callbackURL||(e.query?.currentURL?he(e.query?.currentURL):"")||e.context.options.baseURL;if(!r)throw new Ae("BAD_REQUEST",{message:"callbackURL is required"});let o=gt(),i=ht(),n=JSON.stringify({callbackURL:r,codeVerifier:o,errorURL:e.body?.errorCallbackURL||e.query?.currentURL,newUserURL:e.body?.newUserCallbackURL,link:t,expiresAt:Date.now()+10*60*1e3}),s=new Date;s.setMinutes(s.getMinutes()+10);let c=await e.context.internalAdapter.createVerificationValue({value:n,identifier:i,expiresAt:s});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 Ae("INTERNAL_SERVER_ERROR",{message:"Unable to create verification"});return{state:c.identifier,codeVerifier:o}}async function ke(e){let t=e.query.state||e.body.state,r=await e.context.internalAdapter.findVerificationValue(t);if(!r)throw e.context.logger.error("State Mismatch. Verification not found",{state:t}),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let o=L.object({callbackURL:L.string(),codeVerifier:L.string(),errorURL:L.string().optional(),newUserURL:L.string().optional(),expiresAt:L.number(),link:L.object({email:L.string(),userId:L.string()}).optional()}).parse(JSON.parse(r.value));if(o.errorURL||(o.errorURL=`${e.context.baseURL}/error`),o.expiresAt<Date.now())throw await e.context.internalAdapter.deleteVerificationValue(r.id),e.context.logger.error("State expired.",{state:t}),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);return await e.context.internalAdapter.deleteVerificationValue(r.id),o}var Re=e=>{let t="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:r,scopes:o,redirectURI:i}){let n=o||["email","name"];return e.scope&&n.push(...e.scope),new URL(`https://appleid.apple.com/auth/authorize?client_id=${e.clientId}&response_type=code&redirect_uri=${i||e.redirectURI}&scope=${n.join(" ")}&state=${r}&response_mode=form_post`)},validateAuthorizationCode:async({code:r,codeVerifier:o,redirectURI:i})=>h({code:r,codeVerifier:o,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:t}),async verifyIdToken(r,o){if(e.disableIdTokenSignIn)return!1;if(e.verifyIdToken)return e.verifyIdToken(r,o);let i=bt(r),{kid:n,alg:s}=i;if(!n||!s)return!1;let c=await Et(n),{payload:a}=await kt(r,c,{algorithms:[s],issuer:"https://appleid.apple.com",audience:e.clientId,maxTokenAge:"1h"});return["email_verified","is_private_email"].forEach(d=>{a[d]!==void 0&&(a[d]=!!a[d])}),o&&a.nonce!==o?!1:!!a},async getUserInfo(r){if(e.getUserInfo)return e.getUserInfo(r);if(!r.idToken)return null;let o=Rt(r.idToken)?.payload;if(!o)return null;let i=o.user?`${o.user.name.firstName} ${o.user.name.lastName}`:o.email,n=await e.mapProfileToUser?.(o);return{user:{id:o.sub,name:i,emailVerified:!1,email:o.email,...n},data:o}}}},Et=async e=>{let t="https://appleid.apple.com",r="/auth/keys",{data:o}=await wt(`${t}${r}`);if(!o?.keys)throw new yt("BAD_REQUEST",{message:"Keys not found"});let i=o.keys.find(n=>n.kid===e);if(!i)throw new Error(`JWK with kid ${e} not found`);return await At(i,i.alg)};import{betterFetch as Ut}from"@better-fetch/fetch";var Ee=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=r||["identify","email"];return e.scope&&i.push(...e.scope),new URL(`https://discord.com/api/oauth2/authorize?scope=${i.join("+")}&response_type=code&client_id=${e.clientId}&redirect_uri=${encodeURIComponent(e.redirectURI||o)}&state=${t}&prompt=${e.prompt||"none"}`)},validateAuthorizationCode:async({code:t,redirectURI:r})=>h({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:o}=await Ut("https://discord.com/api/users/@me",{headers:{authorization:`Bearer ${t.accessToken}`}});if(o)return null;if(r.avatar===null){let n=r.discriminator==="0"?Number(BigInt(r.id)>>BigInt(22))%6:parseInt(r.discriminator)%5;r.image_url=`https://cdn.discordapp.com/embed/avatars/${n}.png`}else{let n=r.avatar.startsWith("a_")?"gif":"png";r.image_url=`https://cdn.discordapp.com/avatars/${r.id}/${r.avatar}.${n}`}let i=await e.mapProfileToUser?.(r);return{user:{id:r.id,name:r.display_name||r.username||"",email:r.email,emailVerified:r.verified,image:r.image_url,...i},data:r}}});import{betterFetch as _t}from"@better-fetch/fetch";var Ue=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=r||["email","public_profile"];return e.scope&&i.push(...e.scope),await y({id:"facebook",options:e,authorizationEndpoint:"https://www.facebook.com/v21.0/dialog/oauth",scopes:i,state:t,redirectURI:o})},validateAuthorizationCode:async({code:t,redirectURI:r})=>h({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://graph.facebook.com/oauth/access_token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:o}=await _t("https://graph.facebook.com/me?fields=id,name,email,picture",{auth:{type:"Bearer",token:t.accessToken}});if(o)return null;let i=await e.mapProfileToUser?.(r);return{user:{id:r.id,name:r.name,email:r.email,image:r.picture.data.url,emailVerified:r.email_verified,...i},data:r}}});import{betterFetch as _e}from"@better-fetch/fetch";var Te=e=>{let t="https://github.com/login/oauth/access_token";return{id:"github",name:"GitHub",createAuthorizationURL({state:r,scopes:o,codeVerifier:i,redirectURI:n}){let s=o||["user:email"];return e.scope&&s.push(...e.scope),y({id:"github",options:e,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:s,state:r,redirectURI:n})},validateAuthorizationCode:async({code:r,redirectURI:o})=>h({code:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:t}),async getUserInfo(r){if(e.getUserInfo)return e.getUserInfo(r);let{data:o,error:i}=await _e("https://api.github.com/user",{headers:{"User-Agent":"better-auth",authorization:`Bearer ${r.accessToken}`}});if(i)return null;let n=!1;if(!o.email){let{data:c,error:a}=await _e("https://api.github.com/user/emails",{headers:{authorization:`Bearer ${r.accessToken}`,"User-Agent":"better-auth"}});a||(o.email=(c.find(d=>d.primary)??c[0])?.email,n=c.find(d=>d.email===o.email)?.verified??!1)}let s=await e.mapProfileToUser?.(o);return{user:{id:o.id.toString(),name:o.name||o.login,email:o.email,image:o.avatar_url,emailVerified:n,...s},data:o}}}};import{parseJWT as xt}from"oslo/jwt";import{createConsola as Tt}from"consola";var ce=["info","success","warn","error","debug"];function St(e,t){return ce.indexOf(t)<=ce.indexOf(e)}var Ot=Tt({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),vt=e=>{let t=e?.disabled!==!0,r=e?.level??"error",o=(i,n,s=[])=>{if(!(!t||!St(r,i))){if(!e||typeof e.log!="function"){Ot[i]("",n,...s);return}e.log(i==="success"?"info":i,n,s)}};return Object.fromEntries(ce.map(i=>[i,(...[n,...s])=>o(i,n,s)]))},v=vt();import{betterFetch as Pt}from"@better-fetch/fetch";var Se=e=>({id:"google",name:"Google",async createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:i}){if(!e.clientId||!e.clientSecret)throw v.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new j("CLIENT_ID_AND_SECRET_REQUIRED");if(!o)throw new j("codeVerifier is required for Google");let n=r||["email","profile","openid"];e.scope&&n.push(...e.scope);let s=await y({id:"google",options:e,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:n,state:t,codeVerifier:o,redirectURI:i});return e.accessType&&s.searchParams.set("access_type",e.accessType),e.prompt&&s.searchParams.set("prompt",e.prompt),s},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>h({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://oauth2.googleapis.com/token"}),async verifyIdToken(t,r){if(e.disableIdTokenSignIn)return!1;if(e.verifyIdToken)return e.verifyIdToken(t,r);let o=`https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=${t}`,{data:i}=await Pt(o);return i?i.aud===e.clientId&&i.iss==="https://accounts.google.com":!1},async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);if(!t.idToken)return null;let r=xt(t.idToken)?.payload,o=await e.mapProfileToUser?.(r);return{user:{id:r.sub,name:r.name,email:r.email,image:r.picture,emailVerified:r.email_verified,...o},data:r}}});import{betterFetch as It}from"@better-fetch/fetch";import{parseJWT as Lt}from"oslo/jwt";var Oe=e=>{let t=e.tenantId||"common",r=`https://login.microsoftonline.com/${t}/oauth2/v2.0/authorize`,o=`https://login.microsoftonline.com/${t}/oauth2/v2.0/token`;return{id:"microsoft",name:"Microsoft EntraID",createAuthorizationURL(i){let n=i.scopes||["openid","profile","email","User.Read"];return e.scope&&n.push(...e.scope),y({id:"microsoft",options:e,authorizationEndpoint:r,state:i.state,codeVerifier:i.codeVerifier,scopes:n,redirectURI:i.redirectURI})},validateAuthorizationCode({code:i,codeVerifier:n,redirectURI:s}){return h({code:i,codeVerifier:n,redirectURI:e.redirectURI||s,options:e,tokenEndpoint:o})},async getUserInfo(i){if(e.getUserInfo)return e.getUserInfo(i);if(!i.idToken)return null;let n=Lt(i.idToken)?.payload,s=e.profilePhotoSize||48;await It(`https://graph.microsoft.com/v1.0/me/photos/${s}x${s}/$value`,{headers:{Authorization:`Bearer ${i.accessToken}`},async onResponse(a){if(!(e.disableProfilePhoto||!a.response.ok))try{let p=await a.response.clone().arrayBuffer(),f=Buffer.from(p).toString("base64");n.picture=`data:image/jpeg;base64, ${f}`}catch(d){v.error(d&&typeof d=="object"&&"name"in d?d.name:"",d)}}});let c=await e.mapProfileToUser?.(n);return{user:{id:n.sub,name:n.name,email:n.email,image:n.picture,emailVerified:!0,...c},data:n}}}};import{betterFetch as Dt}from"@better-fetch/fetch";var ve=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:i}){let n=r||["user-read-email"];return e.scope&&n.push(...e.scope),y({id:"spotify",options:e,authorizationEndpoint:"https://accounts.spotify.com/authorize",scopes:n,state:t,codeVerifier:o,redirectURI:i})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>h({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://accounts.spotify.com/api/token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:o}=await Dt("https://api.spotify.com/v1/me",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});if(o)return null;let i=await e.mapProfileToUser?.(r);return{user:{id:r.id,name:r.display_name,email:r.email,image:r.images[0]?.url,emailVerified:!1,...i},data:r}}});var $={isAction:!1};import{nanoid as Ct}from"nanoid";var xe=e=>Ct(e);import{parseJWT as jt}from"oslo/jwt";var Pe=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=r||["user:read:email","openid"];return e.scope&&i.push(...e.scope),y({id:"twitch",redirectURI:o,options:e,authorizationEndpoint:"https://id.twitch.tv/oauth2/authorize",scopes:i,state:t,claims:e.claims||["email","email_verified","preferred_username","picture"]})},validateAuthorizationCode:async({code:t,redirectURI:r})=>h({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let r=t.idToken;if(!r)return v.error("No idToken found in token"),null;let o=jt(r)?.payload,i=await e.mapProfileToUser?.(o);return{user:{id:o.sub,name:o.preferred_username,email:o.email,image:o.picture,emailVerified:!1,...i},data:o}}});import{betterFetch as Nt}from"@better-fetch/fetch";var Ie=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(t){let r=t.scopes||["users.read","tweet.read","offline.access"];return e.scope&&r.push(...e.scope),y({id:"twitter",options:e,authorizationEndpoint:"https://x.com/i/oauth2/authorize",scopes:r,state:t.state,codeVerifier:t.codeVerifier,redirectURI:t.redirectURI})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>h({code:t,codeVerifier:r,authentication:"basic",redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://api.x.com/2/oauth2/token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:o}=await Nt("https://api.x.com/2/users/me?user.fields=profile_image_url",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});if(o)return null;let i=await e.mapProfileToUser?.(r);return{user:{id:r.data.id,name:r.data.name,email:r.data.username||null,image:r.data.profile_image_url,emailVerified:r.data.verified||!1,...i},data:r}}});import{betterFetch as Bt}from"@better-fetch/fetch";var Le=e=>{let t="https://api.dropboxapi.com/oauth2/token";return{id:"dropbox",name:"Dropbox",createAuthorizationURL:async({state:r,scopes:o,codeVerifier:i,redirectURI:n})=>{let s=o||["account_info.read"];return e.scope&&s.push(...e.scope),await y({id:"dropbox",options:e,authorizationEndpoint:"https://www.dropbox.com/oauth2/authorize",scopes:s,state:r,redirectURI:n,codeVerifier:i})},validateAuthorizationCode:async({code:r,codeVerifier:o,redirectURI:i})=>await h({code:r,codeVerifier:o,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:t}),async getUserInfo(r){if(e.getUserInfo)return e.getUserInfo(r);let{data:o,error:i}=await Bt("https://api.dropboxapi.com/2/users/get_current_account",{method:"POST",headers:{Authorization:`Bearer ${r.accessToken}`}});if(i)return null;let n=await e.mapProfileToUser?.(o);return{user:{id:o.account_id,name:o.name?.display_name,email:o.email,emailVerified:o.email_verified||!1,image:o.profile_photo_url,...n},data:o}}}};import{betterFetch as Vt}from"@better-fetch/fetch";var De=e=>{let t="https://www.linkedin.com/oauth/v2/authorization",r="https://www.linkedin.com/oauth/v2/accessToken";return{id:"linkedin",name:"Linkedin",createAuthorizationURL:async({state:o,scopes:i,redirectURI:n})=>{let s=i||["profile","email","openid"];return e.scope&&s.push(...e.scope),await y({id:"linkedin",options:e,authorizationEndpoint:t,scopes:s,state:o,redirectURI:n})},validateAuthorizationCode:async({code:o,redirectURI:i})=>await h({code:o,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:r}),async getUserInfo(o){let{data:i,error:n}=await Vt("https://api.linkedin.com/v2/userinfo",{method:"GET",headers:{Authorization:`Bearer ${o.accessToken}`}});if(n)return null;let s=await e.mapProfileToUser?.(i);return{user:{id:i.sub,name:i.name,email:i.email,emailVerified:i.email_verified||!1,image:i.picture,...s},data:i}}}};import{betterFetch as $t}from"@better-fetch/fetch";var de=(e="")=>e.split("://").map(t=>t.replace(/\/{2,}/g,"/")).join("://"),zt=e=>{let t=e||"https://gitlab.com";return{authorizationEndpoint:de(`${t}/oauth/authorize`),tokenEndpoint:de(`${t}/oauth/token`),userinfoEndpoint:de(`${t}/api/v4/user`)}},Ce=e=>{let{authorizationEndpoint:t,tokenEndpoint:r,userinfoEndpoint:o}=zt(e.issuer),i="gitlab";return{id:i,name:"Gitlab",createAuthorizationURL:async({state:s,scopes:c,codeVerifier:a,redirectURI:d})=>{let p=c||["read_user"];return e.scope&&p.push(...e.scope),await y({id:i,options:e,authorizationEndpoint:t,scopes:p,state:s,redirectURI:d,codeVerifier:a})},validateAuthorizationCode:async({code:s,redirectURI:c,codeVerifier:a})=>h({code:s,redirectURI:e.redirectURI||c,options:e,codeVerifier:a,tokenEndpoint:r}),async getUserInfo(s){if(e.getUserInfo)return e.getUserInfo(s);let{data:c,error:a}=await $t(o,{headers:{authorization:`Bearer ${s.accessToken}`}});if(a||c.state!=="active"||c.locked)return null;let d=await e.mapProfileToUser?.(c);return{user:{id:c.id.toString(),name:c.name??c.username,email:c.email,image:c.avatar_url,emailVerified:!0,...d},data:c}}}};import{betterFetch as je}from"@better-fetch/fetch";var Ne=e=>({id:"reddit",name:"Reddit",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=r||["identity"];return e.scope&&i.push(...e.scope),y({id:"reddit",options:e,authorizationEndpoint:"https://www.reddit.com/api/v1/authorize",scopes:i,state:t,redirectURI:o,duration:e.duration})},validateAuthorizationCode:async({code:t,redirectURI:r})=>{let o=new URLSearchParams({grant_type:"authorization_code",code:t,redirect_uri:e.redirectURI||r}),i={"content-type":"application/x-www-form-urlencoded",accept:"text/plain","user-agent":"better-auth",Authorization:`Basic ${Buffer.from(`${e.clientId}:${e.clientSecret}`).toString("base64")}`},{data:n,error:s}=await je("https://www.reddit.com/api/v1/access_token",{method:"POST",headers:i,body:o.toString()});if(s)throw s;return Z(n)},async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:o}=await je("https://oauth.reddit.com/api/v1/me",{headers:{Authorization:`Bearer ${t.accessToken}`,"User-Agent":"better-auth"}});if(o)return null;let i=await e.mapProfileToUser?.(r);return{user:{id:r.id,name:r.name,email:r.oauth_client_id,emailVerified:r.has_verified_email,image:r.icon_img?.split("?")[0],...i},data:r}}});var qt={apple:Re,discord:Ee,facebook:Ue,github:Te,microsoft:Oe,google:Se,spotify:ve,twitch:Pe,twitter:Ie,dropbox:Le,linkedin:De,gitlab:Ce,reddit:Ne},Y=Object.keys(qt);import{TimeSpan as Gt}from"oslo";import{createJWT as Kt,validateJWT as Jt}from"oslo/jwt";import{z as x}from"zod";import{APIError as F}from"better-call";import{APIError as D}from"better-call";import{z as B}from"zod";function Be(e){try{return JSON.parse(e)}catch{return null}}var l={USER_NOT_FOUND:"User not found",FAILED_TO_CREATE_USER:"Failed to create user",FAILED_TO_CREATE_SESSION:"Failed to create session",FAILED_TO_UPDATE_USER:"Failed to update user",FAILED_TO_GET_SESSION:"Failed to get session",INVALID_PASSWORD:"Invalid password",INVALID_EMAIL:"Invalid email",INVALID_EMAIL_OR_PASSWORD:"Invalid email or password",SOCIAL_ACCOUNT_ALREADY_LINKED:"Social account already linked",PROVIDER_NOT_FOUND:"Provider not found",INVALID_TOKEN:"invalid token",ID_TOKEN_NOT_SUPPORTED:"id_token not supported",FAILED_TO_GET_USER_INFO:"Failed to get user info",USER_EMAIL_NOT_FOUND:"User email not found",EMAIL_NOT_VERIFIED:"Email not verified",PASSWORD_TOO_SHORT:"Password too short",PASSWORD_TOO_LONG:"Password too long",USER_ALREADY_EXISTS:"User already exists",EMAIL_CAN_NOT_BE_UPDATED:"Email can not be updated",CREDENTIAL_ACCOUNT_NOT_FOUND:"Credential account not found"};var Ve=()=>m("/get-session",{method:"GET",query:B.optional(B.object({disableCookieCache:B.boolean({description:"Disable cookie cache and fetch session from database"}).or(B.string().transform(e=>e==="true")).optional(),disableRefresh:B.boolean({description:"Disable session refresh. Useful for checking session status, without updating the session"}).optional()})),requireHeaders:!0,metadata:{openapi:{description:"Get the current session",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{session:{type:"object",properties:{token:{type:"string"},userId:{type:"string"},expiresAt:{type:"string"}}},user:{type:"object",$ref:"#/components/schemas/User"}}}}}}}}}},async e=>{try{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)return e.json(null);let r=e.getCookie(e.context.authCookies.sessionData.name),o=r?Be(Buffer.from(r,"base64").toString()):null;if(o&&!await W.verify({value:JSON.stringify(o.session),signature:o?.signature,secret:e.context.secret}))return I(e),e.json(null);let i=await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret);if(o?.session&&e.context.options.session?.cookieCache?.enabled&&!e.query?.disableCookieCache){let p=o.session;if(o.expiresAt<Date.now()||p.session.expiresAt<new Date){let A=e.context.authCookies.sessionData.name;e.setCookie(A,"",{maxAge:0})}else return e.json(p)}let n=await e.context.internalAdapter.findSession(t);if(e.context.session=n,!n||n.session.expiresAt<new Date)return I(e),n&&await e.context.internalAdapter.deleteSession(n.session.token),e.json(null);if(i||e.query?.disableRefresh)return e.json(n);let s=e.context.sessionConfig.expiresIn,c=e.context.sessionConfig.updateAge;if(n.session.expiresAt.valueOf()-s*1e3+c*1e3<=Date.now()){let p=await e.context.internalAdapter.updateSession(n.session.token,{expiresAt:N(e.context.sessionConfig.expiresIn,"sec")});if(!p)return I(e),e.json(null,{status:401});let f=(p.expiresAt.valueOf()-Date.now())/1e3;return await T(e,{session:p,user:n.user},!1,{maxAge:f}),e.json({session:p,user:n.user})}return e.json(n)}catch(t){throw e.context.logger.error("INTERNAL_SERVER_ERROR",t),new D("INTERNAL_SERVER_ERROR",{message:l.FAILED_TO_GET_SESSION})}}),V=async(e,t)=>{if(e.context.session)return e.context.session;let r=await Ve()({...e,_flag:"json",headers:e.headers,query:t}).catch(o=>null);return e.context.session=r,r},S=q(async e=>{let t=await V(e);if(!t?.session)throw new D("UNAUTHORIZED");return{session:t}}),$e=q(async e=>{let t=await V(e);if(!t?.session)throw new D("UNAUTHORIZED");if(e.context.sessionConfig.freshAge===0)return{session:t};let r=e.context.sessionConfig.freshAge,o=t.session.createdAt.valueOf(),i=Date.now();if(!(o+r*1e3>i))throw new D("FORBIDDEN",{message:"Session is not fresh"});return{session:t}});var Mt=m("/revoke-session",{method:"POST",body:B.object({token:B.string({description:"The token to revoke"})}),use:[S],requireHeaders:!0,metadata:{openapi:{description:"Revoke a single session",requestBody:{content:{"application/json":{schema:{type:"object",properties:{token:{type:"string"}},required:["token"]}}}}}}},async e=>{let t=e.body.token,r=await e.context.internalAdapter.findSession(t);if(!r)throw new D("BAD_REQUEST",{message:"Session not found"});if(r.session.userId!==e.context.session.user.id)throw new D("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(t)}catch(o){throw e.context.logger.error(o&&typeof o=="object"&&"name"in o?o.name:"",o),new D("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),Ft=m("/revoke-sessions",{method:"POST",use:[S],requireHeaders:!0,metadata:{openapi:{description:"Revoke all sessions for the user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean"}},required:["status"]}}}}}}}},async e=>{try{await e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(t){throw e.context.logger.error(t&&typeof t=="object"&&"name"in t?t.name:"",t),new D("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),Ht=m("/revoke-other-sessions",{method:"POST",requireHeaders:!0,use:[S],metadata:{openapi:{description:"Revoke all other sessions for the user except the current one",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean"}}}}}}}}}},async e=>{let t=e.context.session;if(!t.user)throw new D("UNAUTHORIZED");let i=(await e.context.internalAdapter.listSessions(t.user.id)).filter(n=>n.expiresAt>new Date).filter(n=>n.token!==e.context.session.session.token);return await Promise.all(i.map(n=>e.context.internalAdapter.deleteSession(n.token))),e.json({status:!0})});async function C(e,t,r){return await Kt("HS256",Buffer.from(e),{email:t.toLowerCase(),updateTo:r},{expiresIn:new Gt(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}async function Wt(e,t){if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new F("BAD_REQUEST",{message:"Verification email isn't enabled"});let r=await C(e.context.secret,t.email),o=`${e.context.baseURL}/verify-email?token=${r}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;await e.context.options.emailVerification.sendVerificationEmail({user:t,url:o,token:r},e.request)}var Zt=m("/send-verification-email",{method:"POST",query:x.object({currentURL:x.string({description:"The URL to use for email verification callback"}).optional()}).optional(),body:x.object({email:x.string({description:"The email to send the verification email to"}).email(),callbackURL:x.string({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"},callbackURL:{type:"string",description:"The URL to use for email verification callback"}},required:["email"]}}}},responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean"}}}}}}}}}},async e=>{if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new F("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:t}=e.body,r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw new F("BAD_REQUEST",{message:l.USER_NOT_FOUND});return await Wt(e,r.user),e.json({status:!0})}),Qt=m("/verify-email",{method:"GET",query:x.object({token:x.string({description:"The token to verify the email"}),callbackURL:x.string({description:"The URL to redirect to after email verification"}).optional()}),metadata:{openapi:{description:"Verify the email of the user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{user:{type:"object"},status:{type:"boolean"}},required:["user","status"]}}}}}}}},async e=>{function t(c){throw e.query.callbackURL?e.query.callbackURL.includes("?")?e.redirect(`${e.query.callbackURL}&error=${c}`):e.redirect(`${e.query.callbackURL}?error=${c}`):new F("UNAUTHORIZED",{message:c})}let{token:r}=e.query,o;try{o=await Jt("HS256",Buffer.from(e.context.secret),r)}catch(c){return e.context.logger.error("Failed to verify email",c),t("invalid_token")}let n=x.object({email:x.string().email(),updateTo:x.string().optional()}).parse(o.payload),s=await e.context.internalAdapter.findUserByEmail(n.email);if(!s)return t("user_not_found");if(n.updateTo){let c=await V(e);if(!c){if(e.query.callbackURL)throw e.redirect(`${e.query.callbackURL}?error=unauthorized`);return t("unauthorized")}if(c.user.email!==n.email){if(e.query.callbackURL)throw e.redirect(`${e.query.callbackURL}?error=unauthorized`);return t("unauthorized")}let a=await e.context.internalAdapter.updateUserByEmail(n.email,{email:n.updateTo,emailVerified:!1}),d=await C(e.context.secret,n.updateTo);if(await e.context.options.emailVerification?.sendVerificationEmail?.({user:a,url:`${e.context.baseURL}/verify-email?token=${d}`,token:d},e.request),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:a,status:!0})}if(await e.context.internalAdapter.updateUserByEmail(n.email,{emailVerified:!0}),e.context.options.emailVerification?.autoSignInAfterVerification&&!await V(e)){let a=await e.context.internalAdapter.createSession(s.user.id,e.request);if(!a)throw new F("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});await T(e,{session:a,user:s.user})}if(e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:null,status:!0})});async function X(e,{userInfo:t,account:r,callbackURL:o}){let i=await e.context.internalAdapter.findUserByEmail(t.email.toLowerCase(),{includeAccounts:!0}).catch(a=>{throw v.error(`Better auth was unable to query your database.
2
+ `,`Current list of trustedOrigins: ${p}`),new st("FORBIDDEN",{message:`Invalid ${E}`})};f&&!e.context.options.advanced?.disableCSRFCheck&&g(i,"origin"),n&&g(n,"callbackURL"),s&&g(s,"redirectURL"),c&&g(c,"currentURL"),a&&g(a,"errorCallbackURL"),d&&g(s,"newUserCallbackURL")});import{APIError as R}from"better-call";import{z as b}from"zod";import{TimeSpan as eo}from"oslo";import{base64url as lt}from"oslo/encoding";import{HMAC as ye,sha256 as Kr}from"oslo/crypto";async function dt({value:e,secret:t}){return new ye("SHA-256").sign(new TextEncoder().encode(t),new TextEncoder().encode(e)).then(o=>Buffer.from(o).toString("base64"))}function pt({value:e,signature:t,secret:r}){return new ye("SHA-256").verify(new TextEncoder().encode(r),Buffer.from(t,"base64"),new TextEncoder().encode(e))}var W={sign:dt,verify:pt};var N=(e,t="ms")=>new Date(Date.now()+(t==="sec"?e*1e3:e));async function T(e,t,r,o){let i=e.context.authCookies.sessionToken.options,n=r?void 0:e.context.sessionConfig.expiresIn;if(await e.setSignedCookie(e.context.authCookies.sessionToken.name,t.session.token,e.context.secret,{...i,maxAge:n,...o}),r&&await e.setSignedCookie(e.context.authCookies.dontRememberToken.name,"true",e.context.secret,e.context.authCookies.dontRememberToken.options),e.context.options.session?.cookieCache?.enabled){let c=lt.encode(new TextEncoder().encode(JSON.stringify({session:t,expiresAt:N(e.context.authCookies.sessionData.options.maxAge||60,"sec").getTime(),signature:await W.sign({value:JSON.stringify(t),secret:e.context.secret})})),{includePadding:!1});if(c.length>4093)throw new j("Session data is too large to store in the cookie. Please disable session cookie caching or reduce the size of the session data");e.setCookie(e.context.authCookies.sessionData.name,c,e.context.authCookies.sessionData.options)}e.context.setNewSession(t),e.context.options.secondaryStorage&&await e.context.secondaryStorage?.set(t.session.token,JSON.stringify({user:t.user,session:t.session}),Math.floor((new Date(t.session.expiresAt).getTime()-Date.now())/1e3))}function I(e){e.setCookie(e.context.authCookies.sessionToken.name,"",{...e.context.authCookies.sessionToken.options,maxAge:0}),e.setCookie(e.context.authCookies.sessionData.name,"",{...e.context.authCookies.sessionData.options,maxAge:0}),e.setCookie(e.context.authCookies.dontRememberToken.name,"",{...e.context.authCookies.dontRememberToken.options,maxAge:0})}import{betterFetch as wt}from"@better-fetch/fetch";import{APIError as yt}from"better-call";import{decodeProtectedHeader as bt,importJWK as At,jwtVerify as kt}from"jose";import{parseJWT as Rt}from"oslo/jwt";import{sha256 as ut}from"oslo/crypto";import{base64url as mt}from"oslo/encoding";async function be(e){let t=await ut(new TextEncoder().encode(e));return mt.encode(new Uint8Array(t),{includePadding:!1})}function Z(e){return{tokenType:e.token_type,accessToken:e.access_token,refreshToken:e.refresh_token,accessTokenExpiresAt:e.expires_in?N(e.expires_in,"sec"):void 0,scopes:e?.scope?typeof e.scope=="string"?e.scope.split(" "):e.scope:[],idToken:e.id_token}}async function y({id:e,options:t,authorizationEndpoint:r,state:o,codeVerifier:i,scopes:n,claims:s,redirectURI:c,duration:a}){let d=new URL(r);if(d.searchParams.set("response_type","code"),d.searchParams.set("client_id",t.clientId),d.searchParams.set("state",o),d.searchParams.set("scope",n.join(" ")),d.searchParams.set("redirect_uri",t.redirectURI||c),i){let p=await be(i);d.searchParams.set("code_challenge_method","S256"),d.searchParams.set("code_challenge",p)}if(s){let p=s.reduce((f,A)=>(f[A]=null,f),{});d.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...p}}))}return a&&d.searchParams.set("duration",a),d}import{betterFetch as ft}from"@better-fetch/fetch";async function h({code:e,codeVerifier:t,redirectURI:r,options:o,tokenEndpoint:i,authentication:n}){let s=new URLSearchParams,c={"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"};if(s.set("grant_type","authorization_code"),s.set("code",e),t&&s.set("code_verifier",t),s.set("redirect_uri",r),n==="basic"){let f=btoa(`${o.clientId}:${o.clientSecret}`);c.authorization=`Basic ${f}`}else s.set("client_id",o.clientId),s.set("client_secret",o.clientSecret);let{data:a,error:d}=await ft(i,{method:"POST",body:s,headers:c});if(d)throw d;return Z(a)}import{generateCodeVerifier as gt,generateState as ht}from"oslo/oauth2";import{z as L}from"zod";import{APIError as Ae}from"better-call";async function Q(e,t){let r=e.body?.callbackURL||(e.query?.currentURL?he(e.query?.currentURL):"")||e.context.options.baseURL;if(!r)throw new Ae("BAD_REQUEST",{message:"callbackURL is required"});let o=gt(),i=ht(),n=JSON.stringify({callbackURL:r,codeVerifier:o,errorURL:e.body?.errorCallbackURL||e.query?.currentURL,newUserURL:e.body?.newUserCallbackURL,link:t,expiresAt:Date.now()+10*60*1e3}),s=new Date;s.setMinutes(s.getMinutes()+10);let c=await e.context.internalAdapter.createVerificationValue({value:n,identifier:i,expiresAt:s});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 Ae("INTERNAL_SERVER_ERROR",{message:"Unable to create verification"});return{state:c.identifier,codeVerifier:o}}async function ke(e){let t=e.query.state||e.body.state,r=await e.context.internalAdapter.findVerificationValue(t);if(!r)throw e.context.logger.error("State Mismatch. Verification not found",{state:t}),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let o=L.object({callbackURL:L.string(),codeVerifier:L.string(),errorURL:L.string().optional(),newUserURL:L.string().optional(),expiresAt:L.number(),link:L.object({email:L.string(),userId:L.string()}).optional()}).parse(JSON.parse(r.value));if(o.errorURL||(o.errorURL=`${e.context.baseURL}/error`),o.expiresAt<Date.now())throw await e.context.internalAdapter.deleteVerificationValue(r.id),e.context.logger.error("State expired.",{state:t}),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);return await e.context.internalAdapter.deleteVerificationValue(r.id),o}var Re=e=>{let t="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:r,scopes:o,redirectURI:i}){let n=o||["email","name"];return e.scope&&n.push(...e.scope),new URL(`https://appleid.apple.com/auth/authorize?client_id=${e.clientId}&response_type=code&redirect_uri=${i||e.redirectURI}&scope=${n.join(" ")}&state=${r}&response_mode=form_post`)},validateAuthorizationCode:async({code:r,codeVerifier:o,redirectURI:i})=>h({code:r,codeVerifier:o,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:t}),async verifyIdToken(r,o){if(e.disableIdTokenSignIn)return!1;if(e.verifyIdToken)return e.verifyIdToken(r,o);let i=bt(r),{kid:n,alg:s}=i;if(!n||!s)return!1;let c=await Et(n),{payload:a}=await kt(r,c,{algorithms:[s],issuer:"https://appleid.apple.com",audience:e.clientId,maxTokenAge:"1h"});return["email_verified","is_private_email"].forEach(d=>{a[d]!==void 0&&(a[d]=!!a[d])}),o&&a.nonce!==o?!1:!!a},async getUserInfo(r){if(e.getUserInfo)return e.getUserInfo(r);if(!r.idToken)return null;let o=Rt(r.idToken)?.payload;if(!o)return null;let i=o.user?`${o.user.name.firstName} ${o.user.name.lastName}`:o.email,n=await e.mapProfileToUser?.(o);return{user:{id:o.sub,name:i,emailVerified:!1,email:o.email,...n},data:o}}}},Et=async e=>{let t="https://appleid.apple.com",r="/auth/keys",{data:o}=await wt(`${t}${r}`);if(!o?.keys)throw new yt("BAD_REQUEST",{message:"Keys not found"});let i=o.keys.find(n=>n.kid===e);if(!i)throw new Error(`JWK with kid ${e} not found`);return await At(i,i.alg)};import{betterFetch as Ut}from"@better-fetch/fetch";var Ee=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=r||["identify","email"];return e.scope&&i.push(...e.scope),new URL(`https://discord.com/api/oauth2/authorize?scope=${i.join("+")}&response_type=code&client_id=${e.clientId}&redirect_uri=${encodeURIComponent(e.redirectURI||o)}&state=${t}&prompt=${e.prompt||"none"}`)},validateAuthorizationCode:async({code:t,redirectURI:r})=>h({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:o}=await Ut("https://discord.com/api/users/@me",{headers:{authorization:`Bearer ${t.accessToken}`}});if(o)return null;if(r.avatar===null){let n=r.discriminator==="0"?Number(BigInt(r.id)>>BigInt(22))%6:parseInt(r.discriminator)%5;r.image_url=`https://cdn.discordapp.com/embed/avatars/${n}.png`}else{let n=r.avatar.startsWith("a_")?"gif":"png";r.image_url=`https://cdn.discordapp.com/avatars/${r.id}/${r.avatar}.${n}`}let i=await e.mapProfileToUser?.(r);return{user:{id:r.id,name:r.display_name||r.username||"",email:r.email,emailVerified:r.verified,image:r.image_url,...i},data:r}}});import{betterFetch as _t}from"@better-fetch/fetch";var Ue=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=r||["email","public_profile"];return e.scope&&i.push(...e.scope),await y({id:"facebook",options:e,authorizationEndpoint:"https://www.facebook.com/v21.0/dialog/oauth",scopes:i,state:t,redirectURI:o})},validateAuthorizationCode:async({code:t,redirectURI:r})=>h({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://graph.facebook.com/oauth/access_token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:o}=await _t("https://graph.facebook.com/me?fields=id,name,email,picture",{auth:{type:"Bearer",token:t.accessToken}});if(o)return null;let i=await e.mapProfileToUser?.(r);return{user:{id:r.id,name:r.name,email:r.email,image:r.picture.data.url,emailVerified:r.email_verified,...i},data:r}}});import{betterFetch as _e}from"@better-fetch/fetch";var Te=e=>{let t="https://github.com/login/oauth/access_token";return{id:"github",name:"GitHub",createAuthorizationURL({state:r,scopes:o,codeVerifier:i,redirectURI:n}){let s=o||["user:email"];return e.scope&&s.push(...e.scope),y({id:"github",options:e,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:s,state:r,redirectURI:n})},validateAuthorizationCode:async({code:r,redirectURI:o})=>h({code:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:t}),async getUserInfo(r){if(e.getUserInfo)return e.getUserInfo(r);let{data:o,error:i}=await _e("https://api.github.com/user",{headers:{"User-Agent":"better-auth",authorization:`Bearer ${r.accessToken}`}});if(i)return null;let n=!1;if(!o.email){let{data:c,error:a}=await _e("https://api.github.com/user/emails",{headers:{authorization:`Bearer ${r.accessToken}`,"User-Agent":"better-auth"}});a||(o.email=(c.find(d=>d.primary)??c[0])?.email,n=c.find(d=>d.email===o.email)?.verified??!1)}let s=await e.mapProfileToUser?.(o);return{user:{id:o.id.toString(),name:o.name||o.login,email:o.email,image:o.avatar_url,emailVerified:n,...s},data:o}}}};import{parseJWT as xt}from"oslo/jwt";import{createConsola as Tt}from"consola";var ce=["info","success","warn","error","debug"];function St(e,t){return ce.indexOf(t)<=ce.indexOf(e)}var Ot=Tt({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),vt=e=>{let t=e?.disabled!==!0,r=e?.level??"error",o=(i,n,s=[])=>{if(!(!t||!St(r,i))){if(!e||typeof e.log!="function"){Ot[i]("",n,...s);return}e.log(i==="success"?"info":i,n,s)}};return Object.fromEntries(ce.map(i=>[i,(...[n,...s])=>o(i,n,s)]))},v=vt();import{betterFetch as Pt}from"@better-fetch/fetch";var Se=e=>({id:"google",name:"Google",async createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:i}){if(!e.clientId||!e.clientSecret)throw v.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new j("CLIENT_ID_AND_SECRET_REQUIRED");if(!o)throw new j("codeVerifier is required for Google");let n=r||["email","profile","openid"];e.scope&&n.push(...e.scope);let s=await y({id:"google",options:e,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:n,state:t,codeVerifier:o,redirectURI:i});return e.accessType&&s.searchParams.set("access_type",e.accessType),e.prompt&&s.searchParams.set("prompt",e.prompt),s},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>h({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://oauth2.googleapis.com/token"}),async verifyIdToken(t,r){if(e.disableIdTokenSignIn)return!1;if(e.verifyIdToken)return e.verifyIdToken(t,r);let o=`https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=${t}`,{data:i}=await Pt(o);return i?i.aud===e.clientId&&i.iss==="https://accounts.google.com":!1},async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);if(!t.idToken)return null;let r=xt(t.idToken)?.payload,o=await e.mapProfileToUser?.(r);return{user:{id:r.sub,name:r.name,email:r.email,image:r.picture,emailVerified:r.email_verified,...o},data:r}}});import{betterFetch as It}from"@better-fetch/fetch";import{parseJWT as Lt}from"oslo/jwt";var Oe=e=>{let t=e.tenantId||"common",r=`https://login.microsoftonline.com/${t}/oauth2/v2.0/authorize`,o=`https://login.microsoftonline.com/${t}/oauth2/v2.0/token`;return{id:"microsoft",name:"Microsoft EntraID",createAuthorizationURL(i){let n=i.scopes||["openid","profile","email","User.Read"];return e.scope&&n.push(...e.scope),y({id:"microsoft",options:e,authorizationEndpoint:r,state:i.state,codeVerifier:i.codeVerifier,scopes:n,redirectURI:i.redirectURI})},validateAuthorizationCode({code:i,codeVerifier:n,redirectURI:s}){return h({code:i,codeVerifier:n,redirectURI:e.redirectURI||s,options:e,tokenEndpoint:o})},async getUserInfo(i){if(e.getUserInfo)return e.getUserInfo(i);if(!i.idToken)return null;let n=Lt(i.idToken)?.payload,s=e.profilePhotoSize||48;await It(`https://graph.microsoft.com/v1.0/me/photos/${s}x${s}/$value`,{headers:{Authorization:`Bearer ${i.accessToken}`},async onResponse(a){if(!(e.disableProfilePhoto||!a.response.ok))try{let p=await a.response.clone().arrayBuffer(),f=Buffer.from(p).toString("base64");n.picture=`data:image/jpeg;base64, ${f}`}catch(d){v.error(d&&typeof d=="object"&&"name"in d?d.name:"",d)}}});let c=await e.mapProfileToUser?.(n);return{user:{id:n.sub,name:n.name,email:n.email,image:n.picture,emailVerified:!0,...c},data:n}}}};import{betterFetch as Dt}from"@better-fetch/fetch";var ve=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:i}){let n=r||["user-read-email"];return e.scope&&n.push(...e.scope),y({id:"spotify",options:e,authorizationEndpoint:"https://accounts.spotify.com/authorize",scopes:n,state:t,codeVerifier:o,redirectURI:i})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>h({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://accounts.spotify.com/api/token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:o}=await Dt("https://api.spotify.com/v1/me",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});if(o)return null;let i=await e.mapProfileToUser?.(r);return{user:{id:r.id,name:r.display_name,email:r.email,image:r.images[0]?.url,emailVerified:!1,...i},data:r}}});var $={isAction:!1};import{nanoid as Ct}from"nanoid";var xe=e=>Ct(e);import{parseJWT as jt}from"oslo/jwt";var Pe=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=r||["user:read:email","openid"];return e.scope&&i.push(...e.scope),y({id:"twitch",redirectURI:o,options:e,authorizationEndpoint:"https://id.twitch.tv/oauth2/authorize",scopes:i,state:t,claims:e.claims||["email","email_verified","preferred_username","picture"]})},validateAuthorizationCode:async({code:t,redirectURI:r})=>h({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let r=t.idToken;if(!r)return v.error("No idToken found in token"),null;let o=jt(r)?.payload,i=await e.mapProfileToUser?.(o);return{user:{id:o.sub,name:o.preferred_username,email:o.email,image:o.picture,emailVerified:!1,...i},data:o}}});import{betterFetch as Nt}from"@better-fetch/fetch";var Ie=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(t){let r=t.scopes||["users.read","tweet.read","offline.access"];return e.scope&&r.push(...e.scope),y({id:"twitter",options:e,authorizationEndpoint:"https://x.com/i/oauth2/authorize",scopes:r,state:t.state,codeVerifier:t.codeVerifier,redirectURI:t.redirectURI})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>h({code:t,codeVerifier:r,authentication:"basic",redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://api.x.com/2/oauth2/token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:o}=await Nt("https://api.x.com/2/users/me?user.fields=profile_image_url",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});if(o)return null;let i=await e.mapProfileToUser?.(r);return{user:{id:r.data.id,name:r.data.name,email:r.data.username||null,image:r.data.profile_image_url,emailVerified:r.data.verified||!1,...i},data:r}}});import{betterFetch as Bt}from"@better-fetch/fetch";var Le=e=>{let t="https://api.dropboxapi.com/oauth2/token";return{id:"dropbox",name:"Dropbox",createAuthorizationURL:async({state:r,scopes:o,codeVerifier:i,redirectURI:n})=>{let s=o||["account_info.read"];return e.scope&&s.push(...e.scope),await y({id:"dropbox",options:e,authorizationEndpoint:"https://www.dropbox.com/oauth2/authorize",scopes:s,state:r,redirectURI:n,codeVerifier:i})},validateAuthorizationCode:async({code:r,codeVerifier:o,redirectURI:i})=>await h({code:r,codeVerifier:o,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:t}),async getUserInfo(r){if(e.getUserInfo)return e.getUserInfo(r);let{data:o,error:i}=await Bt("https://api.dropboxapi.com/2/users/get_current_account",{method:"POST",headers:{Authorization:`Bearer ${r.accessToken}`}});if(i)return null;let n=await e.mapProfileToUser?.(o);return{user:{id:o.account_id,name:o.name?.display_name,email:o.email,emailVerified:o.email_verified||!1,image:o.profile_photo_url,...n},data:o}}}};import{betterFetch as Vt}from"@better-fetch/fetch";var De=e=>{let t="https://www.linkedin.com/oauth/v2/authorization",r="https://www.linkedin.com/oauth/v2/accessToken";return{id:"linkedin",name:"Linkedin",createAuthorizationURL:async({state:o,scopes:i,redirectURI:n})=>{let s=i||["profile","email","openid"];return e.scope&&s.push(...e.scope),await y({id:"linkedin",options:e,authorizationEndpoint:t,scopes:s,state:o,redirectURI:n})},validateAuthorizationCode:async({code:o,redirectURI:i})=>await h({code:o,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:r}),async getUserInfo(o){let{data:i,error:n}=await Vt("https://api.linkedin.com/v2/userinfo",{method:"GET",headers:{Authorization:`Bearer ${o.accessToken}`}});if(n)return null;let s=await e.mapProfileToUser?.(i);return{user:{id:i.sub,name:i.name,email:i.email,emailVerified:i.email_verified||!1,image:i.picture,...s},data:i}}}};import{betterFetch as $t}from"@better-fetch/fetch";var de=(e="")=>e.split("://").map(t=>t.replace(/\/{2,}/g,"/")).join("://"),zt=e=>{let t=e||"https://gitlab.com";return{authorizationEndpoint:de(`${t}/oauth/authorize`),tokenEndpoint:de(`${t}/oauth/token`),userinfoEndpoint:de(`${t}/api/v4/user`)}},Ce=e=>{let{authorizationEndpoint:t,tokenEndpoint:r,userinfoEndpoint:o}=zt(e.issuer),i="gitlab";return{id:i,name:"Gitlab",createAuthorizationURL:async({state:s,scopes:c,codeVerifier:a,redirectURI:d})=>{let p=c||["read_user"];return e.scope&&p.push(...e.scope),await y({id:i,options:e,authorizationEndpoint:t,scopes:p,state:s,redirectURI:d,codeVerifier:a})},validateAuthorizationCode:async({code:s,redirectURI:c,codeVerifier:a})=>h({code:s,redirectURI:e.redirectURI||c,options:e,codeVerifier:a,tokenEndpoint:r}),async getUserInfo(s){if(e.getUserInfo)return e.getUserInfo(s);let{data:c,error:a}=await $t(o,{headers:{authorization:`Bearer ${s.accessToken}`}});if(a||c.state!=="active"||c.locked)return null;let d=await e.mapProfileToUser?.(c);return{user:{id:c.id.toString(),name:c.name??c.username,email:c.email,image:c.avatar_url,emailVerified:!0,...d},data:c}}}};import{betterFetch as je}from"@better-fetch/fetch";var Ne=e=>({id:"reddit",name:"Reddit",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=r||["identity"];return e.scope&&i.push(...e.scope),y({id:"reddit",options:e,authorizationEndpoint:"https://www.reddit.com/api/v1/authorize",scopes:i,state:t,redirectURI:o,duration:e.duration})},validateAuthorizationCode:async({code:t,redirectURI:r})=>{let o=new URLSearchParams({grant_type:"authorization_code",code:t,redirect_uri:e.redirectURI||r}),i={"content-type":"application/x-www-form-urlencoded",accept:"text/plain","user-agent":"better-auth",Authorization:`Basic ${Buffer.from(`${e.clientId}:${e.clientSecret}`).toString("base64")}`},{data:n,error:s}=await je("https://www.reddit.com/api/v1/access_token",{method:"POST",headers:i,body:o.toString()});if(s)throw s;return Z(n)},async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:o}=await je("https://oauth.reddit.com/api/v1/me",{headers:{Authorization:`Bearer ${t.accessToken}`,"User-Agent":"better-auth"}});if(o)return null;let i=await e.mapProfileToUser?.(r);return{user:{id:r.id,name:r.name,email:r.oauth_client_id,emailVerified:r.has_verified_email,image:r.icon_img?.split("?")[0],...i},data:r}}});var qt={apple:Re,discord:Ee,facebook:Ue,github:Te,microsoft:Oe,google:Se,spotify:ve,twitch:Pe,twitter:Ie,dropbox:Le,linkedin:De,gitlab:Ce,reddit:Ne},Y=Object.keys(qt);import{TimeSpan as Gt}from"oslo";import{createJWT as Kt,validateJWT as Jt}from"oslo/jwt";import{z as x}from"zod";import{APIError as F}from"better-call";import{APIError as D}from"better-call";import{z as B}from"zod";function Be(e){try{return JSON.parse(e)}catch{return null}}var l={USER_NOT_FOUND:"User not found",FAILED_TO_CREATE_USER:"Failed to create user",FAILED_TO_CREATE_SESSION:"Failed to create session",FAILED_TO_UPDATE_USER:"Failed to update user",FAILED_TO_GET_SESSION:"Failed to get session",INVALID_PASSWORD:"Invalid password",INVALID_EMAIL:"Invalid email",INVALID_EMAIL_OR_PASSWORD:"Invalid email or password",SOCIAL_ACCOUNT_ALREADY_LINKED:"Social account already linked",PROVIDER_NOT_FOUND:"Provider not found",INVALID_TOKEN:"invalid token",ID_TOKEN_NOT_SUPPORTED:"id_token not supported",FAILED_TO_GET_USER_INFO:"Failed to get user info",USER_EMAIL_NOT_FOUND:"User email not found",EMAIL_NOT_VERIFIED:"Email not verified",PASSWORD_TOO_SHORT:"Password too short",PASSWORD_TOO_LONG:"Password too long",USER_ALREADY_EXISTS:"User already exists",EMAIL_CAN_NOT_BE_UPDATED:"Email can not be updated",CREDENTIAL_ACCOUNT_NOT_FOUND:"Credential account not found"};var Ve=()=>m("/get-session",{method:"GET",query:B.optional(B.object({disableCookieCache:B.boolean({description:"Disable cookie cache and fetch session from database"}).or(B.string().transform(e=>e==="true")).optional(),disableRefresh:B.boolean({description:"Disable session refresh. Useful for checking session status, without updating the session"}).optional()})),requireHeaders:!0,metadata:{openapi:{description:"Get the current session",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{session:{type:"object",properties:{token:{type:"string"},userId:{type:"string"},expiresAt:{type:"string"}}},user:{type:"object",$ref:"#/components/schemas/User"}}}}}}}}}},async e=>{try{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)return e.json(null);let r=e.getCookie(e.context.authCookies.sessionData.name),o=r?Be(Buffer.from(r,"base64").toString()):null;if(o&&!await W.verify({value:JSON.stringify(o.session),signature:o?.signature,secret:e.context.secret}))return I(e),e.json(null);let i=await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret);if(o?.session&&e.context.options.session?.cookieCache?.enabled&&!e.query?.disableCookieCache){let p=o.session;if(o.expiresAt<Date.now()||p.session.expiresAt<new Date){let A=e.context.authCookies.sessionData.name;e.setCookie(A,"",{maxAge:0})}else return e.json(p)}let n=await e.context.internalAdapter.findSession(t);if(e.context.session=n,!n||n.session.expiresAt<new Date)return I(e),n&&await e.context.internalAdapter.deleteSession(n.session.token),e.json(null);if(i||e.query?.disableRefresh)return e.json(n);let s=e.context.sessionConfig.expiresIn,c=e.context.sessionConfig.updateAge;if(n.session.expiresAt.valueOf()-s*1e3+c*1e3<=Date.now()){let p=await e.context.internalAdapter.updateSession(n.session.token,{expiresAt:N(e.context.sessionConfig.expiresIn,"sec")});if(!p)return I(e),e.json(null,{status:401});let f=(p.expiresAt.valueOf()-Date.now())/1e3;return await T(e,{session:p,user:n.user},!1,{maxAge:f}),e.json({session:p,user:n.user})}return e.json(n)}catch(t){throw e.context.logger.error("INTERNAL_SERVER_ERROR",t),new D("INTERNAL_SERVER_ERROR",{message:l.FAILED_TO_GET_SESSION})}}),V=async(e,t)=>{if(e.context.session)return e.context.session;let r=await Ve()({...e,_flag:"json",headers:e.headers,query:t}).catch(o=>null);return e.context.session=r,r},S=q(async e=>{let t=await V(e);if(!t?.session)throw new D("UNAUTHORIZED");return{session:t}}),$e=q(async e=>{let t=await V(e);if(!t?.session)throw new D("UNAUTHORIZED");if(e.context.sessionConfig.freshAge===0)return{session:t};let r=e.context.sessionConfig.freshAge,o=t.session.updatedAt?.valueOf()||t.session.createdAt.valueOf();if(!(Date.now()-o<r*1e3))throw new D("FORBIDDEN",{message:"Session is not fresh"});return{session:t}});var Mt=m("/revoke-session",{method:"POST",body:B.object({token:B.string({description:"The token to revoke"})}),use:[S],requireHeaders:!0,metadata:{openapi:{description:"Revoke a single session",requestBody:{content:{"application/json":{schema:{type:"object",properties:{token:{type:"string"}},required:["token"]}}}}}}},async e=>{let t=e.body.token,r=await e.context.internalAdapter.findSession(t);if(!r)throw new D("BAD_REQUEST",{message:"Session not found"});if(r.session.userId!==e.context.session.user.id)throw new D("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(t)}catch(o){throw e.context.logger.error(o&&typeof o=="object"&&"name"in o?o.name:"",o),new D("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),Ft=m("/revoke-sessions",{method:"POST",use:[S],requireHeaders:!0,metadata:{openapi:{description:"Revoke all sessions for the user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean"}},required:["status"]}}}}}}}},async e=>{try{await e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(t){throw e.context.logger.error(t&&typeof t=="object"&&"name"in t?t.name:"",t),new D("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),Ht=m("/revoke-other-sessions",{method:"POST",requireHeaders:!0,use:[S],metadata:{openapi:{description:"Revoke all other sessions for the user except the current one",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean"}}}}}}}}}},async e=>{let t=e.context.session;if(!t.user)throw new D("UNAUTHORIZED");let i=(await e.context.internalAdapter.listSessions(t.user.id)).filter(n=>n.expiresAt>new Date).filter(n=>n.token!==e.context.session.session.token);return await Promise.all(i.map(n=>e.context.internalAdapter.deleteSession(n.token))),e.json({status:!0})});async function C(e,t,r){return await Kt("HS256",Buffer.from(e),{email:t.toLowerCase(),updateTo:r},{expiresIn:new Gt(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}async function Wt(e,t){if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new F("BAD_REQUEST",{message:"Verification email isn't enabled"});let r=await C(e.context.secret,t.email),o=`${e.context.baseURL}/verify-email?token=${r}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;await e.context.options.emailVerification.sendVerificationEmail({user:t,url:o,token:r},e.request)}var Zt=m("/send-verification-email",{method:"POST",query:x.object({currentURL:x.string({description:"The URL to use for email verification callback"}).optional()}).optional(),body:x.object({email:x.string({description:"The email to send the verification email to"}).email(),callbackURL:x.string({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"},callbackURL:{type:"string",description:"The URL to use for email verification callback"}},required:["email"]}}}},responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean"}}}}}}}}}},async e=>{if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new F("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:t}=e.body,r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw new F("BAD_REQUEST",{message:l.USER_NOT_FOUND});return await Wt(e,r.user),e.json({status:!0})}),Qt=m("/verify-email",{method:"GET",query:x.object({token:x.string({description:"The token to verify the email"}),callbackURL:x.string({description:"The URL to redirect to after email verification"}).optional()}),metadata:{openapi:{description:"Verify the email of the user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{user:{type:"object"},status:{type:"boolean"}},required:["user","status"]}}}}}}}},async e=>{function t(c){throw e.query.callbackURL?e.query.callbackURL.includes("?")?e.redirect(`${e.query.callbackURL}&error=${c}`):e.redirect(`${e.query.callbackURL}?error=${c}`):new F("UNAUTHORIZED",{message:c})}let{token:r}=e.query,o;try{o=await Jt("HS256",Buffer.from(e.context.secret),r)}catch(c){return e.context.logger.error("Failed to verify email",c),t("invalid_token")}let n=x.object({email:x.string().email(),updateTo:x.string().optional()}).parse(o.payload),s=await e.context.internalAdapter.findUserByEmail(n.email);if(!s)return t("user_not_found");if(n.updateTo){let c=await V(e);if(!c){if(e.query.callbackURL)throw e.redirect(`${e.query.callbackURL}?error=unauthorized`);return t("unauthorized")}if(c.user.email!==n.email){if(e.query.callbackURL)throw e.redirect(`${e.query.callbackURL}?error=unauthorized`);return t("unauthorized")}let a=await e.context.internalAdapter.updateUserByEmail(n.email,{email:n.updateTo,emailVerified:!1}),d=await C(e.context.secret,n.updateTo);if(await e.context.options.emailVerification?.sendVerificationEmail?.({user:a,url:`${e.context.baseURL}/verify-email?token=${d}`,token:d},e.request),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:a,status:!0})}if(await e.context.internalAdapter.updateUserByEmail(n.email,{emailVerified:!0}),e.context.options.emailVerification?.autoSignInAfterVerification&&!await V(e)){let a=await e.context.internalAdapter.createSession(s.user.id,e.request);if(!a)throw new F("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});await T(e,{session:a,user:s.user})}if(e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:null,status:!0})});async function X(e,{userInfo:t,account:r,callbackURL:o}){let i=await e.context.internalAdapter.findUserByEmail(t.email.toLowerCase(),{includeAccounts:!0}).catch(a=>{throw v.error(`Better auth was unable to query your database.
3
3
  Error: `,a),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)}),n=i?.user,s=!n;if(i){let a=i.accounts.find(d=>d.providerId===r.providerId);if(a){let d=Object.fromEntries(Object.entries({accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,accessTokenExpiresAt:r.accessTokenExpiresAt,refreshTokenExpiresAt:r.refreshTokenExpiresAt}).filter(([p,f])=>f!==void 0));Object.keys(d).length>0&&await e.context.internalAdapter.updateAccount(a.id,d)}else{if(!e.context.options.account?.accountLinking?.trustedProviders?.includes(r.providerId)&&!t.emailVerified||e.context.options.account?.accountLinking?.enabled===!1)return ae&&v.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:i.user.id,accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,accessTokenExpiresAt:r.accessTokenExpiresAt,refreshTokenExpiresAt:r.refreshTokenExpiresAt,scope:r.scope})}catch(f){return v.error("Unable to link account",f),{error:"unable to link account",data:null}}n=await e.context.internalAdapter.updateUser(i.user.id,{...t,updatedAt:new Date})}}else if(n=await e.context.internalAdapter.createOAuthUser({...t,email:t.email.toLowerCase(),id:void 0},{accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,accessTokenExpiresAt:r.accessTokenExpiresAt,refreshTokenExpiresAt:r.refreshTokenExpiresAt,scope:r.scope,providerId:r.providerId,accountId:t.id.toString()}).then(a=>a?.user),!t.emailVerified&&n&&e.context.options.emailVerification?.sendOnSignUp){let a=await C(e.context.secret,n.email),d=`${e.context.baseURL}/verify-email?token=${a}&callbackURL=${o}`;await e.context.options.emailVerification?.sendVerificationEmail?.({user:n,url:d,token:a},e.request)}if(!n)return{error:"unable to create user",data:null,isRegister:!1};let c=await e.context.internalAdapter.createSession(n.id,e.request);return c?{data:{session:c,user:n},error:null,isRegister:s}:{error:"unable to create session",data:null,isRegister:!1}}var Yt=m("/sign-in/social",{method:"POST",query:b.object({currentURL:b.string().optional()}).optional(),body:b.object({callbackURL:b.string({description:"Callback URL to redirect to after the user has signed in"}).optional(),newUserCallbackURL:b.string().optional(),errorCallbackURL:b.string({description:"Callback URL to redirect to if an error happens"}).optional(),provider:b.enum(Y,{description:"OAuth2 provider to use"}),disableRedirect:b.boolean({description:"Disable automatic redirection to the provider. Useful for handling the redirection yourself"}).optional(),idToken:b.optional(b.object({token:b.string({description:"ID token from the provider"}),nonce:b.string({description:"Nonce used to generate the token"}).optional(),accessToken:b.string({description:"Access token from the provider"}).optional(),refreshToken:b.string({description:"Refresh token from the provider"}).optional(),expiresAt:b.number({description:"Expiry date of the token"}).optional()}),{description:"ID token from the provider to sign in the user with id token"})}),metadata:{openapi:{description:"Sign in with a social provider",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{session:{type:"string"},user:{type:"object"},url:{type:"string"},redirect:{type:"boolean"}},required:["session","user","url","redirect"]}}}}}}}},async e=>{let t=e.context.socialProviders.find(n=>n.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 R("NOT_FOUND",{message:l.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 R("NOT_FOUND",{message:l.ID_TOKEN_NOT_SUPPORTED});let{token:n,nonce:s}=e.body.idToken;if(!await t.verifyIdToken(n,s))throw e.context.logger.error("Invalid id token",{provider:e.body.provider}),new R("UNAUTHORIZED",{message:l.INVALID_TOKEN});let a=await t.getUserInfo({idToken:n,accessToken:e.body.idToken.accessToken,refreshToken:e.body.idToken.refreshToken});if(!a||!a?.user)throw e.context.logger.error("Failed to get user info",{provider:e.body.provider}),new R("UNAUTHORIZED",{message:l.FAILED_TO_GET_USER_INFO});if(!a.user.email)throw e.context.logger.error("User email not found",{provider:e.body.provider}),new R("UNAUTHORIZED",{message:l.USER_EMAIL_NOT_FOUND});let d=await X(e,{userInfo:{email:a.user.email,id:a.user.id,name:a.user.name||"",image:a.user.image,emailVerified:a.user.emailVerified||!1},account:{providerId:t.id,accountId:a.user.id,accessToken:e.body.idToken.accessToken}});if(d.error)throw new R("UNAUTHORIZED",{message:d.error});return await T(e,d.data),e.json({session:d.data.session,user:d.data.user,url:void 0,redirect:!1})}let{codeVerifier:r,state:o}=await Q(e),i=await t.createAuthorizationURL({state:o,codeVerifier:r,redirectURI:`${e.context.baseURL}/callback/${t.id}`});return e.json({url:i.toString(),redirect:!e.body.disableRedirect})}),Xt=m("/sign-in/email",{method:"POST",body:b.object({email:b.string({description:"Email of the user"}),password:b.string({description:"Password of the user"}),callbackURL:b.string({description:"Callback URL to use as a redirect for email verification"}).optional(),rememberMe:b.boolean({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",content:{"application/json":{schema:{type:"object",properties:{user:{type:"object"},url:{type:"string"},redirect:{type:"boolean"}},required:["session","user","url","redirect"]}}}}}}}},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 R("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:t,password:r}=e.body;if(!b.string().email().safeParse(t).success)throw new R("BAD_REQUEST",{message:l.INVALID_EMAIL});let i=await e.context.internalAdapter.findUserByEmail(t,{includeAccounts:!0});if(!i)throw await e.context.password.hash(r),e.context.logger.error("User not found",{email:t}),new R("UNAUTHORIZED",{message:l.INVALID_EMAIL_OR_PASSWORD});let n=i.accounts.find(d=>d.providerId==="credential");if(!n)throw e.context.logger.error("Credential account not found",{email:t}),new R("UNAUTHORIZED",{message:l.INVALID_EMAIL_OR_PASSWORD});let s=n?.password;if(!s)throw e.context.logger.error("Password not found",{email:t}),new R("UNAUTHORIZED",{message:l.INVALID_EMAIL_OR_PASSWORD});if(!await e.context.password.verify({hash:s,password:r}))throw e.context.logger.error("Invalid password"),new R("UNAUTHORIZED",{message:l.INVALID_EMAIL_OR_PASSWORD});if(e.context.options?.emailAndPassword?.requireEmailVerification&&!i.user.emailVerified){if(!e.context.options?.emailVerification?.sendVerificationEmail)throw new R("UNAUTHORIZED",{message:l.EMAIL_NOT_VERIFIED});let d=await C(e.context.secret,i.user.email),p=`${e.context.baseURL}/verify-email?token=${d}&callbackURL=${e.body.callbackURL||"/"}`;throw await e.context.options.emailVerification.sendVerificationEmail({user:i.user,url:p,token:d},e.request),e.context.logger.error("Email not verified",{email:t}),new R("FORBIDDEN",{message:l.EMAIL_NOT_VERIFIED})}let a=await e.context.internalAdapter.createSession(i.user.id,e.headers,e.body.rememberMe===!1);if(!a)throw e.context.logger.error("Failed to create session"),new R("UNAUTHORIZED",{message:l.FAILED_TO_CREATE_SESSION});return await T(e,{session:a,user:i.user},e.body.rememberMe===!1),e.json({user:{id:i.user.id,email:i.user.email,name:i.user.name,image:i.user.image,emailVerified:i.user.emailVerified,createdAt:i.user.createdAt,updatedAt:i.user.updatedAt},redirect:!!e.body.callbackURL,url:e.body.callbackURL})});import{z as H}from"zod";var ee=H.object({code:H.string().optional(),error:H.string().optional(),error_description:H.string().optional(),state:H.string().optional()}),er=m("/callback/:id",{method:["GET","POST"],body:ee.optional(),query:ee.optional(),metadata:$},async e=>{let t;try{if(e.method==="GET")t=ee.parse(e.query);else if(e.method==="POST")t=ee.parse(e.body);else throw new Error("Unsupported method")}catch(_){throw e.context.logger.error("INVALID_CALLBACK_REQUEST",_),e.redirect(`${e.context.baseURL}/error?error=invalid_callback_request`)}let{code:r,error:o,state:i,error_description:n}=t;if(!i)throw e.context.logger.error("State not found",o),e.redirect(`${e.context.baseURL}/error?error=state_not_found`);if(!r)throw e.context.logger.error("Code not found"),e.redirect(`${e.context.baseURL}/error?error=${o||"no_code"}&error_description=${n}`);let s=e.context.socialProviders.find(_=>_.id===e.params.id);if(!s)throw e.context.logger.error("Oauth provider with id",e.params.id,"not found"),e.redirect(`${e.context.baseURL}/error?error=oauth_provider_not_found`);let{codeVerifier:c,callbackURL:a,link:d,errorURL:p,newUserURL:f}=await ke(e),A;try{A=await s.validateAuthorizationCode({code:r,codeVerifier:c,redirectURI:`${e.context.baseURL}/callback/${s.id}`})}catch(_){throw e.context.logger.error("",_),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let g=await s.getUserInfo(A).then(_=>_?.user);function w(_){let P=p||a||`${e.context.baseURL}/error`;throw P.includes("?")?P=`${P}&error=${_}`:P=`${P}?error=${_}`,e.redirect(P)}if(!g)return e.context.logger.error("Unable to get user info"),w("unable_to_get_user_info");if(!g.email)return e.context.logger.error("Provider did not return email. This could be due to misconfiguration in the provider settings."),w("email_not_found");if(!a)throw e.context.logger.error("No callback URL found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(d){if(d.email!==g.email.toLowerCase())return w("email_doesn't_match");if(!await e.context.internalAdapter.createAccount({userId:d.userId,providerId:s.id,accountId:g.id}))return w("unable_to_link_account");let P;try{P=a.toString()}catch{P=a}throw e.redirect(P)}let E=await X(e,{userInfo:{...g,email:g.email,name:g.name||g.email},account:{providerId:s.id,accountId:g.id,...A,scope:A.scopes?.join(",")},callbackURL:a});if(E.error)return e.context.logger.error(E.error.split(" ").join("_")),w(E.error.split(" ").join("_"));let{session:pe,user:te}=E.data;await T(e,{session:pe,user:te});let re;try{re=(E.isRegister&&f||a).toString()}catch{re=E.isRegister&&f||a}throw e.redirect(re)});import"zod";import{APIError as tr}from"better-call";var rr=m("/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);if(!t)throw I(e),new tr("BAD_REQUEST",{message:l.FAILED_TO_GET_SESSION});return await e.context.internalAdapter.deleteSession(t),I(e),e.json({success:!0})});import{z as O}from"zod";import{APIError as G}from"better-call";function ze(e,t,r){let o=t?new URL(t,e.baseURL):new URL(`${e.baseURL}/error`);return r&&Object.entries(r).forEach(([i,n])=>o.searchParams.set(i,n)),o.href}function or(e,t,r){let o=new URL(t,e.baseURL);return r&&Object.entries(r).forEach(([i,n])=>o.searchParams.set(i,n)),o.href}var ir=m("/forget-password",{method:"POST",body:O.object({email:O.string({description:"The email address of the user to send a password reset email to"}).email(),redirectTo:O.string({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"}}}}}}}}}},async e=>{if(!e.context.options.emailAndPassword?.sendResetPassword)throw e.context.logger.error("Reset password isn't enabled.Please pass an emailAndPassword.sendResetPasswordToken function in your auth config!"),new G("BAD_REQUEST",{message:"Reset password isn't enabled"});let{email:t,redirectTo:r}=e.body,o=await e.context.internalAdapter.findUserByEmail(t,{includeAccounts:!0});if(!o)return e.context.logger.error("Reset Password: User not found",{email:t}),e.json({status:!1},{body:{status:!0}});let i=60*60*1,n=N(e.context.options.emailAndPassword.resetPasswordTokenExpiresIn||i,"sec"),s=xe(24);await e.context.internalAdapter.createVerificationValue({value:o.user.id.toString(),identifier:`reset-password:${s}`,expiresAt:n});let c=`${e.context.baseURL}/reset-password/${s}?callbackURL=${r}`;return await e.context.options.emailAndPassword.sendResetPassword({user:o.user,url:c,token:s},e.request),e.json({status:!0})}),nr=m("/reset-password/:token",{method:"GET",query:O.object({callbackURL:O.string({description:"The URL to redirect the user to reset their password"})}),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(ze(e.context,r,{error:"INVALID_TOKEN"}));let o=await e.context.internalAdapter.findVerificationValue(`reset-password:${t}`);throw!o||o.expiresAt<new Date?e.redirect(ze(e.context,r,{error:"INVALID_TOKEN"})):e.redirect(or(e.context,r,{token:t}))}),sr=m("/reset-password",{query:O.optional(O.object({token:O.string().optional(),currentURL:O.string().optional()})),method:"POST",body:O.object({newPassword:O.string({description:"The new password to set"}),token:O.string({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||(e.query?.currentURL?new URL(e.query.currentURL).searchParams.get("token"):"");if(!t)throw new G("BAD_REQUEST",{message:l.INVALID_TOKEN});let{newPassword:r}=e.body,o=e.context.password?.config.minPasswordLength,i=e.context.password?.config.maxPasswordLength;if(r.length<o)throw new G("BAD_REQUEST",{message:l.PASSWORD_TOO_SHORT});if(r.length>i)throw new G("BAD_REQUEST",{message:l.PASSWORD_TOO_LONG});let n=`reset-password:${t}`,s=await e.context.internalAdapter.findVerificationValue(n);if(!s||s.expiresAt<new Date)throw new G("BAD_REQUEST",{message:l.INVALID_TOKEN});await e.context.internalAdapter.deleteVerificationValue(s.id);let c=s.value,a=await e.context.password.hash(r);return(await e.context.internalAdapter.findAccounts(c)).find(f=>f.providerId==="credential")?(await e.context.internalAdapter.updatePassword(c,a),e.json({status:!0})):(await e.context.internalAdapter.createAccount({userId:c,providerId:"credential",password:a,accountId:c}),e.json({status:!0}))});import{z as U}from"zod";import{APIError as k}from"better-call";import{z as u}from"zod";import{APIError as fs}from"better-call";var gs=u.object({id:u.string(),providerId:u.string(),accountId:u.string(),userId:u.string(),accessToken:u.string().nullish(),refreshToken:u.string().nullish(),idToken:u.string().nullish(),accessTokenExpiresAt:u.date().nullish(),refreshTokenExpiresAt:u.date().nullish(),scope:u.string().nullish(),password:u.string().nullish(),createdAt:u.date().default(()=>new Date),updatedAt:u.date().default(()=>new Date)}),hs=u.object({id:u.string(),email:u.string().transform(e=>e.toLowerCase()),emailVerified:u.boolean().default(!1),name:u.string(),image:u.string().nullish(),createdAt:u.date().default(()=>new Date),updatedAt:u.date().default(()=>new Date)}),ws=u.object({id:u.string(),userId:u.string(),expiresAt:u.date(),createdAt:u.date().default(()=>new Date),updatedAt:u.date().default(()=>new Date),token:u.string(),ipAddress:u.string().nullish(),userAgent:u.string().nullish()}),ys=u.object({id:u.string(),value:u.string(),createdAt:u.date().default(()=>new Date),updatedAt:u.date().default(()=>new Date),expiresAt:u.date(),identifier:u.string()});function qe(e,t){if(!t)return e;for(let r in t){let o=t[r]?.modelName;o&&(e[r].modelName=o);for(let i in e[r].fields){let n=t[r]?.fields?.[i];n&&(e[r].fields[i].fieldName=n)}}return e}import{xchacha20poly1305 as Ke}from"@noble/ciphers/chacha";import{bytesToHex as pr,hexToBytes as lr,utf8ToBytes as ur}from"@noble/ciphers/utils";import{managedNonce as Je}from"@noble/ciphers/webcrypto";import{sha256 as We}from"oslo/crypto";import js from"uncrypto";import{decodeHex as ks,encodeHex as Rs}from"oslo/encoding";import{scryptAsync as _s}from"@noble/hashes/scrypt";import{getRandomValues as Ss}from"uncrypto";import Me from"uncrypto";function ar(e){return e.toString(2).padStart(8,"0")}function cr(e){return[...e].map(t=>ar(t)).join("")}function Fe(e){return parseInt(cr(e),2)}function dr(e){if(e<0||!Number.isInteger(e))throw new Error("Argument 'max' must be an integer greater than or equal to 0");let t=(e-1).toString(2).length,r=t%8,o=new Uint8Array(Math.ceil(t/8));Me.getRandomValues(o),r!==0&&(o[0]&=(1<<r)-1);let i=Fe(o);for(;i>=e;)Me.getRandomValues(o),r!==0&&(o[0]&=(1<<r)-1),i=Fe(o);return i}function He(e,t){let r="";for(let o=0;o<e;o++)r+=t[dr(t.length)];return r}function Ge(...e){let t=new Set(e),r="";for(let o of t)o==="a-z"?r+="abcdefghijklmnopqrstuvwxyz":o==="A-Z"?r+="ABCDEFGHIJKLMNOPQRSTUVWXYZ":o==="0-9"?r+="0123456789":r+=o;return r}var Ze=async({key:e,data:t})=>{let r=await We(new TextEncoder().encode(e)),o=ur(t),i=Je(Ke)(new Uint8Array(r));return pr(i.encrypt(o))},Qe=async({key:e,data:t})=>{let r=await We(new TextEncoder().encode(e)),o=lr(t),i=Je(Ke)(new Uint8Array(r));return new TextDecoder().decode(i.decrypt(o))};var fr=m("/change-password",{method:"POST",body:U.object({newPassword:U.string({description:"The new password to set"}),currentPassword:U.string({description:"The current password"}),revokeOtherSessions:U.boolean({description:"Revoke all other sessions"}).optional()}),use:[S],metadata:{openapi:{description:"Change the password of the user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{user:{description:"The user object",$ref:"#/components/schemas/User"}}}}}}}}}},async e=>{let{newPassword:t,currentPassword:r,revokeOtherSessions:o}=e.body,i=e.context.session,n=e.context.password.config.minPasswordLength;if(t.length<n)throw e.context.logger.error("Password is too short"),new k("BAD_REQUEST",{message:l.PASSWORD_TOO_SHORT});let s=e.context.password.config.maxPasswordLength;if(t.length>s)throw e.context.logger.error("Password is too long"),new k("BAD_REQUEST",{message:l.PASSWORD_TOO_LONG});let a=(await e.context.internalAdapter.findAccounts(i.user.id)).find(f=>f.providerId==="credential"&&f.password);if(!a||!a.password)throw new k("BAD_REQUEST",{message:l.CREDENTIAL_ACCOUNT_NOT_FOUND});let d=await e.context.password.hash(t);if(!await e.context.password.verify({hash:a.password,password:r}))throw new k("BAD_REQUEST",{message:l.INVALID_PASSWORD});if(await e.context.internalAdapter.updateAccount(a.id,{password:d}),o){await e.context.internalAdapter.deleteSessions(i.user.id);let f=await e.context.internalAdapter.createSession(i.user.id,e.headers);if(!f)throw new k("INTERNAL_SERVER_ERROR",{message:l.FAILED_TO_GET_SESSION});await T(e,{session:f,user:i.user})}return e.json(i.user)}),gr=m("/set-password",{method:"POST",body:U.object({newPassword:U.string()}),metadata:{SERVER_ONLY:!0},use:[S]},async e=>{let{newPassword:t}=e.body,r=e.context.session,o=e.context.password.config.minPasswordLength;if(t.length<o)throw e.context.logger.error("Password is too short"),new k("BAD_REQUEST",{message:l.PASSWORD_TOO_SHORT});let i=e.context.password.config.maxPasswordLength;if(t.length>i)throw e.context.logger.error("Password is too long"),new k("BAD_REQUEST",{message:l.PASSWORD_TOO_LONG});let s=(await e.context.internalAdapter.findAccounts(r.user.id)).find(a=>a.providerId==="credential"&&a.password),c=await e.context.password.hash(t);if(!s)return await e.context.internalAdapter.linkAccount({userId:r.user.id,providerId:"credential",accountId:r.user.id,password:c}),e.json(r.user);throw new k("BAD_REQUEST",{message:"user already has a password"})}),hr=m("/delete-user",{method:"POST",use:[$e],metadata:{openapi:{description:"Delete the user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object"}}}}}}}},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 k("NOT_FOUND");let t=e.context.session;if(e.context.options.user.deleteUser?.sendDeleteAccountVerification){let i=He(32,Ge("a-z","A-Z","0-9"));await e.context.internalAdapter.createVerificationValue({value:t.user.id,identifier:`delete-account-${i}`,expiresAt:new Date(Date.now()+1e3*60*60*24)});let n=`${e.context.baseURL}/delete-user/callback?token=${i}`;return await e.context.options.user.deleteUser.sendDeleteAccountVerification({user:t.user,url:n,token:i},e.request),e.json({success:!0,message:"Verification email sent"})}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),I(e);let o=e.context.options.user.deleteUser?.afterDelete;return o&&await o(t.user,e.request),e.json({success:!0,message:"User deleted"})}),wr=m("/delete-user/callback",{method:"GET",query:U.object({token:U.string()})},async e=>{if(!e.context.options.user?.deleteUser?.enabled)throw e.context.logger.error("Delete user is disabled. Enable it in the options"),new k("NOT_FOUND");let t=await V(e);if(!t)throw new k("NOT_FOUND",{message:l.FAILED_TO_GET_USER_INFO});let r=await e.context.internalAdapter.findVerificationValue(`delete-account-${e.query.token}`);if(!r||r.expiresAt<new Date)throw r&&await e.context.internalAdapter.deleteVerificationValue(r.id),new k("NOT_FOUND",{message:l.INVALID_TOKEN});if(r.value!==t.user.id)throw new k("NOT_FOUND",{message:l.INVALID_TOKEN});let o=e.context.options.user.deleteUser?.beforeDelete;o&&await o(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),I(e);let i=e.context.options.user.deleteUser?.afterDelete;return i&&await i(t.user,e.request),e.json({success:!0,message:"User deleted"})}),yr=m("/change-email",{method:"POST",query:U.object({currentURL:U.string().optional()}).optional(),body:U.object({newEmail:U.string({description:"The new email to set"}).email(),callbackURL:U.string({description:"The URL to redirect to after email verification"}).optional()}),use:[S],metadata:{openapi:{responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{user:{type:"object"},status:{type:"boolean"}}}}}}}}}},async e=>{if(!e.context.options.user?.changeEmail?.enabled)throw e.context.logger.error("Change email is disabled."),new k("BAD_REQUEST",{message:"Change email is disabled"});if(e.body.newEmail===e.context.session.user.email)throw e.context.logger.error("Email is the same"),new k("BAD_REQUEST",{message:"Email is the same"});if(await e.context.internalAdapter.findUserByEmail(e.body.newEmail))throw e.context.logger.error("Email already exists"),new k("BAD_REQUEST",{message:"Couldn't update your email"});if(e.context.session.user.emailVerified!==!0){let i=await e.context.internalAdapter.updateUserByEmail(e.context.session.user.email,{email:e.body.newEmail});return e.json({user:i,status:!0})}if(!e.context.options.user.changeEmail.sendChangeEmailVerification)throw e.context.logger.error("Verification email isn't enabled."),new k("BAD_REQUEST",{message:"Verification email isn't enabled"});let r=await C(e.context.secret,e.context.session.user.email,e.body.newEmail),o=`${e.context.baseURL}/verify-email?token=${r}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.user.changeEmail.sendChangeEmailVerification({user:e.context.session.user,newEmail:e.body.newEmail,url:o,token:r},e.request),e.json({user:null,status:!0})});var br=(e="Unknown")=>`<!DOCTYPE html>
4
4
  <html lang="en">
5
5
  <head>
@@ -80,4 +80,4 @@ Error: `,a),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)
80
80
  <div class="error-code">Error Code: <span id="errorCode">${e}</span></div>
81
81
  </div>
82
82
  </body>
83
- </html>`,Ar=m("/error",{method:"GET",metadata:{...$,openapi:{description:"Displays an error page",responses:{200:{description:"Success",content:{"text/html":{schema:{type:"string"}}}}}}}},async e=>{let t=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(br(t),{headers:{"Content-Type":"text/html"}})});var kr=m("/ok",{method:"GET",metadata:{...$,openapi:{description:"Check if the API is working",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{ok:{type:"boolean"}}}}}}}}}},async e=>e.json({ok:!0}));import{z as da}from"zod";import{APIError as ha}from"better-call";import{z as K}from"zod";import{APIError as Ye}from"better-call";var Rr=m("/list-accounts",{method:"GET",use:[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"},provider:{type:"string"}}}}}}}}}}},async e=>{let t=e.context.session,r=await e.context.internalAdapter.findAccounts(t.user.id);return e.json(r.map(o=>({id:o.id,provider:o.providerId})))}),Er=m("/link-social",{method:"POST",requireHeaders:!0,query:K.object({currentURL:K.string().optional()}).optional(),body:K.object({callbackURL:K.string({description:"The URL to redirect to after the user has signed in"}).optional(),provider:K.enum(Y,{description:"The OAuth2 provider to use"})}),use:[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"},redirect:{type:"boolean"}},required:["url","redirect"]}}}}}}}},async e=>{let t=e.context.session;if((await e.context.internalAdapter.findAccounts(t.user.id)).find(c=>c.providerId===e.body.provider))throw new Ye("BAD_REQUEST",{message:l.SOCIAL_ACCOUNT_ALREADY_LINKED});let i=e.context.socialProviders.find(c=>c.id===e.body.provider);if(!i)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new Ye("NOT_FOUND",{message:l.PROVIDER_NOT_FOUND});let n=await Q(e,{userId:t.user.id,email:t.user.email}),s=await i.createAuthorizationURL({state:n.state,codeVerifier:n.codeVerifier,redirectURI:`${e.context.baseURL}/callback/${i.id}`});return e.json({url:s.toString(),redirect:!0})});import fc from"defu";import{APIError as Ac}from"better-call";var Sc=e=>({id:"jwt",endpoints:{getJwks:m("/jwks",{method:"GET",metadata:{openapi:{description:"Get the JSON Web Key Set",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{keys:{type:"array",items:{type:"object",properties:{kid:{type:"string"},kty:{type:"string"},use:{type:"string"},alg:{type:"string"},n:{type:"string"},e:{type:"string"}}}}}}}}}}}}},async t=>{let o=await oe(t.context.adapter).getAllKeys();return t.json({keys:o.map(i=>({...JSON.parse(i.publicKey),kid:i.id}))})}),getToken:m("/token",{method:"GET",requireHeaders:!0,use:[S],metadata:{openapi:{description:"Get a JWT token",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{token:{type:"string"}}}}}}}}}},async t=>{let r=oe(t.context.adapter),o=await r.getLatestKey(),i=!e?.jwks?.disablePrivateKeyEncryption;if(o===void 0){let{publicKey:d,privateKey:p}=await Ur(e?.jwks?.keyPairConfig?.alg??"EdDSA",e?.jwks?.keyPairConfig??{crv:"Ed25519"}),f=await Xe(d),A=await Xe(p),g=JSON.stringify(A),w={id:crypto.randomUUID(),publicKey:JSON.stringify(f),privateKey:i?JSON.stringify(await Ze({key:t.context.options.secret,data:g})):g,createdAt:new Date};o=await r.createJwk(w)}let n=i?await Qe({key:t.context.options.secret,data:JSON.parse(o.privateKey)}):o.privateKey,s=await _r(JSON.parse(n)),c=e?.jwt?.definePayload?await e?.jwt.definePayload(t.context.session.user):t.context.session.user,a=await new Tr({...c,...t.context.session.session.impersonatedBy?{impersonatedBy:t.context.session.session.impersonatedBy}:{}}).setProtectedHeader({alg:e?.jwks?.keyPairConfig?.alg??"EdDSA",kid:o.id}).setIssuedAt().setIssuer(e?.jwt?.issuer??t.context.options.baseURL).setAudience(e?.jwt?.audience??t.context.options.baseURL).setExpirationTime(e?.jwt?.expirationTime??"15m").setSubject(t.context.session.user.id).sign(s);return t.json({token:a})})},schema:qe(le,e?.schema)});export{Sc as jwt};
83
+ </html>`,Ar=m("/error",{method:"GET",metadata:{...$,openapi:{description:"Displays an error page",responses:{200:{description:"Success",content:{"text/html":{schema:{type:"string"}}}}}}}},async e=>{let t=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(br(t),{headers:{"Content-Type":"text/html"}})});var kr=m("/ok",{method:"GET",metadata:{...$,openapi:{description:"Check if the API is working",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{ok:{type:"boolean"}}}}}}}}}},async e=>e.json({ok:!0}));import{z as da}from"zod";import{APIError as ha}from"better-call";import{z as K}from"zod";import{APIError as Ye}from"better-call";var Rr=m("/list-accounts",{method:"GET",use:[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"},provider:{type:"string"}}}}}}}}}}},async e=>{let t=e.context.session,r=await e.context.internalAdapter.findAccounts(t.user.id);return e.json(r.map(o=>({id:o.id,provider:o.providerId})))}),Er=m("/link-social",{method:"POST",requireHeaders:!0,query:K.object({currentURL:K.string().optional()}).optional(),body:K.object({callbackURL:K.string({description:"The URL to redirect to after the user has signed in"}).optional(),provider:K.enum(Y,{description:"The OAuth2 provider to use"})}),use:[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"},redirect:{type:"boolean"}},required:["url","redirect"]}}}}}}}},async e=>{let t=e.context.session;if((await e.context.internalAdapter.findAccounts(t.user.id)).find(c=>c.providerId===e.body.provider))throw new Ye("BAD_REQUEST",{message:l.SOCIAL_ACCOUNT_ALREADY_LINKED});let i=e.context.socialProviders.find(c=>c.id===e.body.provider);if(!i)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new Ye("NOT_FOUND",{message:l.PROVIDER_NOT_FOUND});let n=await Q(e,{userId:t.user.id,email:t.user.email}),s=await i.createAuthorizationURL({state:n.state,codeVerifier:n.codeVerifier,redirectURI:`${e.context.baseURL}/callback/${i.id}`});return e.json({url:s.toString(),redirect:!0})});import fc from"defu";import{APIError as Ac}from"better-call";var Sc=e=>({id:"jwt",endpoints:{getJwks:m("/jwks",{method:"GET",metadata:{openapi:{description:"Get the JSON Web Key Set",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{keys:{type:"array",items:{type:"object",properties:{kid:{type:"string"},kty:{type:"string"},use:{type:"string"},alg:{type:"string"},n:{type:"string"},e:{type:"string"}}}}}}}}}}}}},async t=>{let o=await oe(t.context.adapter).getAllKeys();return t.json({keys:o.map(i=>({...JSON.parse(i.publicKey),kid:i.id}))})}),getToken:m("/token",{method:"GET",requireHeaders:!0,use:[S],metadata:{openapi:{description:"Get a JWT token",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{token:{type:"string"}}}}}}}}}},async t=>{let r=oe(t.context.adapter),o=await r.getLatestKey(),i=!e?.jwks?.disablePrivateKeyEncryption;if(o===void 0){let{publicKey:d,privateKey:p}=await Ur(e?.jwks?.keyPairConfig?.alg??"EdDSA",e?.jwks?.keyPairConfig??{crv:"Ed25519",extractable:!0}),f=await Xe(d),A=await Xe(p),g=JSON.stringify(A),w={id:crypto.randomUUID(),publicKey:JSON.stringify(f),privateKey:i?JSON.stringify(await Ze({key:t.context.options.secret,data:g})):g,createdAt:new Date};o=await r.createJwk(w)}let n=i?await Qe({key:t.context.options.secret,data:JSON.parse(o.privateKey)}):o.privateKey,s=await _r(JSON.parse(n)),c=e?.jwt?.definePayload?await e?.jwt.definePayload(t.context.session.user):t.context.session.user,a=await new Tr({...c,...t.context.session.session.impersonatedBy?{impersonatedBy:t.context.session.session.impersonatedBy}:{}}).setProtectedHeader({alg:e?.jwks?.keyPairConfig?.alg??"EdDSA",kid:o.id}).setIssuedAt().setIssuer(e?.jwt?.issuer??t.context.options.baseURL).setAudience(e?.jwt?.audience??t.context.options.baseURL).setExpirationTime(e?.jwt?.expirationTime??"15m").setSubject(t.context.session.user.id).sign(s);return t.json({token:a})})},schema:qe(le,e?.schema)});export{Sc as jwt};
@@ -1,5 +1,5 @@
1
1
  "use strict";var St=Object.create;var X=Object.defineProperty;var Ot=Object.getOwnPropertyDescriptor;var vt=Object.getOwnPropertyNames;var It=Object.getPrototypeOf,Lt=Object.prototype.hasOwnProperty;var xt=(e,t)=>{for(var r in t)X(e,r,{get:t[r],enumerable:!0})},Te=(e,t,r,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of vt(t))!Lt.call(e,o)&&o!==r&&X(e,o,{get:()=>t[o],enumerable:!(i=Ot(t,o))||i.enumerable});return e};var pe=(e,t,r)=>(r=e!=null?St(It(e)):{},Te(t||!e||!e.__esModule?X(r,"default",{value:e,enumerable:!0}):r,e)),Pt=e=>Te(X({},"__esModule",{value:!0}),e);var Cr={};xt(Cr,{multiSession:()=>Pr});module.exports=Pt(Cr);var Y=require("zod");var Z=require("better-call");var xe=require("better-call");var $=require("better-call"),Se=(0,$.createMiddleware)(async()=>({})),N=(0,$.createMiddlewareCreator)({use:[Se,(0,$.createMiddleware)(async()=>({}))]}),g=(0,$.createEndpointCreator)({use:[Se]});function me(e){return e==="-"||e==="^"||e==="$"||e==="+"||e==="."||e==="("||e===")"||e==="|"||e==="["||e==="]"||e==="{"||e==="}"||e==="*"||e==="?"||e==="\\"?`\\${e}`:e}function Ct(e){let t="";for(let r=0;r<e.length;r++)t+=me(e[r]);return t}function Oe(e,t=!0){if(Array.isArray(e))return`(?:${e.map(l=>`^${Oe(l,t)}$`).join("|")})`;let r="",i="",o=".";t===!0?(r="/",i="[/\\\\]",o="[^/\\\\]"):t&&(r=t,i=Ct(r),i.length>1?(i=`(?:${i})`,o=`((?!${i}).)`):o=`[^${i}]`);let n=t?`${i}+?`:"",s=t?`${i}*?`:"",c=t?e.split(r):[e],a="";for(let d=0;d<c.length;d++){let l=c[d],p=c[d+1],y="";if(!(!l&&d>0)){if(t&&(d===c.length-1?y=s:p!=="**"?y=n:y=""),t&&l==="**"){y&&(a+=d===0?"":y,a+=`(?:${o}*?${y})*?`);continue}for(let h=0;h<l.length;h++){let f=l[h];f==="\\"?h<l.length-1&&(a+=me(l[h+1]),h++):f==="?"?a+=o:f==="*"?a+=`${o}*?`:a+=me(f)}a+=y}}return a}function Dt(e,t){if(typeof t!="string")throw new TypeError(`Sample must be a string, but ${typeof t} given`);return e.test(t)}function fe(e,t){if(typeof e!="string"&&!Array.isArray(e))throw new TypeError(`The first argument must be a single pattern string or an array of patterns, but ${typeof e} given`);if((typeof t=="string"||typeof t=="boolean")&&(t={separator:t}),arguments.length===2&&!(typeof t>"u"||typeof t=="object"&&t!==null&&!Array.isArray(t)))throw new TypeError(`The second argument must be an options object or a string/boolean separator, but ${typeof t} given`);if(t=t||{},t.separator==="\\")throw new Error("\\ is not a valid separator because it is used for escaping. Try setting the separator to `true` instead");let r=Oe(e,t.separator),i=new RegExp(`^${r}$`,t.flags),o=Dt.bind(null,i);return o.options=t,o.pattern=e,o.regexp=i,o}var ee=Object.create(null),Q=e=>globalThis.process?.env||globalThis.Deno?.env.toObject()||globalThis.__env__||(e?ee:globalThis),ve=new Proxy(ee,{get(e,t){return Q()[t]??ee[t]},has(e,t){let r=Q();return t in r||t in ee},set(e,t,r){let i=Q(!0);return i[t]=r,!0},deleteProperty(e,t){if(!t)return!1;let r=Q(!0);return delete r[t],!0},ownKeys(){let e=Q(!0);return Object.keys(e)}});function Nt(e){return e?e!=="false":!1}var ge=typeof process<"u"&&process.env&&process.env.NODE_ENV||"";var he=ge==="dev"||ge==="development",jt=ge==="test"||Nt(ve.TEST);var j=class extends Error{constructor(t,r){super(t),this.name="BetterAuthError",this.message=t,this.cause=r,this.stack=""}};function Ie(e){try{return new URL(e).origin}catch{return null}}function Le(e){return e.includes("://")?new URL(e).host:e}var Vt=N(async e=>{if(e.request?.method!=="POST")return;let{body:t,query:r,context:i}=e,o=e.headers?.get("origin")||e.headers?.get("referer")||"",n=t?.callbackURL||r?.callbackURL,s=t?.redirectTo,c=r?.currentURL,a=t?.errorCallbackURL,d=t?.newUserCallbackURL,l=i.trustedOrigins,p=e.headers?.has("cookie"),y=(f,b)=>f.startsWith("/")?!1:b.includes("*")?fe(b)(Le(f)):f.startsWith(b),h=(f,b)=>{if(!f)return;if(!l.some(le=>y(f,le)||f?.startsWith("/")&&b!=="origin"&&!f.includes(":")))throw e.context.logger.error(`Invalid ${b}: ${f}`),e.context.logger.info(`If it's a valid URL, please add ${f} to trustedOrigins in your auth config
2
- `,`Current list of trustedOrigins: ${l}`),new xe.APIError("FORBIDDEN",{message:`Invalid ${b}`})};p&&!e.context.options.advanced?.disableCSRFCheck&&h(o,"origin"),n&&h(n,"callbackURL"),s&&h(s,"redirectURL"),c&&h(c,"currentURL"),a&&h(a,"errorCallbackURL"),d&&h(s,"newUserCallbackURL")});var E=require("better-call"),k=require("zod");var qt=require("oslo"),Ce=require("oslo/encoding");var te=require("oslo/crypto");async function $t({value:e,secret:t}){return new te.HMAC("SHA-256").sign(new TextEncoder().encode(t),new TextEncoder().encode(e)).then(i=>Buffer.from(i).toString("base64"))}function zt({value:e,signature:t,secret:r}){return new te.HMAC("SHA-256").verify(new TextEncoder().encode(r),Buffer.from(t,"base64"),new TextEncoder().encode(e))}var re={sign:$t,verify:zt};var V=(e,t="ms")=>new Date(Date.now()+(t==="sec"?e*1e3:e));function Pe(e){let t=new Map;return e.split(", ").forEach(i=>{let o=i.split(";").map(p=>p.trim()),[n,...s]=o,[c,...a]=n.split("="),d=a.join("=");if(!c||d===void 0)return;let l={value:d};s.forEach(p=>{let[y,...h]=p.split("="),f=h.join("="),b=y.trim().toLowerCase();switch(b){case"max-age":l["max-age"]=f?parseInt(f.trim(),10):void 0;break;case"expires":l.expires=f?new Date(f.trim()):void 0;break;case"domain":l.domain=f?f.trim():void 0;break;case"path":l.path=f?f.trim():void 0;break;case"secure":l.secure=!0;break;case"httponly":l.httponly=!0;break;case"samesite":l.samesite=f?f.trim().toLowerCase():void 0;break;default:l[b]=f?f.trim():!0;break}}),t.set(c,l)}),t}async function U(e,t,r,i){let o=e.context.authCookies.sessionToken.options,n=r?void 0:e.context.sessionConfig.expiresIn;if(await e.setSignedCookie(e.context.authCookies.sessionToken.name,t.session.token,e.context.secret,{...o,maxAge:n,...i}),r&&await e.setSignedCookie(e.context.authCookies.dontRememberToken.name,"true",e.context.secret,e.context.authCookies.dontRememberToken.options),e.context.options.session?.cookieCache?.enabled){let c=Ce.base64url.encode(new TextEncoder().encode(JSON.stringify({session:t,expiresAt:V(e.context.authCookies.sessionData.options.maxAge||60,"sec").getTime(),signature:await re.sign({value:JSON.stringify(t),secret:e.context.secret})})),{includePadding:!1});if(c.length>4093)throw new j("Session data is too large to store in the cookie. Please disable session cookie caching or reduce the size of the session data");e.setCookie(e.context.authCookies.sessionData.name,c,e.context.authCookies.sessionData.options)}e.context.setNewSession(t),e.context.options.secondaryStorage&&await e.context.secondaryStorage?.set(t.session.token,JSON.stringify({user:t.user,session:t.session}),Math.floor((new Date(t.session.expiresAt).getTime()-Date.now())/1e3))}function _(e){e.setCookie(e.context.authCookies.sessionToken.name,"",{...e.context.authCookies.sessionToken.options,maxAge:0}),e.setCookie(e.context.authCookies.sessionData.name,"",{...e.context.authCookies.sessionData.options,maxAge:0}),e.setCookie(e.context.authCookies.dontRememberToken.name,"",{...e.context.authCookies.dontRememberToken.options,maxAge:0})}function K(e){let t=e.split("; "),r=new Map;return t.forEach(i=>{let[o,n]=i.split("=");r.set(o,n)}),r}var $e=require("@better-fetch/fetch"),ze=require("better-call"),q=require("jose"),qe=require("oslo/jwt");var De=require("oslo/crypto"),Ne=require("oslo/encoding");async function je(e){let t=await(0,De.sha256)(new TextEncoder().encode(e));return Ne.base64url.encode(new Uint8Array(t),{includePadding:!1})}function oe(e){return{tokenType:e.token_type,accessToken:e.access_token,refreshToken:e.refresh_token,accessTokenExpiresAt:e.expires_in?V(e.expires_in,"sec"):void 0,scopes:e?.scope?typeof e.scope=="string"?e.scope.split(" "):e.scope:[],idToken:e.id_token}}async function A({id:e,options:t,authorizationEndpoint:r,state:i,codeVerifier:o,scopes:n,claims:s,redirectURI:c,duration:a}){let d=new URL(r);if(d.searchParams.set("response_type","code"),d.searchParams.set("client_id",t.clientId),d.searchParams.set("state",i),d.searchParams.set("scope",n.join(" ")),d.searchParams.set("redirect_uri",t.redirectURI||c),o){let l=await je(o);d.searchParams.set("code_challenge_method","S256"),d.searchParams.set("code_challenge",l)}if(s){let l=s.reduce((p,y)=>(p[y]=null,p),{});d.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...l}}))}return a&&d.searchParams.set("duration",a),d}var Ve=require("@better-fetch/fetch");async function w({code:e,codeVerifier:t,redirectURI:r,options:i,tokenEndpoint:o,authentication:n}){let s=new URLSearchParams,c={"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"};if(s.set("grant_type","authorization_code"),s.set("code",e),t&&s.set("code_verifier",t),s.set("redirect_uri",r),n==="basic"){let p=btoa(`${i.clientId}:${i.clientSecret}`);c.authorization=`Basic ${p}`}else s.set("client_id",i.clientId),s.set("client_secret",i.clientSecret);let{data:a,error:d}=await(0,Ve.betterFetch)(o,{method:"POST",body:s,headers:c});if(d)throw d;return oe(a)}var ie=require("oslo/oauth2"),P=require("zod"),we=require("better-call");async function ne(e,t){let r=e.body?.callbackURL||(e.query?.currentURL?Ie(e.query?.currentURL):"")||e.context.options.baseURL;if(!r)throw new we.APIError("BAD_REQUEST",{message:"callbackURL is required"});let i=(0,ie.generateCodeVerifier)(),o=(0,ie.generateState)(),n=JSON.stringify({callbackURL:r,codeVerifier:i,errorURL:e.body?.errorCallbackURL||e.query?.currentURL,newUserURL:e.body?.newUserCallbackURL,link:t,expiresAt:Date.now()+10*60*1e3}),s=new Date;s.setMinutes(s.getMinutes()+10);let c=await e.context.internalAdapter.createVerificationValue({value:n,identifier:o,expiresAt:s});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 we.APIError("INTERNAL_SERVER_ERROR",{message:"Unable to create verification"});return{state:c.identifier,codeVerifier:i}}async function Be(e){let t=e.query.state||e.body.state,r=await e.context.internalAdapter.findVerificationValue(t);if(!r)throw e.context.logger.error("State Mismatch. Verification not found",{state:t}),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let i=P.z.object({callbackURL:P.z.string(),codeVerifier:P.z.string(),errorURL:P.z.string().optional(),newUserURL:P.z.string().optional(),expiresAt:P.z.number(),link:P.z.object({email:P.z.string(),userId:P.z.string()}).optional()}).parse(JSON.parse(r.value));if(i.errorURL||(i.errorURL=`${e.context.baseURL}/error`),i.expiresAt<Date.now())throw await e.context.internalAdapter.deleteVerificationValue(r.id),e.context.logger.error("State expired.",{state:t}),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);return await e.context.internalAdapter.deleteVerificationValue(r.id),i}var Me=e=>{let t="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:r,scopes:i,redirectURI:o}){let n=i||["email","name"];return e.scope&&n.push(...e.scope),new URL(`https://appleid.apple.com/auth/authorize?client_id=${e.clientId}&response_type=code&redirect_uri=${o||e.redirectURI}&scope=${n.join(" ")}&state=${r}&response_mode=form_post`)},validateAuthorizationCode:async({code:r,codeVerifier:i,redirectURI:o})=>w({code:r,codeVerifier:i,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:t}),async verifyIdToken(r,i){if(e.disableIdTokenSignIn)return!1;if(e.verifyIdToken)return e.verifyIdToken(r,i);let o=(0,q.decodeProtectedHeader)(r),{kid:n,alg:s}=o;if(!n||!s)return!1;let c=await Mt(n),{payload:a}=await(0,q.jwtVerify)(r,c,{algorithms:[s],issuer:"https://appleid.apple.com",audience:e.clientId,maxTokenAge:"1h"});return["email_verified","is_private_email"].forEach(d=>{a[d]!==void 0&&(a[d]=!!a[d])}),i&&a.nonce!==i?!1:!!a},async getUserInfo(r){if(e.getUserInfo)return e.getUserInfo(r);if(!r.idToken)return null;let i=(0,qe.parseJWT)(r.idToken)?.payload;if(!i)return null;let o=i.user?`${i.user.name.firstName} ${i.user.name.lastName}`:i.email,n=await e.mapProfileToUser?.(i);return{user:{id:i.sub,name:o,emailVerified:!1,email:i.email,...n},data:i}}}},Mt=async e=>{let t="https://appleid.apple.com",r="/auth/keys",{data:i}=await(0,$e.betterFetch)(`${t}${r}`);if(!i?.keys)throw new ze.APIError("BAD_REQUEST",{message:"Keys not found"});let o=i.keys.find(n=>n.kid===e);if(!o)throw new Error(`JWK with kid ${e} not found`);return await(0,q.importJWK)(o,o.alg)};var Fe=require("@better-fetch/fetch");var He=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:t,scopes:r,redirectURI:i}){let o=r||["identify","email"];return e.scope&&o.push(...e.scope),new URL(`https://discord.com/api/oauth2/authorize?scope=${o.join("+")}&response_type=code&client_id=${e.clientId}&redirect_uri=${encodeURIComponent(e.redirectURI||i)}&state=${t}&prompt=${e.prompt||"none"}`)},validateAuthorizationCode:async({code:t,redirectURI:r})=>w({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:i}=await(0,Fe.betterFetch)("https://discord.com/api/users/@me",{headers:{authorization:`Bearer ${t.accessToken}`}});if(i)return null;if(r.avatar===null){let n=r.discriminator==="0"?Number(BigInt(r.id)>>BigInt(22))%6:parseInt(r.discriminator)%5;r.image_url=`https://cdn.discordapp.com/embed/avatars/${n}.png`}else{let n=r.avatar.startsWith("a_")?"gif":"png";r.image_url=`https://cdn.discordapp.com/avatars/${r.id}/${r.avatar}.${n}`}let o=await e.mapProfileToUser?.(r);return{user:{id:r.id,name:r.display_name||r.username||"",email:r.email,emailVerified:r.verified,image:r.image_url,...o},data:r}}});var Ge=require("@better-fetch/fetch");var We=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:t,scopes:r,redirectURI:i}){let o=r||["email","public_profile"];return e.scope&&o.push(...e.scope),await A({id:"facebook",options:e,authorizationEndpoint:"https://www.facebook.com/v21.0/dialog/oauth",scopes:o,state:t,redirectURI:i})},validateAuthorizationCode:async({code:t,redirectURI:r})=>w({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://graph.facebook.com/oauth/access_token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:i}=await(0,Ge.betterFetch)("https://graph.facebook.com/me?fields=id,name,email,picture",{auth:{type:"Bearer",token:t.accessToken}});if(i)return null;let o=await e.mapProfileToUser?.(r);return{user:{id:r.id,name:r.name,email:r.email,image:r.picture.data.url,emailVerified:r.email_verified,...o},data:r}}});var ye=require("@better-fetch/fetch");var Ze=e=>{let t="https://github.com/login/oauth/access_token";return{id:"github",name:"GitHub",createAuthorizationURL({state:r,scopes:i,codeVerifier:o,redirectURI:n}){let s=i||["user:email"];return e.scope&&s.push(...e.scope),A({id:"github",options:e,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:s,state:r,redirectURI:n})},validateAuthorizationCode:async({code:r,redirectURI:i})=>w({code:r,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:t}),async getUserInfo(r){if(e.getUserInfo)return e.getUserInfo(r);let{data:i,error:o}=await(0,ye.betterFetch)("https://api.github.com/user",{headers:{"User-Agent":"better-auth",authorization:`Bearer ${r.accessToken}`}});if(o)return null;let n=!1;if(!i.email){let{data:c,error:a}=await(0,ye.betterFetch)("https://api.github.com/user/emails",{headers:{authorization:`Bearer ${r.accessToken}`,"User-Agent":"better-auth"}});a||(i.email=(c.find(d=>d.primary)??c[0])?.email,n=c.find(d=>d.email===i.email)?.verified??!1)}let s=await e.mapProfileToUser?.(i);return{user:{id:i.id.toString(),name:i.name||i.login,email:i.email,image:i.avatar_url,emailVerified:n,...s},data:i}}}};var Ke=require("oslo/jwt");var Qe=require("consola"),be=["info","success","warn","error","debug"];function Ft(e,t){return be.indexOf(t)<=be.indexOf(e)}var Ht=(0,Qe.createConsola)({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),Gt=e=>{let t=e?.disabled!==!0,r=e?.level??"error",i=(o,n,s=[])=>{if(!(!t||!Ft(r,o))){if(!e||typeof e.log!="function"){Ht[o]("",n,...s);return}e.log(o==="success"?"info":o,n,s)}};return Object.fromEntries(be.map(o=>[o,(...[n,...s])=>i(o,n,s)]))},L=Gt();var Je=require("@better-fetch/fetch"),Ye=e=>({id:"google",name:"Google",async createAuthorizationURL({state:t,scopes:r,codeVerifier:i,redirectURI:o}){if(!e.clientId||!e.clientSecret)throw L.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new j("CLIENT_ID_AND_SECRET_REQUIRED");if(!i)throw new j("codeVerifier is required for Google");let n=r||["email","profile","openid"];e.scope&&n.push(...e.scope);let s=await A({id:"google",options:e,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:n,state:t,codeVerifier:i,redirectURI:o});return e.accessType&&s.searchParams.set("access_type",e.accessType),e.prompt&&s.searchParams.set("prompt",e.prompt),s},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:i})=>w({code:t,codeVerifier:r,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:"https://oauth2.googleapis.com/token"}),async verifyIdToken(t,r){if(e.disableIdTokenSignIn)return!1;if(e.verifyIdToken)return e.verifyIdToken(t,r);let i=`https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=${t}`,{data:o}=await(0,Je.betterFetch)(i);return o?o.aud===e.clientId&&o.iss==="https://accounts.google.com":!1},async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);if(!t.idToken)return null;let r=(0,Ke.parseJWT)(t.idToken)?.payload,i=await e.mapProfileToUser?.(r);return{user:{id:r.sub,name:r.name,email:r.email,image:r.picture,emailVerified:r.email_verified,...i},data:r}}});var Xe=require("@better-fetch/fetch"),et=require("oslo/jwt");var tt=e=>{let t=e.tenantId||"common",r=`https://login.microsoftonline.com/${t}/oauth2/v2.0/authorize`,i=`https://login.microsoftonline.com/${t}/oauth2/v2.0/token`;return{id:"microsoft",name:"Microsoft EntraID",createAuthorizationURL(o){let n=o.scopes||["openid","profile","email","User.Read"];return e.scope&&n.push(...e.scope),A({id:"microsoft",options:e,authorizationEndpoint:r,state:o.state,codeVerifier:o.codeVerifier,scopes:n,redirectURI:o.redirectURI})},validateAuthorizationCode({code:o,codeVerifier:n,redirectURI:s}){return w({code:o,codeVerifier:n,redirectURI:e.redirectURI||s,options:e,tokenEndpoint:i})},async getUserInfo(o){if(e.getUserInfo)return e.getUserInfo(o);if(!o.idToken)return null;let n=(0,et.parseJWT)(o.idToken)?.payload,s=e.profilePhotoSize||48;await(0,Xe.betterFetch)(`https://graph.microsoft.com/v1.0/me/photos/${s}x${s}/$value`,{headers:{Authorization:`Bearer ${o.accessToken}`},async onResponse(a){if(!(e.disableProfilePhoto||!a.response.ok))try{let l=await a.response.clone().arrayBuffer(),p=Buffer.from(l).toString("base64");n.picture=`data:image/jpeg;base64, ${p}`}catch(d){L.error(d&&typeof d=="object"&&"name"in d?d.name:"",d)}}});let c=await e.mapProfileToUser?.(n);return{user:{id:n.sub,name:n.name,email:n.email,image:n.picture,emailVerified:!0,...c},data:n}}}};var rt=require("@better-fetch/fetch");var ot=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:t,scopes:r,codeVerifier:i,redirectURI:o}){let n=r||["user-read-email"];return e.scope&&n.push(...e.scope),A({id:"spotify",options:e,authorizationEndpoint:"https://accounts.spotify.com/authorize",scopes:n,state:t,codeVerifier:i,redirectURI:o})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:i})=>w({code:t,codeVerifier:r,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:"https://accounts.spotify.com/api/token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:i}=await(0,rt.betterFetch)("https://api.spotify.com/v1/me",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});if(i)return null;let o=await e.mapProfileToUser?.(r);return{user:{id:r.id,name:r.display_name,email:r.email,image:r.images[0]?.url,emailVerified:!1,...o},data:r}}});var M={isAction:!1};var it=require("nanoid"),nt=e=>(0,it.nanoid)(e);var st=require("oslo/jwt");var at=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:t,scopes:r,redirectURI:i}){let o=r||["user:read:email","openid"];return e.scope&&o.push(...e.scope),A({id:"twitch",redirectURI:i,options:e,authorizationEndpoint:"https://id.twitch.tv/oauth2/authorize",scopes:o,state:t,claims:e.claims||["email","email_verified","preferred_username","picture"]})},validateAuthorizationCode:async({code:t,redirectURI:r})=>w({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let r=t.idToken;if(!r)return L.error("No idToken found in token"),null;let i=(0,st.parseJWT)(r)?.payload,o=await e.mapProfileToUser?.(i);return{user:{id:i.sub,name:i.preferred_username,email:i.email,image:i.picture,emailVerified:!1,...o},data:i}}});var ct=require("@better-fetch/fetch");var dt=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(t){let r=t.scopes||["users.read","tweet.read","offline.access"];return e.scope&&r.push(...e.scope),A({id:"twitter",options:e,authorizationEndpoint:"https://x.com/i/oauth2/authorize",scopes:r,state:t.state,codeVerifier:t.codeVerifier,redirectURI:t.redirectURI})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:i})=>w({code:t,codeVerifier:r,authentication:"basic",redirectURI:e.redirectURI||i,options:e,tokenEndpoint:"https://api.x.com/2/oauth2/token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:i}=await(0,ct.betterFetch)("https://api.x.com/2/users/me?user.fields=profile_image_url",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});if(i)return null;let o=await e.mapProfileToUser?.(r);return{user:{id:r.data.id,name:r.data.name,email:r.data.username||null,image:r.data.profile_image_url,emailVerified:r.data.verified||!1,...o},data:r}}});var lt=require("@better-fetch/fetch");var ut=e=>{let t="https://api.dropboxapi.com/oauth2/token";return{id:"dropbox",name:"Dropbox",createAuthorizationURL:async({state:r,scopes:i,codeVerifier:o,redirectURI:n})=>{let s=i||["account_info.read"];return e.scope&&s.push(...e.scope),await A({id:"dropbox",options:e,authorizationEndpoint:"https://www.dropbox.com/oauth2/authorize",scopes:s,state:r,redirectURI:n,codeVerifier:o})},validateAuthorizationCode:async({code:r,codeVerifier:i,redirectURI:o})=>await w({code:r,codeVerifier:i,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:t}),async getUserInfo(r){if(e.getUserInfo)return e.getUserInfo(r);let{data:i,error:o}=await(0,lt.betterFetch)("https://api.dropboxapi.com/2/users/get_current_account",{method:"POST",headers:{Authorization:`Bearer ${r.accessToken}`}});if(o)return null;let n=await e.mapProfileToUser?.(i);return{user:{id:i.account_id,name:i.name?.display_name,email:i.email,emailVerified:i.email_verified||!1,image:i.profile_photo_url,...n},data:i}}}};var pt=require("@better-fetch/fetch");var mt=e=>{let t="https://www.linkedin.com/oauth/v2/authorization",r="https://www.linkedin.com/oauth/v2/accessToken";return{id:"linkedin",name:"Linkedin",createAuthorizationURL:async({state:i,scopes:o,redirectURI:n})=>{let s=o||["profile","email","openid"];return e.scope&&s.push(...e.scope),await A({id:"linkedin",options:e,authorizationEndpoint:t,scopes:s,state:i,redirectURI:n})},validateAuthorizationCode:async({code:i,redirectURI:o})=>await w({code:i,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:r}),async getUserInfo(i){let{data:o,error:n}=await(0,pt.betterFetch)("https://api.linkedin.com/v2/userinfo",{method:"GET",headers:{Authorization:`Bearer ${i.accessToken}`}});if(n)return null;let s=await e.mapProfileToUser?.(o);return{user:{id:o.sub,name:o.name,email:o.email,emailVerified:o.email_verified||!1,image:o.picture,...s},data:o}}}};var ft=require("@better-fetch/fetch");var Ae=(e="")=>e.split("://").map(t=>t.replace(/\/{2,}/g,"/")).join("://"),Wt=e=>{let t=e||"https://gitlab.com";return{authorizationEndpoint:Ae(`${t}/oauth/authorize`),tokenEndpoint:Ae(`${t}/oauth/token`),userinfoEndpoint:Ae(`${t}/api/v4/user`)}},gt=e=>{let{authorizationEndpoint:t,tokenEndpoint:r,userinfoEndpoint:i}=Wt(e.issuer),o="gitlab";return{id:o,name:"Gitlab",createAuthorizationURL:async({state:s,scopes:c,codeVerifier:a,redirectURI:d})=>{let l=c||["read_user"];return e.scope&&l.push(...e.scope),await A({id:o,options:e,authorizationEndpoint:t,scopes:l,state:s,redirectURI:d,codeVerifier:a})},validateAuthorizationCode:async({code:s,redirectURI:c,codeVerifier:a})=>w({code:s,redirectURI:e.redirectURI||c,options:e,codeVerifier:a,tokenEndpoint:r}),async getUserInfo(s){if(e.getUserInfo)return e.getUserInfo(s);let{data:c,error:a}=await(0,ft.betterFetch)(i,{headers:{authorization:`Bearer ${s.accessToken}`}});if(a||c.state!=="active"||c.locked)return null;let d=await e.mapProfileToUser?.(c);return{user:{id:c.id.toString(),name:c.name??c.username,email:c.email,image:c.avatar_url,emailVerified:!0,...d},data:c}}}};var ke=require("@better-fetch/fetch");var ht=e=>({id:"reddit",name:"Reddit",createAuthorizationURL({state:t,scopes:r,redirectURI:i}){let o=r||["identity"];return e.scope&&o.push(...e.scope),A({id:"reddit",options:e,authorizationEndpoint:"https://www.reddit.com/api/v1/authorize",scopes:o,state:t,redirectURI:i,duration:e.duration})},validateAuthorizationCode:async({code:t,redirectURI:r})=>{let i=new URLSearchParams({grant_type:"authorization_code",code:t,redirect_uri:e.redirectURI||r}),o={"content-type":"application/x-www-form-urlencoded",accept:"text/plain","user-agent":"better-auth",Authorization:`Basic ${Buffer.from(`${e.clientId}:${e.clientSecret}`).toString("base64")}`},{data:n,error:s}=await(0,ke.betterFetch)("https://www.reddit.com/api/v1/access_token",{method:"POST",headers:o,body:i.toString()});if(s)throw s;return oe(n)},async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:i}=await(0,ke.betterFetch)("https://oauth.reddit.com/api/v1/me",{headers:{Authorization:`Bearer ${t.accessToken}`,"User-Agent":"better-auth"}});if(i)return null;let o=await e.mapProfileToUser?.(r);return{user:{id:r.id,name:r.name,email:r.oauth_client_id,emailVerified:r.has_verified_email,image:r.icon_img?.split("?")[0],...o},data:r}}});var Zt={apple:Me,discord:He,facebook:We,github:Ze,microsoft:tt,google:Ye,spotify:ot,twitch:at,twitter:dt,dropbox:ut,linkedin:mt,gitlab:gt,reddit:ht},se=Object.keys(Zt);var At=require("oslo"),ae=require("oslo/jwt"),I=require("zod");var F=require("better-call");var C=require("better-call");var B=require("zod");function wt(e){try{return JSON.parse(e)}catch{return null}}var u={USER_NOT_FOUND:"User not found",FAILED_TO_CREATE_USER:"Failed to create user",FAILED_TO_CREATE_SESSION:"Failed to create session",FAILED_TO_UPDATE_USER:"Failed to update user",FAILED_TO_GET_SESSION:"Failed to get session",INVALID_PASSWORD:"Invalid password",INVALID_EMAIL:"Invalid email",INVALID_EMAIL_OR_PASSWORD:"Invalid email or password",SOCIAL_ACCOUNT_ALREADY_LINKED:"Social account already linked",PROVIDER_NOT_FOUND:"Provider not found",INVALID_TOKEN:"invalid token",ID_TOKEN_NOT_SUPPORTED:"id_token not supported",FAILED_TO_GET_USER_INFO:"Failed to get user info",USER_EMAIL_NOT_FOUND:"User email not found",EMAIL_NOT_VERIFIED:"Email not verified",PASSWORD_TOO_SHORT:"Password too short",PASSWORD_TOO_LONG:"Password too long",USER_ALREADY_EXISTS:"User already exists",EMAIL_CAN_NOT_BE_UPDATED:"Email can not be updated",CREDENTIAL_ACCOUNT_NOT_FOUND:"Credential account not found"};var yt=()=>g("/get-session",{method:"GET",query:B.z.optional(B.z.object({disableCookieCache:B.z.boolean({description:"Disable cookie cache and fetch session from database"}).or(B.z.string().transform(e=>e==="true")).optional(),disableRefresh:B.z.boolean({description:"Disable session refresh. Useful for checking session status, without updating the session"}).optional()})),requireHeaders:!0,metadata:{openapi:{description:"Get the current session",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{session:{type:"object",properties:{token:{type:"string"},userId:{type:"string"},expiresAt:{type:"string"}}},user:{type:"object",$ref:"#/components/schemas/User"}}}}}}}}}},async e=>{try{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)return e.json(null);let r=e.getCookie(e.context.authCookies.sessionData.name),i=r?wt(Buffer.from(r,"base64").toString()):null;if(i&&!await re.verify({value:JSON.stringify(i.session),signature:i?.signature,secret:e.context.secret}))return _(e),e.json(null);let o=await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret);if(i?.session&&e.context.options.session?.cookieCache?.enabled&&!e.query?.disableCookieCache){let l=i.session;if(i.expiresAt<Date.now()||l.session.expiresAt<new Date){let y=e.context.authCookies.sessionData.name;e.setCookie(y,"",{maxAge:0})}else return e.json(l)}let n=await e.context.internalAdapter.findSession(t);if(e.context.session=n,!n||n.session.expiresAt<new Date)return _(e),n&&await e.context.internalAdapter.deleteSession(n.session.token),e.json(null);if(o||e.query?.disableRefresh)return e.json(n);let s=e.context.sessionConfig.expiresIn,c=e.context.sessionConfig.updateAge;if(n.session.expiresAt.valueOf()-s*1e3+c*1e3<=Date.now()){let l=await e.context.internalAdapter.updateSession(n.session.token,{expiresAt:V(e.context.sessionConfig.expiresIn,"sec")});if(!l)return _(e),e.json(null,{status:401});let p=(l.expiresAt.valueOf()-Date.now())/1e3;return await U(e,{session:l,user:n.user},!1,{maxAge:p}),e.json({session:l,user:n.user})}return e.json(n)}catch(t){throw e.context.logger.error("INTERNAL_SERVER_ERROR",t),new C.APIError("INTERNAL_SERVER_ERROR",{message:u.FAILED_TO_GET_SESSION})}}),z=async(e,t)=>{if(e.context.session)return e.context.session;let r=await yt()({...e,_flag:"json",headers:e.headers,query:t}).catch(i=>null);return e.context.session=r,r},S=N(async e=>{let t=await z(e);if(!t?.session)throw new C.APIError("UNAUTHORIZED");return{session:t}}),bt=N(async e=>{let t=await z(e);if(!t?.session)throw new C.APIError("UNAUTHORIZED");if(e.context.sessionConfig.freshAge===0)return{session:t};let r=e.context.sessionConfig.freshAge,i=t.session.createdAt.valueOf(),o=Date.now();if(!(i+r*1e3>o))throw new C.APIError("FORBIDDEN",{message:"Session is not fresh"});return{session:t}});var Qt=g("/revoke-session",{method:"POST",body:B.z.object({token:B.z.string({description:"The token to revoke"})}),use:[S],requireHeaders:!0,metadata:{openapi:{description:"Revoke a single session",requestBody:{content:{"application/json":{schema:{type:"object",properties:{token:{type:"string"}},required:["token"]}}}}}}},async e=>{let t=e.body.token,r=await e.context.internalAdapter.findSession(t);if(!r)throw new C.APIError("BAD_REQUEST",{message:"Session not found"});if(r.session.userId!==e.context.session.user.id)throw new C.APIError("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(t)}catch(i){throw e.context.logger.error(i&&typeof i=="object"&&"name"in i?i.name:"",i),new C.APIError("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),Kt=g("/revoke-sessions",{method:"POST",use:[S],requireHeaders:!0,metadata:{openapi:{description:"Revoke all sessions for the user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean"}},required:["status"]}}}}}}}},async e=>{try{await e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(t){throw e.context.logger.error(t&&typeof t=="object"&&"name"in t?t.name:"",t),new C.APIError("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),Jt=g("/revoke-other-sessions",{method:"POST",requireHeaders:!0,use:[S],metadata:{openapi:{description:"Revoke all other sessions for the user except the current one",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean"}}}}}}}}}},async e=>{let t=e.context.session;if(!t.user)throw new C.APIError("UNAUTHORIZED");let o=(await e.context.internalAdapter.listSessions(t.user.id)).filter(n=>n.expiresAt>new Date).filter(n=>n.token!==e.context.session.session.token);return await Promise.all(o.map(n=>e.context.internalAdapter.deleteSession(n.token))),e.json({status:!0})});async function D(e,t,r){return await(0,ae.createJWT)("HS256",Buffer.from(e),{email:t.toLowerCase(),updateTo:r},{expiresIn:new At.TimeSpan(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}async function Yt(e,t){if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new F.APIError("BAD_REQUEST",{message:"Verification email isn't enabled"});let r=await D(e.context.secret,t.email),i=`${e.context.baseURL}/verify-email?token=${r}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;await e.context.options.emailVerification.sendVerificationEmail({user:t,url:i,token:r},e.request)}var Xt=g("/send-verification-email",{method:"POST",query:I.z.object({currentURL:I.z.string({description:"The URL to use for email verification callback"}).optional()}).optional(),body:I.z.object({email:I.z.string({description:"The email to send the verification email to"}).email(),callbackURL:I.z.string({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"},callbackURL:{type:"string",description:"The URL to use for email verification callback"}},required:["email"]}}}},responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean"}}}}}}}}}},async e=>{if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new F.APIError("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:t}=e.body,r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw new F.APIError("BAD_REQUEST",{message:u.USER_NOT_FOUND});return await Yt(e,r.user),e.json({status:!0})}),er=g("/verify-email",{method:"GET",query:I.z.object({token:I.z.string({description:"The token to verify the email"}),callbackURL:I.z.string({description:"The URL to redirect to after email verification"}).optional()}),metadata:{openapi:{description:"Verify the email of the user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{user:{type:"object"},status:{type:"boolean"}},required:["user","status"]}}}}}}}},async e=>{function t(c){throw e.query.callbackURL?e.query.callbackURL.includes("?")?e.redirect(`${e.query.callbackURL}&error=${c}`):e.redirect(`${e.query.callbackURL}?error=${c}`):new F.APIError("UNAUTHORIZED",{message:c})}let{token:r}=e.query,i;try{i=await(0,ae.validateJWT)("HS256",Buffer.from(e.context.secret),r)}catch(c){return e.context.logger.error("Failed to verify email",c),t("invalid_token")}let n=I.z.object({email:I.z.string().email(),updateTo:I.z.string().optional()}).parse(i.payload),s=await e.context.internalAdapter.findUserByEmail(n.email);if(!s)return t("user_not_found");if(n.updateTo){let c=await z(e);if(!c){if(e.query.callbackURL)throw e.redirect(`${e.query.callbackURL}?error=unauthorized`);return t("unauthorized")}if(c.user.email!==n.email){if(e.query.callbackURL)throw e.redirect(`${e.query.callbackURL}?error=unauthorized`);return t("unauthorized")}let a=await e.context.internalAdapter.updateUserByEmail(n.email,{email:n.updateTo,emailVerified:!1}),d=await D(e.context.secret,n.updateTo);if(await e.context.options.emailVerification?.sendVerificationEmail?.({user:a,url:`${e.context.baseURL}/verify-email?token=${d}`,token:d},e.request),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:a,status:!0})}if(await e.context.internalAdapter.updateUserByEmail(n.email,{emailVerified:!0}),e.context.options.emailVerification?.autoSignInAfterVerification&&!await z(e)){let a=await e.context.internalAdapter.createSession(s.user.id,e.request);if(!a)throw new F.APIError("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});await U(e,{session:a,user:s.user})}if(e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:null,status:!0})});async function ce(e,{userInfo:t,account:r,callbackURL:i}){let o=await e.context.internalAdapter.findUserByEmail(t.email.toLowerCase(),{includeAccounts:!0}).catch(a=>{throw L.error(`Better auth was unable to query your database.
2
+ `,`Current list of trustedOrigins: ${l}`),new xe.APIError("FORBIDDEN",{message:`Invalid ${b}`})};p&&!e.context.options.advanced?.disableCSRFCheck&&h(o,"origin"),n&&h(n,"callbackURL"),s&&h(s,"redirectURL"),c&&h(c,"currentURL"),a&&h(a,"errorCallbackURL"),d&&h(s,"newUserCallbackURL")});var E=require("better-call"),k=require("zod");var qt=require("oslo"),Ce=require("oslo/encoding");var te=require("oslo/crypto");async function $t({value:e,secret:t}){return new te.HMAC("SHA-256").sign(new TextEncoder().encode(t),new TextEncoder().encode(e)).then(i=>Buffer.from(i).toString("base64"))}function zt({value:e,signature:t,secret:r}){return new te.HMAC("SHA-256").verify(new TextEncoder().encode(r),Buffer.from(t,"base64"),new TextEncoder().encode(e))}var re={sign:$t,verify:zt};var V=(e,t="ms")=>new Date(Date.now()+(t==="sec"?e*1e3:e));function Pe(e){let t=new Map;return e.split(", ").forEach(i=>{let o=i.split(";").map(p=>p.trim()),[n,...s]=o,[c,...a]=n.split("="),d=a.join("=");if(!c||d===void 0)return;let l={value:d};s.forEach(p=>{let[y,...h]=p.split("="),f=h.join("="),b=y.trim().toLowerCase();switch(b){case"max-age":l["max-age"]=f?parseInt(f.trim(),10):void 0;break;case"expires":l.expires=f?new Date(f.trim()):void 0;break;case"domain":l.domain=f?f.trim():void 0;break;case"path":l.path=f?f.trim():void 0;break;case"secure":l.secure=!0;break;case"httponly":l.httponly=!0;break;case"samesite":l.samesite=f?f.trim().toLowerCase():void 0;break;default:l[b]=f?f.trim():!0;break}}),t.set(c,l)}),t}async function U(e,t,r,i){let o=e.context.authCookies.sessionToken.options,n=r?void 0:e.context.sessionConfig.expiresIn;if(await e.setSignedCookie(e.context.authCookies.sessionToken.name,t.session.token,e.context.secret,{...o,maxAge:n,...i}),r&&await e.setSignedCookie(e.context.authCookies.dontRememberToken.name,"true",e.context.secret,e.context.authCookies.dontRememberToken.options),e.context.options.session?.cookieCache?.enabled){let c=Ce.base64url.encode(new TextEncoder().encode(JSON.stringify({session:t,expiresAt:V(e.context.authCookies.sessionData.options.maxAge||60,"sec").getTime(),signature:await re.sign({value:JSON.stringify(t),secret:e.context.secret})})),{includePadding:!1});if(c.length>4093)throw new j("Session data is too large to store in the cookie. Please disable session cookie caching or reduce the size of the session data");e.setCookie(e.context.authCookies.sessionData.name,c,e.context.authCookies.sessionData.options)}e.context.setNewSession(t),e.context.options.secondaryStorage&&await e.context.secondaryStorage?.set(t.session.token,JSON.stringify({user:t.user,session:t.session}),Math.floor((new Date(t.session.expiresAt).getTime()-Date.now())/1e3))}function _(e){e.setCookie(e.context.authCookies.sessionToken.name,"",{...e.context.authCookies.sessionToken.options,maxAge:0}),e.setCookie(e.context.authCookies.sessionData.name,"",{...e.context.authCookies.sessionData.options,maxAge:0}),e.setCookie(e.context.authCookies.dontRememberToken.name,"",{...e.context.authCookies.dontRememberToken.options,maxAge:0})}function K(e){let t=e.split("; "),r=new Map;return t.forEach(i=>{let[o,n]=i.split("=");r.set(o,n)}),r}var $e=require("@better-fetch/fetch"),ze=require("better-call"),q=require("jose"),qe=require("oslo/jwt");var De=require("oslo/crypto"),Ne=require("oslo/encoding");async function je(e){let t=await(0,De.sha256)(new TextEncoder().encode(e));return Ne.base64url.encode(new Uint8Array(t),{includePadding:!1})}function oe(e){return{tokenType:e.token_type,accessToken:e.access_token,refreshToken:e.refresh_token,accessTokenExpiresAt:e.expires_in?V(e.expires_in,"sec"):void 0,scopes:e?.scope?typeof e.scope=="string"?e.scope.split(" "):e.scope:[],idToken:e.id_token}}async function A({id:e,options:t,authorizationEndpoint:r,state:i,codeVerifier:o,scopes:n,claims:s,redirectURI:c,duration:a}){let d=new URL(r);if(d.searchParams.set("response_type","code"),d.searchParams.set("client_id",t.clientId),d.searchParams.set("state",i),d.searchParams.set("scope",n.join(" ")),d.searchParams.set("redirect_uri",t.redirectURI||c),o){let l=await je(o);d.searchParams.set("code_challenge_method","S256"),d.searchParams.set("code_challenge",l)}if(s){let l=s.reduce((p,y)=>(p[y]=null,p),{});d.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...l}}))}return a&&d.searchParams.set("duration",a),d}var Ve=require("@better-fetch/fetch");async function w({code:e,codeVerifier:t,redirectURI:r,options:i,tokenEndpoint:o,authentication:n}){let s=new URLSearchParams,c={"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"};if(s.set("grant_type","authorization_code"),s.set("code",e),t&&s.set("code_verifier",t),s.set("redirect_uri",r),n==="basic"){let p=btoa(`${i.clientId}:${i.clientSecret}`);c.authorization=`Basic ${p}`}else s.set("client_id",i.clientId),s.set("client_secret",i.clientSecret);let{data:a,error:d}=await(0,Ve.betterFetch)(o,{method:"POST",body:s,headers:c});if(d)throw d;return oe(a)}var ie=require("oslo/oauth2"),P=require("zod"),we=require("better-call");async function ne(e,t){let r=e.body?.callbackURL||(e.query?.currentURL?Ie(e.query?.currentURL):"")||e.context.options.baseURL;if(!r)throw new we.APIError("BAD_REQUEST",{message:"callbackURL is required"});let i=(0,ie.generateCodeVerifier)(),o=(0,ie.generateState)(),n=JSON.stringify({callbackURL:r,codeVerifier:i,errorURL:e.body?.errorCallbackURL||e.query?.currentURL,newUserURL:e.body?.newUserCallbackURL,link:t,expiresAt:Date.now()+10*60*1e3}),s=new Date;s.setMinutes(s.getMinutes()+10);let c=await e.context.internalAdapter.createVerificationValue({value:n,identifier:o,expiresAt:s});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 we.APIError("INTERNAL_SERVER_ERROR",{message:"Unable to create verification"});return{state:c.identifier,codeVerifier:i}}async function Be(e){let t=e.query.state||e.body.state,r=await e.context.internalAdapter.findVerificationValue(t);if(!r)throw e.context.logger.error("State Mismatch. Verification not found",{state:t}),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let i=P.z.object({callbackURL:P.z.string(),codeVerifier:P.z.string(),errorURL:P.z.string().optional(),newUserURL:P.z.string().optional(),expiresAt:P.z.number(),link:P.z.object({email:P.z.string(),userId:P.z.string()}).optional()}).parse(JSON.parse(r.value));if(i.errorURL||(i.errorURL=`${e.context.baseURL}/error`),i.expiresAt<Date.now())throw await e.context.internalAdapter.deleteVerificationValue(r.id),e.context.logger.error("State expired.",{state:t}),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);return await e.context.internalAdapter.deleteVerificationValue(r.id),i}var Me=e=>{let t="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:r,scopes:i,redirectURI:o}){let n=i||["email","name"];return e.scope&&n.push(...e.scope),new URL(`https://appleid.apple.com/auth/authorize?client_id=${e.clientId}&response_type=code&redirect_uri=${o||e.redirectURI}&scope=${n.join(" ")}&state=${r}&response_mode=form_post`)},validateAuthorizationCode:async({code:r,codeVerifier:i,redirectURI:o})=>w({code:r,codeVerifier:i,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:t}),async verifyIdToken(r,i){if(e.disableIdTokenSignIn)return!1;if(e.verifyIdToken)return e.verifyIdToken(r,i);let o=(0,q.decodeProtectedHeader)(r),{kid:n,alg:s}=o;if(!n||!s)return!1;let c=await Mt(n),{payload:a}=await(0,q.jwtVerify)(r,c,{algorithms:[s],issuer:"https://appleid.apple.com",audience:e.clientId,maxTokenAge:"1h"});return["email_verified","is_private_email"].forEach(d=>{a[d]!==void 0&&(a[d]=!!a[d])}),i&&a.nonce!==i?!1:!!a},async getUserInfo(r){if(e.getUserInfo)return e.getUserInfo(r);if(!r.idToken)return null;let i=(0,qe.parseJWT)(r.idToken)?.payload;if(!i)return null;let o=i.user?`${i.user.name.firstName} ${i.user.name.lastName}`:i.email,n=await e.mapProfileToUser?.(i);return{user:{id:i.sub,name:o,emailVerified:!1,email:i.email,...n},data:i}}}},Mt=async e=>{let t="https://appleid.apple.com",r="/auth/keys",{data:i}=await(0,$e.betterFetch)(`${t}${r}`);if(!i?.keys)throw new ze.APIError("BAD_REQUEST",{message:"Keys not found"});let o=i.keys.find(n=>n.kid===e);if(!o)throw new Error(`JWK with kid ${e} not found`);return await(0,q.importJWK)(o,o.alg)};var Fe=require("@better-fetch/fetch");var He=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:t,scopes:r,redirectURI:i}){let o=r||["identify","email"];return e.scope&&o.push(...e.scope),new URL(`https://discord.com/api/oauth2/authorize?scope=${o.join("+")}&response_type=code&client_id=${e.clientId}&redirect_uri=${encodeURIComponent(e.redirectURI||i)}&state=${t}&prompt=${e.prompt||"none"}`)},validateAuthorizationCode:async({code:t,redirectURI:r})=>w({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:i}=await(0,Fe.betterFetch)("https://discord.com/api/users/@me",{headers:{authorization:`Bearer ${t.accessToken}`}});if(i)return null;if(r.avatar===null){let n=r.discriminator==="0"?Number(BigInt(r.id)>>BigInt(22))%6:parseInt(r.discriminator)%5;r.image_url=`https://cdn.discordapp.com/embed/avatars/${n}.png`}else{let n=r.avatar.startsWith("a_")?"gif":"png";r.image_url=`https://cdn.discordapp.com/avatars/${r.id}/${r.avatar}.${n}`}let o=await e.mapProfileToUser?.(r);return{user:{id:r.id,name:r.display_name||r.username||"",email:r.email,emailVerified:r.verified,image:r.image_url,...o},data:r}}});var Ge=require("@better-fetch/fetch");var We=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:t,scopes:r,redirectURI:i}){let o=r||["email","public_profile"];return e.scope&&o.push(...e.scope),await A({id:"facebook",options:e,authorizationEndpoint:"https://www.facebook.com/v21.0/dialog/oauth",scopes:o,state:t,redirectURI:i})},validateAuthorizationCode:async({code:t,redirectURI:r})=>w({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://graph.facebook.com/oauth/access_token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:i}=await(0,Ge.betterFetch)("https://graph.facebook.com/me?fields=id,name,email,picture",{auth:{type:"Bearer",token:t.accessToken}});if(i)return null;let o=await e.mapProfileToUser?.(r);return{user:{id:r.id,name:r.name,email:r.email,image:r.picture.data.url,emailVerified:r.email_verified,...o},data:r}}});var ye=require("@better-fetch/fetch");var Ze=e=>{let t="https://github.com/login/oauth/access_token";return{id:"github",name:"GitHub",createAuthorizationURL({state:r,scopes:i,codeVerifier:o,redirectURI:n}){let s=i||["user:email"];return e.scope&&s.push(...e.scope),A({id:"github",options:e,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:s,state:r,redirectURI:n})},validateAuthorizationCode:async({code:r,redirectURI:i})=>w({code:r,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:t}),async getUserInfo(r){if(e.getUserInfo)return e.getUserInfo(r);let{data:i,error:o}=await(0,ye.betterFetch)("https://api.github.com/user",{headers:{"User-Agent":"better-auth",authorization:`Bearer ${r.accessToken}`}});if(o)return null;let n=!1;if(!i.email){let{data:c,error:a}=await(0,ye.betterFetch)("https://api.github.com/user/emails",{headers:{authorization:`Bearer ${r.accessToken}`,"User-Agent":"better-auth"}});a||(i.email=(c.find(d=>d.primary)??c[0])?.email,n=c.find(d=>d.email===i.email)?.verified??!1)}let s=await e.mapProfileToUser?.(i);return{user:{id:i.id.toString(),name:i.name||i.login,email:i.email,image:i.avatar_url,emailVerified:n,...s},data:i}}}};var Ke=require("oslo/jwt");var Qe=require("consola"),be=["info","success","warn","error","debug"];function Ft(e,t){return be.indexOf(t)<=be.indexOf(e)}var Ht=(0,Qe.createConsola)({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),Gt=e=>{let t=e?.disabled!==!0,r=e?.level??"error",i=(o,n,s=[])=>{if(!(!t||!Ft(r,o))){if(!e||typeof e.log!="function"){Ht[o]("",n,...s);return}e.log(o==="success"?"info":o,n,s)}};return Object.fromEntries(be.map(o=>[o,(...[n,...s])=>i(o,n,s)]))},L=Gt();var Je=require("@better-fetch/fetch"),Ye=e=>({id:"google",name:"Google",async createAuthorizationURL({state:t,scopes:r,codeVerifier:i,redirectURI:o}){if(!e.clientId||!e.clientSecret)throw L.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new j("CLIENT_ID_AND_SECRET_REQUIRED");if(!i)throw new j("codeVerifier is required for Google");let n=r||["email","profile","openid"];e.scope&&n.push(...e.scope);let s=await A({id:"google",options:e,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:n,state:t,codeVerifier:i,redirectURI:o});return e.accessType&&s.searchParams.set("access_type",e.accessType),e.prompt&&s.searchParams.set("prompt",e.prompt),s},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:i})=>w({code:t,codeVerifier:r,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:"https://oauth2.googleapis.com/token"}),async verifyIdToken(t,r){if(e.disableIdTokenSignIn)return!1;if(e.verifyIdToken)return e.verifyIdToken(t,r);let i=`https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=${t}`,{data:o}=await(0,Je.betterFetch)(i);return o?o.aud===e.clientId&&o.iss==="https://accounts.google.com":!1},async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);if(!t.idToken)return null;let r=(0,Ke.parseJWT)(t.idToken)?.payload,i=await e.mapProfileToUser?.(r);return{user:{id:r.sub,name:r.name,email:r.email,image:r.picture,emailVerified:r.email_verified,...i},data:r}}});var Xe=require("@better-fetch/fetch"),et=require("oslo/jwt");var tt=e=>{let t=e.tenantId||"common",r=`https://login.microsoftonline.com/${t}/oauth2/v2.0/authorize`,i=`https://login.microsoftonline.com/${t}/oauth2/v2.0/token`;return{id:"microsoft",name:"Microsoft EntraID",createAuthorizationURL(o){let n=o.scopes||["openid","profile","email","User.Read"];return e.scope&&n.push(...e.scope),A({id:"microsoft",options:e,authorizationEndpoint:r,state:o.state,codeVerifier:o.codeVerifier,scopes:n,redirectURI:o.redirectURI})},validateAuthorizationCode({code:o,codeVerifier:n,redirectURI:s}){return w({code:o,codeVerifier:n,redirectURI:e.redirectURI||s,options:e,tokenEndpoint:i})},async getUserInfo(o){if(e.getUserInfo)return e.getUserInfo(o);if(!o.idToken)return null;let n=(0,et.parseJWT)(o.idToken)?.payload,s=e.profilePhotoSize||48;await(0,Xe.betterFetch)(`https://graph.microsoft.com/v1.0/me/photos/${s}x${s}/$value`,{headers:{Authorization:`Bearer ${o.accessToken}`},async onResponse(a){if(!(e.disableProfilePhoto||!a.response.ok))try{let l=await a.response.clone().arrayBuffer(),p=Buffer.from(l).toString("base64");n.picture=`data:image/jpeg;base64, ${p}`}catch(d){L.error(d&&typeof d=="object"&&"name"in d?d.name:"",d)}}});let c=await e.mapProfileToUser?.(n);return{user:{id:n.sub,name:n.name,email:n.email,image:n.picture,emailVerified:!0,...c},data:n}}}};var rt=require("@better-fetch/fetch");var ot=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:t,scopes:r,codeVerifier:i,redirectURI:o}){let n=r||["user-read-email"];return e.scope&&n.push(...e.scope),A({id:"spotify",options:e,authorizationEndpoint:"https://accounts.spotify.com/authorize",scopes:n,state:t,codeVerifier:i,redirectURI:o})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:i})=>w({code:t,codeVerifier:r,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:"https://accounts.spotify.com/api/token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:i}=await(0,rt.betterFetch)("https://api.spotify.com/v1/me",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});if(i)return null;let o=await e.mapProfileToUser?.(r);return{user:{id:r.id,name:r.display_name,email:r.email,image:r.images[0]?.url,emailVerified:!1,...o},data:r}}});var M={isAction:!1};var it=require("nanoid"),nt=e=>(0,it.nanoid)(e);var st=require("oslo/jwt");var at=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:t,scopes:r,redirectURI:i}){let o=r||["user:read:email","openid"];return e.scope&&o.push(...e.scope),A({id:"twitch",redirectURI:i,options:e,authorizationEndpoint:"https://id.twitch.tv/oauth2/authorize",scopes:o,state:t,claims:e.claims||["email","email_verified","preferred_username","picture"]})},validateAuthorizationCode:async({code:t,redirectURI:r})=>w({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let r=t.idToken;if(!r)return L.error("No idToken found in token"),null;let i=(0,st.parseJWT)(r)?.payload,o=await e.mapProfileToUser?.(i);return{user:{id:i.sub,name:i.preferred_username,email:i.email,image:i.picture,emailVerified:!1,...o},data:i}}});var ct=require("@better-fetch/fetch");var dt=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(t){let r=t.scopes||["users.read","tweet.read","offline.access"];return e.scope&&r.push(...e.scope),A({id:"twitter",options:e,authorizationEndpoint:"https://x.com/i/oauth2/authorize",scopes:r,state:t.state,codeVerifier:t.codeVerifier,redirectURI:t.redirectURI})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:i})=>w({code:t,codeVerifier:r,authentication:"basic",redirectURI:e.redirectURI||i,options:e,tokenEndpoint:"https://api.x.com/2/oauth2/token"}),async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:i}=await(0,ct.betterFetch)("https://api.x.com/2/users/me?user.fields=profile_image_url",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});if(i)return null;let o=await e.mapProfileToUser?.(r);return{user:{id:r.data.id,name:r.data.name,email:r.data.username||null,image:r.data.profile_image_url,emailVerified:r.data.verified||!1,...o},data:r}}});var lt=require("@better-fetch/fetch");var ut=e=>{let t="https://api.dropboxapi.com/oauth2/token";return{id:"dropbox",name:"Dropbox",createAuthorizationURL:async({state:r,scopes:i,codeVerifier:o,redirectURI:n})=>{let s=i||["account_info.read"];return e.scope&&s.push(...e.scope),await A({id:"dropbox",options:e,authorizationEndpoint:"https://www.dropbox.com/oauth2/authorize",scopes:s,state:r,redirectURI:n,codeVerifier:o})},validateAuthorizationCode:async({code:r,codeVerifier:i,redirectURI:o})=>await w({code:r,codeVerifier:i,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:t}),async getUserInfo(r){if(e.getUserInfo)return e.getUserInfo(r);let{data:i,error:o}=await(0,lt.betterFetch)("https://api.dropboxapi.com/2/users/get_current_account",{method:"POST",headers:{Authorization:`Bearer ${r.accessToken}`}});if(o)return null;let n=await e.mapProfileToUser?.(i);return{user:{id:i.account_id,name:i.name?.display_name,email:i.email,emailVerified:i.email_verified||!1,image:i.profile_photo_url,...n},data:i}}}};var pt=require("@better-fetch/fetch");var mt=e=>{let t="https://www.linkedin.com/oauth/v2/authorization",r="https://www.linkedin.com/oauth/v2/accessToken";return{id:"linkedin",name:"Linkedin",createAuthorizationURL:async({state:i,scopes:o,redirectURI:n})=>{let s=o||["profile","email","openid"];return e.scope&&s.push(...e.scope),await A({id:"linkedin",options:e,authorizationEndpoint:t,scopes:s,state:i,redirectURI:n})},validateAuthorizationCode:async({code:i,redirectURI:o})=>await w({code:i,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:r}),async getUserInfo(i){let{data:o,error:n}=await(0,pt.betterFetch)("https://api.linkedin.com/v2/userinfo",{method:"GET",headers:{Authorization:`Bearer ${i.accessToken}`}});if(n)return null;let s=await e.mapProfileToUser?.(o);return{user:{id:o.sub,name:o.name,email:o.email,emailVerified:o.email_verified||!1,image:o.picture,...s},data:o}}}};var ft=require("@better-fetch/fetch");var Ae=(e="")=>e.split("://").map(t=>t.replace(/\/{2,}/g,"/")).join("://"),Wt=e=>{let t=e||"https://gitlab.com";return{authorizationEndpoint:Ae(`${t}/oauth/authorize`),tokenEndpoint:Ae(`${t}/oauth/token`),userinfoEndpoint:Ae(`${t}/api/v4/user`)}},gt=e=>{let{authorizationEndpoint:t,tokenEndpoint:r,userinfoEndpoint:i}=Wt(e.issuer),o="gitlab";return{id:o,name:"Gitlab",createAuthorizationURL:async({state:s,scopes:c,codeVerifier:a,redirectURI:d})=>{let l=c||["read_user"];return e.scope&&l.push(...e.scope),await A({id:o,options:e,authorizationEndpoint:t,scopes:l,state:s,redirectURI:d,codeVerifier:a})},validateAuthorizationCode:async({code:s,redirectURI:c,codeVerifier:a})=>w({code:s,redirectURI:e.redirectURI||c,options:e,codeVerifier:a,tokenEndpoint:r}),async getUserInfo(s){if(e.getUserInfo)return e.getUserInfo(s);let{data:c,error:a}=await(0,ft.betterFetch)(i,{headers:{authorization:`Bearer ${s.accessToken}`}});if(a||c.state!=="active"||c.locked)return null;let d=await e.mapProfileToUser?.(c);return{user:{id:c.id.toString(),name:c.name??c.username,email:c.email,image:c.avatar_url,emailVerified:!0,...d},data:c}}}};var ke=require("@better-fetch/fetch");var ht=e=>({id:"reddit",name:"Reddit",createAuthorizationURL({state:t,scopes:r,redirectURI:i}){let o=r||["identity"];return e.scope&&o.push(...e.scope),A({id:"reddit",options:e,authorizationEndpoint:"https://www.reddit.com/api/v1/authorize",scopes:o,state:t,redirectURI:i,duration:e.duration})},validateAuthorizationCode:async({code:t,redirectURI:r})=>{let i=new URLSearchParams({grant_type:"authorization_code",code:t,redirect_uri:e.redirectURI||r}),o={"content-type":"application/x-www-form-urlencoded",accept:"text/plain","user-agent":"better-auth",Authorization:`Basic ${Buffer.from(`${e.clientId}:${e.clientSecret}`).toString("base64")}`},{data:n,error:s}=await(0,ke.betterFetch)("https://www.reddit.com/api/v1/access_token",{method:"POST",headers:o,body:i.toString()});if(s)throw s;return oe(n)},async getUserInfo(t){if(e.getUserInfo)return e.getUserInfo(t);let{data:r,error:i}=await(0,ke.betterFetch)("https://oauth.reddit.com/api/v1/me",{headers:{Authorization:`Bearer ${t.accessToken}`,"User-Agent":"better-auth"}});if(i)return null;let o=await e.mapProfileToUser?.(r);return{user:{id:r.id,name:r.name,email:r.oauth_client_id,emailVerified:r.has_verified_email,image:r.icon_img?.split("?")[0],...o},data:r}}});var Zt={apple:Me,discord:He,facebook:We,github:Ze,microsoft:tt,google:Ye,spotify:ot,twitch:at,twitter:dt,dropbox:ut,linkedin:mt,gitlab:gt,reddit:ht},se=Object.keys(Zt);var At=require("oslo"),ae=require("oslo/jwt"),I=require("zod");var F=require("better-call");var C=require("better-call");var B=require("zod");function wt(e){try{return JSON.parse(e)}catch{return null}}var u={USER_NOT_FOUND:"User not found",FAILED_TO_CREATE_USER:"Failed to create user",FAILED_TO_CREATE_SESSION:"Failed to create session",FAILED_TO_UPDATE_USER:"Failed to update user",FAILED_TO_GET_SESSION:"Failed to get session",INVALID_PASSWORD:"Invalid password",INVALID_EMAIL:"Invalid email",INVALID_EMAIL_OR_PASSWORD:"Invalid email or password",SOCIAL_ACCOUNT_ALREADY_LINKED:"Social account already linked",PROVIDER_NOT_FOUND:"Provider not found",INVALID_TOKEN:"invalid token",ID_TOKEN_NOT_SUPPORTED:"id_token not supported",FAILED_TO_GET_USER_INFO:"Failed to get user info",USER_EMAIL_NOT_FOUND:"User email not found",EMAIL_NOT_VERIFIED:"Email not verified",PASSWORD_TOO_SHORT:"Password too short",PASSWORD_TOO_LONG:"Password too long",USER_ALREADY_EXISTS:"User already exists",EMAIL_CAN_NOT_BE_UPDATED:"Email can not be updated",CREDENTIAL_ACCOUNT_NOT_FOUND:"Credential account not found"};var yt=()=>g("/get-session",{method:"GET",query:B.z.optional(B.z.object({disableCookieCache:B.z.boolean({description:"Disable cookie cache and fetch session from database"}).or(B.z.string().transform(e=>e==="true")).optional(),disableRefresh:B.z.boolean({description:"Disable session refresh. Useful for checking session status, without updating the session"}).optional()})),requireHeaders:!0,metadata:{openapi:{description:"Get the current session",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{session:{type:"object",properties:{token:{type:"string"},userId:{type:"string"},expiresAt:{type:"string"}}},user:{type:"object",$ref:"#/components/schemas/User"}}}}}}}}}},async e=>{try{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)return e.json(null);let r=e.getCookie(e.context.authCookies.sessionData.name),i=r?wt(Buffer.from(r,"base64").toString()):null;if(i&&!await re.verify({value:JSON.stringify(i.session),signature:i?.signature,secret:e.context.secret}))return _(e),e.json(null);let o=await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret);if(i?.session&&e.context.options.session?.cookieCache?.enabled&&!e.query?.disableCookieCache){let l=i.session;if(i.expiresAt<Date.now()||l.session.expiresAt<new Date){let y=e.context.authCookies.sessionData.name;e.setCookie(y,"",{maxAge:0})}else return e.json(l)}let n=await e.context.internalAdapter.findSession(t);if(e.context.session=n,!n||n.session.expiresAt<new Date)return _(e),n&&await e.context.internalAdapter.deleteSession(n.session.token),e.json(null);if(o||e.query?.disableRefresh)return e.json(n);let s=e.context.sessionConfig.expiresIn,c=e.context.sessionConfig.updateAge;if(n.session.expiresAt.valueOf()-s*1e3+c*1e3<=Date.now()){let l=await e.context.internalAdapter.updateSession(n.session.token,{expiresAt:V(e.context.sessionConfig.expiresIn,"sec")});if(!l)return _(e),e.json(null,{status:401});let p=(l.expiresAt.valueOf()-Date.now())/1e3;return await U(e,{session:l,user:n.user},!1,{maxAge:p}),e.json({session:l,user:n.user})}return e.json(n)}catch(t){throw e.context.logger.error("INTERNAL_SERVER_ERROR",t),new C.APIError("INTERNAL_SERVER_ERROR",{message:u.FAILED_TO_GET_SESSION})}}),z=async(e,t)=>{if(e.context.session)return e.context.session;let r=await yt()({...e,_flag:"json",headers:e.headers,query:t}).catch(i=>null);return e.context.session=r,r},S=N(async e=>{let t=await z(e);if(!t?.session)throw new C.APIError("UNAUTHORIZED");return{session:t}}),bt=N(async e=>{let t=await z(e);if(!t?.session)throw new C.APIError("UNAUTHORIZED");if(e.context.sessionConfig.freshAge===0)return{session:t};let r=e.context.sessionConfig.freshAge,i=t.session.updatedAt?.valueOf()||t.session.createdAt.valueOf();if(!(Date.now()-i<r*1e3))throw new C.APIError("FORBIDDEN",{message:"Session is not fresh"});return{session:t}});var Qt=g("/revoke-session",{method:"POST",body:B.z.object({token:B.z.string({description:"The token to revoke"})}),use:[S],requireHeaders:!0,metadata:{openapi:{description:"Revoke a single session",requestBody:{content:{"application/json":{schema:{type:"object",properties:{token:{type:"string"}},required:["token"]}}}}}}},async e=>{let t=e.body.token,r=await e.context.internalAdapter.findSession(t);if(!r)throw new C.APIError("BAD_REQUEST",{message:"Session not found"});if(r.session.userId!==e.context.session.user.id)throw new C.APIError("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(t)}catch(i){throw e.context.logger.error(i&&typeof i=="object"&&"name"in i?i.name:"",i),new C.APIError("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),Kt=g("/revoke-sessions",{method:"POST",use:[S],requireHeaders:!0,metadata:{openapi:{description:"Revoke all sessions for the user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean"}},required:["status"]}}}}}}}},async e=>{try{await e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(t){throw e.context.logger.error(t&&typeof t=="object"&&"name"in t?t.name:"",t),new C.APIError("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),Jt=g("/revoke-other-sessions",{method:"POST",requireHeaders:!0,use:[S],metadata:{openapi:{description:"Revoke all other sessions for the user except the current one",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean"}}}}}}}}}},async e=>{let t=e.context.session;if(!t.user)throw new C.APIError("UNAUTHORIZED");let o=(await e.context.internalAdapter.listSessions(t.user.id)).filter(n=>n.expiresAt>new Date).filter(n=>n.token!==e.context.session.session.token);return await Promise.all(o.map(n=>e.context.internalAdapter.deleteSession(n.token))),e.json({status:!0})});async function D(e,t,r){return await(0,ae.createJWT)("HS256",Buffer.from(e),{email:t.toLowerCase(),updateTo:r},{expiresIn:new At.TimeSpan(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}async function Yt(e,t){if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new F.APIError("BAD_REQUEST",{message:"Verification email isn't enabled"});let r=await D(e.context.secret,t.email),i=`${e.context.baseURL}/verify-email?token=${r}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;await e.context.options.emailVerification.sendVerificationEmail({user:t,url:i,token:r},e.request)}var Xt=g("/send-verification-email",{method:"POST",query:I.z.object({currentURL:I.z.string({description:"The URL to use for email verification callback"}).optional()}).optional(),body:I.z.object({email:I.z.string({description:"The email to send the verification email to"}).email(),callbackURL:I.z.string({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"},callbackURL:{type:"string",description:"The URL to use for email verification callback"}},required:["email"]}}}},responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{status:{type:"boolean"}}}}}}}}}},async e=>{if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new F.APIError("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:t}=e.body,r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw new F.APIError("BAD_REQUEST",{message:u.USER_NOT_FOUND});return await Yt(e,r.user),e.json({status:!0})}),er=g("/verify-email",{method:"GET",query:I.z.object({token:I.z.string({description:"The token to verify the email"}),callbackURL:I.z.string({description:"The URL to redirect to after email verification"}).optional()}),metadata:{openapi:{description:"Verify the email of the user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{user:{type:"object"},status:{type:"boolean"}},required:["user","status"]}}}}}}}},async e=>{function t(c){throw e.query.callbackURL?e.query.callbackURL.includes("?")?e.redirect(`${e.query.callbackURL}&error=${c}`):e.redirect(`${e.query.callbackURL}?error=${c}`):new F.APIError("UNAUTHORIZED",{message:c})}let{token:r}=e.query,i;try{i=await(0,ae.validateJWT)("HS256",Buffer.from(e.context.secret),r)}catch(c){return e.context.logger.error("Failed to verify email",c),t("invalid_token")}let n=I.z.object({email:I.z.string().email(),updateTo:I.z.string().optional()}).parse(i.payload),s=await e.context.internalAdapter.findUserByEmail(n.email);if(!s)return t("user_not_found");if(n.updateTo){let c=await z(e);if(!c){if(e.query.callbackURL)throw e.redirect(`${e.query.callbackURL}?error=unauthorized`);return t("unauthorized")}if(c.user.email!==n.email){if(e.query.callbackURL)throw e.redirect(`${e.query.callbackURL}?error=unauthorized`);return t("unauthorized")}let a=await e.context.internalAdapter.updateUserByEmail(n.email,{email:n.updateTo,emailVerified:!1}),d=await D(e.context.secret,n.updateTo);if(await e.context.options.emailVerification?.sendVerificationEmail?.({user:a,url:`${e.context.baseURL}/verify-email?token=${d}`,token:d},e.request),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:a,status:!0})}if(await e.context.internalAdapter.updateUserByEmail(n.email,{emailVerified:!0}),e.context.options.emailVerification?.autoSignInAfterVerification&&!await z(e)){let a=await e.context.internalAdapter.createSession(s.user.id,e.request);if(!a)throw new F.APIError("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});await U(e,{session:a,user:s.user})}if(e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:null,status:!0})});async function ce(e,{userInfo:t,account:r,callbackURL:i}){let o=await e.context.internalAdapter.findUserByEmail(t.email.toLowerCase(),{includeAccounts:!0}).catch(a=>{throw L.error(`Better auth was unable to query your database.
3
3
  Error: `,a),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)}),n=o?.user,s=!n;if(o){let a=o.accounts.find(d=>d.providerId===r.providerId);if(a){let d=Object.fromEntries(Object.entries({accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,accessTokenExpiresAt:r.accessTokenExpiresAt,refreshTokenExpiresAt:r.refreshTokenExpiresAt}).filter(([l,p])=>p!==void 0));Object.keys(d).length>0&&await e.context.internalAdapter.updateAccount(a.id,d)}else{if(!e.context.options.account?.accountLinking?.trustedProviders?.includes(r.providerId)&&!t.emailVerified||e.context.options.account?.accountLinking?.enabled===!1)return he&&L.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:o.user.id,accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,accessTokenExpiresAt:r.accessTokenExpiresAt,refreshTokenExpiresAt:r.refreshTokenExpiresAt,scope:r.scope})}catch(p){return L.error("Unable to link account",p),{error:"unable to link account",data:null}}n=await e.context.internalAdapter.updateUser(o.user.id,{...t,updatedAt:new Date})}}else if(n=await e.context.internalAdapter.createOAuthUser({...t,email:t.email.toLowerCase(),id:void 0},{accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,accessTokenExpiresAt:r.accessTokenExpiresAt,refreshTokenExpiresAt:r.refreshTokenExpiresAt,scope:r.scope,providerId:r.providerId,accountId:t.id.toString()}).then(a=>a?.user),!t.emailVerified&&n&&e.context.options.emailVerification?.sendOnSignUp){let a=await D(e.context.secret,n.email),d=`${e.context.baseURL}/verify-email?token=${a}&callbackURL=${i}`;await e.context.options.emailVerification?.sendVerificationEmail?.({user:n,url:d,token:a},e.request)}if(!n)return{error:"unable to create user",data:null,isRegister:!1};let c=await e.context.internalAdapter.createSession(n.id,e.request);return c?{data:{session:c,user:n},error:null,isRegister:s}:{error:"unable to create session",data:null,isRegister:!1}}var tr=g("/sign-in/social",{method:"POST",query:k.z.object({currentURL:k.z.string().optional()}).optional(),body:k.z.object({callbackURL:k.z.string({description:"Callback URL to redirect to after the user has signed in"}).optional(),newUserCallbackURL:k.z.string().optional(),errorCallbackURL:k.z.string({description:"Callback URL to redirect to if an error happens"}).optional(),provider:k.z.enum(se,{description:"OAuth2 provider to use"}),disableRedirect:k.z.boolean({description:"Disable automatic redirection to the provider. Useful for handling the redirection yourself"}).optional(),idToken:k.z.optional(k.z.object({token:k.z.string({description:"ID token from the provider"}),nonce:k.z.string({description:"Nonce used to generate the token"}).optional(),accessToken:k.z.string({description:"Access token from the provider"}).optional(),refreshToken:k.z.string({description:"Refresh token from the provider"}).optional(),expiresAt:k.z.number({description:"Expiry date of the token"}).optional()}),{description:"ID token from the provider to sign in the user with id token"})}),metadata:{openapi:{description:"Sign in with a social provider",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{session:{type:"string"},user:{type:"object"},url:{type:"string"},redirect:{type:"boolean"}},required:["session","user","url","redirect"]}}}}}}}},async e=>{let t=e.context.socialProviders.find(n=>n.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 E.APIError("NOT_FOUND",{message:u.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 E.APIError("NOT_FOUND",{message:u.ID_TOKEN_NOT_SUPPORTED});let{token:n,nonce:s}=e.body.idToken;if(!await t.verifyIdToken(n,s))throw e.context.logger.error("Invalid id token",{provider:e.body.provider}),new E.APIError("UNAUTHORIZED",{message:u.INVALID_TOKEN});let a=await t.getUserInfo({idToken:n,accessToken:e.body.idToken.accessToken,refreshToken:e.body.idToken.refreshToken});if(!a||!a?.user)throw e.context.logger.error("Failed to get user info",{provider:e.body.provider}),new E.APIError("UNAUTHORIZED",{message:u.FAILED_TO_GET_USER_INFO});if(!a.user.email)throw e.context.logger.error("User email not found",{provider:e.body.provider}),new E.APIError("UNAUTHORIZED",{message:u.USER_EMAIL_NOT_FOUND});let d=await ce(e,{userInfo:{email:a.user.email,id:a.user.id,name:a.user.name||"",image:a.user.image,emailVerified:a.user.emailVerified||!1},account:{providerId:t.id,accountId:a.user.id,accessToken:e.body.idToken.accessToken}});if(d.error)throw new E.APIError("UNAUTHORIZED",{message:d.error});return await U(e,d.data),e.json({session:d.data.session,user:d.data.user,url:void 0,redirect:!1})}let{codeVerifier:r,state:i}=await ne(e),o=await t.createAuthorizationURL({state:i,codeVerifier:r,redirectURI:`${e.context.baseURL}/callback/${t.id}`});return e.json({url:o.toString(),redirect:!e.body.disableRedirect})}),rr=g("/sign-in/email",{method:"POST",body:k.z.object({email:k.z.string({description:"Email of the user"}),password:k.z.string({description:"Password of the user"}),callbackURL:k.z.string({description:"Callback URL to use as a redirect for email verification"}).optional(),rememberMe:k.z.boolean({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",content:{"application/json":{schema:{type:"object",properties:{user:{type:"object"},url:{type:"string"},redirect:{type:"boolean"}},required:["session","user","url","redirect"]}}}}}}}},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 E.APIError("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:t,password:r}=e.body;if(!k.z.string().email().safeParse(t).success)throw new E.APIError("BAD_REQUEST",{message:u.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 E.APIError("UNAUTHORIZED",{message:u.INVALID_EMAIL_OR_PASSWORD});let n=o.accounts.find(d=>d.providerId==="credential");if(!n)throw e.context.logger.error("Credential account not found",{email:t}),new E.APIError("UNAUTHORIZED",{message:u.INVALID_EMAIL_OR_PASSWORD});let s=n?.password;if(!s)throw e.context.logger.error("Password not found",{email:t}),new E.APIError("UNAUTHORIZED",{message:u.INVALID_EMAIL_OR_PASSWORD});if(!await e.context.password.verify({hash:s,password:r}))throw e.context.logger.error("Invalid password"),new E.APIError("UNAUTHORIZED",{message:u.INVALID_EMAIL_OR_PASSWORD});if(e.context.options?.emailAndPassword?.requireEmailVerification&&!o.user.emailVerified){if(!e.context.options?.emailVerification?.sendVerificationEmail)throw new E.APIError("UNAUTHORIZED",{message:u.EMAIL_NOT_VERIFIED});let d=await D(e.context.secret,o.user.email),l=`${e.context.baseURL}/verify-email?token=${d}&callbackURL=${e.body.callbackURL||"/"}`;throw await e.context.options.emailVerification.sendVerificationEmail({user:o.user,url:l,token:d},e.request),e.context.logger.error("Email not verified",{email:t}),new E.APIError("FORBIDDEN",{message:u.EMAIL_NOT_VERIFIED})}let a=await e.context.internalAdapter.createSession(o.user.id,e.headers,e.body.rememberMe===!1);if(!a)throw e.context.logger.error("Failed to create session"),new E.APIError("UNAUTHORIZED",{message:u.FAILED_TO_CREATE_SESSION});return await U(e,{session:a,user:o.user},e.body.rememberMe===!1),e.json({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},redirect:!!e.body.callbackURL,url:e.body.callbackURL})});var H=require("zod");var de=H.z.object({code:H.z.string().optional(),error:H.z.string().optional(),error_description:H.z.string().optional(),state:H.z.string().optional()}),or=g("/callback/:id",{method:["GET","POST"],body:de.optional(),query:de.optional(),metadata:M},async e=>{let t;try{if(e.method==="GET")t=de.parse(e.query);else if(e.method==="POST")t=de.parse(e.body);else throw new Error("Unsupported method")}catch(v){throw e.context.logger.error("INVALID_CALLBACK_REQUEST",v),e.redirect(`${e.context.baseURL}/error?error=invalid_callback_request`)}let{code:r,error:i,state:o,error_description:n}=t;if(!o)throw e.context.logger.error("State not found",i),e.redirect(`${e.context.baseURL}/error?error=state_not_found`);if(!r)throw e.context.logger.error("Code not found"),e.redirect(`${e.context.baseURL}/error?error=${i||"no_code"}&error_description=${n}`);let s=e.context.socialProviders.find(v=>v.id===e.params.id);if(!s)throw e.context.logger.error("Oauth provider with id",e.params.id,"not found"),e.redirect(`${e.context.baseURL}/error?error=oauth_provider_not_found`);let{codeVerifier:c,callbackURL:a,link:d,errorURL:l,newUserURL:p}=await Be(e),y;try{y=await s.validateAuthorizationCode({code:r,codeVerifier:c,redirectURI:`${e.context.baseURL}/callback/${s.id}`})}catch(v){throw e.context.logger.error("",v),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let h=await s.getUserInfo(y).then(v=>v?.user);function f(v){let x=l||a||`${e.context.baseURL}/error`;throw x.includes("?")?x=`${x}&error=${v}`:x=`${x}?error=${v}`,e.redirect(x)}if(!h)return e.context.logger.error("Unable to get user info"),f("unable_to_get_user_info");if(!h.email)return e.context.logger.error("Provider did not return email. This could be due to misconfiguration in the provider settings."),f("email_not_found");if(!a)throw e.context.logger.error("No callback URL found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(d){if(d.email!==h.email.toLowerCase())return f("email_doesn't_match");if(!await e.context.internalAdapter.createAccount({userId:d.userId,providerId:s.id,accountId:h.id}))return f("unable_to_link_account");let x;try{x=a.toString()}catch{x=a}throw e.redirect(x)}let b=await ce(e,{userInfo:{...h,email:h.email,name:h.name||h.email},account:{providerId:s.id,accountId:h.id,...y,scope:y.scopes?.join(",")},callbackURL:a});if(b.error)return e.context.logger.error(b.error.split(" ").join("_")),f(b.error.split(" ").join("_"));let{session:_e,user:le}=b.data;await U(e,{session:_e,user:le});let ue;try{ue=(b.isRegister&&p||a).toString()}catch{ue=b.isRegister&&p||a}throw e.redirect(ue)});var gn=require("zod");var kt=require("better-call");var ir=g("/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);if(!t)throw _(e),new kt.APIError("BAD_REQUEST",{message:u.FAILED_TO_GET_SESSION});return await e.context.internalAdapter.deleteSession(t),_(e),e.json({success:!0})});var O=require("zod");var G=require("better-call");function Rt(e,t,r){let i=t?new URL(t,e.baseURL):new URL(`${e.baseURL}/error`);return r&&Object.entries(r).forEach(([o,n])=>i.searchParams.set(o,n)),i.href}function nr(e,t,r){let i=new URL(t,e.baseURL);return r&&Object.entries(r).forEach(([o,n])=>i.searchParams.set(o,n)),i.href}var sr=g("/forget-password",{method:"POST",body:O.z.object({email:O.z.string({description:"The email address of the user to send a password reset email to"}).email(),redirectTo:O.z.string({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"}}}}}}}}}},async e=>{if(!e.context.options.emailAndPassword?.sendResetPassword)throw e.context.logger.error("Reset password isn't enabled.Please pass an emailAndPassword.sendResetPasswordToken function in your auth config!"),new G.APIError("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:!1},{body:{status:!0}});let o=60*60*1,n=V(e.context.options.emailAndPassword.resetPasswordTokenExpiresIn||o,"sec"),s=nt(24);await e.context.internalAdapter.createVerificationValue({value:i.user.id.toString(),identifier:`reset-password:${s}`,expiresAt:n});let c=`${e.context.baseURL}/reset-password/${s}?callbackURL=${r}`;return await e.context.options.emailAndPassword.sendResetPassword({user:i.user,url:c,token:s},e.request),e.json({status:!0})}),ar=g("/reset-password/:token",{method:"GET",query:O.z.object({callbackURL:O.z.string({description:"The URL to redirect the user to reset their password"})}),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(Rt(e.context,r,{error:"INVALID_TOKEN"}));let i=await e.context.internalAdapter.findVerificationValue(`reset-password:${t}`);throw!i||i.expiresAt<new Date?e.redirect(Rt(e.context,r,{error:"INVALID_TOKEN"})):e.redirect(nr(e.context,r,{token:t}))}),cr=g("/reset-password",{query:O.z.optional(O.z.object({token:O.z.string().optional(),currentURL:O.z.string().optional()})),method:"POST",body:O.z.object({newPassword:O.z.string({description:"The new password to set"}),token:O.z.string({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||(e.query?.currentURL?new URL(e.query.currentURL).searchParams.get("token"):"");if(!t)throw new G.APIError("BAD_REQUEST",{message:u.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 G.APIError("BAD_REQUEST",{message:u.PASSWORD_TOO_SHORT});if(r.length>o)throw new G.APIError("BAD_REQUEST",{message:u.PASSWORD_TOO_LONG});let n=`reset-password:${t}`,s=await e.context.internalAdapter.findVerificationValue(n);if(!s||s.expiresAt<new Date)throw new G.APIError("BAD_REQUEST",{message:u.INVALID_TOKEN});await e.context.internalAdapter.deleteVerificationValue(s.id);let c=s.value,a=await e.context.password.hash(r);return(await e.context.internalAdapter.findAccounts(c)).find(p=>p.providerId==="credential")?(await e.context.internalAdapter.updatePassword(c,a),e.json({status:!0})):(await e.context.internalAdapter.createAccount({userId:c,providerId:"credential",password:a,accountId:c}),e.json({status:!0}))});var T=require("zod");var R=require("better-call");var m=require("zod"),dr=require("better-call"),Tn=m.z.object({id:m.z.string(),providerId:m.z.string(),accountId:m.z.string(),userId:m.z.string(),accessToken:m.z.string().nullish(),refreshToken:m.z.string().nullish(),idToken:m.z.string().nullish(),accessTokenExpiresAt:m.z.date().nullish(),refreshTokenExpiresAt:m.z.date().nullish(),scope:m.z.string().nullish(),password:m.z.string().nullish(),createdAt:m.z.date().default(()=>new Date),updatedAt:m.z.date().default(()=>new Date)}),Sn=m.z.object({id:m.z.string(),email:m.z.string().transform(e=>e.toLowerCase()),emailVerified:m.z.boolean().default(!1),name:m.z.string(),image:m.z.string().nullish(),createdAt:m.z.date().default(()=>new Date),updatedAt:m.z.date().default(()=>new Date)}),On=m.z.object({id:m.z.string(),userId:m.z.string(),expiresAt:m.z.date(),createdAt:m.z.date().default(()=>new Date),updatedAt:m.z.date().default(()=>new Date),token:m.z.string(),ipAddress:m.z.string().nullish(),userAgent:m.z.string().nullish()}),vn=m.z.object({id:m.z.string(),value:m.z.string(),createdAt:m.z.date().default(()=>new Date),updatedAt:m.z.date().default(()=>new Date),expiresAt:m.z.date(),identifier:m.z.string()});var gr=require("@noble/ciphers/chacha"),Ee=require("@noble/ciphers/utils"),hr=require("@noble/ciphers/webcrypto"),wr=require("oslo/crypto"),yr=pe(require("uncrypto"),1);var Et=require("oslo/encoding");var lr=require("@noble/hashes/scrypt"),ur=require("uncrypto");var Re=pe(require("uncrypto"),1);function pr(e){return e.toString(2).padStart(8,"0")}function mr(e){return[...e].map(t=>pr(t)).join("")}function Ut(e){return parseInt(mr(e),2)}function fr(e){if(e<0||!Number.isInteger(e))throw new Error("Argument 'max' must be an integer greater than or equal to 0");let t=(e-1).toString(2).length,r=t%8,i=new Uint8Array(Math.ceil(t/8));Re.default.getRandomValues(i),r!==0&&(i[0]&=(1<<r)-1);let o=Ut(i);for(;o>=e;)Re.default.getRandomValues(i),r!==0&&(i[0]&=(1<<r)-1),o=Ut(i);return o}function _t(e,t){let r="";for(let i=0;i<e;i++)r+=t[fr(t.length)];return r}function Tt(...e){let t=new Set(e),r="";for(let i of t)i==="a-z"?r+="abcdefghijklmnopqrstuvwxyz":i==="A-Z"?r+="ABCDEFGHIJKLMNOPQRSTUVWXYZ":i==="0-9"?r+="0123456789":r+=i;return r}var Ar=g("/change-password",{method:"POST",body:T.z.object({newPassword:T.z.string({description:"The new password to set"}),currentPassword:T.z.string({description:"The current password"}),revokeOtherSessions:T.z.boolean({description:"Revoke all other sessions"}).optional()}),use:[S],metadata:{openapi:{description:"Change the password of the user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{user:{description:"The user object",$ref:"#/components/schemas/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 R.APIError("BAD_REQUEST",{message:u.PASSWORD_TOO_SHORT});let s=e.context.password.config.maxPasswordLength;if(t.length>s)throw e.context.logger.error("Password is too long"),new R.APIError("BAD_REQUEST",{message:u.PASSWORD_TOO_LONG});let a=(await e.context.internalAdapter.findAccounts(o.user.id)).find(p=>p.providerId==="credential"&&p.password);if(!a||!a.password)throw new R.APIError("BAD_REQUEST",{message:u.CREDENTIAL_ACCOUNT_NOT_FOUND});let d=await e.context.password.hash(t);if(!await e.context.password.verify({hash:a.password,password:r}))throw new R.APIError("BAD_REQUEST",{message:u.INVALID_PASSWORD});if(await e.context.internalAdapter.updateAccount(a.id,{password:d}),i){await e.context.internalAdapter.deleteSessions(o.user.id);let p=await e.context.internalAdapter.createSession(o.user.id,e.headers);if(!p)throw new R.APIError("INTERNAL_SERVER_ERROR",{message:u.FAILED_TO_GET_SESSION});await U(e,{session:p,user:o.user})}return e.json(o.user)}),kr=g("/set-password",{method:"POST",body:T.z.object({newPassword:T.z.string()}),metadata:{SERVER_ONLY:!0},use:[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 R.APIError("BAD_REQUEST",{message:u.PASSWORD_TOO_SHORT});let o=e.context.password.config.maxPasswordLength;if(t.length>o)throw e.context.logger.error("Password is too long"),new R.APIError("BAD_REQUEST",{message:u.PASSWORD_TOO_LONG});let s=(await e.context.internalAdapter.findAccounts(r.user.id)).find(a=>a.providerId==="credential"&&a.password),c=await e.context.password.hash(t);if(!s)return await e.context.internalAdapter.linkAccount({userId:r.user.id,providerId:"credential",accountId:r.user.id,password:c}),e.json(r.user);throw new R.APIError("BAD_REQUEST",{message:"user already has a password"})}),Rr=g("/delete-user",{method:"POST",use:[bt],metadata:{openapi:{description:"Delete the user",responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object"}}}}}}}},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 R.APIError("NOT_FOUND");let t=e.context.session;if(e.context.options.user.deleteUser?.sendDeleteAccountVerification){let o=_t(32,Tt("a-z","A-Z","0-9"));await e.context.internalAdapter.createVerificationValue({value:t.user.id,identifier:`delete-account-${o}`,expiresAt:new Date(Date.now()+1e3*60*60*24)});let n=`${e.context.baseURL}/delete-user/callback?token=${o}`;return await e.context.options.user.deleteUser.sendDeleteAccountVerification({user:t.user,url:n,token:o},e.request),e.json({success:!0,message:"Verification email sent"})}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),_(e);let i=e.context.options.user.deleteUser?.afterDelete;return i&&await i(t.user,e.request),e.json({success:!0,message:"User deleted"})}),Er=g("/delete-user/callback",{method:"GET",query:T.z.object({token:T.z.string()})},async e=>{if(!e.context.options.user?.deleteUser?.enabled)throw e.context.logger.error("Delete user is disabled. Enable it in the options"),new R.APIError("NOT_FOUND");let t=await z(e);if(!t)throw new R.APIError("NOT_FOUND",{message:u.FAILED_TO_GET_USER_INFO});let r=await e.context.internalAdapter.findVerificationValue(`delete-account-${e.query.token}`);if(!r||r.expiresAt<new Date)throw r&&await e.context.internalAdapter.deleteVerificationValue(r.id),new R.APIError("NOT_FOUND",{message:u.INVALID_TOKEN});if(r.value!==t.user.id)throw new R.APIError("NOT_FOUND",{message:u.INVALID_TOKEN});let i=e.context.options.user.deleteUser?.beforeDelete;i&&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),_(e);let o=e.context.options.user.deleteUser?.afterDelete;return o&&await o(t.user,e.request),e.json({success:!0,message:"User deleted"})}),Ur=g("/change-email",{method:"POST",query:T.z.object({currentURL:T.z.string().optional()}).optional(),body:T.z.object({newEmail:T.z.string({description:"The new email to set"}).email(),callbackURL:T.z.string({description:"The URL to redirect to after email verification"}).optional()}),use:[S],metadata:{openapi:{responses:{200:{description:"Success",content:{"application/json":{schema:{type:"object",properties:{user:{type:"object"},status:{type:"boolean"}}}}}}}}}},async e=>{if(!e.context.options.user?.changeEmail?.enabled)throw e.context.logger.error("Change email is disabled."),new R.APIError("BAD_REQUEST",{message:"Change email is disabled"});if(e.body.newEmail===e.context.session.user.email)throw e.context.logger.error("Email is the same"),new R.APIError("BAD_REQUEST",{message:"Email is the same"});if(await e.context.internalAdapter.findUserByEmail(e.body.newEmail))throw e.context.logger.error("Email already exists"),new R.APIError("BAD_REQUEST",{message:"Couldn't update your email"});if(e.context.session.user.emailVerified!==!0){let o=await e.context.internalAdapter.updateUserByEmail(e.context.session.user.email,{email:e.body.newEmail});return e.json({user:o,status:!0})}if(!e.context.options.user.changeEmail.sendChangeEmailVerification)throw e.context.logger.error("Verification email isn't enabled."),new R.APIError("BAD_REQUEST",{message:"Verification email isn't enabled"});let r=await D(e.context.secret,e.context.session.user.email,e.body.newEmail),i=`${e.context.baseURL}/verify-email?token=${r}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.user.changeEmail.sendChangeEmailVerification({user:e.context.session.user,newEmail:e.body.newEmail,url:i,token:r},e.request),e.json({user:null,status:!0})});var _r=(e="Unknown")=>`<!DOCTYPE html>
4
4
  <html lang="en">
5
5
  <head>