better-auth 0.5.3-beta.13 → 0.5.3-beta.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import{APIError as st,createRouter as Ht,statusCode as Zt}from"better-call";import{APIError as J}from"better-call";import{z as de}from"zod";import{xchacha20poly1305 as ar}from"@noble/ciphers/chacha";import{bytesToHex as cr,hexToBytes as lr,utf8ToBytes as ur}from"@noble/ciphers/utils";import{managedNonce as mr}from"@noble/ciphers/webcrypto";import{sha256 as gr}from"oslo/crypto";import ie from"uncrypto";function W(e,r){let t=new Uint8Array(e),o=new Uint8Array(r);if(t.length!==o.length)return!1;let n=0;for(let i=0;i<t.length;i++)n|=t[i]^o[i];return n===0}import{decodeHex as Jt,encodeHex as Kt}from"oslo/encoding";import{scryptAsync as er}from"@noble/hashes/scrypt";import{getRandomValues as rr}from"uncrypto";import te from"uncrypto";function at(e){return e.toString(2).padStart(8,"0")}function dt(e){return[...e].map(r=>at(r)).join("")}function re(e){return parseInt(dt(e),2)}function ct(e){if(e<0||!Number.isInteger(e))throw new Error("Argument 'max' must be an integer greater than or equal to 0");let r=(e-1).toString(2).length,t=r%8,o=new Uint8Array(Math.ceil(r/8));te.getRandomValues(o),t!==0&&(o[0]&=(1<<t)-1);let n=re(o);for(;n>=e;)te.getRandomValues(o),t!==0&&(o[0]&=(1<<t)-1),n=re(o);return n}function oe(e,r){let t="";for(let o=0;o<e;o++)t+=r[ct(r.length)];return t}function ne(...e){let r=new Set(e),t="";for(let o of r)o==="a-z"?t+="abcdefghijklmnopqrstuvwxyz":o==="A-Z"?t+="ABCDEFGHIJKLMNOPQRSTUVWXYZ":o==="0-9"?t+="0123456789":t+=o;return t}async function F(e,r){let t=new TextEncoder,o={name:"HMAC",hash:"SHA-256"},n=await ie.subtle.importKey("raw",t.encode(e),o,!1,["sign","verify"]),i=await ie.subtle.sign(o.name,n,t.encode(r));return btoa(String.fromCharCode(...new Uint8Array(i)))}import{createEndpointCreator as lt,createMiddleware as se,createMiddlewareCreator as ut}from"better-call";var ae=se(async()=>({})),z=ut({use:[ae,se(async()=>({}))]}),m=lt({use:[ae]});var ce=z({body:de.object({csrfToken:de.string().optional()}).optional()},async e=>{if(e.request?.method!=="POST"||e.context.options.advanced?.disableCSRFCheck)return;let r=e.headers?.get("origin")||"";if(r){let a=new URL(r).origin;if(e.context.trustedOrigins.includes(a))return}let t=e.body?.csrfToken;if(!t)throw new J("UNAUTHORIZED",{message:"CSRF Token is required"});let o=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret),[n,i]=o?.split("!")||[null,null];if(!t||!n||!i||n!==t)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new J("UNAUTHORIZED",{message:"Invalid CSRF Token"});let s=await F(e.context.secret,n);if(i!==s)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new J("UNAUTHORIZED",{message:"Invalid CSRF Token"})});import{APIError as P}from"better-call";import{generateCodeVerifier as Bt}from"oslo/oauth2";import{z as v}from"zod";import{generateState as pt}from"oslo/oauth2";import{z as H}from"zod";import{sha256 as le}from"oslo/crypto";async function ue(e){let r=await le(typeof e=="string"?new TextEncoder().encode(e):e);return Buffer.from(r).toString("base64")}async function pe(e,r){let t=await le(typeof e=="string"?new TextEncoder().encode(e):e),o=Buffer.from(r,"base64");return W(t,o)}import"better-call";async function me(e){let r=pt(),t=JSON.stringify({code:r,callbackURL:e}),o=await ue(t);return{raw:t,hash:o}}function K(e){return H.object({code:H.string(),callbackURL:H.string().optional(),currentURL:H.string().optional()}).safeParse(JSON.parse(e))}import{TimeSpan as qr}from"oslo";var $=class extends Error{constructor(r,t){super(r),this.name="BetterAuthError",this.message=r,this.cause=t}};import{env as Fr,isProduction as Hr}from"std-env";async function S(e,r,t,o){let n=e.context.authCookies.sessionToken.options;n.maxAge=t?void 0:e.context.sessionConfig.expiresIn,await e.setSignedCookie(e.context.authCookies.sessionToken.name,r,e.context.secret,{...n,...o}),t&&await e.setSignedCookie(e.context.authCookies.dontRememberToken.name,"true",e.context.secret,e.context.authCookies.dontRememberToken.options)}function N(e){e.setCookie(e.context.authCookies.sessionToken.name,"",{maxAge:0}),e.setCookie(e.context.authCookies.dontRememberToken.name,"",{maxAge:0})}import{APIError as gt}from"better-call";import{createConsola as mt}from"consola";var D=mt({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),ft=e=>({log:(...r)=>{!e?.disabled&&D.log("",...r)},error:(...r)=>{!e?.disabled&&D.error("",...r)},warn:(...r)=>{!e?.disabled&&D.warn("",...r)},info:(...r)=>{!e?.disabled&&D.info("",...r)},debug:(...r)=>{!e?.disabled&&D.debug("",...r)},box:(...r)=>{!e?.disabled&&D.box("",...r)},success:(...r)=>{!e?.disabled&&D.success("",...r)},break:(...r)=>{!e?.disabled&&console.log(`
2
- `)}}),w=ft();var E=z(async e=>{let{body:r,query:t,headers:o,context:n}=e,i=r?.callbackURL||t?.callbackURL||t?.redirectTo||r?.redirectTo,s=t?.currentURL||o?.get("referer")||n.baseURL,a=n.trustedOrigins,c=(d,l)=>{if(d?.startsWith("http")&&!a.some(g=>d.startsWith(g)))throw w.error(`Invalid ${l}`,{[l]:d,trustedOrigins:a}),new gt("FORBIDDEN",{message:`Invalid ${l}`})};c(i,"callbackURL"),c(s,"currentURL")});import{parseJWT as bt}from"oslo/jwt";import{sha256 as ht}from"oslo/crypto";import{base64url as wt}from"oslo/encoding";async function fe(e){let r=await ht(new TextEncoder().encode(e));return wt.encode(new Uint8Array(r),{includePadding:!1})}function ge(e){return{tokenType:e.token_type,accessToken:e.access_token,refreshToken:e.refresh_token,accessTokenExpiresAt:e.expires_at?new Date((Date.now()+e.expires_in)*1e3):void 0,scopes:e?.scope?typeof e.scope=="string"?e.scope.split(" "):e.scope:[],idToken:e.id_token}}async function b({id:e,options:r,authorizationEndpoint:t,state:o,codeVerifier:n,scopes:i,claims:s,disablePkce:a,redirectURI:c}){let d=new URL(t);if(d.searchParams.set("response_type","code"),d.searchParams.set("client_id",r.clientId),d.searchParams.set("state",o),d.searchParams.set("scope",i.join(" ")),d.searchParams.set("redirect_uri",r.redirectURI||c),!a&&n){let l=await fe(n);d.searchParams.set("code_challenge_method","S256"),d.searchParams.set("code_challenge",l)}if(s){let l=s.reduce((h,g)=>(h[g]=null,h),{});d.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...l}}))}return d}import{betterFetch as yt}from"@better-fetch/fetch";async function y({code:e,codeVerifier:r,redirectURI:t,options:o,tokenEndpoint:n}){let i=new URLSearchParams;i.set("grant_type","authorization_code"),i.set("code",e),r&&i.set("code_verifier",r),i.set("redirect_uri",t),i.set("client_id",o.clientId),i.set("client_secret",o.clientSecret);let{data:s,error:a}=await yt(n,{method:"POST",body:i,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(a)throw a;return ge(s)}function Y(e){let r=e.accessToken,t=e.refreshToken,o;try{o=e.accessTokenExpiresAt}catch{}return{accessToken:r,refreshToken:t,expiresAt:o}}var he=e=>{let r="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:t,scopes:o,redirectURI:n}){let i=e.scope||o||["email","name","openid"];return new URL(`https://appleid.apple.com/auth/authorize?client_id=${e.clientId}&response_type=code&redirect_uri=${n||e.redirectURI}&scope=${i.join(" ")}&state=${t}`)},validateAuthorizationCode:async({code:t,codeVerifier:o,redirectURI:n})=>y({code:t,codeVerifier:o,redirectURI:e.redirectURI||n,options:e,tokenEndpoint:r}),async getUserInfo(t){if(!t.idToken)return null;let o=bt(t.idToken)?.payload;return o?{user:{id:o.sub,name:o.name,email:o.email,emailVerified:o.email_verified==="true"},data:o}:null}}};import{betterFetch as At}from"@better-fetch/fetch";var we=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:r,scopes:t,redirectURI:o}){let n=e.scope||t||["identify","email"];return new URL(`https://discord.com/api/oauth2/authorize?scope=${n.join("+")}&response_type=code&client_id=${e.clientId}&redirect_uri=${encodeURIComponent(e.redirectURI||o)}&state=${r}`)},validateAuthorizationCode:async({code:r,redirectURI:t})=>y({code:r,redirectURI:e.redirectURI||t,options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(r){let{data:t,error:o}=await At("https://discord.com/api/users/@me",{headers:{authorization:`Bearer ${r.accessToken}`}});if(o)return null;if(t.avatar===null){let n=t.discriminator==="0"?Number(BigInt(t.id)>>BigInt(22))%6:parseInt(t.discriminator)%5;t.image_url=`https://cdn.discordapp.com/embed/avatars/${n}.png`}else{let n=t.avatar.startsWith("a_")?"gif":"png";t.image_url=`https://cdn.discordapp.com/avatars/${t.id}/${t.avatar}.${n}`}return{user:{id:t.id,name:t.display_name||t.username||"",email:t.email,emailVerified:t.verified,image:t.image_url},data:t}}});import{betterFetch as kt}from"@better-fetch/fetch";var ye=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:r,scopes:t,redirectURI:o}){let n=e.scope||t||["email","public_profile"];return await b({id:"facebook",options:e,authorizationEndpoint:"https://www.facebook.com/v21.0/dialog/oauth",scopes:n,state:r,redirectURI:o})},validateAuthorizationCode:async({code:r,redirectURI:t})=>y({code:r,redirectURI:e.redirectURI||t,options:e,tokenEndpoint:"https://graph.facebook.com/oauth/access_token"}),async getUserInfo(r){let{data:t,error:o}=await kt("https://graph.facebook.com/me?fields=id,name,email,picture",{auth:{type:"Bearer",token:r.accessToken}});return o?null:{user:{id:t.id,name:t.name,email:t.email,image:t.picture.data.url,emailVerified:t.email_verified},data:t}}});import{betterFetch as be}from"@better-fetch/fetch";var Ae=e=>{let r="https://github.com/login/oauth/access_token";return{id:"github",name:"Github",createAuthorizationURL({state:t,scopes:o,codeVerifier:n,redirectURI:i}){let s=e.scope||o||["user:email"];return b({id:"github",options:e,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:s,state:t,redirectURI:i,codeVerifier:n})},validateAuthorizationCode:async({code:t,redirectURI:o})=>y({code:t,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:r}),async getUserInfo(t){let{data:o,error:n}=await be("https://api.github.com/user",{headers:{"User-Agent":"better-auth",authorization:`Bearer ${t.accessToken}`}});if(n)return null;let i=!1;if(!o.email){let{data:s,error:a}=await be("https://api.github.com/user/emails",{headers:{authorization:`Bearer ${t.accessToken}`,"User-Agent":"better-auth"}});a||(o.email=(s.find(c=>c.primary)??s[0])?.email,i=s.find(c=>c.email===o.email)?.verified??!1)}return{user:{id:o.id.toString(),name:o.name||o.login,email:o.email,image:o.avatar_url,emailVerified:i},data:o}}}};import{parseJWT as Rt}from"oslo/jwt";var ke=e=>({id:"google",name:"Google",createAuthorizationURL({state:r,scopes:t,codeVerifier:o,redirectURI:n}){if(!e.clientId||!e.clientSecret)throw w.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new $("CLIENT_ID_AND_SECRET_REQUIRED");if(!o)throw new $("codeVerifier is required for Google");let i=e.scope||t||["email","profile"];return b({id:"google",options:e,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:i,state:r,codeVerifier:o,redirectURI:n})},validateAuthorizationCode:async({code:r,codeVerifier:t,redirectURI:o})=>y({code:r,codeVerifier:t,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://oauth2.googleapis.com/token"}),async getUserInfo(r){if(!r.idToken)return null;let t=Rt(r.idToken)?.payload;return{user:{id:t.sub,name:t.name,email:t.email,image:t.picture,emailVerified:t.email_verified},data:t}}});import{betterFetch as Ut}from"@better-fetch/fetch";import{parseJWT as Et}from"oslo/jwt";var Re=e=>{let r=e.tenantId||"common",t=`https://login.microsoftonline.com/${r}/oauth2/v2.0/authorize`,o=`https://login.microsoftonline.com/${r}/oauth2/v2.0/token`;return{id:"microsoft",name:"Microsoft EntraID",createAuthorizationURL(n){let i=e.scope||n.scopes||["openid","profile","email","User.Read"];return b({id:"microsoft",options:e,authorizationEndpoint:t,state:n.state,codeVerifier:n.codeVerifier,scopes:i,redirectURI:n.redirectURI})},validateAuthorizationCode({code:n,codeVerifier:i,redirectURI:s}){return y({code:n,codeVerifier:i,redirectURI:e.redirectURI||s,options:e,tokenEndpoint:o})},async getUserInfo(n){if(!n.idToken)return null;let i=Et(n.idToken)?.payload,s=e.profilePhotoSize||48;return await Ut(`https://graph.microsoft.com/v1.0/me/photos/${s}x${s}/$value`,{headers:{Authorization:`Bearer ${n.accessToken}`},async onResponse(a){if(!(e.disableProfilePhoto||!a.response.ok))try{let d=await a.response.clone().arrayBuffer(),l=Buffer.from(d).toString("base64");i.picture=`data:image/jpeg;base64, ${l}`}catch(c){w.error(c)}}}),{user:{id:i.sub,name:i.name,email:i.email,image:i.picture,emailVerified:!0},data:i}}}};import{betterFetch as xt}from"@better-fetch/fetch";var Ue=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:r,scopes:t,codeVerifier:o,redirectURI:n}){let i=e.scope||t||["user-read-email"];return b({id:"spotify",options:e,authorizationEndpoint:"https://accounts.spotify.com/authorize",scopes:i,state:r,codeVerifier:o,redirectURI:n})},validateAuthorizationCode:async({code:r,codeVerifier:t,redirectURI:o})=>y({code:r,codeVerifier:t,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://accounts.spotify.com/api/token"}),async getUserInfo(r){let{data:t,error:o}=await xt("https://api.spotify.com/v1/me",{method:"GET",headers:{Authorization:`Bearer ${r.accessToken}`}});return o?null:{user:{id:t.id,name:t.display_name,email:t.email,image:t.images[0]?.url,emailVerified:!1},data:t}}});import"@better-fetch/fetch";var C={isAction:!1};import{nanoid as vt}from"nanoid";var Ee=e=>vt(e);import{parseJWT as Tt}from"oslo/jwt";var xe=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:r,scopes:t,redirectURI:o}){let n=e.scope||t||["user:read:email","openid"];return b({id:"twitch",redirectURI:o,options:e,authorizationEndpoint:"https://id.twitch.tv/oauth2/authorize",scopes:n,state:r,claims:e.claims||["email","email_verified","preferred_username","picture"]})},validateAuthorizationCode:async({code:r,redirectURI:t})=>y({code:r,redirectURI:e.redirectURI||t,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(r){let t=r.idToken;if(!t)return w.error("No idToken found in token"),null;let o=Tt(t)?.payload;return{user:{id:o.sub,name:o.preferred_username,email:o.email,image:o.picture,emailVerified:!1},data:o}}});import{betterFetch as Pt}from"@better-fetch/fetch";var ve=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(r){let t=e.scope||r.scopes||["account_info.read"];return b({id:"twitter",options:e,authorizationEndpoint:"https://twitter.com/i/oauth2/authorize",scopes:t,state:r.state,codeVerifier:r.codeVerifier,redirectURI:r.redirectURI})},validateAuthorizationCode:async({code:r,codeVerifier:t,redirectURI:o})=>y({code:r,codeVerifier:t,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(r){let{data:t,error:o}=await Pt("https://api.x.com/2/users/me?user.fields=profile_image_url",{method:"GET",headers:{Authorization:`Bearer ${r.accessToken}`}});return o||!t.data.email?null:{user:{id:t.data.id,name:t.data.name,email:t.data.email,image:t.data.profile_image_url,emailVerified:t.data.verified||!1},data:t}}});import{betterFetch as _t}from"@better-fetch/fetch";var Te=e=>{let r="https://api.dropboxapi.com/oauth2/token";return{id:"dropbox",name:"Dropbox",createAuthorizationURL:async({state:t,scopes:o,codeVerifier:n,redirectURI:i})=>{let s=e.scope||o||["account_info.read"];return await b({id:"dropbox",options:e,authorizationEndpoint:"https://www.dropbox.com/oauth2/authorize",scopes:s,state:t,redirectURI:i,codeVerifier:n})},validateAuthorizationCode:async({code:t,codeVerifier:o,redirectURI:n})=>await y({code:t,codeVerifier:o,redirectURI:e.redirectURI||n,options:e,tokenEndpoint:r}),async getUserInfo(t){let{data:o,error:n}=await _t("https://api.dropboxapi.com/2/users/get_current_account",{method:"POST",headers:{Authorization:`Bearer ${t.accessToken}`}});return n?null:{user:{id:o.account_id,name:o.name?.display_name,email:o.email,emailVerified:o.email_verified||!1,image:o.profile_photo_url},data:o}}}};import{betterFetch as St}from"@better-fetch/fetch";var Pe=e=>{let r="https://www.linkedin.com/oauth/v2/authorization",t="https://www.linkedin.com/oauth/v2/accessToken";return{id:"linkedin",name:"Linkedin",createAuthorizationURL:async({state:o,scopes:n,redirectURI:i})=>{let s=e.scope||n||["profile","email","openid"];return await b({id:"linkedin",options:e,authorizationEndpoint:r,scopes:s,state:o,redirectURI:i})},validateAuthorizationCode:async({code:o,redirectURI:n})=>await y({code:o,redirectURI:e.redirectURI||n,options:e,tokenEndpoint:t}),async getUserInfo(o){let{data:n,error:i}=await St("https://api.linkedin.com/v2/userinfo",{method:"GET",headers:{Authorization:`Bearer ${o.accessToken}`}});return i?null:{user:{id:n.sub,name:n.name,email:n.email,emailVerified:n.email_verified||!1,image:n.picture},data:n}}}};var Ot={apple:he,discord:we,facebook:ye,github:Ae,microsoft:Re,google:ke,spotify:Ue,twitch:xe,twitter:ve,dropbox:Te,linkedin:Pe},_e=Object.keys(Ot);import{TimeSpan as Lt}from"oslo";import{createJWT as It,validateJWT as Ct}from"oslo/jwt";import{z as T}from"zod";import{APIError as V}from"better-call";import{APIError as M}from"better-call";var Z=(e,r="ms")=>new Date(Date.now()+(r==="sec"?e*1e3:e));import{z as Se}from"zod";var X=()=>m("/session",{method:"GET",requireHeaders:!0},async e=>{try{let r=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!r)return e.json(null,{status:401});let t=await e.context.internalAdapter.findSession(r);if(!t||t.session.expiresAt<new Date)return N(e),t&&await e.context.internalAdapter.deleteSession(t.session.id),e.json(null,{status:401});if(await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret))return e.json(t);let n=e.context.sessionConfig.expiresIn,i=e.context.sessionConfig.updateAge;if(t.session.expiresAt.valueOf()-n*1e3+i*1e3<=Date.now()){let c=await e.context.internalAdapter.updateSession(t.session.id,{expiresAt:Z(e.context.sessionConfig.expiresIn,"sec")});if(!c)return N(e),e.json(null,{status:401});let d=(c.expiresAt.valueOf()-Date.now())/1e3;return await S(e,c.id,!1,{maxAge:d}),e.json({session:c,user:t.user})}return e.json(t)}catch(r){return e.context.logger.error(r),e.json(null,{status:500})}}),ee=async e=>await X()({...e,_flag:"json",headers:e.headers}),O=z(async e=>{let r=await ee(e);if(!r?.session)throw new M("UNAUTHORIZED");return{session:r}}),Oe=()=>m("/user/list-sessions",{method:"GET",use:[O],requireHeaders:!0},async e=>{let t=(await e.context.internalAdapter.listSessions(e.context.session.user.id)).filter(o=>o.expiresAt>new Date);return e.json(t)}),Le=m("/user/revoke-session",{method:"POST",body:Se.object({id:Se.string()}),use:[O],requireHeaders:!0},async e=>{let r=e.body.id,t=await e.context.internalAdapter.findSession(r);if(!t)throw new M("BAD_REQUEST",{message:"Session not found"});if(t.session.userId!==e.context.session.user.id)throw new M("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(r)}catch(o){throw e.context.logger.error(o),new M("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),Ie=m("/user/revoke-sessions",{method:"POST",use:[O],requireHeaders:!0},async e=>{try{await e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(r){throw e.context.logger.error(r),new M("INTERNAL_SERVER_ERROR")}return e.json({status:!0})});async function L(e,r,t){return await It("HS256",Buffer.from(e),{email:r.toLowerCase(),updateTo:t},{expiresIn:new Lt(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[r],includeIssuedTimestamp:!0})}var Ce=m("/send-verification-email",{method:"POST",query:T.object({currentURL:T.string().optional()}).optional(),body:T.object({email:T.string().email(),callbackURL:T.string().optional()}),use:[E]},async e=>{if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new V("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:r}=e.body,t=await e.context.internalAdapter.findUserByEmail(r);if(!t)throw new V("BAD_REQUEST",{message:"User not found"});let o=await L(e.context.secret,r),n=`${e.context.baseURL}/verify-email?token=${o}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.emailVerification.sendVerificationEmail(t.user,n,o),e.json({status:!0})}),Be=m("/verify-email",{method:"GET",query:T.object({token:T.string(),callbackURL:T.string().optional()}),use:[E]},async e=>{let{token:r}=e.query,t;try{t=await Ct("HS256",Buffer.from(e.context.secret),r)}catch(s){throw e.context.logger.error("Failed to verify email",s),new V("BAD_REQUEST",{message:"Invalid token"})}let n=T.object({email:T.string().email(),updateTo:T.string().optional()}).parse(t.payload);if(!await e.context.internalAdapter.findUserByEmail(n.email))throw new V("BAD_REQUEST",{message:"User not found"});if(n.updateTo){let s=await ee(e);if(!s)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new V("UNAUTHORIZED",{message:"Session not found"});if(s.user.email!==n.email)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new V("UNAUTHORIZED",{message:"Invalid session"});let a=await e.context.internalAdapter.updateUserByEmail(n.email,{email:n.updateTo});if(await e.context.options.emailVerification?.sendVerificationEmail?.(a,`${e.context.baseURL}/verify-email?token=${r}`,r),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.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:null,status:!0})});var De=m("/sign-in/social",{method:"POST",requireHeaders:!0,query:v.object({currentURL:v.string().optional()}).optional(),body:v.object({callbackURL:v.string().optional(),provider:v.enum(_e)}),use:[E]},async e=>{let r=e.context.socialProviders.find(c=>c.id===e.body.provider);if(!r)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new P("NOT_FOUND",{message:"Provider not found"});let t=e.context.authCookies,o=e.query?.currentURL?new URL(e.query?.currentURL):null,n=e.body.callbackURL?.startsWith("http")?e.body.callbackURL:`${o?.origin}${e.body.callbackURL||""}`,i=await me(n||o?.origin||e.context.options.baseURL);await e.setSignedCookie(t.state.name,i.hash,e.context.secret,t.state.options);let s=Bt();await e.setSignedCookie(t.pkCodeVerifier.name,s,e.context.secret,t.pkCodeVerifier.options);let a=await r.createAuthorizationURL({state:i.raw,codeVerifier:s,redirectURI:`${e.context.baseURL}/callback/${r.id}`});return e.json({url:a.toString(),state:i,codeVerifier:s,redirect:!0})}),ze=m("/sign-in/email",{method:"POST",body:v.object({email:v.string(),password:v.string(),callbackURL:v.string().optional(),dontRememberMe:v.boolean().default(!1).optional()}),use:[E]},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 P("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:r,password:t}=e.body;if(!v.string().email().safeParse(r).success)throw new P("BAD_REQUEST",{message:"Invalid email"});if(!v.string().email().safeParse(r).success)throw new P("BAD_REQUEST",{message:"Invalid email"});let i=await e.context.internalAdapter.findUserByEmail(r,{includeAccounts:!0});if(!i)throw await e.context.password.hash(t),e.context.logger.error("User not found",{email:r}),new P("UNAUTHORIZED",{message:"Invalid email or password"});let s=i.accounts.find(l=>l.providerId==="credential");if(!s)throw e.context.logger.error("Credential account not found",{email:r}),new P("UNAUTHORIZED",{message:"Invalid email or password"});let a=s?.password;if(!a)throw e.context.logger.error("Password not found",{email:r}),new P("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(a,t))throw e.context.logger.error("Invalid password"),new P("UNAUTHORIZED",{message:"Invalid email or password"});if(e.context.options?.emailAndPassword?.requireEmailVerification&&!i.user.emailVerified){if(!e.context.options?.emailVerification?.sendVerificationEmail)throw w.error("Email verification is required but no email verification handler is provided"),new P("INTERNAL_SERVER_ERROR",{message:"Email is not verified."});let l=await L(e.context.secret,i.user.email),h=`${e.context.options.baseURL}/verify-email?token=${l}`;throw await e.context.options.emailVerification.sendVerificationEmail(i.user,h,l),e.context.logger.error("Email not verified",{email:r}),new P("FORBIDDEN",{message:"Email is not verified. Check your email for a verification link"})}let d=await e.context.internalAdapter.createSession(i.user.id,e.headers,e.body.dontRememberMe);if(!d)throw e.context.logger.error("Failed to create session"),new P("UNAUTHORIZED",{message:"Failed to create session"});return await S(e,d.id,e.body.dontRememberMe),e.json({user:i.user,session:d,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});import{z as Q}from"zod";import{z as f}from"zod";var li=f.object({id:f.string(),providerId:f.string(),accountId:f.string(),userId:f.string(),accessToken:f.string().nullable().optional(),refreshToken:f.string().nullable().optional(),idToken:f.string().nullable().optional(),expiresAt:f.date().nullable().optional(),password:f.string().optional().nullable()}),$e=f.object({id:f.string(),email:f.string().transform(e=>e.toLowerCase()),emailVerified:f.boolean().default(!1),name:f.string(),image:f.string().optional(),createdAt:f.date().default(new Date),updatedAt:f.date().default(new Date)}),ui=f.object({id:f.string(),userId:f.string(),expiresAt:f.date(),ipAddress:f.string().optional(),userAgent:f.string().optional()}),pi=f.object({id:f.string(),value:f.string(),expiresAt:f.date(),identifier:f.string()});function Ve(e,r){let t={...r==="user"?e.user?.additionalFields:{},...r==="session"?e.session?.additionalFields:{}};for(let o of e.plugins||[])o.schema&&o.schema[r]&&(t={...t,...o.schema[r].fields});return t}function je(e,r){let t=r.fields,o={};for(let n in t){if(n in e){if(t[n].input===!1){if(t[n].defaultValue){o[n]=t[n].defaultValue;continue}continue}o[n]=e[n];continue}if(t[n].defaultValue){o[n]=t[n].defaultValue;continue}}return o}function qe(e,r){let t=Ve(e,"user");return je(r||{},{fields:t})}function Ne(e,r){let t=Ve(e,"user");return je(r||{},{fields:t})}var Me=m("/callback/:id",{method:"GET",query:Q.object({state:Q.string(),code:Q.string().optional(),error:Q.string().optional()}),metadata:C},async e=>{if(e.query.error||!e.query.code){let R=K(e.query.state).data?.callbackURL||`${e.context.baseURL}/error`;throw e.context.logger.error(e.query.error,e.params.id),e.redirect(`${R}?error=${e.query.error||"oAuth_code_missing"}`)}let r=e.context.socialProviders.find(p=>p.id===e.params.id);if(!r)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 t=K(e.query.state);if(!t.success)throw e.context.logger.error("Unable to parse state"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let{data:{callbackURL:o,currentURL:n}}=t,i=await e.getSignedCookie(e.context.authCookies.state.name,e.context.secret);if(!i)throw w.error("No stored state found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!await pe(e.query.state,i))throw w.error("OAuth state mismatch"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let a=await e.getSignedCookie(e.context.authCookies.pkCodeVerifier.name,e.context.secret),c;try{c=await r.validateAuthorizationCode({code:e.query.code,codeVerifier:a,redirectURI:`${e.context.baseURL}/callback/${r.id}`})}catch(p){throw e.context.logger.error(p),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let d=await r.getUserInfo(c).then(p=>p?.user),l=Ee(),h=$e.safeParse({...d,id:l});if(!d||h.success===!1)throw w.error("Unable to get user info",h.error),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!o)throw e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);function g(p){throw e.redirect(`${n||o||`${e.context.baseURL}/error`}?error=${p}`)}let u=await e.context.internalAdapter.findUserByEmail(d.email,{includeAccounts:!0}).catch(p=>{throw w.error(`Better auth was unable to query your database.
2
+ `)}}),w=ft();var E=z(async e=>{let{body:r,query:t,headers:o,context:n}=e,i=r?.callbackURL||t?.callbackURL||t?.redirectTo||r?.redirectTo,s=t?.currentURL||o?.get("referer")||n.baseURL,a=n.trustedOrigins,c=(d,l)=>{if(d?.startsWith("http")&&!a.some(g=>d.startsWith(g)))throw w.error(`Invalid ${l}`,{[l]:d,trustedOrigins:a}),new gt("FORBIDDEN",{message:`Invalid ${l}`})};c(i,"callbackURL"),c(s,"currentURL")});import{parseJWT as bt}from"oslo/jwt";import{sha256 as ht}from"oslo/crypto";import{base64url as wt}from"oslo/encoding";async function fe(e){let r=await ht(new TextEncoder().encode(e));return wt.encode(new Uint8Array(r),{includePadding:!1})}function ge(e){return{tokenType:e.token_type,accessToken:e.access_token,refreshToken:e.refresh_token,accessTokenExpiresAt:e.expires_at?new Date((Date.now()+e.expires_in)*1e3):void 0,scopes:e?.scope?typeof e.scope=="string"?e.scope.split(" "):e.scope:[],idToken:e.id_token}}async function b({id:e,options:r,authorizationEndpoint:t,state:o,codeVerifier:n,scopes:i,claims:s,disablePkce:a,redirectURI:c}){let d=new URL(t);if(d.searchParams.set("response_type","code"),d.searchParams.set("client_id",r.clientId),d.searchParams.set("state",o),d.searchParams.set("scope",i.join(" ")),d.searchParams.set("redirect_uri",r.redirectURI||c),!a&&n){let l=await fe(n);d.searchParams.set("code_challenge_method","S256"),d.searchParams.set("code_challenge",l)}if(s){let l=s.reduce((h,g)=>(h[g]=null,h),{});d.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...l}}))}return d}import{betterFetch as yt}from"@better-fetch/fetch";async function y({code:e,codeVerifier:r,redirectURI:t,options:o,tokenEndpoint:n}){let i=new URLSearchParams;i.set("grant_type","authorization_code"),i.set("code",e),r&&i.set("code_verifier",r),i.set("redirect_uri",t),i.set("client_id",o.clientId),i.set("client_secret",o.clientSecret);let{data:s,error:a}=await yt(n,{method:"POST",body:i,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(a)throw a;return ge(s)}function Y(e){let r=e.accessToken,t=e.refreshToken,o;try{o=e.accessTokenExpiresAt}catch{}return{accessToken:r,refreshToken:t,expiresAt:o}}var he=e=>{let r="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:t,scopes:o,redirectURI:n}){let i=e.scope||o||["email","name","openid"];return new URL(`https://appleid.apple.com/auth/authorize?client_id=${e.clientId}&response_type=code&redirect_uri=${n||e.redirectURI}&scope=${i.join(" ")}&state=${t}`)},validateAuthorizationCode:async({code:t,codeVerifier:o,redirectURI:n})=>y({code:t,codeVerifier:o,redirectURI:e.redirectURI||n,options:e,tokenEndpoint:r}),async getUserInfo(t){if(!t.idToken)return null;let o=bt(t.idToken)?.payload;return o?{user:{id:o.sub,name:o.name,email:o.email,emailVerified:o.email_verified==="true"},data:o}:null}}};import{betterFetch as At}from"@better-fetch/fetch";var we=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:r,scopes:t,redirectURI:o}){let n=e.scope||t||["identify","email"];return new URL(`https://discord.com/api/oauth2/authorize?scope=${n.join("+")}&response_type=code&client_id=${e.clientId}&redirect_uri=${encodeURIComponent(e.redirectURI||o)}&state=${r}`)},validateAuthorizationCode:async({code:r,redirectURI:t})=>y({code:r,redirectURI:e.redirectURI||t,options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(r){let{data:t,error:o}=await At("https://discord.com/api/users/@me",{headers:{authorization:`Bearer ${r.accessToken}`}});if(o)return null;if(t.avatar===null){let n=t.discriminator==="0"?Number(BigInt(t.id)>>BigInt(22))%6:parseInt(t.discriminator)%5;t.image_url=`https://cdn.discordapp.com/embed/avatars/${n}.png`}else{let n=t.avatar.startsWith("a_")?"gif":"png";t.image_url=`https://cdn.discordapp.com/avatars/${t.id}/${t.avatar}.${n}`}return{user:{id:t.id,name:t.display_name||t.username||"",email:t.email,emailVerified:t.verified,image:t.image_url},data:t}}});import{betterFetch as kt}from"@better-fetch/fetch";var ye=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:r,scopes:t,redirectURI:o}){let n=e.scope||t||["email","public_profile"];return await b({id:"facebook",options:e,authorizationEndpoint:"https://www.facebook.com/v21.0/dialog/oauth",scopes:n,state:r,redirectURI:o})},validateAuthorizationCode:async({code:r,redirectURI:t})=>y({code:r,redirectURI:e.redirectURI||t,options:e,tokenEndpoint:"https://graph.facebook.com/oauth/access_token"}),async getUserInfo(r){let{data:t,error:o}=await kt("https://graph.facebook.com/me?fields=id,name,email,picture",{auth:{type:"Bearer",token:r.accessToken}});return o?null:{user:{id:t.id,name:t.name,email:t.email,image:t.picture.data.url,emailVerified:t.email_verified},data:t}}});import{betterFetch as be}from"@better-fetch/fetch";var Ae=e=>{let r="https://github.com/login/oauth/access_token";return{id:"github",name:"GitHub",createAuthorizationURL({state:t,scopes:o,codeVerifier:n,redirectURI:i}){let s=e.scope||o||["user:email"];return b({id:"github",options:e,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:s,state:t,redirectURI:i,codeVerifier:n})},validateAuthorizationCode:async({code:t,redirectURI:o})=>y({code:t,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:r}),async getUserInfo(t){let{data:o,error:n}=await be("https://api.github.com/user",{headers:{"User-Agent":"better-auth",authorization:`Bearer ${t.accessToken}`}});if(n)return null;let i=!1;if(!o.email){let{data:s,error:a}=await be("https://api.github.com/user/emails",{headers:{authorization:`Bearer ${t.accessToken}`,"User-Agent":"better-auth"}});a||(o.email=(s.find(c=>c.primary)??s[0])?.email,i=s.find(c=>c.email===o.email)?.verified??!1)}return{user:{id:o.id.toString(),name:o.name||o.login,email:o.email,image:o.avatar_url,emailVerified:i},data:o}}}};import{parseJWT as Rt}from"oslo/jwt";var ke=e=>({id:"google",name:"Google",createAuthorizationURL({state:r,scopes:t,codeVerifier:o,redirectURI:n}){if(!e.clientId||!e.clientSecret)throw w.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new $("CLIENT_ID_AND_SECRET_REQUIRED");if(!o)throw new $("codeVerifier is required for Google");let i=e.scope||t||["email","profile"];return b({id:"google",options:e,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:i,state:r,codeVerifier:o,redirectURI:n})},validateAuthorizationCode:async({code:r,codeVerifier:t,redirectURI:o})=>y({code:r,codeVerifier:t,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://oauth2.googleapis.com/token"}),async getUserInfo(r){if(!r.idToken)return null;let t=Rt(r.idToken)?.payload;return{user:{id:t.sub,name:t.name,email:t.email,image:t.picture,emailVerified:t.email_verified},data:t}}});import{betterFetch as Ut}from"@better-fetch/fetch";import{parseJWT as Et}from"oslo/jwt";var Re=e=>{let r=e.tenantId||"common",t=`https://login.microsoftonline.com/${r}/oauth2/v2.0/authorize`,o=`https://login.microsoftonline.com/${r}/oauth2/v2.0/token`;return{id:"microsoft",name:"Microsoft EntraID",createAuthorizationURL(n){let i=e.scope||n.scopes||["openid","profile","email","User.Read"];return b({id:"microsoft",options:e,authorizationEndpoint:t,state:n.state,codeVerifier:n.codeVerifier,scopes:i,redirectURI:n.redirectURI})},validateAuthorizationCode({code:n,codeVerifier:i,redirectURI:s}){return y({code:n,codeVerifier:i,redirectURI:e.redirectURI||s,options:e,tokenEndpoint:o})},async getUserInfo(n){if(!n.idToken)return null;let i=Et(n.idToken)?.payload,s=e.profilePhotoSize||48;return await Ut(`https://graph.microsoft.com/v1.0/me/photos/${s}x${s}/$value`,{headers:{Authorization:`Bearer ${n.accessToken}`},async onResponse(a){if(!(e.disableProfilePhoto||!a.response.ok))try{let d=await a.response.clone().arrayBuffer(),l=Buffer.from(d).toString("base64");i.picture=`data:image/jpeg;base64, ${l}`}catch(c){w.error(c)}}}),{user:{id:i.sub,name:i.name,email:i.email,image:i.picture,emailVerified:!0},data:i}}}};import{betterFetch as xt}from"@better-fetch/fetch";var Ue=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:r,scopes:t,codeVerifier:o,redirectURI:n}){let i=e.scope||t||["user-read-email"];return b({id:"spotify",options:e,authorizationEndpoint:"https://accounts.spotify.com/authorize",scopes:i,state:r,codeVerifier:o,redirectURI:n})},validateAuthorizationCode:async({code:r,codeVerifier:t,redirectURI:o})=>y({code:r,codeVerifier:t,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://accounts.spotify.com/api/token"}),async getUserInfo(r){let{data:t,error:o}=await xt("https://api.spotify.com/v1/me",{method:"GET",headers:{Authorization:`Bearer ${r.accessToken}`}});return o?null:{user:{id:t.id,name:t.display_name,email:t.email,image:t.images[0]?.url,emailVerified:!1},data:t}}});import"@better-fetch/fetch";var C={isAction:!1};import{nanoid as vt}from"nanoid";var Ee=e=>vt(e);import{parseJWT as Tt}from"oslo/jwt";var xe=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:r,scopes:t,redirectURI:o}){let n=e.scope||t||["user:read:email","openid"];return b({id:"twitch",redirectURI:o,options:e,authorizationEndpoint:"https://id.twitch.tv/oauth2/authorize",scopes:n,state:r,claims:e.claims||["email","email_verified","preferred_username","picture"]})},validateAuthorizationCode:async({code:r,redirectURI:t})=>y({code:r,redirectURI:e.redirectURI||t,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(r){let t=r.idToken;if(!t)return w.error("No idToken found in token"),null;let o=Tt(t)?.payload;return{user:{id:o.sub,name:o.preferred_username,email:o.email,image:o.picture,emailVerified:!1},data:o}}});import{betterFetch as Pt}from"@better-fetch/fetch";var ve=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(r){let t=e.scope||r.scopes||["account_info.read"];return b({id:"twitter",options:e,authorizationEndpoint:"https://twitter.com/i/oauth2/authorize",scopes:t,state:r.state,codeVerifier:r.codeVerifier,redirectURI:r.redirectURI})},validateAuthorizationCode:async({code:r,codeVerifier:t,redirectURI:o})=>y({code:r,codeVerifier:t,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(r){let{data:t,error:o}=await Pt("https://api.x.com/2/users/me?user.fields=profile_image_url",{method:"GET",headers:{Authorization:`Bearer ${r.accessToken}`}});return o||!t.data.email?null:{user:{id:t.data.id,name:t.data.name,email:t.data.email,image:t.data.profile_image_url,emailVerified:t.data.verified||!1},data:t}}});import{betterFetch as _t}from"@better-fetch/fetch";var Te=e=>{let r="https://api.dropboxapi.com/oauth2/token";return{id:"dropbox",name:"Dropbox",createAuthorizationURL:async({state:t,scopes:o,codeVerifier:n,redirectURI:i})=>{let s=e.scope||o||["account_info.read"];return await b({id:"dropbox",options:e,authorizationEndpoint:"https://www.dropbox.com/oauth2/authorize",scopes:s,state:t,redirectURI:i,codeVerifier:n})},validateAuthorizationCode:async({code:t,codeVerifier:o,redirectURI:n})=>await y({code:t,codeVerifier:o,redirectURI:e.redirectURI||n,options:e,tokenEndpoint:r}),async getUserInfo(t){let{data:o,error:n}=await _t("https://api.dropboxapi.com/2/users/get_current_account",{method:"POST",headers:{Authorization:`Bearer ${t.accessToken}`}});return n?null:{user:{id:o.account_id,name:o.name?.display_name,email:o.email,emailVerified:o.email_verified||!1,image:o.profile_photo_url},data:o}}}};import{betterFetch as St}from"@better-fetch/fetch";var Pe=e=>{let r="https://www.linkedin.com/oauth/v2/authorization",t="https://www.linkedin.com/oauth/v2/accessToken";return{id:"linkedin",name:"Linkedin",createAuthorizationURL:async({state:o,scopes:n,redirectURI:i})=>{let s=e.scope||n||["profile","email","openid"];return await b({id:"linkedin",options:e,authorizationEndpoint:r,scopes:s,state:o,redirectURI:i})},validateAuthorizationCode:async({code:o,redirectURI:n})=>await y({code:o,redirectURI:e.redirectURI||n,options:e,tokenEndpoint:t}),async getUserInfo(o){let{data:n,error:i}=await St("https://api.linkedin.com/v2/userinfo",{method:"GET",headers:{Authorization:`Bearer ${o.accessToken}`}});return i?null:{user:{id:n.sub,name:n.name,email:n.email,emailVerified:n.email_verified||!1,image:n.picture},data:n}}}};var Ot={apple:he,discord:we,facebook:ye,github:Ae,microsoft:Re,google:ke,spotify:Ue,twitch:xe,twitter:ve,dropbox:Te,linkedin:Pe},_e=Object.keys(Ot);import{TimeSpan as Lt}from"oslo";import{createJWT as It,validateJWT as Ct}from"oslo/jwt";import{z as T}from"zod";import{APIError as V}from"better-call";import{APIError as M}from"better-call";var Z=(e,r="ms")=>new Date(Date.now()+(r==="sec"?e*1e3:e));import{z as Se}from"zod";var X=()=>m("/session",{method:"GET",requireHeaders:!0},async e=>{try{let r=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!r)return e.json(null,{status:401});let t=await e.context.internalAdapter.findSession(r);if(!t||t.session.expiresAt<new Date)return N(e),t&&await e.context.internalAdapter.deleteSession(t.session.id),e.json(null,{status:401});if(await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret))return e.json(t);let n=e.context.sessionConfig.expiresIn,i=e.context.sessionConfig.updateAge;if(t.session.expiresAt.valueOf()-n*1e3+i*1e3<=Date.now()){let c=await e.context.internalAdapter.updateSession(t.session.id,{expiresAt:Z(e.context.sessionConfig.expiresIn,"sec")});if(!c)return N(e),e.json(null,{status:401});let d=(c.expiresAt.valueOf()-Date.now())/1e3;return await S(e,c.id,!1,{maxAge:d}),e.json({session:c,user:t.user})}return e.json(t)}catch(r){return e.context.logger.error(r),e.json(null,{status:500})}}),ee=async e=>await X()({...e,_flag:"json",headers:e.headers}),O=z(async e=>{let r=await ee(e);if(!r?.session)throw new M("UNAUTHORIZED");return{session:r}}),Oe=()=>m("/user/list-sessions",{method:"GET",use:[O],requireHeaders:!0},async e=>{let t=(await e.context.internalAdapter.listSessions(e.context.session.user.id)).filter(o=>o.expiresAt>new Date);return e.json(t)}),Le=m("/user/revoke-session",{method:"POST",body:Se.object({id:Se.string()}),use:[O],requireHeaders:!0},async e=>{let r=e.body.id,t=await e.context.internalAdapter.findSession(r);if(!t)throw new M("BAD_REQUEST",{message:"Session not found"});if(t.session.userId!==e.context.session.user.id)throw new M("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(r)}catch(o){throw e.context.logger.error(o),new M("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),Ie=m("/user/revoke-sessions",{method:"POST",use:[O],requireHeaders:!0},async e=>{try{await e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(r){throw e.context.logger.error(r),new M("INTERNAL_SERVER_ERROR")}return e.json({status:!0})});async function L(e,r,t){return await It("HS256",Buffer.from(e),{email:r.toLowerCase(),updateTo:t},{expiresIn:new Lt(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[r],includeIssuedTimestamp:!0})}var Ce=m("/send-verification-email",{method:"POST",query:T.object({currentURL:T.string().optional()}).optional(),body:T.object({email:T.string().email(),callbackURL:T.string().optional()}),use:[E]},async e=>{if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new V("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:r}=e.body,t=await e.context.internalAdapter.findUserByEmail(r);if(!t)throw new V("BAD_REQUEST",{message:"User not found"});let o=await L(e.context.secret,r),n=`${e.context.baseURL}/verify-email?token=${o}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.emailVerification.sendVerificationEmail(t.user,n,o),e.json({status:!0})}),Be=m("/verify-email",{method:"GET",query:T.object({token:T.string(),callbackURL:T.string().optional()}),use:[E]},async e=>{let{token:r}=e.query,t;try{t=await Ct("HS256",Buffer.from(e.context.secret),r)}catch(s){throw e.context.logger.error("Failed to verify email",s),new V("BAD_REQUEST",{message:"Invalid token"})}let n=T.object({email:T.string().email(),updateTo:T.string().optional()}).parse(t.payload);if(!await e.context.internalAdapter.findUserByEmail(n.email))throw new V("BAD_REQUEST",{message:"User not found"});if(n.updateTo){let s=await ee(e);if(!s)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new V("UNAUTHORIZED",{message:"Session not found"});if(s.user.email!==n.email)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new V("UNAUTHORIZED",{message:"Invalid session"});let a=await e.context.internalAdapter.updateUserByEmail(n.email,{email:n.updateTo});if(await e.context.options.emailVerification?.sendVerificationEmail?.(a,`${e.context.baseURL}/verify-email?token=${r}`,r),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.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:null,status:!0})});var De=m("/sign-in/social",{method:"POST",requireHeaders:!0,query:v.object({currentURL:v.string().optional()}).optional(),body:v.object({callbackURL:v.string().optional(),provider:v.enum(_e)}),use:[E]},async e=>{let r=e.context.socialProviders.find(c=>c.id===e.body.provider);if(!r)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new P("NOT_FOUND",{message:"Provider not found"});let t=e.context.authCookies,o=e.query?.currentURL?new URL(e.query?.currentURL):null,n=e.body.callbackURL?.startsWith("http")?e.body.callbackURL:`${o?.origin}${e.body.callbackURL||""}`,i=await me(n||o?.origin||e.context.options.baseURL);await e.setSignedCookie(t.state.name,i.hash,e.context.secret,t.state.options);let s=Bt();await e.setSignedCookie(t.pkCodeVerifier.name,s,e.context.secret,t.pkCodeVerifier.options);let a=await r.createAuthorizationURL({state:i.raw,codeVerifier:s,redirectURI:`${e.context.baseURL}/callback/${r.id}`});return e.json({url:a.toString(),state:i,codeVerifier:s,redirect:!0})}),ze=m("/sign-in/email",{method:"POST",body:v.object({email:v.string(),password:v.string(),callbackURL:v.string().optional(),dontRememberMe:v.boolean().default(!1).optional()}),use:[E]},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 P("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:r,password:t}=e.body;if(!v.string().email().safeParse(r).success)throw new P("BAD_REQUEST",{message:"Invalid email"});if(!v.string().email().safeParse(r).success)throw new P("BAD_REQUEST",{message:"Invalid email"});let i=await e.context.internalAdapter.findUserByEmail(r,{includeAccounts:!0});if(!i)throw await e.context.password.hash(t),e.context.logger.error("User not found",{email:r}),new P("UNAUTHORIZED",{message:"Invalid email or password"});let s=i.accounts.find(l=>l.providerId==="credential");if(!s)throw e.context.logger.error("Credential account not found",{email:r}),new P("UNAUTHORIZED",{message:"Invalid email or password"});let a=s?.password;if(!a)throw e.context.logger.error("Password not found",{email:r}),new P("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(a,t))throw e.context.logger.error("Invalid password"),new P("UNAUTHORIZED",{message:"Invalid email or password"});if(e.context.options?.emailAndPassword?.requireEmailVerification&&!i.user.emailVerified){if(!e.context.options?.emailVerification?.sendVerificationEmail)throw w.error("Email verification is required but no email verification handler is provided"),new P("INTERNAL_SERVER_ERROR",{message:"Email is not verified."});let l=await L(e.context.secret,i.user.email),h=`${e.context.options.baseURL}/verify-email?token=${l}`;throw await e.context.options.emailVerification.sendVerificationEmail(i.user,h,l),e.context.logger.error("Email not verified",{email:r}),new P("FORBIDDEN",{message:"Email is not verified. Check your email for a verification link"})}let d=await e.context.internalAdapter.createSession(i.user.id,e.headers,e.body.dontRememberMe);if(!d)throw e.context.logger.error("Failed to create session"),new P("UNAUTHORIZED",{message:"Failed to create session"});return await S(e,d.id,e.body.dontRememberMe),e.json({user:i.user,session:d,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});import{z as Q}from"zod";import{z as f}from"zod";var li=f.object({id:f.string(),providerId:f.string(),accountId:f.string(),userId:f.string(),accessToken:f.string().nullable().optional(),refreshToken:f.string().nullable().optional(),idToken:f.string().nullable().optional(),expiresAt:f.date().nullable().optional(),password:f.string().optional().nullable()}),$e=f.object({id:f.string(),email:f.string().transform(e=>e.toLowerCase()),emailVerified:f.boolean().default(!1),name:f.string(),image:f.string().optional(),createdAt:f.date().default(new Date),updatedAt:f.date().default(new Date)}),ui=f.object({id:f.string(),userId:f.string(),expiresAt:f.date(),ipAddress:f.string().optional(),userAgent:f.string().optional()}),pi=f.object({id:f.string(),value:f.string(),expiresAt:f.date(),identifier:f.string()});function Ve(e,r){let t={...r==="user"?e.user?.additionalFields:{},...r==="session"?e.session?.additionalFields:{}};for(let o of e.plugins||[])o.schema&&o.schema[r]&&(t={...t,...o.schema[r].fields});return t}function je(e,r){let t=r.fields,o={};for(let n in t){if(n in e){if(t[n].input===!1){if(t[n].defaultValue){o[n]=t[n].defaultValue;continue}continue}o[n]=e[n];continue}if(t[n].defaultValue){o[n]=t[n].defaultValue;continue}}return o}function qe(e,r){let t=Ve(e,"user");return je(r||{},{fields:t})}function Ne(e,r){let t=Ve(e,"user");return je(r||{},{fields:t})}var Me=m("/callback/:id",{method:"GET",query:Q.object({state:Q.string(),code:Q.string().optional(),error:Q.string().optional()}),metadata:C},async e=>{if(e.query.error||!e.query.code){let R=K(e.query.state).data?.callbackURL||`${e.context.baseURL}/error`;throw e.context.logger.error(e.query.error,e.params.id),e.redirect(`${R}?error=${e.query.error||"oAuth_code_missing"}`)}let r=e.context.socialProviders.find(p=>p.id===e.params.id);if(!r)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 t=K(e.query.state);if(!t.success)throw e.context.logger.error("Unable to parse state"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let{data:{callbackURL:o,currentURL:n}}=t,i=await e.getSignedCookie(e.context.authCookies.state.name,e.context.secret);if(!i)throw w.error("No stored state found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!await pe(e.query.state,i))throw w.error("OAuth state mismatch"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let a=await e.getSignedCookie(e.context.authCookies.pkCodeVerifier.name,e.context.secret),c;try{c=await r.validateAuthorizationCode({code:e.query.code,codeVerifier:a,redirectURI:`${e.context.baseURL}/callback/${r.id}`})}catch(p){throw e.context.logger.error(p),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let d=await r.getUserInfo(c).then(p=>p?.user),l=Ee(),h=$e.safeParse({...d,id:l});if(!d||h.success===!1)throw w.error("Unable to get user info",h.error),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!o)throw e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);function g(p){throw e.redirect(`${n||o||`${e.context.baseURL}/error`}?error=${p}`)}let u=await e.context.internalAdapter.findUserByEmail(d.email,{includeAccounts:!0}).catch(p=>{throw w.error(`Better auth was unable to query your database.
3
3
  Error: `,p),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)}),A=u?.user.id;if(u){if(!u.accounts.find(R=>R.providerId===r.id)){(!e.context.options.account?.accountLinking?.trustedProviders?.includes(r.id)&&!d.emailVerified||!e.context.options.account?.accountLinking?.enabled)&&g("account_not_linked");try{await e.context.internalAdapter.linkAccount({providerId:r.id,accountId:d.id.toString(),id:`${r.id}:${d.id}`,userId:u.user.id,...Y(c)})}catch(B){w.error("Unable to link account",B),g("unable_to_link_account")}}}else try{let p=d.emailVerified||!1,R=await e.context.internalAdapter.createOAuthUser({...h.data,emailVerified:p},{...Y(c),providerId:r.id,accountId:d.id.toString()});if(A=R?.user.id,!p&&R&&e.context.options.emailVerification?.sendOnSignUp){let q=await L(e.context.secret,d.email),B=`${e.context.baseURL}/verify-email?token=${q}&callbackURL=${o}`;await e.context.options.emailVerification?.sendVerificationEmail?.(R.user,B,q)}}catch(p){w.error("Unable to create user",p),g("unable_to_create_user")}A||g("unable_to_create_user");let x=await e.context.internalAdapter.createSession(A,e.request);throw x||g("unable_to_create_session"),await S(e,x.id),e.redirect(o)});import"zod";import{APIError as Dt}from"better-call";var Fe=m("/sign-out",{method:"POST"},async e=>{let r=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!r)throw new Dt("BAD_REQUEST",{message:"Session not found"});return await e.context.internalAdapter.deleteSession(r),N(e),e.json({success:!0})});import{z as _}from"zod";import{APIError as G}from"better-call";var He=m("/forget-password",{method:"POST",body:_.object({email:_.string().email(),redirectTo:_.string()}),use:[E]},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:r,redirectTo:t}=e.body,o=await e.context.internalAdapter.findUserByEmail(r,{includeAccounts:!0});if(!o)return e.context.logger.error("Reset Password: User not found",{email:r}),e.json({status:!1},{body:{status:!0}});let n=60*60*1,i=new Date(Date.now()+1e3*(e.context.options.emailAndPassword.resetPasswordTokenExpiresIn||n)),s=e.context.uuid();await e.context.internalAdapter.createVerificationValue({value:o.user.id,identifier:`reset-password:${s}`,expiresAt:i});let a=`${e.context.baseURL}/reset-password/${s}?callbackURL=${t}`;return await e.context.options.emailAndPassword.sendResetPassword(o.user,a),e.json({status:!0})}),Ze=m("/reset-password/:token",{method:"GET",query:_.object({callbackURL:_.string()}),use:[E]},async e=>{let{token:r}=e.params,t=e.query.callbackURL,o=t.startsWith("http")?t:`${e.context.options.baseURL}${t}`;if(!r||!t)throw e.redirect(`${e.context.baseURL}/error?error=INVALID_TOKEN`);let n=await e.context.internalAdapter.findVerificationValue(`reset-password:${r}`);throw!n||n.expiresAt<new Date?e.redirect(`${o}?error=INVALID_TOKEN`):e.redirect(`${o}?token=${r}`)}),Qe=m("/reset-password",{query:_.optional(_.object({token:_.string().optional(),currentURL:_.string().optional()})),method:"POST",body:_.object({newPassword:_.string()})},async e=>{let r=e.query?.token||(e.query?.currentURL?new URL(e.query.currentURL).searchParams.get("token"):"");if(!r)throw new G("BAD_REQUEST",{message:"Token not found"});let{newPassword:t}=e.body,o=`reset-password:${r}`,n=await e.context.internalAdapter.findVerificationValue(o);if(!n||n.expiresAt<new Date)throw new G("BAD_REQUEST",{message:"Invalid token"});await e.context.internalAdapter.deleteVerificationValue(n.id);let i=n.value,s=await e.context.password.hash(t);if(!(await e.context.internalAdapter.findAccounts(i)).find(l=>l.providerId==="credential"))return await e.context.internalAdapter.createAccount({userId:i,providerId:"credential",password:s,accountId:e.context.uuid()}),e.json({status:!0});if(!await e.context.internalAdapter.updatePassword(i,s))throw new G("BAD_REQUEST",{message:"Failed to update password"});return e.json({status:!0})});import{z as k}from"zod";import{APIError as U}from"better-call";var Ge=()=>m("/user/update",{method:"POST",body:k.record(k.string(),k.any()),use:[O,E]},async e=>{let r=e.body;if(r.email)throw new U("BAD_REQUEST",{message:"You can't update email"});let{name:t,image:o,...n}=r,i=e.context.session;if(!o&&!t&&Object.keys(n).length===0)return e.json({user:i.user});let s=qe(e.context.options,n),a=await e.context.internalAdapter.updateUserByEmail(i.user.email,{name:t,image:o,...s});return e.json({user:a})}),We=m("/user/change-password",{method:"POST",body:k.object({newPassword:k.string(),currentPassword:k.string(),revokeOtherSessions:k.boolean().optional()}),use:[O]},async e=>{let{newPassword:r,currentPassword:t,revokeOtherSessions:o}=e.body,n=e.context.session,i=e.context.password.config.minPasswordLength;if(r.length<i)throw e.context.logger.error("Password is too short"),new U("BAD_REQUEST",{message:"Password is too short"});let s=e.context.password.config.maxPasswordLength;if(r.length>s)throw e.context.logger.error("Password is too long"),new U("BAD_REQUEST",{message:"Password too long"});let c=(await e.context.internalAdapter.findAccounts(n.user.id)).find(h=>h.providerId==="credential"&&h.password);if(!c||!c.password)throw new U("BAD_REQUEST",{message:"User does not have a password"});let d=await e.context.password.hash(r);if(!await e.context.password.verify(c.password,t))throw new U("BAD_REQUEST",{message:"Incorrect password"});if(await e.context.internalAdapter.updateAccount(c.id,{password:d}),o){await e.context.internalAdapter.deleteSessions(n.user.id);let h=await e.context.internalAdapter.createSession(n.user.id,e.headers);if(!h)throw new U("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});await S(e,h.id)}return e.json(n.user)}),Je=m("/user/set-password",{method:"POST",body:k.object({newPassword:k.string()}),use:[O]},async e=>{let{newPassword:r}=e.body,t=e.context.session,o=e.context.password.config.minPasswordLength;if(r.length<o)throw e.context.logger.error("Password is too short"),new U("BAD_REQUEST",{message:"Password is too short"});let n=e.context.password.config.maxPasswordLength;if(r.length>n)throw e.context.logger.error("Password is too long"),new U("BAD_REQUEST",{message:"Password too long"});let s=(await e.context.internalAdapter.findAccounts(t.user.id)).find(c=>c.providerId==="credential"&&c.password),a=await e.context.password.hash(r);if(!s)return await e.context.internalAdapter.linkAccount({userId:t.user.id,providerId:"credential",accountId:t.user.id,password:a}),e.json(t.user);throw new U("BAD_REQUEST",{message:"user already has a password"})}),Ke=m("/user/delete",{method:"POST",body:k.object({password:k.string()}),use:[O]},async e=>{let{password:r}=e.body,t=e.context.session,n=(await e.context.internalAdapter.findAccounts(t.user.id)).find(a=>a.providerId==="credential"&&a.password);if(!n||!n.password)throw new U("BAD_REQUEST",{message:"User does not have a password"});if(!await e.context.password.verify(n.password,r))throw new U("BAD_REQUEST",{message:"Incorrect password"});await e.context.internalAdapter.deleteUser(t.user.id),await e.context.internalAdapter.deleteSessions(t.user.id);let s=e.context.authCookies.sessionToken;return e.setCookie(s.name,"",{maxAge:0}),e.json(null)}),Ye=m("/user/change-email",{method:"POST",query:k.object({currentURL:k.string().optional()}).optional(),body:k.object({newEmail:k.string().email(),callbackURL:k.string().optional()}),use:[O,E]},async e=>{if(!e.context.options.user?.changeEmail?.enabled)throw e.context.logger.error("Change email is disabled."),new U("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 U("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 U("BAD_REQUEST",{message:"Couldn't update your email"});if(e.context.session.user.emailVerified!==!0){let n=await e.context.internalAdapter.updateUserByEmail(e.context.session.user.email,{email:e.body.newEmail});return e.json({user:n,status:!0})}if(!e.context.options.user.changeEmail.sendChangeEmailVerification)throw e.context.logger.error("Verification email isn't enabled."),new U("BAD_REQUEST",{message:"Verification email isn't enabled"});let t=await L(e.context.secret,e.context.session.user.email,e.body.newEmail),o=`${e.context.baseURL}/verify-email?token=${t}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.user.changeEmail.sendChangeEmailVerification(e.context.session.user,e.body.newEmail,o,t),e.json({user:null,status:!0})});var Xe=m("/csrf",{method:"GET",metadata:C},async e=>{let r=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret);if(r){let[i,s]=r.split("!")||[null,null];return e.json({csrfToken:i})}let t=oe(32,ne("a-z","0-9","A-Z")),o=await F(e.context.secret,t),n=`${t}!${o}`;return await e.setSignedCookie(e.context.authCookies.csrfToken.name,n,e.context.secret,e.context.authCookies.csrfToken.options),e.json({csrfToken:t})});var zt=(e="Unknown")=>`<!DOCTYPE html>
4
4
  <html lang="en">
5
5
  <head>
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import{APIError as Pt,createRouter as Pr,statusCode as Sr}from"better-call";import{APIError as se}from"better-call";import{z as Pe}from"zod";import{xchacha20poly1305 as Zr}from"@noble/ciphers/chacha";import{bytesToHex as Qr,hexToBytes as Wr,utf8ToBytes as Jr}from"@noble/ciphers/utils";import{managedNonce as Xr}from"@noble/ciphers/webcrypto";import{sha256 as to}from"oslo/crypto";import Ee from"uncrypto";function X(e,t){let r=new Uint8Array(e),o=new Uint8Array(t);if(r.length!==o.length)return!1;let i=0;for(let n=0;n<r.length;n++)i|=r[n]^o[n];return i===0}import{decodeHex as jt,encodeHex as be}from"oslo/encoding";import{scryptAsync as Mt}from"@noble/hashes/scrypt";import{getRandomValues as Ht}from"uncrypto";var j={N:16384,r:16,p:1,dkLen:64};async function Ae(e,t){return await Mt(e.normalize("NFKC"),t,{N:j.N,p:j.p,r:j.r,dkLen:j.dkLen,maxmem:128*j.N*j.r*2})}var ke=async e=>{let t=be(Ht(new Uint8Array(16))),r=await Ae(e,t);return`${t}:${be(r)}`},Re=async(e,t)=>{let[r,o]=e.split(":"),i=await Ae(t,r);return X(i,jt(o))};import xe from"uncrypto";function Kt(e){return e.toString(2).padStart(8,"0")}function Zt(e){return[...e].map(t=>Kt(t)).join("")}function Ue(e){return parseInt(Zt(e),2)}function Gt(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));xe.getRandomValues(o),r!==0&&(o[0]&=(1<<r)-1);let i=Ue(o);for(;i>=e;)xe.getRandomValues(o),r!==0&&(o[0]&=(1<<r)-1),i=Ue(o);return i}function Te(e,t){let r="";for(let o=0;o<e;o++)r+=t[Gt(t.length)];return r}function ve(...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}async function ee(e,t){let r=new TextEncoder,o={name:"HMAC",hash:"SHA-256"},i=await Ee.subtle.importKey("raw",r.encode(e),o,!1,["sign","verify"]),n=await Ee.subtle.sign(o.name,i,r.encode(t));return btoa(String.fromCharCode(...new Uint8Array(n)))}import{createEndpointCreator as Qt,createMiddleware as Oe,createMiddlewareCreator as Wt}from"better-call";var Ie=Oe(async()=>({})),M=Wt({use:[Ie,Oe(async()=>({}))]}),y=Qt({use:[Ie]});var Se=M({body:Pe.object({csrfToken:Pe.string().optional()}).optional()},async e=>{if(e.request?.method!=="POST"||e.context.options.advanced?.disableCSRFCheck)return;let t=e.headers?.get("origin")||"";if(t){let c=new URL(t).origin;if(e.context.trustedOrigins.includes(c))return}let r=e.body?.csrfToken;if(!r)throw new se("UNAUTHORIZED",{message:"CSRF Token is required"});let o=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret),[i,n]=o?.split("!")||[null,null];if(!r||!i||!n||i!==r)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new se("UNAUTHORIZED",{message:"Invalid CSRF Token"});let a=await ee(e.context.secret,i);if(n!==a)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new se("UNAUTHORIZED",{message:"Invalid CSRF Token"})});import{APIError as S}from"better-call";import{generateCodeVerifier as Ar}from"oslo/oauth2";import{z as I}from"zod";import{generateState as Jt}from"oslo/oauth2";import{z as te}from"zod";import{sha256 as Le}from"oslo/crypto";async function _e(e){let t=await Le(typeof e=="string"?new TextEncoder().encode(e):e);return Buffer.from(t).toString("base64")}async function Ce(e,t){let r=await Le(typeof e=="string"?new TextEncoder().encode(e):e),o=Buffer.from(t,"base64");return X(r,o)}import"better-call";async function Be(e){let t=Jt(),r=JSON.stringify({code:t,callbackURL:e}),o=await _e(r);return{raw:r,hash:o}}function ae(e){return te.object({code:te.string(),callbackURL:te.string().optional(),currentURL:te.string().optional()}).safeParse(JSON.parse(e))}import{TimeSpan as Yt}from"oslo";var O=class extends Error{constructor(t,r){super(t),this.name="BetterAuthError",this.message=t,this.cause=r}},De=class extends O{constructor(t){super(`The package "${t}" is required. Make sure it is installed.`,t)}};import{env as Xt,isProduction as Fe}from"std-env";function Ne(e){let r=(e.advanced?.useSecureCookies!==void 0?e.advanced?.useSecureCookies:e.baseURL!==void 0?!!e.baseURL.startsWith("https://"):Fe)?"__Secure-":"",o="better-auth",i=e.session?.expiresIn||new Yt(7,"d").seconds(),n=!!e.advanced?.crossSubDomainCookies?.enabled,a=n?e.advanced?.crossSubDomainCookies?.domain||(e.baseURL?new URL(e.baseURL).hostname:void 0):void 0;if(n&&!a)throw new O("baseURL is required when crossSubdomainCookies are enabled");let c=n?"none":"lax";return{sessionToken:{name:`${r}${o}.session_token`,options:{httpOnly:!0,sameSite:c,path:"/",secure:!!r,maxAge:i,...n?{domain:a}:{}}},csrfToken:{name:`${r}${o}.csrf_token`,options:{httpOnly:!0,sameSite:c,path:"/",secure:!!r,maxAge:60*60*24*7,...n?{domain:a}:{}}},state:{name:`${r}${o}.state`,options:{httpOnly:!0,sameSite:c,path:"/",secure:!!r,maxAge:60*15,...n?{domain:a}:{}}},pkCodeVerifier:{name:`${r}${o}.pk_code_verifier`,options:{httpOnly:!0,sameSite:c,path:"/",secure:!!r,maxAge:60*15,...n?{domain:a}:{}}},dontRememberToken:{name:`${r}${o}.dont_remember`,options:{httpOnly:!0,sameSite:c,path:"/",secure:!!r,...n?{domain:a}:{}}},nonce:{name:`${r}${o}.nonce`,options:{httpOnly:!0,sameSite:c,path:"/",secure:!!r,maxAge:60*15,...n?{domain:a}:{}}}}}function qe(e){let r=(e.advanced?.useSecureCookies!==void 0?e.advanced?.useSecureCookies:e.baseURL?.startsWith("https://")||Fe)?"__Secure-":"",o="better-auth",i=e.advanced?.crossSubDomainCookies?.domain||(e.baseURL?new URL(e.baseURL).hostname:void 0);function n(a,c){let s=e.advanced?.crossSubDomainCookies?.enabled?e.advanced.crossSubDomainCookies.additionalCookies?.includes(a):void 0;return{name:Xt.NODE_ENV==="production"?`${r}${o}.${a}`:`${o}.${a}`,options:{secure:!!r,sameSite:"lax",path:"/",maxAge:60*15,...c,...s?{domain:i}:{}}}}return n}async function _(e,t,r,o){let i=e.context.authCookies.sessionToken.options;i.maxAge=r?void 0:e.context.sessionConfig.expiresIn,await e.setSignedCookie(e.context.authCookies.sessionToken.name,t,e.context.secret,{...i,...o}),r&&await e.setSignedCookie(e.context.authCookies.dontRememberToken.name,"true",e.context.secret,e.context.authCookies.dontRememberToken.options)}function G(e){e.setCookie(e.context.authCookies.sessionToken.name,"",{maxAge:0}),e.setCookie(e.context.authCookies.dontRememberToken.name,"",{maxAge:0})}function Po(e){let t=new Map;return e.split(", ").forEach(o=>{let[i,...n]=o.split("; "),[a,c]=i.split("="),s={value:c};n.forEach(d=>{let[l,f]=d.split("=");s[l.toLowerCase()]=f||!0}),t.set(a,s)}),t}function So(e){let t=e.split("; "),r=new Map;return t.forEach(o=>{let[i,n]=o.split("=");r.set(i,n)}),r}import{APIError as tr}from"better-call";import{createConsola as er}from"consola";var V=er({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),de=e=>({log:(...t)=>{!e?.disabled&&V.log("",...t)},error:(...t)=>{!e?.disabled&&V.error("",...t)},warn:(...t)=>{!e?.disabled&&V.warn("",...t)},info:(...t)=>{!e?.disabled&&V.info("",...t)},debug:(...t)=>{!e?.disabled&&V.debug("",...t)},box:(...t)=>{!e?.disabled&&V.box("",...t)},success:(...t)=>{!e?.disabled&&V.success("",...t)},break:(...t)=>{!e?.disabled&&console.log(`
2
- `)}}),b=de();var T=M(async e=>{let{body:t,query:r,headers:o,context:i}=e,n=t?.callbackURL||r?.callbackURL||r?.redirectTo||t?.redirectTo,a=r?.currentURL||o?.get("referer")||i.baseURL,c=i.trustedOrigins,s=(d,l)=>{if(d?.startsWith("http")&&!c.some(u=>d.startsWith(u)))throw b.error(`Invalid ${l}`,{[l]:d,trustedOrigins:c}),new tr("FORBIDDEN",{message:`Invalid ${l}`})};s(n,"callbackURL"),s(a,"currentURL")});import{parseJWT as ir}from"oslo/jwt";import{sha256 as rr}from"oslo/crypto";import{base64url as or}from"oslo/encoding";async function Ve(e){let t=await rr(new TextEncoder().encode(e));return or.encode(new Uint8Array(t),{includePadding:!1})}function $e(e){return{tokenType:e.token_type,accessToken:e.access_token,refreshToken:e.refresh_token,accessTokenExpiresAt:e.expires_at?new Date((Date.now()+e.expires_in)*1e3):void 0,scopes:e?.scope?typeof e.scope=="string"?e.scope.split(" "):e.scope:[],idToken:e.id_token}}async function k({id:e,options:t,authorizationEndpoint:r,state:o,codeVerifier:i,scopes:n,claims:a,disablePkce:c,redirectURI:s}){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||s),!c&&i){let l=await Ve(i);d.searchParams.set("code_challenge_method","S256"),d.searchParams.set("code_challenge",l)}if(a){let l=a.reduce((f,u)=>(f[u]=null,f),{});d.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...l}}))}return d}import{betterFetch as nr}from"@better-fetch/fetch";async function A({code:e,codeVerifier:t,redirectURI:r,options:o,tokenEndpoint:i}){let n=new URLSearchParams;n.set("grant_type","authorization_code"),n.set("code",e),t&&n.set("code_verifier",t),n.set("redirect_uri",r),n.set("client_id",o.clientId),n.set("client_secret",o.clientSecret);let{data:a,error:c}=await nr(i,{method:"POST",body:n,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(c)throw c;return $e(a)}function ce(e){let t=e.accessToken,r=e.refreshToken,o;try{o=e.accessTokenExpiresAt}catch{}return{accessToken:t,refreshToken:r,expiresAt:o}}var ze=e=>{let t="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:r,scopes:o,redirectURI:i}){let n=e.scope||o||["email","name","openid"];return 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}`)},validateAuthorizationCode:async({code:r,codeVerifier:o,redirectURI:i})=>A({code:r,codeVerifier:o,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:t}),async getUserInfo(r){if(!r.idToken)return null;let o=ir(r.idToken)?.payload;return o?{user:{id:o.sub,name:o.name,email:o.email,emailVerified:o.email_verified==="true"},data:o}:null}}};import{betterFetch as sr}from"@better-fetch/fetch";var je=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=e.scope||r||["identify","email"];return 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}`)},validateAuthorizationCode:async({code:t,redirectURI:r})=>A({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await sr("https://discord.com/api/users/@me",{headers:{authorization:`Bearer ${t.accessToken}`}});if(o)return null;if(r.avatar===null){let i=r.discriminator==="0"?Number(BigInt(r.id)>>BigInt(22))%6:parseInt(r.discriminator)%5;r.image_url=`https://cdn.discordapp.com/embed/avatars/${i}.png`}else{let i=r.avatar.startsWith("a_")?"gif":"png";r.image_url=`https://cdn.discordapp.com/avatars/${r.id}/${r.avatar}.${i}`}return{user:{id:r.id,name:r.display_name||r.username||"",email:r.email,emailVerified:r.verified,image:r.image_url},data:r}}});import{betterFetch as ar}from"@better-fetch/fetch";var Me=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=e.scope||r||["email","public_profile"];return await k({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})=>A({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://graph.facebook.com/oauth/access_token"}),async getUserInfo(t){let{data:r,error:o}=await ar("https://graph.facebook.com/me?fields=id,name,email,picture",{auth:{type:"Bearer",token:t.accessToken}});return o?null:{user:{id:r.id,name:r.name,email:r.email,image:r.picture.data.url,emailVerified:r.email_verified},data:r}}});import{betterFetch as He}from"@better-fetch/fetch";var Ke=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 a=e.scope||o||["user:email"];return k({id:"github",options:e,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:a,state:r,redirectURI:n,codeVerifier:i})},validateAuthorizationCode:async({code:r,redirectURI:o})=>A({code:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:t}),async getUserInfo(r){let{data:o,error:i}=await He("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:a,error:c}=await He("https://api.github.com/user/emails",{headers:{authorization:`Bearer ${r.accessToken}`,"User-Agent":"better-auth"}});c||(o.email=(a.find(s=>s.primary)??a[0])?.email,n=a.find(s=>s.email===o.email)?.verified??!1)}return{user:{id:o.id.toString(),name:o.name||o.login,email:o.email,image:o.avatar_url,emailVerified:n},data:o}}}};import{parseJWT as dr}from"oslo/jwt";var Ze=e=>({id:"google",name:"Google",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:i}){if(!e.clientId||!e.clientSecret)throw b.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new O("CLIENT_ID_AND_SECRET_REQUIRED");if(!o)throw new O("codeVerifier is required for Google");let n=e.scope||r||["email","profile"];return k({id:"google",options:e,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:n,state:t,codeVerifier:o,redirectURI:i})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>A({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://oauth2.googleapis.com/token"}),async getUserInfo(t){if(!t.idToken)return null;let r=dr(t.idToken)?.payload;return{user:{id:r.sub,name:r.name,email:r.email,image:r.picture,emailVerified:r.email_verified},data:r}}});import{betterFetch as cr}from"@better-fetch/fetch";import{parseJWT as lr}from"oslo/jwt";var Ge=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=e.scope||i.scopes||["openid","profile","email","User.Read"];return k({id:"microsoft",options:e,authorizationEndpoint:r,state:i.state,codeVerifier:i.codeVerifier,scopes:n,redirectURI:i.redirectURI})},validateAuthorizationCode({code:i,codeVerifier:n,redirectURI:a}){return A({code:i,codeVerifier:n,redirectURI:e.redirectURI||a,options:e,tokenEndpoint:o})},async getUserInfo(i){if(!i.idToken)return null;let n=lr(i.idToken)?.payload,a=e.profilePhotoSize||48;return await cr(`https://graph.microsoft.com/v1.0/me/photos/${a}x${a}/$value`,{headers:{Authorization:`Bearer ${i.accessToken}`},async onResponse(c){if(!(e.disableProfilePhoto||!c.response.ok))try{let d=await c.response.clone().arrayBuffer(),l=Buffer.from(d).toString("base64");n.picture=`data:image/jpeg;base64, ${l}`}catch(s){b.error(s)}}}),{user:{id:n.sub,name:n.name,email:n.email,image:n.picture,emailVerified:!0},data:n}}}};import{betterFetch as ur}from"@better-fetch/fetch";var Qe=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:i}){let n=e.scope||r||["user-read-email"];return k({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})=>A({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://accounts.spotify.com/api/token"}),async getUserInfo(t){let{data:r,error:o}=await ur("https://api.spotify.com/v1/me",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});return o?null:{user:{id:r.id,name:r.display_name,email:r.email,image:r.images[0]?.url,emailVerified:!1},data:r}}});import"@better-fetch/fetch";function En(e){return e.charAt(0).toUpperCase()+e.slice(1)}var N={isAction:!1};import{nanoid as pr}from"nanoid";var v=e=>pr(e);import{parseJWT as fr}from"oslo/jwt";var We=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=e.scope||r||["user:read:email","openid"];return k({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})=>A({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){let r=t.idToken;if(!r)return b.error("No idToken found in token"),null;let o=fr(r)?.payload;return{user:{id:o.sub,name:o.preferred_username,email:o.email,image:o.picture,emailVerified:!1},data:o}}});import{betterFetch as mr}from"@better-fetch/fetch";var Je=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(t){let r=e.scope||t.scopes||["account_info.read"];return k({id:"twitter",options:e,authorizationEndpoint:"https://twitter.com/i/oauth2/authorize",scopes:r,state:t.state,codeVerifier:t.codeVerifier,redirectURI:t.redirectURI})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>A({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await mr("https://api.x.com/2/users/me?user.fields=profile_image_url",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});return o||!r.data.email?null:{user:{id:r.data.id,name:r.data.name,email:r.data.email,image:r.data.profile_image_url,emailVerified:r.data.verified||!1},data:r}}});import{betterFetch as gr}from"@better-fetch/fetch";var Ye=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 a=e.scope||o||["account_info.read"];return await k({id:"dropbox",options:e,authorizationEndpoint:"https://www.dropbox.com/oauth2/authorize",scopes:a,state:r,redirectURI:n,codeVerifier:i})},validateAuthorizationCode:async({code:r,codeVerifier:o,redirectURI:i})=>await A({code:r,codeVerifier:o,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:t}),async getUserInfo(r){let{data:o,error:i}=await gr("https://api.dropboxapi.com/2/users/get_current_account",{method:"POST",headers:{Authorization:`Bearer ${r.accessToken}`}});return i?null:{user:{id:o.account_id,name:o.name?.display_name,email:o.email,emailVerified:o.email_verified||!1,image:o.profile_photo_url},data:o}}}};import{betterFetch as hr}from"@better-fetch/fetch";var Xe=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 a=e.scope||i||["profile","email","openid"];return await k({id:"linkedin",options:e,authorizationEndpoint:t,scopes:a,state:o,redirectURI:n})},validateAuthorizationCode:async({code:o,redirectURI:i})=>await A({code:o,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:r}),async getUserInfo(o){let{data:i,error:n}=await hr("https://api.linkedin.com/v2/userinfo",{method:"GET",headers:{Authorization:`Bearer ${o.accessToken}`}});return n?null:{user:{id:i.sub,name:i.name,email:i.email,emailVerified:i.email_verified||!1,image:i.picture},data:i}}}};var le={apple:ze,discord:je,facebook:Me,github:Ke,microsoft:Ge,google:Ze,spotify:Qe,twitch:We,twitter:Je,dropbox:Ye,linkedin:Xe},et=Object.keys(le);import{TimeSpan as yr}from"oslo";import{createJWT as wr,validateJWT as br}from"oslo/jwt";import{z as P}from"zod";import{APIError as H}from"better-call";import{APIError as Q}from"better-call";var $=(e,t="ms")=>new Date(Date.now()+(t==="sec"?e*1e3:e));import{z as tt}from"zod";var ue=()=>y("/session",{method:"GET",requireHeaders:!0},async e=>{try{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)return e.json(null,{status:401});let r=await e.context.internalAdapter.findSession(t);if(!r||r.session.expiresAt<new Date)return G(e),r&&await e.context.internalAdapter.deleteSession(r.session.id),e.json(null,{status:401});if(await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret))return e.json(r);let i=e.context.sessionConfig.expiresIn,n=e.context.sessionConfig.updateAge;if(r.session.expiresAt.valueOf()-i*1e3+n*1e3<=Date.now()){let s=await e.context.internalAdapter.updateSession(r.session.id,{expiresAt:$(e.context.sessionConfig.expiresIn,"sec")});if(!s)return G(e),e.json(null,{status:401});let d=(s.expiresAt.valueOf()-Date.now())/1e3;return await _(e,s.id,!1,{maxAge:d}),e.json({session:s,user:r.user})}return e.json(r)}catch(t){return e.context.logger.error(t),e.json(null,{status:500})}}),pe=async e=>await ue()({...e,_flag:"json",headers:e.headers}),C=M(async e=>{let t=await pe(e);if(!t?.session)throw new Q("UNAUTHORIZED");return{session:t}}),rt=()=>y("/user/list-sessions",{method:"GET",use:[C],requireHeaders:!0},async e=>{let r=(await e.context.internalAdapter.listSessions(e.context.session.user.id)).filter(o=>o.expiresAt>new Date);return e.json(r)}),ot=y("/user/revoke-session",{method:"POST",body:tt.object({id:tt.string()}),use:[C],requireHeaders:!0},async e=>{let t=e.body.id,r=await e.context.internalAdapter.findSession(t);if(!r)throw new Q("BAD_REQUEST",{message:"Session not found"});if(r.session.userId!==e.context.session.user.id)throw new Q("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(t)}catch(o){throw e.context.logger.error(o),new Q("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),nt=y("/user/revoke-sessions",{method:"POST",use:[C],requireHeaders:!0},async e=>{try{await e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(t){throw e.context.logger.error(t),new Q("INTERNAL_SERVER_ERROR")}return e.json({status:!0})});async function B(e,t,r){return await wr("HS256",Buffer.from(e),{email:t.toLowerCase(),updateTo:r},{expiresIn:new yr(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}var it=y("/send-verification-email",{method:"POST",query:P.object({currentURL:P.string().optional()}).optional(),body:P.object({email:P.string().email(),callbackURL:P.string().optional()}),use:[T]},async e=>{if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new H("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:t}=e.body,r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw new H("BAD_REQUEST",{message:"User not found"});let o=await B(e.context.secret,t),i=`${e.context.baseURL}/verify-email?token=${o}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.emailVerification.sendVerificationEmail(r.user,i,o),e.json({status:!0})}),st=y("/verify-email",{method:"GET",query:P.object({token:P.string(),callbackURL:P.string().optional()}),use:[T]},async e=>{let{token:t}=e.query,r;try{r=await br("HS256",Buffer.from(e.context.secret),t)}catch(a){throw e.context.logger.error("Failed to verify email",a),new H("BAD_REQUEST",{message:"Invalid token"})}let i=P.object({email:P.string().email(),updateTo:P.string().optional()}).parse(r.payload);if(!await e.context.internalAdapter.findUserByEmail(i.email))throw new H("BAD_REQUEST",{message:"User not found"});if(i.updateTo){let a=await pe(e);if(!a)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new H("UNAUTHORIZED",{message:"Session not found"});if(a.user.email!==i.email)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new H("UNAUTHORIZED",{message:"Invalid session"});let c=await e.context.internalAdapter.updateUserByEmail(i.email,{email:i.updateTo});if(await e.context.options.emailVerification?.sendVerificationEmail?.(c,`${e.context.baseURL}/verify-email?token=${t}`,t),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:c,status:!0})}if(await e.context.internalAdapter.updateUserByEmail(i.email,{emailVerified:!0}),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:null,status:!0})});var at=y("/sign-in/social",{method:"POST",requireHeaders:!0,query:I.object({currentURL:I.string().optional()}).optional(),body:I.object({callbackURL:I.string().optional(),provider:I.enum(et)}),use:[T]},async e=>{let t=e.context.socialProviders.find(s=>s.id===e.body.provider);if(!t)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new S("NOT_FOUND",{message:"Provider not found"});let r=e.context.authCookies,o=e.query?.currentURL?new URL(e.query?.currentURL):null,i=e.body.callbackURL?.startsWith("http")?e.body.callbackURL:`${o?.origin}${e.body.callbackURL||""}`,n=await Be(i||o?.origin||e.context.options.baseURL);await e.setSignedCookie(r.state.name,n.hash,e.context.secret,r.state.options);let a=Ar();await e.setSignedCookie(r.pkCodeVerifier.name,a,e.context.secret,r.pkCodeVerifier.options);let c=await t.createAuthorizationURL({state:n.raw,codeVerifier:a,redirectURI:`${e.context.baseURL}/callback/${t.id}`});return e.json({url:c.toString(),state:n,codeVerifier:a,redirect:!0})}),dt=y("/sign-in/email",{method:"POST",body:I.object({email:I.string(),password:I.string(),callbackURL:I.string().optional(),dontRememberMe:I.boolean().default(!1).optional()}),use:[T]},async e=>{if(!e.context.options?.emailAndPassword?.enabled)throw e.context.logger.error("Email and password is not enabled. Make sure to enable it in the options on you `auth.ts` file. Check `https://better-auth.com/docs/authentication/email-password` for more!"),new S("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:t,password:r}=e.body;if(!I.string().email().safeParse(t).success)throw new S("BAD_REQUEST",{message:"Invalid email"});if(!I.string().email().safeParse(t).success)throw new S("BAD_REQUEST",{message:"Invalid email"});let n=await e.context.internalAdapter.findUserByEmail(t,{includeAccounts:!0});if(!n)throw await e.context.password.hash(r),e.context.logger.error("User not found",{email:t}),new S("UNAUTHORIZED",{message:"Invalid email or password"});let a=n.accounts.find(l=>l.providerId==="credential");if(!a)throw e.context.logger.error("Credential account not found",{email:t}),new S("UNAUTHORIZED",{message:"Invalid email or password"});let c=a?.password;if(!c)throw e.context.logger.error("Password not found",{email:t}),new S("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(c,r))throw e.context.logger.error("Invalid password"),new S("UNAUTHORIZED",{message:"Invalid email or password"});if(e.context.options?.emailAndPassword?.requireEmailVerification&&!n.user.emailVerified){if(!e.context.options?.emailVerification?.sendVerificationEmail)throw b.error("Email verification is required but no email verification handler is provided"),new S("INTERNAL_SERVER_ERROR",{message:"Email is not verified."});let l=await B(e.context.secret,n.user.email),f=`${e.context.options.baseURL}/verify-email?token=${l}`;throw await e.context.options.emailVerification.sendVerificationEmail(n.user,f,l),e.context.logger.error("Email not verified",{email:t}),new S("FORBIDDEN",{message:"Email is not verified. Check your email for a verification link"})}let d=await e.context.internalAdapter.createSession(n.user.id,e.headers,e.body.dontRememberMe);if(!d)throw e.context.logger.error("Failed to create session"),new S("UNAUTHORIZED",{message:"Failed to create session"});return await _(e,d.id,e.body.dontRememberMe),e.json({user:n.user,session:d,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});import{z as re}from"zod";import{z as w}from"zod";var Wi=w.object({id:w.string(),providerId:w.string(),accountId:w.string(),userId:w.string(),accessToken:w.string().nullable().optional(),refreshToken:w.string().nullable().optional(),idToken:w.string().nullable().optional(),expiresAt:w.date().nullable().optional(),password:w.string().optional().nullable()}),ct=w.object({id:w.string(),email:w.string().transform(e=>e.toLowerCase()),emailVerified:w.boolean().default(!1),name:w.string(),image:w.string().optional(),createdAt:w.date().default(new Date),updatedAt:w.date().default(new Date)}),Ji=w.object({id:w.string(),userId:w.string(),expiresAt:w.date(),ipAddress:w.string().optional(),userAgent:w.string().optional()}),Yi=w.object({id:w.string(),value:w.string(),expiresAt:w.date(),identifier:w.string()});function lt(e,t){let r={...t==="user"?e.user?.additionalFields:{},...t==="session"?e.session?.additionalFields:{}};for(let o of e.plugins||[])o.schema&&o.schema[t]&&(r={...r,...o.schema[t].fields});return r}function ut(e,t){let r=t.fields,o={};for(let i in r){if(i in e){if(r[i].input===!1){if(r[i].defaultValue){o[i]=r[i].defaultValue;continue}continue}o[i]=e[i];continue}if(r[i].defaultValue){o[i]=r[i].defaultValue;continue}}return o}function pt(e,t){let r=lt(e,"user");return ut(t||{},{fields:r})}function ft(e,t){let r=lt(e,"user");return ut(t||{},{fields:r})}var mt=y("/callback/:id",{method:"GET",query:re.object({state:re.string(),code:re.string().optional(),error:re.string().optional()}),metadata:N},async e=>{if(e.query.error||!e.query.code){let x=ae(e.query.state).data?.callbackURL||`${e.context.baseURL}/error`;throw e.context.logger.error(e.query.error,e.params.id),e.redirect(`${x}?error=${e.query.error||"oAuth_code_missing"}`)}let t=e.context.socialProviders.find(m=>m.id===e.params.id);if(!t)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 r=ae(e.query.state);if(!r.success)throw e.context.logger.error("Unable to parse state"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let{data:{callbackURL:o,currentURL:i}}=r,n=await e.getSignedCookie(e.context.authCookies.state.name,e.context.secret);if(!n)throw b.error("No stored state found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!await Ce(e.query.state,n))throw b.error("OAuth state mismatch"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let c=await e.getSignedCookie(e.context.authCookies.pkCodeVerifier.name,e.context.secret),s;try{s=await t.validateAuthorizationCode({code:e.query.code,codeVerifier:c,redirectURI:`${e.context.baseURL}/callback/${t.id}`})}catch(m){throw e.context.logger.error(m),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let d=await t.getUserInfo(s).then(m=>m?.user),l=v(),f=ct.safeParse({...d,id:l});if(!d||f.success===!1)throw b.error("Unable to get user info",f.error),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!o)throw e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);function u(m){throw e.redirect(`${i||o||`${e.context.baseURL}/error`}?error=${m}`)}let p=await e.context.internalAdapter.findUserByEmail(d.email,{includeAccounts:!0}).catch(m=>{throw b.error(`Better auth was unable to query your database.
2
+ `)}}),b=de();var T=M(async e=>{let{body:t,query:r,headers:o,context:i}=e,n=t?.callbackURL||r?.callbackURL||r?.redirectTo||t?.redirectTo,a=r?.currentURL||o?.get("referer")||i.baseURL,c=i.trustedOrigins,s=(d,l)=>{if(d?.startsWith("http")&&!c.some(u=>d.startsWith(u)))throw b.error(`Invalid ${l}`,{[l]:d,trustedOrigins:c}),new tr("FORBIDDEN",{message:`Invalid ${l}`})};s(n,"callbackURL"),s(a,"currentURL")});import{parseJWT as ir}from"oslo/jwt";import{sha256 as rr}from"oslo/crypto";import{base64url as or}from"oslo/encoding";async function Ve(e){let t=await rr(new TextEncoder().encode(e));return or.encode(new Uint8Array(t),{includePadding:!1})}function $e(e){return{tokenType:e.token_type,accessToken:e.access_token,refreshToken:e.refresh_token,accessTokenExpiresAt:e.expires_at?new Date((Date.now()+e.expires_in)*1e3):void 0,scopes:e?.scope?typeof e.scope=="string"?e.scope.split(" "):e.scope:[],idToken:e.id_token}}async function k({id:e,options:t,authorizationEndpoint:r,state:o,codeVerifier:i,scopes:n,claims:a,disablePkce:c,redirectURI:s}){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||s),!c&&i){let l=await Ve(i);d.searchParams.set("code_challenge_method","S256"),d.searchParams.set("code_challenge",l)}if(a){let l=a.reduce((f,u)=>(f[u]=null,f),{});d.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...l}}))}return d}import{betterFetch as nr}from"@better-fetch/fetch";async function A({code:e,codeVerifier:t,redirectURI:r,options:o,tokenEndpoint:i}){let n=new URLSearchParams;n.set("grant_type","authorization_code"),n.set("code",e),t&&n.set("code_verifier",t),n.set("redirect_uri",r),n.set("client_id",o.clientId),n.set("client_secret",o.clientSecret);let{data:a,error:c}=await nr(i,{method:"POST",body:n,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(c)throw c;return $e(a)}function ce(e){let t=e.accessToken,r=e.refreshToken,o;try{o=e.accessTokenExpiresAt}catch{}return{accessToken:t,refreshToken:r,expiresAt:o}}var ze=e=>{let t="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:r,scopes:o,redirectURI:i}){let n=e.scope||o||["email","name","openid"];return 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}`)},validateAuthorizationCode:async({code:r,codeVerifier:o,redirectURI:i})=>A({code:r,codeVerifier:o,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:t}),async getUserInfo(r){if(!r.idToken)return null;let o=ir(r.idToken)?.payload;return o?{user:{id:o.sub,name:o.name,email:o.email,emailVerified:o.email_verified==="true"},data:o}:null}}};import{betterFetch as sr}from"@better-fetch/fetch";var je=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=e.scope||r||["identify","email"];return 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}`)},validateAuthorizationCode:async({code:t,redirectURI:r})=>A({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await sr("https://discord.com/api/users/@me",{headers:{authorization:`Bearer ${t.accessToken}`}});if(o)return null;if(r.avatar===null){let i=r.discriminator==="0"?Number(BigInt(r.id)>>BigInt(22))%6:parseInt(r.discriminator)%5;r.image_url=`https://cdn.discordapp.com/embed/avatars/${i}.png`}else{let i=r.avatar.startsWith("a_")?"gif":"png";r.image_url=`https://cdn.discordapp.com/avatars/${r.id}/${r.avatar}.${i}`}return{user:{id:r.id,name:r.display_name||r.username||"",email:r.email,emailVerified:r.verified,image:r.image_url},data:r}}});import{betterFetch as ar}from"@better-fetch/fetch";var Me=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=e.scope||r||["email","public_profile"];return await k({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})=>A({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://graph.facebook.com/oauth/access_token"}),async getUserInfo(t){let{data:r,error:o}=await ar("https://graph.facebook.com/me?fields=id,name,email,picture",{auth:{type:"Bearer",token:t.accessToken}});return o?null:{user:{id:r.id,name:r.name,email:r.email,image:r.picture.data.url,emailVerified:r.email_verified},data:r}}});import{betterFetch as He}from"@better-fetch/fetch";var Ke=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 a=e.scope||o||["user:email"];return k({id:"github",options:e,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:a,state:r,redirectURI:n,codeVerifier:i})},validateAuthorizationCode:async({code:r,redirectURI:o})=>A({code:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:t}),async getUserInfo(r){let{data:o,error:i}=await He("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:a,error:c}=await He("https://api.github.com/user/emails",{headers:{authorization:`Bearer ${r.accessToken}`,"User-Agent":"better-auth"}});c||(o.email=(a.find(s=>s.primary)??a[0])?.email,n=a.find(s=>s.email===o.email)?.verified??!1)}return{user:{id:o.id.toString(),name:o.name||o.login,email:o.email,image:o.avatar_url,emailVerified:n},data:o}}}};import{parseJWT as dr}from"oslo/jwt";var Ze=e=>({id:"google",name:"Google",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:i}){if(!e.clientId||!e.clientSecret)throw b.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new O("CLIENT_ID_AND_SECRET_REQUIRED");if(!o)throw new O("codeVerifier is required for Google");let n=e.scope||r||["email","profile"];return k({id:"google",options:e,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:n,state:t,codeVerifier:o,redirectURI:i})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>A({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://oauth2.googleapis.com/token"}),async getUserInfo(t){if(!t.idToken)return null;let r=dr(t.idToken)?.payload;return{user:{id:r.sub,name:r.name,email:r.email,image:r.picture,emailVerified:r.email_verified},data:r}}});import{betterFetch as cr}from"@better-fetch/fetch";import{parseJWT as lr}from"oslo/jwt";var Ge=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=e.scope||i.scopes||["openid","profile","email","User.Read"];return k({id:"microsoft",options:e,authorizationEndpoint:r,state:i.state,codeVerifier:i.codeVerifier,scopes:n,redirectURI:i.redirectURI})},validateAuthorizationCode({code:i,codeVerifier:n,redirectURI:a}){return A({code:i,codeVerifier:n,redirectURI:e.redirectURI||a,options:e,tokenEndpoint:o})},async getUserInfo(i){if(!i.idToken)return null;let n=lr(i.idToken)?.payload,a=e.profilePhotoSize||48;return await cr(`https://graph.microsoft.com/v1.0/me/photos/${a}x${a}/$value`,{headers:{Authorization:`Bearer ${i.accessToken}`},async onResponse(c){if(!(e.disableProfilePhoto||!c.response.ok))try{let d=await c.response.clone().arrayBuffer(),l=Buffer.from(d).toString("base64");n.picture=`data:image/jpeg;base64, ${l}`}catch(s){b.error(s)}}}),{user:{id:n.sub,name:n.name,email:n.email,image:n.picture,emailVerified:!0},data:n}}}};import{betterFetch as ur}from"@better-fetch/fetch";var Qe=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:i}){let n=e.scope||r||["user-read-email"];return k({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})=>A({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://accounts.spotify.com/api/token"}),async getUserInfo(t){let{data:r,error:o}=await ur("https://api.spotify.com/v1/me",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});return o?null:{user:{id:r.id,name:r.display_name,email:r.email,image:r.images[0]?.url,emailVerified:!1},data:r}}});import"@better-fetch/fetch";function En(e){return e.charAt(0).toUpperCase()+e.slice(1)}var N={isAction:!1};import{nanoid as pr}from"nanoid";var v=e=>pr(e);import{parseJWT as fr}from"oslo/jwt";var We=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=e.scope||r||["user:read:email","openid"];return k({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})=>A({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){let r=t.idToken;if(!r)return b.error("No idToken found in token"),null;let o=fr(r)?.payload;return{user:{id:o.sub,name:o.preferred_username,email:o.email,image:o.picture,emailVerified:!1},data:o}}});import{betterFetch as mr}from"@better-fetch/fetch";var Je=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(t){let r=e.scope||t.scopes||["account_info.read"];return k({id:"twitter",options:e,authorizationEndpoint:"https://twitter.com/i/oauth2/authorize",scopes:r,state:t.state,codeVerifier:t.codeVerifier,redirectURI:t.redirectURI})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>A({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await mr("https://api.x.com/2/users/me?user.fields=profile_image_url",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});return o||!r.data.email?null:{user:{id:r.data.id,name:r.data.name,email:r.data.email,image:r.data.profile_image_url,emailVerified:r.data.verified||!1},data:r}}});import{betterFetch as gr}from"@better-fetch/fetch";var Ye=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 a=e.scope||o||["account_info.read"];return await k({id:"dropbox",options:e,authorizationEndpoint:"https://www.dropbox.com/oauth2/authorize",scopes:a,state:r,redirectURI:n,codeVerifier:i})},validateAuthorizationCode:async({code:r,codeVerifier:o,redirectURI:i})=>await A({code:r,codeVerifier:o,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:t}),async getUserInfo(r){let{data:o,error:i}=await gr("https://api.dropboxapi.com/2/users/get_current_account",{method:"POST",headers:{Authorization:`Bearer ${r.accessToken}`}});return i?null:{user:{id:o.account_id,name:o.name?.display_name,email:o.email,emailVerified:o.email_verified||!1,image:o.profile_photo_url},data:o}}}};import{betterFetch as hr}from"@better-fetch/fetch";var Xe=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 a=e.scope||i||["profile","email","openid"];return await k({id:"linkedin",options:e,authorizationEndpoint:t,scopes:a,state:o,redirectURI:n})},validateAuthorizationCode:async({code:o,redirectURI:i})=>await A({code:o,redirectURI:e.redirectURI||i,options:e,tokenEndpoint:r}),async getUserInfo(o){let{data:i,error:n}=await hr("https://api.linkedin.com/v2/userinfo",{method:"GET",headers:{Authorization:`Bearer ${o.accessToken}`}});return n?null:{user:{id:i.sub,name:i.name,email:i.email,emailVerified:i.email_verified||!1,image:i.picture},data:i}}}};var le={apple:ze,discord:je,facebook:Me,github:Ke,microsoft:Ge,google:Ze,spotify:Qe,twitch:We,twitter:Je,dropbox:Ye,linkedin:Xe},et=Object.keys(le);import{TimeSpan as yr}from"oslo";import{createJWT as wr,validateJWT as br}from"oslo/jwt";import{z as P}from"zod";import{APIError as H}from"better-call";import{APIError as Q}from"better-call";var $=(e,t="ms")=>new Date(Date.now()+(t==="sec"?e*1e3:e));import{z as tt}from"zod";var ue=()=>y("/session",{method:"GET",requireHeaders:!0},async e=>{try{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)return e.json(null,{status:401});let r=await e.context.internalAdapter.findSession(t);if(!r||r.session.expiresAt<new Date)return G(e),r&&await e.context.internalAdapter.deleteSession(r.session.id),e.json(null,{status:401});if(await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret))return e.json(r);let i=e.context.sessionConfig.expiresIn,n=e.context.sessionConfig.updateAge;if(r.session.expiresAt.valueOf()-i*1e3+n*1e3<=Date.now()){let s=await e.context.internalAdapter.updateSession(r.session.id,{expiresAt:$(e.context.sessionConfig.expiresIn,"sec")});if(!s)return G(e),e.json(null,{status:401});let d=(s.expiresAt.valueOf()-Date.now())/1e3;return await _(e,s.id,!1,{maxAge:d}),e.json({session:s,user:r.user})}return e.json(r)}catch(t){return e.context.logger.error(t),e.json(null,{status:500})}}),pe=async e=>await ue()({...e,_flag:"json",headers:e.headers}),C=M(async e=>{let t=await pe(e);if(!t?.session)throw new Q("UNAUTHORIZED");return{session:t}}),rt=()=>y("/user/list-sessions",{method:"GET",use:[C],requireHeaders:!0},async e=>{let r=(await e.context.internalAdapter.listSessions(e.context.session.user.id)).filter(o=>o.expiresAt>new Date);return e.json(r)}),ot=y("/user/revoke-session",{method:"POST",body:tt.object({id:tt.string()}),use:[C],requireHeaders:!0},async e=>{let t=e.body.id,r=await e.context.internalAdapter.findSession(t);if(!r)throw new Q("BAD_REQUEST",{message:"Session not found"});if(r.session.userId!==e.context.session.user.id)throw new Q("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(t)}catch(o){throw e.context.logger.error(o),new Q("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),nt=y("/user/revoke-sessions",{method:"POST",use:[C],requireHeaders:!0},async e=>{try{await e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(t){throw e.context.logger.error(t),new Q("INTERNAL_SERVER_ERROR")}return e.json({status:!0})});async function B(e,t,r){return await wr("HS256",Buffer.from(e),{email:t.toLowerCase(),updateTo:r},{expiresIn:new yr(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}var it=y("/send-verification-email",{method:"POST",query:P.object({currentURL:P.string().optional()}).optional(),body:P.object({email:P.string().email(),callbackURL:P.string().optional()}),use:[T]},async e=>{if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new H("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:t}=e.body,r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw new H("BAD_REQUEST",{message:"User not found"});let o=await B(e.context.secret,t),i=`${e.context.baseURL}/verify-email?token=${o}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.emailVerification.sendVerificationEmail(r.user,i,o),e.json({status:!0})}),st=y("/verify-email",{method:"GET",query:P.object({token:P.string(),callbackURL:P.string().optional()}),use:[T]},async e=>{let{token:t}=e.query,r;try{r=await br("HS256",Buffer.from(e.context.secret),t)}catch(a){throw e.context.logger.error("Failed to verify email",a),new H("BAD_REQUEST",{message:"Invalid token"})}let i=P.object({email:P.string().email(),updateTo:P.string().optional()}).parse(r.payload);if(!await e.context.internalAdapter.findUserByEmail(i.email))throw new H("BAD_REQUEST",{message:"User not found"});if(i.updateTo){let a=await pe(e);if(!a)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new H("UNAUTHORIZED",{message:"Session not found"});if(a.user.email!==i.email)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new H("UNAUTHORIZED",{message:"Invalid session"});let c=await e.context.internalAdapter.updateUserByEmail(i.email,{email:i.updateTo});if(await e.context.options.emailVerification?.sendVerificationEmail?.(c,`${e.context.baseURL}/verify-email?token=${t}`,t),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:c,status:!0})}if(await e.context.internalAdapter.updateUserByEmail(i.email,{emailVerified:!0}),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:null,status:!0})});var at=y("/sign-in/social",{method:"POST",requireHeaders:!0,query:I.object({currentURL:I.string().optional()}).optional(),body:I.object({callbackURL:I.string().optional(),provider:I.enum(et)}),use:[T]},async e=>{let t=e.context.socialProviders.find(s=>s.id===e.body.provider);if(!t)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new S("NOT_FOUND",{message:"Provider not found"});let r=e.context.authCookies,o=e.query?.currentURL?new URL(e.query?.currentURL):null,i=e.body.callbackURL?.startsWith("http")?e.body.callbackURL:`${o?.origin}${e.body.callbackURL||""}`,n=await Be(i||o?.origin||e.context.options.baseURL);await e.setSignedCookie(r.state.name,n.hash,e.context.secret,r.state.options);let a=Ar();await e.setSignedCookie(r.pkCodeVerifier.name,a,e.context.secret,r.pkCodeVerifier.options);let c=await t.createAuthorizationURL({state:n.raw,codeVerifier:a,redirectURI:`${e.context.baseURL}/callback/${t.id}`});return e.json({url:c.toString(),state:n,codeVerifier:a,redirect:!0})}),dt=y("/sign-in/email",{method:"POST",body:I.object({email:I.string(),password:I.string(),callbackURL:I.string().optional(),dontRememberMe:I.boolean().default(!1).optional()}),use:[T]},async e=>{if(!e.context.options?.emailAndPassword?.enabled)throw e.context.logger.error("Email and password is not enabled. Make sure to enable it in the options on you `auth.ts` file. Check `https://better-auth.com/docs/authentication/email-password` for more!"),new S("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:t,password:r}=e.body;if(!I.string().email().safeParse(t).success)throw new S("BAD_REQUEST",{message:"Invalid email"});if(!I.string().email().safeParse(t).success)throw new S("BAD_REQUEST",{message:"Invalid email"});let n=await e.context.internalAdapter.findUserByEmail(t,{includeAccounts:!0});if(!n)throw await e.context.password.hash(r),e.context.logger.error("User not found",{email:t}),new S("UNAUTHORIZED",{message:"Invalid email or password"});let a=n.accounts.find(l=>l.providerId==="credential");if(!a)throw e.context.logger.error("Credential account not found",{email:t}),new S("UNAUTHORIZED",{message:"Invalid email or password"});let c=a?.password;if(!c)throw e.context.logger.error("Password not found",{email:t}),new S("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(c,r))throw e.context.logger.error("Invalid password"),new S("UNAUTHORIZED",{message:"Invalid email or password"});if(e.context.options?.emailAndPassword?.requireEmailVerification&&!n.user.emailVerified){if(!e.context.options?.emailVerification?.sendVerificationEmail)throw b.error("Email verification is required but no email verification handler is provided"),new S("INTERNAL_SERVER_ERROR",{message:"Email is not verified."});let l=await B(e.context.secret,n.user.email),f=`${e.context.options.baseURL}/verify-email?token=${l}`;throw await e.context.options.emailVerification.sendVerificationEmail(n.user,f,l),e.context.logger.error("Email not verified",{email:t}),new S("FORBIDDEN",{message:"Email is not verified. Check your email for a verification link"})}let d=await e.context.internalAdapter.createSession(n.user.id,e.headers,e.body.dontRememberMe);if(!d)throw e.context.logger.error("Failed to create session"),new S("UNAUTHORIZED",{message:"Failed to create session"});return await _(e,d.id,e.body.dontRememberMe),e.json({user:n.user,session:d,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});import{z as re}from"zod";import{z as w}from"zod";var Wi=w.object({id:w.string(),providerId:w.string(),accountId:w.string(),userId:w.string(),accessToken:w.string().nullable().optional(),refreshToken:w.string().nullable().optional(),idToken:w.string().nullable().optional(),expiresAt:w.date().nullable().optional(),password:w.string().optional().nullable()}),ct=w.object({id:w.string(),email:w.string().transform(e=>e.toLowerCase()),emailVerified:w.boolean().default(!1),name:w.string(),image:w.string().optional(),createdAt:w.date().default(new Date),updatedAt:w.date().default(new Date)}),Ji=w.object({id:w.string(),userId:w.string(),expiresAt:w.date(),ipAddress:w.string().optional(),userAgent:w.string().optional()}),Yi=w.object({id:w.string(),value:w.string(),expiresAt:w.date(),identifier:w.string()});function lt(e,t){let r={...t==="user"?e.user?.additionalFields:{},...t==="session"?e.session?.additionalFields:{}};for(let o of e.plugins||[])o.schema&&o.schema[t]&&(r={...r,...o.schema[t].fields});return r}function ut(e,t){let r=t.fields,o={};for(let i in r){if(i in e){if(r[i].input===!1){if(r[i].defaultValue){o[i]=r[i].defaultValue;continue}continue}o[i]=e[i];continue}if(r[i].defaultValue){o[i]=r[i].defaultValue;continue}}return o}function pt(e,t){let r=lt(e,"user");return ut(t||{},{fields:r})}function ft(e,t){let r=lt(e,"user");return ut(t||{},{fields:r})}var mt=y("/callback/:id",{method:"GET",query:re.object({state:re.string(),code:re.string().optional(),error:re.string().optional()}),metadata:N},async e=>{if(e.query.error||!e.query.code){let x=ae(e.query.state).data?.callbackURL||`${e.context.baseURL}/error`;throw e.context.logger.error(e.query.error,e.params.id),e.redirect(`${x}?error=${e.query.error||"oAuth_code_missing"}`)}let t=e.context.socialProviders.find(m=>m.id===e.params.id);if(!t)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 r=ae(e.query.state);if(!r.success)throw e.context.logger.error("Unable to parse state"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let{data:{callbackURL:o,currentURL:i}}=r,n=await e.getSignedCookie(e.context.authCookies.state.name,e.context.secret);if(!n)throw b.error("No stored state found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!await Ce(e.query.state,n))throw b.error("OAuth state mismatch"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let c=await e.getSignedCookie(e.context.authCookies.pkCodeVerifier.name,e.context.secret),s;try{s=await t.validateAuthorizationCode({code:e.query.code,codeVerifier:c,redirectURI:`${e.context.baseURL}/callback/${t.id}`})}catch(m){throw e.context.logger.error(m),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let d=await t.getUserInfo(s).then(m=>m?.user),l=v(),f=ct.safeParse({...d,id:l});if(!d||f.success===!1)throw b.error("Unable to get user info",f.error),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!o)throw e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);function u(m){throw e.redirect(`${i||o||`${e.context.baseURL}/error`}?error=${m}`)}let p=await e.context.internalAdapter.findUserByEmail(d.email,{includeAccounts:!0}).catch(m=>{throw b.error(`Better auth was unable to query your database.
3
3
  Error: `,m),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)}),g=p?.user.id;if(p){if(!p.accounts.find(x=>x.providerId===t.id)){(!e.context.options.account?.accountLinking?.trustedProviders?.includes(t.id)&&!d.emailVerified||!e.context.options.account?.accountLinking?.enabled)&&u("account_not_linked");try{await e.context.internalAdapter.linkAccount({providerId:t.id,accountId:d.id.toString(),id:`${t.id}:${d.id}`,userId:p.user.id,...ce(s)})}catch(q){b.error("Unable to link account",q),u("unable_to_link_account")}}}else try{let m=d.emailVerified||!1,x=await e.context.internalAdapter.createOAuthUser({...f.data,emailVerified:m},{...ce(s),providerId:t.id,accountId:d.id.toString()});if(g=x?.user.id,!m&&x&&e.context.options.emailVerification?.sendOnSignUp){let Z=await B(e.context.secret,d.email),q=`${e.context.baseURL}/verify-email?token=${Z}&callbackURL=${o}`;await e.context.options.emailVerification?.sendVerificationEmail?.(x.user,q,Z)}}catch(m){b.error("Unable to create user",m),u("unable_to_create_user")}g||u("unable_to_create_user");let h=await e.context.internalAdapter.createSession(g,e.request);throw h||u("unable_to_create_session"),await _(e,h.id),e.redirect(o)});import"zod";import{APIError as kr}from"better-call";var gt=y("/sign-out",{method:"POST"},async e=>{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)throw new kr("BAD_REQUEST",{message:"Session not found"});return await e.context.internalAdapter.deleteSession(t),G(e),e.json({success:!0})});import{z as L}from"zod";import{APIError as oe}from"better-call";var ht=y("/forget-password",{method:"POST",body:L.object({email:L.string().email(),redirectTo:L.string()}),use:[T]},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 oe("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=new Date(Date.now()+1e3*(e.context.options.emailAndPassword.resetPasswordTokenExpiresIn||i)),a=e.context.uuid();await e.context.internalAdapter.createVerificationValue({value:o.user.id,identifier:`reset-password:${a}`,expiresAt:n});let c=`${e.context.baseURL}/reset-password/${a}?callbackURL=${r}`;return await e.context.options.emailAndPassword.sendResetPassword(o.user,c),e.json({status:!0})}),yt=y("/reset-password/:token",{method:"GET",query:L.object({callbackURL:L.string()}),use:[T]},async e=>{let{token:t}=e.params,r=e.query.callbackURL,o=r.startsWith("http")?r:`${e.context.options.baseURL}${r}`;if(!t||!r)throw e.redirect(`${e.context.baseURL}/error?error=INVALID_TOKEN`);let i=await e.context.internalAdapter.findVerificationValue(`reset-password:${t}`);throw!i||i.expiresAt<new Date?e.redirect(`${o}?error=INVALID_TOKEN`):e.redirect(`${o}?token=${t}`)}),wt=y("/reset-password",{query:L.optional(L.object({token:L.string().optional(),currentURL:L.string().optional()})),method:"POST",body:L.object({newPassword:L.string()})},async e=>{let t=e.query?.token||(e.query?.currentURL?new URL(e.query.currentURL).searchParams.get("token"):"");if(!t)throw new oe("BAD_REQUEST",{message:"Token not found"});let{newPassword:r}=e.body,o=`reset-password:${t}`,i=await e.context.internalAdapter.findVerificationValue(o);if(!i||i.expiresAt<new Date)throw new oe("BAD_REQUEST",{message:"Invalid token"});await e.context.internalAdapter.deleteVerificationValue(i.id);let n=i.value,a=await e.context.password.hash(r);if(!(await e.context.internalAdapter.findAccounts(n)).find(l=>l.providerId==="credential"))return await e.context.internalAdapter.createAccount({userId:n,providerId:"credential",password:a,accountId:e.context.uuid()}),e.json({status:!0});if(!await e.context.internalAdapter.updatePassword(n,a))throw new oe("BAD_REQUEST",{message:"Failed to update password"});return e.json({status:!0})});import{z as R}from"zod";import{APIError as U}from"better-call";var bt=()=>y("/user/update",{method:"POST",body:R.record(R.string(),R.any()),use:[C,T]},async e=>{let t=e.body;if(t.email)throw new U("BAD_REQUEST",{message:"You can't update email"});let{name:r,image:o,...i}=t,n=e.context.session;if(!o&&!r&&Object.keys(i).length===0)return e.json({user:n.user});let a=pt(e.context.options,i),c=await e.context.internalAdapter.updateUserByEmail(n.user.email,{name:r,image:o,...a});return e.json({user:c})}),At=y("/user/change-password",{method:"POST",body:R.object({newPassword:R.string(),currentPassword:R.string(),revokeOtherSessions:R.boolean().optional()}),use:[C]},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 U("BAD_REQUEST",{message:"Password is too short"});let a=e.context.password.config.maxPasswordLength;if(t.length>a)throw e.context.logger.error("Password is too long"),new U("BAD_REQUEST",{message:"Password too long"});let s=(await e.context.internalAdapter.findAccounts(i.user.id)).find(f=>f.providerId==="credential"&&f.password);if(!s||!s.password)throw new U("BAD_REQUEST",{message:"User does not have a password"});let d=await e.context.password.hash(t);if(!await e.context.password.verify(s.password,r))throw new U("BAD_REQUEST",{message:"Incorrect password"});if(await e.context.internalAdapter.updateAccount(s.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 U("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});await _(e,f.id)}return e.json(i.user)}),kt=y("/user/set-password",{method:"POST",body:R.object({newPassword:R.string()}),use:[C]},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 U("BAD_REQUEST",{message:"Password is too short"});let i=e.context.password.config.maxPasswordLength;if(t.length>i)throw e.context.logger.error("Password is too long"),new U("BAD_REQUEST",{message:"Password too long"});let a=(await e.context.internalAdapter.findAccounts(r.user.id)).find(s=>s.providerId==="credential"&&s.password),c=await e.context.password.hash(t);if(!a)return await e.context.internalAdapter.linkAccount({userId:r.user.id,providerId:"credential",accountId:r.user.id,password:c}),e.json(r.user);throw new U("BAD_REQUEST",{message:"user already has a password"})}),Rt=y("/user/delete",{method:"POST",body:R.object({password:R.string()}),use:[C]},async e=>{let{password:t}=e.body,r=e.context.session,i=(await e.context.internalAdapter.findAccounts(r.user.id)).find(c=>c.providerId==="credential"&&c.password);if(!i||!i.password)throw new U("BAD_REQUEST",{message:"User does not have a password"});if(!await e.context.password.verify(i.password,t))throw new U("BAD_REQUEST",{message:"Incorrect password"});await e.context.internalAdapter.deleteUser(r.user.id),await e.context.internalAdapter.deleteSessions(r.user.id);let a=e.context.authCookies.sessionToken;return e.setCookie(a.name,"",{maxAge:0}),e.json(null)}),xt=y("/user/change-email",{method:"POST",query:R.object({currentURL:R.string().optional()}).optional(),body:R.object({newEmail:R.string().email(),callbackURL:R.string().optional()}),use:[C,T]},async e=>{if(!e.context.options.user?.changeEmail?.enabled)throw e.context.logger.error("Change email is disabled."),new U("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 U("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 U("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 U("BAD_REQUEST",{message:"Verification email isn't enabled"});let r=await B(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(e.context.session.user,e.body.newEmail,o,r),e.json({user:null,status:!0})});var Ut=y("/csrf",{method:"GET",metadata:N},async e=>{let t=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret);if(t){let[n,a]=t.split("!")||[null,null];return e.json({csrfToken:n})}let r=Te(32,ve("a-z","0-9","A-Z")),o=await ee(e.context.secret,r),i=`${r}!${o}`;return await e.setSignedCookie(e.context.authCookies.csrfToken.name,i,e.context.secret,e.context.authCookies.csrfToken.options),e.json({csrfToken:r})});var Rr=(e="Unknown")=>`<!DOCTYPE html>
4
4
  <html lang="en">
5
5
  <head>
package/dist/plugins.js CHANGED
@@ -1,5 +1,5 @@
1
1
  var wr=Object.defineProperty;var yr=(e,t)=>{for(var r in t)wr(e,r,{get:t[r],enumerable:!0})};import{APIError as Xt}from"better-call";import{z as Ie}from"zod";import{createEndpointCreator as br,createMiddleware as nt,createMiddlewareCreator as Ar}from"better-call";var it=nt(async()=>({})),T=Ar({use:[it,nt(async()=>({}))]}),u=br({use:[it]});import{APIError as J}from"better-call";import{generateCodeVerifier as Kr}from"oslo/oauth2";import{z as V}from"zod";import{generateState as kr}from"oslo/oauth2";import{z as _e}from"zod";import{sha256 as st}from"oslo/crypto";function Ze(e,t){let r=new Uint8Array(e),o=new Uint8Array(t);if(r.length!==o.length)return!1;let n=0;for(let i=0;i<r.length;i++)n|=r[i]^o[i];return n===0}async function at(e){let t=await st(typeof e=="string"?new TextEncoder().encode(e):e);return Buffer.from(t).toString("base64")}async function Ce(e,t){let r=await st(typeof e=="string"?new TextEncoder().encode(e):e),o=Buffer.from(t,"base64");return Ze(r,o)}import"better-call";async function ze(e){let t=kr(),r=JSON.stringify({code:t,callbackURL:e}),o=await at(r);return{raw:r,hash:o}}function ge(e){return _e.object({code:_e.string(),callbackURL:_e.string().optional(),currentURL:_e.string().optional()}).safeParse(JSON.parse(e))}import{TimeSpan as wn}from"oslo";var $=class extends Error{constructor(t,r){super(t),this.name="BetterAuthError",this.message=t,this.cause=r}};import{env as An,isProduction as kn}from"std-env";async function A(e,t,r,o){let n=e.context.authCookies.sessionToken.options;n.maxAge=r?void 0:e.context.sessionConfig.expiresIn,await e.setSignedCookie(e.context.authCookies.sessionToken.name,t,e.context.secret,{...n,...o}),r&&await e.setSignedCookie(e.context.authCookies.dontRememberToken.name,"true",e.context.secret,e.context.authCookies.dontRememberToken.options)}function ke(e){e.setCookie(e.context.authCookies.sessionToken.name,"",{maxAge:0}),e.setCookie(e.context.authCookies.dontRememberToken.name,"",{maxAge:0})}function dt(e){let t=new Map;return e.split(", ").forEach(o=>{let[n,...i]=o.split("; "),[a,s]=n.split("="),d={value:s};i.forEach(c=>{let[l,p]=c.split("=");d[l.toLowerCase()]=p||!0}),t.set(a,d)}),t}function Be(e){let t=e.split("; "),r=new Map;return t.forEach(o=>{let[n,i]=o.split("=");r.set(n,i)}),r}import{APIError as vr}from"better-call";import{createConsola as Or}from"consola";var ce=Or({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),Rr=e=>({log:(...t)=>{!e?.disabled&&ce.log("",...t)},error:(...t)=>{!e?.disabled&&ce.error("",...t)},warn:(...t)=>{!e?.disabled&&ce.warn("",...t)},info:(...t)=>{!e?.disabled&&ce.info("",...t)},debug:(...t)=>{!e?.disabled&&ce.debug("",...t)},box:(...t)=>{!e?.disabled&&ce.box("",...t)},success:(...t)=>{!e?.disabled&&ce.success("",...t)},break:(...t)=>{!e?.disabled&&console.log(`
2
- `)}}),b=Rr();var _=T(async e=>{let{body:t,query:r,headers:o,context:n}=e,i=t?.callbackURL||r?.callbackURL||r?.redirectTo||t?.redirectTo,a=r?.currentURL||o?.get("referer")||n.baseURL,s=n.trustedOrigins,d=(c,l)=>{if(c?.startsWith("http")&&!s.some(f=>c.startsWith(f)))throw b.error(`Invalid ${l}`,{[l]:c,trustedOrigins:s}),new vr("FORBIDDEN",{message:`Invalid ${l}`})};d(i,"callbackURL"),d(a,"currentURL")});import{parseJWT as Tr}from"oslo/jwt";import{sha256 as Ir}from"oslo/crypto";import{base64url as Ur}from"oslo/encoding";async function ct(e){let t=await Ir(new TextEncoder().encode(e));return Ur.encode(new Uint8Array(t),{includePadding:!1})}function ut(e){return{tokenType:e.token_type,accessToken:e.access_token,refreshToken:e.refresh_token,accessTokenExpiresAt:e.expires_at?new Date((Date.now()+e.expires_in)*1e3):void 0,scopes:e?.scope?typeof e.scope=="string"?e.scope.split(" "):e.scope:[],idToken:e.id_token}}async function U({id:e,options:t,authorizationEndpoint:r,state:o,codeVerifier:n,scopes:i,claims:a,disablePkce:s,redirectURI:d}){let c=new URL(r);if(c.searchParams.set("response_type","code"),c.searchParams.set("client_id",t.clientId),c.searchParams.set("state",o),c.searchParams.set("scope",i.join(" ")),c.searchParams.set("redirect_uri",t.redirectURI||d),!s&&n){let l=await ct(n);c.searchParams.set("code_challenge_method","S256"),c.searchParams.set("code_challenge",l)}if(a){let l=a.reduce((p,f)=>(p[f]=null,p),{});c.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...l}}))}return c}import{betterFetch as Er}from"@better-fetch/fetch";async function O({code:e,codeVerifier:t,redirectURI:r,options:o,tokenEndpoint:n}){let i=new URLSearchParams;i.set("grant_type","authorization_code"),i.set("code",e),t&&i.set("code_verifier",t),i.set("redirect_uri",r),i.set("client_id",o.clientId),i.set("client_secret",o.clientSecret);let{data:a,error:s}=await Er(n,{method:"POST",body:i,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(s)throw s;return ut(a)}function he(e){let t=e.accessToken,r=e.refreshToken,o;try{o=e.accessTokenExpiresAt}catch{}return{accessToken:t,refreshToken:r,expiresAt:o}}var lt=e=>{let t="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:r,scopes:o,redirectURI:n}){let i=e.scope||o||["email","name","openid"];return new URL(`https://appleid.apple.com/auth/authorize?client_id=${e.clientId}&response_type=code&redirect_uri=${n||e.redirectURI}&scope=${i.join(" ")}&state=${r}`)},validateAuthorizationCode:async({code:r,codeVerifier:o,redirectURI:n})=>O({code:r,codeVerifier:o,redirectURI:e.redirectURI||n,options:e,tokenEndpoint:t}),async getUserInfo(r){if(!r.idToken)return null;let o=Tr(r.idToken)?.payload;return o?{user:{id:o.sub,name:o.name,email:o.email,emailVerified:o.email_verified==="true"},data:o}:null}}};import{betterFetch as Sr}from"@better-fetch/fetch";var pt=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let n=e.scope||r||["identify","email"];return new URL(`https://discord.com/api/oauth2/authorize?scope=${n.join("+")}&response_type=code&client_id=${e.clientId}&redirect_uri=${encodeURIComponent(e.redirectURI||o)}&state=${t}`)},validateAuthorizationCode:async({code:t,redirectURI:r})=>O({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await Sr("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}`}return{user:{id:r.id,name:r.display_name||r.username||"",email:r.email,emailVerified:r.verified,image:r.image_url},data:r}}});import{betterFetch as Pr}from"@better-fetch/fetch";var mt=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let n=e.scope||r||["email","public_profile"];return await U({id:"facebook",options:e,authorizationEndpoint:"https://www.facebook.com/v21.0/dialog/oauth",scopes:n,state:t,redirectURI:o})},validateAuthorizationCode:async({code:t,redirectURI:r})=>O({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://graph.facebook.com/oauth/access_token"}),async getUserInfo(t){let{data:r,error:o}=await Pr("https://graph.facebook.com/me?fields=id,name,email,picture",{auth:{type:"Bearer",token:t.accessToken}});return o?null:{user:{id:r.id,name:r.name,email:r.email,image:r.picture.data.url,emailVerified:r.email_verified},data:r}}});import{betterFetch as ft}from"@better-fetch/fetch";var gt=e=>{let t="https://github.com/login/oauth/access_token";return{id:"github",name:"Github",createAuthorizationURL({state:r,scopes:o,codeVerifier:n,redirectURI:i}){let a=e.scope||o||["user:email"];return U({id:"github",options:e,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:a,state:r,redirectURI:i,codeVerifier:n})},validateAuthorizationCode:async({code:r,redirectURI:o})=>O({code:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:t}),async getUserInfo(r){let{data:o,error:n}=await ft("https://api.github.com/user",{headers:{"User-Agent":"better-auth",authorization:`Bearer ${r.accessToken}`}});if(n)return null;let i=!1;if(!o.email){let{data:a,error:s}=await ft("https://api.github.com/user/emails",{headers:{authorization:`Bearer ${r.accessToken}`,"User-Agent":"better-auth"}});s||(o.email=(a.find(d=>d.primary)??a[0])?.email,i=a.find(d=>d.email===o.email)?.verified??!1)}return{user:{id:o.id.toString(),name:o.name||o.login,email:o.email,image:o.avatar_url,emailVerified:i},data:o}}}};import{parseJWT as Cr}from"oslo/jwt";var ht=e=>({id:"google",name:"Google",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:n}){if(!e.clientId||!e.clientSecret)throw b.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new $("CLIENT_ID_AND_SECRET_REQUIRED");if(!o)throw new $("codeVerifier is required for Google");let i=e.scope||r||["email","profile"];return U({id:"google",options:e,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:i,state:t,codeVerifier:o,redirectURI:n})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>O({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://oauth2.googleapis.com/token"}),async getUserInfo(t){if(!t.idToken)return null;let r=Cr(t.idToken)?.payload;return{user:{id:r.sub,name:r.name,email:r.email,image:r.picture,emailVerified:r.email_verified},data:r}}});import{betterFetch as _r}from"@better-fetch/fetch";import{parseJWT as zr}from"oslo/jwt";var wt=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(n){let i=e.scope||n.scopes||["openid","profile","email","User.Read"];return U({id:"microsoft",options:e,authorizationEndpoint:r,state:n.state,codeVerifier:n.codeVerifier,scopes:i,redirectURI:n.redirectURI})},validateAuthorizationCode({code:n,codeVerifier:i,redirectURI:a}){return O({code:n,codeVerifier:i,redirectURI:e.redirectURI||a,options:e,tokenEndpoint:o})},async getUserInfo(n){if(!n.idToken)return null;let i=zr(n.idToken)?.payload,a=e.profilePhotoSize||48;return await _r(`https://graph.microsoft.com/v1.0/me/photos/${a}x${a}/$value`,{headers:{Authorization:`Bearer ${n.accessToken}`},async onResponse(s){if(!(e.disableProfilePhoto||!s.response.ok))try{let c=await s.response.clone().arrayBuffer(),l=Buffer.from(c).toString("base64");i.picture=`data:image/jpeg;base64, ${l}`}catch(d){b.error(d)}}}),{user:{id:i.sub,name:i.name,email:i.email,image:i.picture,emailVerified:!0},data:i}}}};import{betterFetch as Br}from"@better-fetch/fetch";var yt=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:n}){let i=e.scope||r||["user-read-email"];return U({id:"spotify",options:e,authorizationEndpoint:"https://accounts.spotify.com/authorize",scopes:i,state:t,codeVerifier:o,redirectURI:n})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>O({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://accounts.spotify.com/api/token"}),async getUserInfo(t){let{data:r,error:o}=await Br("https://api.spotify.com/v1/me",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});return o?null:{user:{id:r.id,name:r.display_name,email:r.email,image:r.images[0]?.url,emailVerified:!1},data:r}}});import"@better-fetch/fetch";var se={isAction:!1};import{nanoid as Lr}from"nanoid";var C=e=>Lr(e);import{parseJWT as Dr}from"oslo/jwt";var bt=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let n=e.scope||r||["user:read:email","openid"];return U({id:"twitch",redirectURI:o,options:e,authorizationEndpoint:"https://id.twitch.tv/oauth2/authorize",scopes:n,state:t,claims:e.claims||["email","email_verified","preferred_username","picture"]})},validateAuthorizationCode:async({code:t,redirectURI:r})=>O({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){let r=t.idToken;if(!r)return b.error("No idToken found in token"),null;let o=Dr(r)?.payload;return{user:{id:o.sub,name:o.preferred_username,email:o.email,image:o.picture,emailVerified:!1},data:o}}});import{betterFetch as xr}from"@better-fetch/fetch";var At=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(t){let r=e.scope||t.scopes||["account_info.read"];return U({id:"twitter",options:e,authorizationEndpoint:"https://twitter.com/i/oauth2/authorize",scopes:r,state:t.state,codeVerifier:t.codeVerifier,redirectURI:t.redirectURI})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>O({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await xr("https://api.x.com/2/users/me?user.fields=profile_image_url",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});return o||!r.data.email?null:{user:{id:r.data.id,name:r.data.name,email:r.data.email,image:r.data.profile_image_url,emailVerified:r.data.verified||!1},data:r}}});import{betterFetch as jr}from"@better-fetch/fetch";var kt=e=>{let t="https://api.dropboxapi.com/oauth2/token";return{id:"dropbox",name:"Dropbox",createAuthorizationURL:async({state:r,scopes:o,codeVerifier:n,redirectURI:i})=>{let a=e.scope||o||["account_info.read"];return await U({id:"dropbox",options:e,authorizationEndpoint:"https://www.dropbox.com/oauth2/authorize",scopes:a,state:r,redirectURI:i,codeVerifier:n})},validateAuthorizationCode:async({code:r,codeVerifier:o,redirectURI:n})=>await O({code:r,codeVerifier:o,redirectURI:e.redirectURI||n,options:e,tokenEndpoint:t}),async getUserInfo(r){let{data:o,error:n}=await jr("https://api.dropboxapi.com/2/users/get_current_account",{method:"POST",headers:{Authorization:`Bearer ${r.accessToken}`}});return n?null:{user:{id:o.account_id,name:o.name?.display_name,email:o.email,emailVerified:o.email_verified||!1,image:o.profile_photo_url},data:o}}}};import{betterFetch as Nr}from"@better-fetch/fetch";var Ot=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:n,redirectURI:i})=>{let a=e.scope||n||["profile","email","openid"];return await U({id:"linkedin",options:e,authorizationEndpoint:t,scopes:a,state:o,redirectURI:i})},validateAuthorizationCode:async({code:o,redirectURI:n})=>await O({code:o,redirectURI:e.redirectURI||n,options:e,tokenEndpoint:r}),async getUserInfo(o){let{data:n,error:i}=await Nr("https://api.linkedin.com/v2/userinfo",{method:"GET",headers:{Authorization:`Bearer ${o.accessToken}`}});return i?null:{user:{id:n.sub,name:n.name,email:n.email,emailVerified:n.email_verified||!1,image:n.picture},data:n}}}};var Fr={apple:lt,discord:pt,facebook:mt,github:gt,microsoft:wt,google:ht,spotify:yt,twitch:bt,twitter:At,dropbox:kt,linkedin:Ot},Rt=Object.keys(Fr);import{TimeSpan as $r}from"oslo";import{createJWT as Vr,validateJWT as Hr}from"oslo/jwt";import{z as Z}from"zod";import{APIError as we}from"better-call";import{APIError as Oe}from"better-call";var X=(e,t="ms")=>new Date(Date.now()+(t==="sec"?e*1e3:e));import{z as vt}from"zod";var It=()=>u("/session",{method:"GET",requireHeaders:!0},async e=>{try{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)return e.json(null,{status:401});let r=await e.context.internalAdapter.findSession(t);if(!r||r.session.expiresAt<new Date)return ke(e),r&&await e.context.internalAdapter.deleteSession(r.session.id),e.json(null,{status:401});if(await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret))return e.json(r);let n=e.context.sessionConfig.expiresIn,i=e.context.sessionConfig.updateAge;if(r.session.expiresAt.valueOf()-n*1e3+i*1e3<=Date.now()){let d=await e.context.internalAdapter.updateSession(r.session.id,{expiresAt:X(e.context.sessionConfig.expiresIn,"sec")});if(!d)return ke(e),e.json(null,{status:401});let c=(d.expiresAt.valueOf()-Date.now())/1e3;return await A(e,d.id,!1,{maxAge:c}),e.json({session:d,user:r.user})}return e.json(r)}catch(t){return e.context.logger.error(t),e.json(null,{status:500})}}),D=async e=>await It()({...e,_flag:"json",headers:e.headers}),w=T(async e=>{let t=await D(e);if(!t?.session)throw new Oe("UNAUTHORIZED");return{session:t}});var Mr=u("/user/revoke-session",{method:"POST",body:vt.object({id:vt.string()}),use:[w],requireHeaders:!0},async e=>{let t=e.body.id,r=await e.context.internalAdapter.findSession(t);if(!r)throw new Oe("BAD_REQUEST",{message:"Session not found"});if(r.session.userId!==e.context.session.user.id)throw new Oe("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(t)}catch(o){throw e.context.logger.error(o),new Oe("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),qr=u("/user/revoke-sessions",{method:"POST",use:[w],requireHeaders:!0},async e=>{try{await e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(t){throw e.context.logger.error(t),new Oe("INTERNAL_SERVER_ERROR")}return e.json({status:!0})});async function ae(e,t,r){return await Vr("HS256",Buffer.from(e),{email:t.toLowerCase(),updateTo:r},{expiresIn:new $r(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}var Qr=u("/send-verification-email",{method:"POST",query:Z.object({currentURL:Z.string().optional()}).optional(),body:Z.object({email:Z.string().email(),callbackURL:Z.string().optional()}),use:[_]},async e=>{if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new we("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:t}=e.body,r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw new we("BAD_REQUEST",{message:"User not found"});let o=await ae(e.context.secret,t),n=`${e.context.baseURL}/verify-email?token=${o}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.emailVerification.sendVerificationEmail(r.user,n,o),e.json({status:!0})}),Wr=u("/verify-email",{method:"GET",query:Z.object({token:Z.string(),callbackURL:Z.string().optional()}),use:[_]},async e=>{let{token:t}=e.query,r;try{r=await Hr("HS256",Buffer.from(e.context.secret),t)}catch(a){throw e.context.logger.error("Failed to verify email",a),new we("BAD_REQUEST",{message:"Invalid token"})}let n=Z.object({email:Z.string().email(),updateTo:Z.string().optional()}).parse(r.payload);if(!await e.context.internalAdapter.findUserByEmail(n.email))throw new we("BAD_REQUEST",{message:"User not found"});if(n.updateTo){let a=await D(e);if(!a)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new we("UNAUTHORIZED",{message:"Session not found"});if(a.user.email!==n.email)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new we("UNAUTHORIZED",{message:"Invalid session"});let s=await e.context.internalAdapter.updateUserByEmail(n.email,{email:n.updateTo});if(await e.context.options.emailVerification?.sendVerificationEmail?.(s,`${e.context.baseURL}/verify-email?token=${t}`,t),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:s,status:!0})}if(await e.context.internalAdapter.updateUserByEmail(n.email,{emailVerified:!0}),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:null,status:!0})});var Zr=u("/sign-in/social",{method:"POST",requireHeaders:!0,query:V.object({currentURL:V.string().optional()}).optional(),body:V.object({callbackURL:V.string().optional(),provider:V.enum(Rt)}),use:[_]},async e=>{let t=e.context.socialProviders.find(d=>d.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 J("NOT_FOUND",{message:"Provider not found"});let r=e.context.authCookies,o=e.query?.currentURL?new URL(e.query?.currentURL):null,n=e.body.callbackURL?.startsWith("http")?e.body.callbackURL:`${o?.origin}${e.body.callbackURL||""}`,i=await ze(n||o?.origin||e.context.options.baseURL);await e.setSignedCookie(r.state.name,i.hash,e.context.secret,r.state.options);let a=Kr();await e.setSignedCookie(r.pkCodeVerifier.name,a,e.context.secret,r.pkCodeVerifier.options);let s=await t.createAuthorizationURL({state:i.raw,codeVerifier:a,redirectURI:`${e.context.baseURL}/callback/${t.id}`});return e.json({url:s.toString(),state:i,codeVerifier:a,redirect:!0})}),Jr=u("/sign-in/email",{method:"POST",body:V.object({email:V.string(),password:V.string(),callbackURL:V.string().optional(),dontRememberMe:V.boolean().default(!1).optional()}),use:[_]},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 J("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:t,password:r}=e.body;if(!V.string().email().safeParse(t).success)throw new J("BAD_REQUEST",{message:"Invalid email"});if(!V.string().email().safeParse(t).success)throw new J("BAD_REQUEST",{message:"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 J("UNAUTHORIZED",{message:"Invalid email or password"});let a=i.accounts.find(l=>l.providerId==="credential");if(!a)throw e.context.logger.error("Credential account not found",{email:t}),new J("UNAUTHORIZED",{message:"Invalid email or password"});let s=a?.password;if(!s)throw e.context.logger.error("Password not found",{email:t}),new J("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(s,r))throw e.context.logger.error("Invalid password"),new J("UNAUTHORIZED",{message:"Invalid email or password"});if(e.context.options?.emailAndPassword?.requireEmailVerification&&!i.user.emailVerified){if(!e.context.options?.emailVerification?.sendVerificationEmail)throw b.error("Email verification is required but no email verification handler is provided"),new J("INTERNAL_SERVER_ERROR",{message:"Email is not verified."});let l=await ae(e.context.secret,i.user.email),p=`${e.context.options.baseURL}/verify-email?token=${l}`;throw await e.context.options.emailVerification.sendVerificationEmail(i.user,p,l),e.context.logger.error("Email not verified",{email:t}),new J("FORBIDDEN",{message:"Email is not verified. Check your email for a verification link"})}let c=await e.context.internalAdapter.createSession(i.user.id,e.headers,e.body.dontRememberMe);if(!c)throw e.context.logger.error("Failed to create session"),new J("UNAUTHORIZED",{message:"Failed to create session"});return await A(e,c.id,e.body.dontRememberMe),e.json({user:i.user,session:c,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});import{z as De}from"zod";import{z as y}from"zod";var js=y.object({id:y.string(),providerId:y.string(),accountId:y.string(),userId:y.string(),accessToken:y.string().nullable().optional(),refreshToken:y.string().nullable().optional(),idToken:y.string().nullable().optional(),expiresAt:y.date().nullable().optional(),password:y.string().optional().nullable()}),Le=y.object({id:y.string(),email:y.string().transform(e=>e.toLowerCase()),emailVerified:y.boolean().default(!1),name:y.string(),image:y.string().optional(),createdAt:y.date().default(new Date),updatedAt:y.date().default(new Date)}),Ns=y.object({id:y.string(),userId:y.string(),expiresAt:y.date(),ipAddress:y.string().optional(),userAgent:y.string().optional()}),Fs=y.object({id:y.string(),value:y.string(),expiresAt:y.date(),identifier:y.string()});var Gr=u("/callback/:id",{method:"GET",query:De.object({state:De.string(),code:De.string().optional(),error:De.string().optional()}),metadata:se},async e=>{if(e.query.error||!e.query.code){let I=ge(e.query.state).data?.callbackURL||`${e.context.baseURL}/error`;throw e.context.logger.error(e.query.error,e.params.id),e.redirect(`${I}?error=${e.query.error||"oAuth_code_missing"}`)}let t=e.context.socialProviders.find(h=>h.id===e.params.id);if(!t)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 r=ge(e.query.state);if(!r.success)throw e.context.logger.error("Unable to parse state"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let{data:{callbackURL:o,currentURL:n}}=r,i=await e.getSignedCookie(e.context.authCookies.state.name,e.context.secret);if(!i)throw b.error("No stored state found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!await Ce(e.query.state,i))throw b.error("OAuth state mismatch"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let s=await e.getSignedCookie(e.context.authCookies.pkCodeVerifier.name,e.context.secret),d;try{d=await t.validateAuthorizationCode({code:e.query.code,codeVerifier:s,redirectURI:`${e.context.baseURL}/callback/${t.id}`})}catch(h){throw e.context.logger.error(h),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let c=await t.getUserInfo(d).then(h=>h?.user),l=C(),p=Le.safeParse({...c,id:l});if(!c||p.success===!1)throw b.error("Unable to get user info",p.error),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!o)throw e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);function f(h){throw e.redirect(`${n||o||`${e.context.baseURL}/error`}?error=${h}`)}let g=await e.context.internalAdapter.findUserByEmail(c.email,{includeAccounts:!0}).catch(h=>{throw b.error(`Better auth was unable to query your database.
2
+ `)}}),b=Rr();var _=T(async e=>{let{body:t,query:r,headers:o,context:n}=e,i=t?.callbackURL||r?.callbackURL||r?.redirectTo||t?.redirectTo,a=r?.currentURL||o?.get("referer")||n.baseURL,s=n.trustedOrigins,d=(c,l)=>{if(c?.startsWith("http")&&!s.some(f=>c.startsWith(f)))throw b.error(`Invalid ${l}`,{[l]:c,trustedOrigins:s}),new vr("FORBIDDEN",{message:`Invalid ${l}`})};d(i,"callbackURL"),d(a,"currentURL")});import{parseJWT as Tr}from"oslo/jwt";import{sha256 as Ir}from"oslo/crypto";import{base64url as Ur}from"oslo/encoding";async function ct(e){let t=await Ir(new TextEncoder().encode(e));return Ur.encode(new Uint8Array(t),{includePadding:!1})}function ut(e){return{tokenType:e.token_type,accessToken:e.access_token,refreshToken:e.refresh_token,accessTokenExpiresAt:e.expires_at?new Date((Date.now()+e.expires_in)*1e3):void 0,scopes:e?.scope?typeof e.scope=="string"?e.scope.split(" "):e.scope:[],idToken:e.id_token}}async function U({id:e,options:t,authorizationEndpoint:r,state:o,codeVerifier:n,scopes:i,claims:a,disablePkce:s,redirectURI:d}){let c=new URL(r);if(c.searchParams.set("response_type","code"),c.searchParams.set("client_id",t.clientId),c.searchParams.set("state",o),c.searchParams.set("scope",i.join(" ")),c.searchParams.set("redirect_uri",t.redirectURI||d),!s&&n){let l=await ct(n);c.searchParams.set("code_challenge_method","S256"),c.searchParams.set("code_challenge",l)}if(a){let l=a.reduce((p,f)=>(p[f]=null,p),{});c.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...l}}))}return c}import{betterFetch as Er}from"@better-fetch/fetch";async function O({code:e,codeVerifier:t,redirectURI:r,options:o,tokenEndpoint:n}){let i=new URLSearchParams;i.set("grant_type","authorization_code"),i.set("code",e),t&&i.set("code_verifier",t),i.set("redirect_uri",r),i.set("client_id",o.clientId),i.set("client_secret",o.clientSecret);let{data:a,error:s}=await Er(n,{method:"POST",body:i,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(s)throw s;return ut(a)}function he(e){let t=e.accessToken,r=e.refreshToken,o;try{o=e.accessTokenExpiresAt}catch{}return{accessToken:t,refreshToken:r,expiresAt:o}}var lt=e=>{let t="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:r,scopes:o,redirectURI:n}){let i=e.scope||o||["email","name","openid"];return new URL(`https://appleid.apple.com/auth/authorize?client_id=${e.clientId}&response_type=code&redirect_uri=${n||e.redirectURI}&scope=${i.join(" ")}&state=${r}`)},validateAuthorizationCode:async({code:r,codeVerifier:o,redirectURI:n})=>O({code:r,codeVerifier:o,redirectURI:e.redirectURI||n,options:e,tokenEndpoint:t}),async getUserInfo(r){if(!r.idToken)return null;let o=Tr(r.idToken)?.payload;return o?{user:{id:o.sub,name:o.name,email:o.email,emailVerified:o.email_verified==="true"},data:o}:null}}};import{betterFetch as Sr}from"@better-fetch/fetch";var pt=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let n=e.scope||r||["identify","email"];return new URL(`https://discord.com/api/oauth2/authorize?scope=${n.join("+")}&response_type=code&client_id=${e.clientId}&redirect_uri=${encodeURIComponent(e.redirectURI||o)}&state=${t}`)},validateAuthorizationCode:async({code:t,redirectURI:r})=>O({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await Sr("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}`}return{user:{id:r.id,name:r.display_name||r.username||"",email:r.email,emailVerified:r.verified,image:r.image_url},data:r}}});import{betterFetch as Pr}from"@better-fetch/fetch";var mt=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let n=e.scope||r||["email","public_profile"];return await U({id:"facebook",options:e,authorizationEndpoint:"https://www.facebook.com/v21.0/dialog/oauth",scopes:n,state:t,redirectURI:o})},validateAuthorizationCode:async({code:t,redirectURI:r})=>O({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://graph.facebook.com/oauth/access_token"}),async getUserInfo(t){let{data:r,error:o}=await Pr("https://graph.facebook.com/me?fields=id,name,email,picture",{auth:{type:"Bearer",token:t.accessToken}});return o?null:{user:{id:r.id,name:r.name,email:r.email,image:r.picture.data.url,emailVerified:r.email_verified},data:r}}});import{betterFetch as ft}from"@better-fetch/fetch";var gt=e=>{let t="https://github.com/login/oauth/access_token";return{id:"github",name:"GitHub",createAuthorizationURL({state:r,scopes:o,codeVerifier:n,redirectURI:i}){let a=e.scope||o||["user:email"];return U({id:"github",options:e,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:a,state:r,redirectURI:i,codeVerifier:n})},validateAuthorizationCode:async({code:r,redirectURI:o})=>O({code:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:t}),async getUserInfo(r){let{data:o,error:n}=await ft("https://api.github.com/user",{headers:{"User-Agent":"better-auth",authorization:`Bearer ${r.accessToken}`}});if(n)return null;let i=!1;if(!o.email){let{data:a,error:s}=await ft("https://api.github.com/user/emails",{headers:{authorization:`Bearer ${r.accessToken}`,"User-Agent":"better-auth"}});s||(o.email=(a.find(d=>d.primary)??a[0])?.email,i=a.find(d=>d.email===o.email)?.verified??!1)}return{user:{id:o.id.toString(),name:o.name||o.login,email:o.email,image:o.avatar_url,emailVerified:i},data:o}}}};import{parseJWT as Cr}from"oslo/jwt";var ht=e=>({id:"google",name:"Google",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:n}){if(!e.clientId||!e.clientSecret)throw b.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new $("CLIENT_ID_AND_SECRET_REQUIRED");if(!o)throw new $("codeVerifier is required for Google");let i=e.scope||r||["email","profile"];return U({id:"google",options:e,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:i,state:t,codeVerifier:o,redirectURI:n})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>O({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://oauth2.googleapis.com/token"}),async getUserInfo(t){if(!t.idToken)return null;let r=Cr(t.idToken)?.payload;return{user:{id:r.sub,name:r.name,email:r.email,image:r.picture,emailVerified:r.email_verified},data:r}}});import{betterFetch as _r}from"@better-fetch/fetch";import{parseJWT as zr}from"oslo/jwt";var wt=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(n){let i=e.scope||n.scopes||["openid","profile","email","User.Read"];return U({id:"microsoft",options:e,authorizationEndpoint:r,state:n.state,codeVerifier:n.codeVerifier,scopes:i,redirectURI:n.redirectURI})},validateAuthorizationCode({code:n,codeVerifier:i,redirectURI:a}){return O({code:n,codeVerifier:i,redirectURI:e.redirectURI||a,options:e,tokenEndpoint:o})},async getUserInfo(n){if(!n.idToken)return null;let i=zr(n.idToken)?.payload,a=e.profilePhotoSize||48;return await _r(`https://graph.microsoft.com/v1.0/me/photos/${a}x${a}/$value`,{headers:{Authorization:`Bearer ${n.accessToken}`},async onResponse(s){if(!(e.disableProfilePhoto||!s.response.ok))try{let c=await s.response.clone().arrayBuffer(),l=Buffer.from(c).toString("base64");i.picture=`data:image/jpeg;base64, ${l}`}catch(d){b.error(d)}}}),{user:{id:i.sub,name:i.name,email:i.email,image:i.picture,emailVerified:!0},data:i}}}};import{betterFetch as Br}from"@better-fetch/fetch";var yt=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:n}){let i=e.scope||r||["user-read-email"];return U({id:"spotify",options:e,authorizationEndpoint:"https://accounts.spotify.com/authorize",scopes:i,state:t,codeVerifier:o,redirectURI:n})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>O({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://accounts.spotify.com/api/token"}),async getUserInfo(t){let{data:r,error:o}=await Br("https://api.spotify.com/v1/me",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});return o?null:{user:{id:r.id,name:r.display_name,email:r.email,image:r.images[0]?.url,emailVerified:!1},data:r}}});import"@better-fetch/fetch";var se={isAction:!1};import{nanoid as Lr}from"nanoid";var C=e=>Lr(e);import{parseJWT as Dr}from"oslo/jwt";var bt=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let n=e.scope||r||["user:read:email","openid"];return U({id:"twitch",redirectURI:o,options:e,authorizationEndpoint:"https://id.twitch.tv/oauth2/authorize",scopes:n,state:t,claims:e.claims||["email","email_verified","preferred_username","picture"]})},validateAuthorizationCode:async({code:t,redirectURI:r})=>O({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){let r=t.idToken;if(!r)return b.error("No idToken found in token"),null;let o=Dr(r)?.payload;return{user:{id:o.sub,name:o.preferred_username,email:o.email,image:o.picture,emailVerified:!1},data:o}}});import{betterFetch as xr}from"@better-fetch/fetch";var At=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(t){let r=e.scope||t.scopes||["account_info.read"];return U({id:"twitter",options:e,authorizationEndpoint:"https://twitter.com/i/oauth2/authorize",scopes:r,state:t.state,codeVerifier:t.codeVerifier,redirectURI:t.redirectURI})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>O({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await xr("https://api.x.com/2/users/me?user.fields=profile_image_url",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});return o||!r.data.email?null:{user:{id:r.data.id,name:r.data.name,email:r.data.email,image:r.data.profile_image_url,emailVerified:r.data.verified||!1},data:r}}});import{betterFetch as jr}from"@better-fetch/fetch";var kt=e=>{let t="https://api.dropboxapi.com/oauth2/token";return{id:"dropbox",name:"Dropbox",createAuthorizationURL:async({state:r,scopes:o,codeVerifier:n,redirectURI:i})=>{let a=e.scope||o||["account_info.read"];return await U({id:"dropbox",options:e,authorizationEndpoint:"https://www.dropbox.com/oauth2/authorize",scopes:a,state:r,redirectURI:i,codeVerifier:n})},validateAuthorizationCode:async({code:r,codeVerifier:o,redirectURI:n})=>await O({code:r,codeVerifier:o,redirectURI:e.redirectURI||n,options:e,tokenEndpoint:t}),async getUserInfo(r){let{data:o,error:n}=await jr("https://api.dropboxapi.com/2/users/get_current_account",{method:"POST",headers:{Authorization:`Bearer ${r.accessToken}`}});return n?null:{user:{id:o.account_id,name:o.name?.display_name,email:o.email,emailVerified:o.email_verified||!1,image:o.profile_photo_url},data:o}}}};import{betterFetch as Nr}from"@better-fetch/fetch";var Ot=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:n,redirectURI:i})=>{let a=e.scope||n||["profile","email","openid"];return await U({id:"linkedin",options:e,authorizationEndpoint:t,scopes:a,state:o,redirectURI:i})},validateAuthorizationCode:async({code:o,redirectURI:n})=>await O({code:o,redirectURI:e.redirectURI||n,options:e,tokenEndpoint:r}),async getUserInfo(o){let{data:n,error:i}=await Nr("https://api.linkedin.com/v2/userinfo",{method:"GET",headers:{Authorization:`Bearer ${o.accessToken}`}});return i?null:{user:{id:n.sub,name:n.name,email:n.email,emailVerified:n.email_verified||!1,image:n.picture},data:n}}}};var Fr={apple:lt,discord:pt,facebook:mt,github:gt,microsoft:wt,google:ht,spotify:yt,twitch:bt,twitter:At,dropbox:kt,linkedin:Ot},Rt=Object.keys(Fr);import{TimeSpan as $r}from"oslo";import{createJWT as Vr,validateJWT as Hr}from"oslo/jwt";import{z as Z}from"zod";import{APIError as we}from"better-call";import{APIError as Oe}from"better-call";var X=(e,t="ms")=>new Date(Date.now()+(t==="sec"?e*1e3:e));import{z as vt}from"zod";var It=()=>u("/session",{method:"GET",requireHeaders:!0},async e=>{try{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)return e.json(null,{status:401});let r=await e.context.internalAdapter.findSession(t);if(!r||r.session.expiresAt<new Date)return ke(e),r&&await e.context.internalAdapter.deleteSession(r.session.id),e.json(null,{status:401});if(await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret))return e.json(r);let n=e.context.sessionConfig.expiresIn,i=e.context.sessionConfig.updateAge;if(r.session.expiresAt.valueOf()-n*1e3+i*1e3<=Date.now()){let d=await e.context.internalAdapter.updateSession(r.session.id,{expiresAt:X(e.context.sessionConfig.expiresIn,"sec")});if(!d)return ke(e),e.json(null,{status:401});let c=(d.expiresAt.valueOf()-Date.now())/1e3;return await A(e,d.id,!1,{maxAge:c}),e.json({session:d,user:r.user})}return e.json(r)}catch(t){return e.context.logger.error(t),e.json(null,{status:500})}}),D=async e=>await It()({...e,_flag:"json",headers:e.headers}),w=T(async e=>{let t=await D(e);if(!t?.session)throw new Oe("UNAUTHORIZED");return{session:t}});var Mr=u("/user/revoke-session",{method:"POST",body:vt.object({id:vt.string()}),use:[w],requireHeaders:!0},async e=>{let t=e.body.id,r=await e.context.internalAdapter.findSession(t);if(!r)throw new Oe("BAD_REQUEST",{message:"Session not found"});if(r.session.userId!==e.context.session.user.id)throw new Oe("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(t)}catch(o){throw e.context.logger.error(o),new Oe("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),qr=u("/user/revoke-sessions",{method:"POST",use:[w],requireHeaders:!0},async e=>{try{await e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(t){throw e.context.logger.error(t),new Oe("INTERNAL_SERVER_ERROR")}return e.json({status:!0})});async function ae(e,t,r){return await Vr("HS256",Buffer.from(e),{email:t.toLowerCase(),updateTo:r},{expiresIn:new $r(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}var Qr=u("/send-verification-email",{method:"POST",query:Z.object({currentURL:Z.string().optional()}).optional(),body:Z.object({email:Z.string().email(),callbackURL:Z.string().optional()}),use:[_]},async e=>{if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new we("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:t}=e.body,r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw new we("BAD_REQUEST",{message:"User not found"});let o=await ae(e.context.secret,t),n=`${e.context.baseURL}/verify-email?token=${o}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.emailVerification.sendVerificationEmail(r.user,n,o),e.json({status:!0})}),Wr=u("/verify-email",{method:"GET",query:Z.object({token:Z.string(),callbackURL:Z.string().optional()}),use:[_]},async e=>{let{token:t}=e.query,r;try{r=await Hr("HS256",Buffer.from(e.context.secret),t)}catch(a){throw e.context.logger.error("Failed to verify email",a),new we("BAD_REQUEST",{message:"Invalid token"})}let n=Z.object({email:Z.string().email(),updateTo:Z.string().optional()}).parse(r.payload);if(!await e.context.internalAdapter.findUserByEmail(n.email))throw new we("BAD_REQUEST",{message:"User not found"});if(n.updateTo){let a=await D(e);if(!a)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new we("UNAUTHORIZED",{message:"Session not found"});if(a.user.email!==n.email)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new we("UNAUTHORIZED",{message:"Invalid session"});let s=await e.context.internalAdapter.updateUserByEmail(n.email,{email:n.updateTo});if(await e.context.options.emailVerification?.sendVerificationEmail?.(s,`${e.context.baseURL}/verify-email?token=${t}`,t),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:s,status:!0})}if(await e.context.internalAdapter.updateUserByEmail(n.email,{emailVerified:!0}),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:null,status:!0})});var Zr=u("/sign-in/social",{method:"POST",requireHeaders:!0,query:V.object({currentURL:V.string().optional()}).optional(),body:V.object({callbackURL:V.string().optional(),provider:V.enum(Rt)}),use:[_]},async e=>{let t=e.context.socialProviders.find(d=>d.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 J("NOT_FOUND",{message:"Provider not found"});let r=e.context.authCookies,o=e.query?.currentURL?new URL(e.query?.currentURL):null,n=e.body.callbackURL?.startsWith("http")?e.body.callbackURL:`${o?.origin}${e.body.callbackURL||""}`,i=await ze(n||o?.origin||e.context.options.baseURL);await e.setSignedCookie(r.state.name,i.hash,e.context.secret,r.state.options);let a=Kr();await e.setSignedCookie(r.pkCodeVerifier.name,a,e.context.secret,r.pkCodeVerifier.options);let s=await t.createAuthorizationURL({state:i.raw,codeVerifier:a,redirectURI:`${e.context.baseURL}/callback/${t.id}`});return e.json({url:s.toString(),state:i,codeVerifier:a,redirect:!0})}),Jr=u("/sign-in/email",{method:"POST",body:V.object({email:V.string(),password:V.string(),callbackURL:V.string().optional(),dontRememberMe:V.boolean().default(!1).optional()}),use:[_]},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 J("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:t,password:r}=e.body;if(!V.string().email().safeParse(t).success)throw new J("BAD_REQUEST",{message:"Invalid email"});if(!V.string().email().safeParse(t).success)throw new J("BAD_REQUEST",{message:"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 J("UNAUTHORIZED",{message:"Invalid email or password"});let a=i.accounts.find(l=>l.providerId==="credential");if(!a)throw e.context.logger.error("Credential account not found",{email:t}),new J("UNAUTHORIZED",{message:"Invalid email or password"});let s=a?.password;if(!s)throw e.context.logger.error("Password not found",{email:t}),new J("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(s,r))throw e.context.logger.error("Invalid password"),new J("UNAUTHORIZED",{message:"Invalid email or password"});if(e.context.options?.emailAndPassword?.requireEmailVerification&&!i.user.emailVerified){if(!e.context.options?.emailVerification?.sendVerificationEmail)throw b.error("Email verification is required but no email verification handler is provided"),new J("INTERNAL_SERVER_ERROR",{message:"Email is not verified."});let l=await ae(e.context.secret,i.user.email),p=`${e.context.options.baseURL}/verify-email?token=${l}`;throw await e.context.options.emailVerification.sendVerificationEmail(i.user,p,l),e.context.logger.error("Email not verified",{email:t}),new J("FORBIDDEN",{message:"Email is not verified. Check your email for a verification link"})}let c=await e.context.internalAdapter.createSession(i.user.id,e.headers,e.body.dontRememberMe);if(!c)throw e.context.logger.error("Failed to create session"),new J("UNAUTHORIZED",{message:"Failed to create session"});return await A(e,c.id,e.body.dontRememberMe),e.json({user:i.user,session:c,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});import{z as De}from"zod";import{z as y}from"zod";var js=y.object({id:y.string(),providerId:y.string(),accountId:y.string(),userId:y.string(),accessToken:y.string().nullable().optional(),refreshToken:y.string().nullable().optional(),idToken:y.string().nullable().optional(),expiresAt:y.date().nullable().optional(),password:y.string().optional().nullable()}),Le=y.object({id:y.string(),email:y.string().transform(e=>e.toLowerCase()),emailVerified:y.boolean().default(!1),name:y.string(),image:y.string().optional(),createdAt:y.date().default(new Date),updatedAt:y.date().default(new Date)}),Ns=y.object({id:y.string(),userId:y.string(),expiresAt:y.date(),ipAddress:y.string().optional(),userAgent:y.string().optional()}),Fs=y.object({id:y.string(),value:y.string(),expiresAt:y.date(),identifier:y.string()});var Gr=u("/callback/:id",{method:"GET",query:De.object({state:De.string(),code:De.string().optional(),error:De.string().optional()}),metadata:se},async e=>{if(e.query.error||!e.query.code){let I=ge(e.query.state).data?.callbackURL||`${e.context.baseURL}/error`;throw e.context.logger.error(e.query.error,e.params.id),e.redirect(`${I}?error=${e.query.error||"oAuth_code_missing"}`)}let t=e.context.socialProviders.find(h=>h.id===e.params.id);if(!t)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 r=ge(e.query.state);if(!r.success)throw e.context.logger.error("Unable to parse state"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let{data:{callbackURL:o,currentURL:n}}=r,i=await e.getSignedCookie(e.context.authCookies.state.name,e.context.secret);if(!i)throw b.error("No stored state found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!await Ce(e.query.state,i))throw b.error("OAuth state mismatch"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let s=await e.getSignedCookie(e.context.authCookies.pkCodeVerifier.name,e.context.secret),d;try{d=await t.validateAuthorizationCode({code:e.query.code,codeVerifier:s,redirectURI:`${e.context.baseURL}/callback/${t.id}`})}catch(h){throw e.context.logger.error(h),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let c=await t.getUserInfo(d).then(h=>h?.user),l=C(),p=Le.safeParse({...c,id:l});if(!c||p.success===!1)throw b.error("Unable to get user info",p.error),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!o)throw e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);function f(h){throw e.redirect(`${n||o||`${e.context.baseURL}/error`}?error=${h}`)}let g=await e.context.internalAdapter.findUserByEmail(c.email,{includeAccounts:!0}).catch(h=>{throw b.error(`Better auth was unable to query your database.
3
3
  Error: `,h),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)}),v=g?.user.id;if(g){if(!g.accounts.find(I=>I.providerId===t.id)){(!e.context.options.account?.accountLinking?.trustedProviders?.includes(t.id)&&!c.emailVerified||!e.context.options.account?.accountLinking?.enabled)&&f("account_not_linked");try{await e.context.internalAdapter.linkAccount({providerId:t.id,accountId:c.id.toString(),id:`${t.id}:${c.id}`,userId:g.user.id,...he(d)})}catch(K){b.error("Unable to link account",K),f("unable_to_link_account")}}}else try{let h=c.emailVerified||!1,I=await e.context.internalAdapter.createOAuthUser({...p.data,emailVerified:h},{...he(d),providerId:t.id,accountId:c.id.toString()});if(v=I?.user.id,!h&&I&&e.context.options.emailVerification?.sendOnSignUp){let q=await ae(e.context.secret,c.email),K=`${e.context.baseURL}/verify-email?token=${q}&callbackURL=${o}`;await e.context.options.emailVerification?.sendVerificationEmail?.(I.user,K,q)}}catch(h){b.error("Unable to create user",h),f("unable_to_create_user")}v||f("unable_to_create_user");let B=await e.context.internalAdapter.createSession(v,e.request);throw B||f("unable_to_create_session"),await A(e,B.id),e.redirect(o)});import"zod";import{APIError as Yr}from"better-call";var Xr=u("/sign-out",{method:"POST"},async e=>{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)throw new Yr("BAD_REQUEST",{message:"Session not found"});return await e.context.internalAdapter.deleteSession(t),ke(e),e.json({success:!0})});import{z as G}from"zod";import{APIError as xe}from"better-call";var eo=u("/forget-password",{method:"POST",body:G.object({email:G.string().email(),redirectTo:G.string()}),use:[_]},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 xe("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 n=60*60*1,i=new Date(Date.now()+1e3*(e.context.options.emailAndPassword.resetPasswordTokenExpiresIn||n)),a=e.context.uuid();await e.context.internalAdapter.createVerificationValue({value:o.user.id,identifier:`reset-password:${a}`,expiresAt:i});let s=`${e.context.baseURL}/reset-password/${a}?callbackURL=${r}`;return await e.context.options.emailAndPassword.sendResetPassword(o.user,s),e.json({status:!0})}),to=u("/reset-password/:token",{method:"GET",query:G.object({callbackURL:G.string()}),use:[_]},async e=>{let{token:t}=e.params,r=e.query.callbackURL,o=r.startsWith("http")?r:`${e.context.options.baseURL}${r}`;if(!t||!r)throw e.redirect(`${e.context.baseURL}/error?error=INVALID_TOKEN`);let n=await e.context.internalAdapter.findVerificationValue(`reset-password:${t}`);throw!n||n.expiresAt<new Date?e.redirect(`${o}?error=INVALID_TOKEN`):e.redirect(`${o}?token=${t}`)}),ro=u("/reset-password",{query:G.optional(G.object({token:G.string().optional(),currentURL:G.string().optional()})),method:"POST",body:G.object({newPassword:G.string()})},async e=>{let t=e.query?.token||(e.query?.currentURL?new URL(e.query.currentURL).searchParams.get("token"):"");if(!t)throw new xe("BAD_REQUEST",{message:"Token not found"});let{newPassword:r}=e.body,o=`reset-password:${t}`,n=await e.context.internalAdapter.findVerificationValue(o);if(!n||n.expiresAt<new Date)throw new xe("BAD_REQUEST",{message:"Invalid token"});await e.context.internalAdapter.deleteVerificationValue(n.id);let i=n.value,a=await e.context.password.hash(r);if(!(await e.context.internalAdapter.findAccounts(i)).find(l=>l.providerId==="credential"))return await e.context.internalAdapter.createAccount({userId:i,providerId:"credential",password:a,accountId:e.context.uuid()}),e.json({status:!0});if(!await e.context.internalAdapter.updatePassword(i,a))throw new xe("BAD_REQUEST",{message:"Failed to update password"});return e.json({status:!0})});import{z as F}from"zod";import Ut from"uncrypto";function oo(e){return e.toString(2).padStart(8,"0")}function no(e){return[...e].map(t=>oo(t)).join("")}function Et(e){return parseInt(no(e),2)}function io(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));Ut.getRandomValues(o),r!==0&&(o[0]&=(1<<r)-1);let n=Et(o);for(;n>=e;)Ut.getRandomValues(o),r!==0&&(o[0]&=(1<<r)-1),n=Et(o);return n}function H(e,t){let r="";for(let o=0;o<e;o++)r+=t[io(t.length)];return r}function Q(...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}import{APIError as N}from"better-call";var so=u("/user/change-password",{method:"POST",body:F.object({newPassword:F.string(),currentPassword:F.string(),revokeOtherSessions:F.boolean().optional()}),use:[w]},async e=>{let{newPassword:t,currentPassword:r,revokeOtherSessions:o}=e.body,n=e.context.session,i=e.context.password.config.minPasswordLength;if(t.length<i)throw e.context.logger.error("Password is too short"),new N("BAD_REQUEST",{message:"Password is too short"});let a=e.context.password.config.maxPasswordLength;if(t.length>a)throw e.context.logger.error("Password is too long"),new N("BAD_REQUEST",{message:"Password too long"});let d=(await e.context.internalAdapter.findAccounts(n.user.id)).find(p=>p.providerId==="credential"&&p.password);if(!d||!d.password)throw new N("BAD_REQUEST",{message:"User does not have a password"});let c=await e.context.password.hash(t);if(!await e.context.password.verify(d.password,r))throw new N("BAD_REQUEST",{message:"Incorrect password"});if(await e.context.internalAdapter.updateAccount(d.id,{password:c}),o){await e.context.internalAdapter.deleteSessions(n.user.id);let p=await e.context.internalAdapter.createSession(n.user.id,e.headers);if(!p)throw new N("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});await A(e,p.id)}return e.json(n.user)}),ao=u("/user/set-password",{method:"POST",body:F.object({newPassword:F.string()}),use:[w]},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 N("BAD_REQUEST",{message:"Password is too short"});let n=e.context.password.config.maxPasswordLength;if(t.length>n)throw e.context.logger.error("Password is too long"),new N("BAD_REQUEST",{message:"Password too long"});let a=(await e.context.internalAdapter.findAccounts(r.user.id)).find(d=>d.providerId==="credential"&&d.password),s=await e.context.password.hash(t);if(!a)return await e.context.internalAdapter.linkAccount({userId:r.user.id,providerId:"credential",accountId:r.user.id,password:s}),e.json(r.user);throw new N("BAD_REQUEST",{message:"user already has a password"})}),co=u("/user/delete",{method:"POST",body:F.object({password:F.string()}),use:[w]},async e=>{let{password:t}=e.body,r=e.context.session,n=(await e.context.internalAdapter.findAccounts(r.user.id)).find(s=>s.providerId==="credential"&&s.password);if(!n||!n.password)throw new N("BAD_REQUEST",{message:"User does not have a password"});if(!await e.context.password.verify(n.password,t))throw new N("BAD_REQUEST",{message:"Incorrect password"});await e.context.internalAdapter.deleteUser(r.user.id),await e.context.internalAdapter.deleteSessions(r.user.id);let a=e.context.authCookies.sessionToken;return e.setCookie(a.name,"",{maxAge:0}),e.json(null)}),uo=u("/user/change-email",{method:"POST",query:F.object({currentURL:F.string().optional()}).optional(),body:F.object({newEmail:F.string().email(),callbackURL:F.string().optional()}),use:[w,_]},async e=>{if(!e.context.options.user?.changeEmail?.enabled)throw e.context.logger.error("Change email is disabled."),new N("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 N("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 N("BAD_REQUEST",{message:"Couldn't update your email"});if(e.context.session.user.emailVerified!==!0){let n=await e.context.internalAdapter.updateUserByEmail(e.context.session.user.email,{email:e.body.newEmail});return e.json({user:n,status:!0})}if(!e.context.options.user.changeEmail.sendChangeEmailVerification)throw e.context.logger.error("Verification email isn't enabled."),new N("BAD_REQUEST",{message:"Verification email isn't enabled"});let r=await ae(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(e.context.session.user,e.body.newEmail,o,r),e.json({user:null,status:!0})});import{xchacha20poly1305 as St}from"@noble/ciphers/chacha";import{bytesToHex as lo,hexToBytes as po,utf8ToBytes as mo}from"@noble/ciphers/utils";import{managedNonce as Pt}from"@noble/ciphers/webcrypto";import{sha256 as Ct}from"oslo/crypto";import Tt from"uncrypto";import{decodeHex as _a,encodeHex as za}from"oslo/encoding";import{scryptAsync as Da}from"@noble/hashes/scrypt";import{getRandomValues as ja}from"uncrypto";async function Y(e,t){let r=new TextEncoder,o={name:"HMAC",hash:"SHA-256"},n=await Tt.subtle.importKey("raw",r.encode(e),o,!1,["sign","verify"]),i=await Tt.subtle.sign(o.name,n,r.encode(t));return btoa(String.fromCharCode(...new Uint8Array(i)))}var je=async({key:e,data:t})=>{let r=await Ct(new TextEncoder().encode(e)),o=mo(t),n=Pt(St)(new Uint8Array(r));return lo(n.encrypt(o))},Ne=async({key:e,data:t})=>{let r=await Ct(new TextEncoder().encode(e)),o=po(t),n=Pt(St)(new Uint8Array(r));return new TextDecoder().decode(n.decrypt(o))};var fo=u("/csrf",{method:"GET",metadata:se},async e=>{let t=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret);if(t){let[i,a]=t.split("!")||[null,null];return e.json({csrfToken:i})}let r=H(32,Q("a-z","0-9","A-Z")),o=await Y(e.context.secret,r),n=`${r}!${o}`;return await e.setSignedCookie(e.context.authCookies.csrfToken.name,n,e.context.secret,e.context.authCookies.csrfToken.options),e.json({csrfToken:r})});var go=(e="Unknown")=>`<!DOCTYPE html>
4
4
  <html lang="en">
5
5
  <head>
package/dist/social.js CHANGED
@@ -1,2 +1,2 @@
1
- import{parseJWT as B}from"oslo/jwt";import{sha256 as E}from"oslo/crypto";import{base64url as L}from"oslo/encoding";async function b(r){let i=await E(new TextEncoder().encode(r));return L.encode(new Uint8Array(i),{includePadding:!1})}function _(r){return{tokenType:r.token_type,accessToken:r.access_token,refreshToken:r.refresh_token,accessTokenExpiresAt:r.expires_at?new Date((Date.now()+r.expires_in)*1e3):void 0,scopes:r?.scope?typeof r.scope=="string"?r.scope.split(" "):r.scope:[],idToken:r.id_token}}async function c({id:r,options:i,authorizationEndpoint:e,state:t,codeVerifier:o,scopes:n,claims:s,disablePkce:p,redirectURI:l}){let d=new URL(e);if(d.searchParams.set("response_type","code"),d.searchParams.set("client_id",i.clientId),d.searchParams.set("state",t),d.searchParams.set("scope",n.join(" ")),d.searchParams.set("redirect_uri",i.redirectURI||l),!p&&o){let f=await b(o);d.searchParams.set("code_challenge_method","S256"),d.searchParams.set("code_challenge",f)}if(s){let f=s.reduce((h,I)=>(h[I]=null,h),{});d.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...f}}))}return d}import{betterFetch as C}from"@better-fetch/fetch";async function a({code:r,codeVerifier:i,redirectURI:e,options:t,tokenEndpoint:o}){let n=new URLSearchParams;n.set("grant_type","authorization_code"),n.set("code",r),i&&n.set("code_verifier",i),n.set("redirect_uri",e),n.set("client_id",t.clientId),n.set("client_secret",t.clientSecret);let{data:s,error:p}=await C(o,{method:"POST",body:n,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(p)throw p;return _(s)}import{generateState as le}from"oslo/oauth2";import{z as me}from"zod";import{sha256 as ae}from"oslo/crypto";import"better-call";var y=r=>{let i="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:e,scopes:t,redirectURI:o}){let n=r.scope||t||["email","name","openid"];return new URL(`https://appleid.apple.com/auth/authorize?client_id=${r.clientId}&response_type=code&redirect_uri=${o||r.redirectURI}&scope=${n.join(" ")}&state=${e}`)},validateAuthorizationCode:async({code:e,codeVerifier:t,redirectURI:o})=>a({code:e,codeVerifier:t,redirectURI:r.redirectURI||o,options:r,tokenEndpoint:i}),async getUserInfo(e){if(!e.idToken)return null;let t=B(e.idToken)?.payload;return t?{user:{id:t.sub,name:t.name,email:t.email,emailVerified:t.email_verified==="true"},data:t}:null}}};import{betterFetch as S}from"@better-fetch/fetch";var v=r=>({id:"discord",name:"Discord",createAuthorizationURL({state:i,scopes:e,redirectURI:t}){let o=r.scope||e||["identify","email"];return new URL(`https://discord.com/api/oauth2/authorize?scope=${o.join("+")}&response_type=code&client_id=${r.clientId}&redirect_uri=${encodeURIComponent(r.redirectURI||t)}&state=${i}`)},validateAuthorizationCode:async({code:i,redirectURI:e})=>a({code:i,redirectURI:r.redirectURI||e,options:r,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(i){let{data:e,error:t}=await S("https://discord.com/api/users/@me",{headers:{authorization:`Bearer ${i.accessToken}`}});if(t)return null;if(e.avatar===null){let o=e.discriminator==="0"?Number(BigInt(e.id)>>BigInt(22))%6:parseInt(e.discriminator)%5;e.image_url=`https://cdn.discordapp.com/embed/avatars/${o}.png`}else{let o=e.avatar.startsWith("a_")?"gif":"png";e.image_url=`https://cdn.discordapp.com/avatars/${e.id}/${e.avatar}.${o}`}return{user:{id:e.id,name:e.display_name||e.username||"",email:e.email,emailVerified:e.verified,image:e.image_url},data:e}}});import{betterFetch as $}from"@better-fetch/fetch";var x=r=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:i,scopes:e,redirectURI:t}){let o=r.scope||e||["email","public_profile"];return await c({id:"facebook",options:r,authorizationEndpoint:"https://www.facebook.com/v21.0/dialog/oauth",scopes:o,state:i,redirectURI:t})},validateAuthorizationCode:async({code:i,redirectURI:e})=>a({code:i,redirectURI:r.redirectURI||e,options:r,tokenEndpoint:"https://graph.facebook.com/oauth/access_token"}),async getUserInfo(i){let{data:e,error:t}=await $("https://graph.facebook.com/me?fields=id,name,email,picture",{auth:{type:"Bearer",token:i.accessToken}});return t?null:{user:{id:e.id,name:e.name,email:e.email,image:e.picture.data.url,emailVerified:e.email_verified},data:e}}});import{betterFetch as A}from"@better-fetch/fetch";var P=r=>{let i="https://github.com/login/oauth/access_token";return{id:"github",name:"Github",createAuthorizationURL({state:e,scopes:t,codeVerifier:o,redirectURI:n}){let s=r.scope||t||["user:email"];return c({id:"github",options:r,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:s,state:e,redirectURI:n,codeVerifier:o})},validateAuthorizationCode:async({code:e,redirectURI:t})=>a({code:e,redirectURI:r.redirectURI||t,options:r,tokenEndpoint:i}),async getUserInfo(e){let{data:t,error:o}=await A("https://api.github.com/user",{headers:{"User-Agent":"better-auth",authorization:`Bearer ${e.accessToken}`}});if(o)return null;let n=!1;if(!t.email){let{data:s,error:p}=await A("https://api.github.com/user/emails",{headers:{authorization:`Bearer ${e.accessToken}`,"User-Agent":"better-auth"}});p||(t.email=(s.find(l=>l.primary)??s[0])?.email,n=s.find(l=>l.email===t.email)?.verified??!1)}return{user:{id:t.id.toString(),name:t.name||t.login,email:t.email,image:t.avatar_url,emailVerified:n},data:t}}}};import{parseJWT as F}from"oslo/jwt";var g=class extends Error{constructor(i,e){super(i),this.name="BetterAuthError",this.message=i,this.cause=e}};import{createConsola as D}from"consola";var u=D({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),V=r=>({log:(...i)=>{!r?.disabled&&u.log("",...i)},error:(...i)=>{!r?.disabled&&u.error("",...i)},warn:(...i)=>{!r?.disabled&&u.warn("",...i)},info:(...i)=>{!r?.disabled&&u.info("",...i)},debug:(...i)=>{!r?.disabled&&u.debug("",...i)},box:(...i)=>{!r?.disabled&&u.box("",...i)},success:(...i)=>{!r?.disabled&&u.success("",...i)},break:(...i)=>{!r?.disabled&&console.log(`
1
+ import{parseJWT as B}from"oslo/jwt";import{sha256 as E}from"oslo/crypto";import{base64url as L}from"oslo/encoding";async function b(r){let i=await E(new TextEncoder().encode(r));return L.encode(new Uint8Array(i),{includePadding:!1})}function _(r){return{tokenType:r.token_type,accessToken:r.access_token,refreshToken:r.refresh_token,accessTokenExpiresAt:r.expires_at?new Date((Date.now()+r.expires_in)*1e3):void 0,scopes:r?.scope?typeof r.scope=="string"?r.scope.split(" "):r.scope:[],idToken:r.id_token}}async function c({id:r,options:i,authorizationEndpoint:e,state:t,codeVerifier:o,scopes:n,claims:s,disablePkce:p,redirectURI:l}){let d=new URL(e);if(d.searchParams.set("response_type","code"),d.searchParams.set("client_id",i.clientId),d.searchParams.set("state",t),d.searchParams.set("scope",n.join(" ")),d.searchParams.set("redirect_uri",i.redirectURI||l),!p&&o){let f=await b(o);d.searchParams.set("code_challenge_method","S256"),d.searchParams.set("code_challenge",f)}if(s){let f=s.reduce((h,I)=>(h[I]=null,h),{});d.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...f}}))}return d}import{betterFetch as C}from"@better-fetch/fetch";async function a({code:r,codeVerifier:i,redirectURI:e,options:t,tokenEndpoint:o}){let n=new URLSearchParams;n.set("grant_type","authorization_code"),n.set("code",r),i&&n.set("code_verifier",i),n.set("redirect_uri",e),n.set("client_id",t.clientId),n.set("client_secret",t.clientSecret);let{data:s,error:p}=await C(o,{method:"POST",body:n,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(p)throw p;return _(s)}import{generateState as le}from"oslo/oauth2";import{z as me}from"zod";import{sha256 as ae}from"oslo/crypto";import"better-call";var y=r=>{let i="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:e,scopes:t,redirectURI:o}){let n=r.scope||t||["email","name","openid"];return new URL(`https://appleid.apple.com/auth/authorize?client_id=${r.clientId}&response_type=code&redirect_uri=${o||r.redirectURI}&scope=${n.join(" ")}&state=${e}`)},validateAuthorizationCode:async({code:e,codeVerifier:t,redirectURI:o})=>a({code:e,codeVerifier:t,redirectURI:r.redirectURI||o,options:r,tokenEndpoint:i}),async getUserInfo(e){if(!e.idToken)return null;let t=B(e.idToken)?.payload;return t?{user:{id:t.sub,name:t.name,email:t.email,emailVerified:t.email_verified==="true"},data:t}:null}}};import{betterFetch as S}from"@better-fetch/fetch";var v=r=>({id:"discord",name:"Discord",createAuthorizationURL({state:i,scopes:e,redirectURI:t}){let o=r.scope||e||["identify","email"];return new URL(`https://discord.com/api/oauth2/authorize?scope=${o.join("+")}&response_type=code&client_id=${r.clientId}&redirect_uri=${encodeURIComponent(r.redirectURI||t)}&state=${i}`)},validateAuthorizationCode:async({code:i,redirectURI:e})=>a({code:i,redirectURI:r.redirectURI||e,options:r,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(i){let{data:e,error:t}=await S("https://discord.com/api/users/@me",{headers:{authorization:`Bearer ${i.accessToken}`}});if(t)return null;if(e.avatar===null){let o=e.discriminator==="0"?Number(BigInt(e.id)>>BigInt(22))%6:parseInt(e.discriminator)%5;e.image_url=`https://cdn.discordapp.com/embed/avatars/${o}.png`}else{let o=e.avatar.startsWith("a_")?"gif":"png";e.image_url=`https://cdn.discordapp.com/avatars/${e.id}/${e.avatar}.${o}`}return{user:{id:e.id,name:e.display_name||e.username||"",email:e.email,emailVerified:e.verified,image:e.image_url},data:e}}});import{betterFetch as $}from"@better-fetch/fetch";var x=r=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:i,scopes:e,redirectURI:t}){let o=r.scope||e||["email","public_profile"];return await c({id:"facebook",options:r,authorizationEndpoint:"https://www.facebook.com/v21.0/dialog/oauth",scopes:o,state:i,redirectURI:t})},validateAuthorizationCode:async({code:i,redirectURI:e})=>a({code:i,redirectURI:r.redirectURI||e,options:r,tokenEndpoint:"https://graph.facebook.com/oauth/access_token"}),async getUserInfo(i){let{data:e,error:t}=await $("https://graph.facebook.com/me?fields=id,name,email,picture",{auth:{type:"Bearer",token:i.accessToken}});return t?null:{user:{id:e.id,name:e.name,email:e.email,image:e.picture.data.url,emailVerified:e.email_verified},data:e}}});import{betterFetch as A}from"@better-fetch/fetch";var P=r=>{let i="https://github.com/login/oauth/access_token";return{id:"github",name:"GitHub",createAuthorizationURL({state:e,scopes:t,codeVerifier:o,redirectURI:n}){let s=r.scope||t||["user:email"];return c({id:"github",options:r,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:s,state:e,redirectURI:n,codeVerifier:o})},validateAuthorizationCode:async({code:e,redirectURI:t})=>a({code:e,redirectURI:r.redirectURI||t,options:r,tokenEndpoint:i}),async getUserInfo(e){let{data:t,error:o}=await A("https://api.github.com/user",{headers:{"User-Agent":"better-auth",authorization:`Bearer ${e.accessToken}`}});if(o)return null;let n=!1;if(!t.email){let{data:s,error:p}=await A("https://api.github.com/user/emails",{headers:{authorization:`Bearer ${e.accessToken}`,"User-Agent":"better-auth"}});p||(t.email=(s.find(l=>l.primary)??s[0])?.email,n=s.find(l=>l.email===t.email)?.verified??!1)}return{user:{id:t.id.toString(),name:t.name||t.login,email:t.email,image:t.avatar_url,emailVerified:n},data:t}}}};import{parseJWT as F}from"oslo/jwt";var g=class extends Error{constructor(i,e){super(i),this.name="BetterAuthError",this.message=i,this.cause=e}};import{createConsola as D}from"consola";var u=D({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),V=r=>({log:(...i)=>{!r?.disabled&&u.log("",...i)},error:(...i)=>{!r?.disabled&&u.error("",...i)},warn:(...i)=>{!r?.disabled&&u.warn("",...i)},info:(...i)=>{!r?.disabled&&u.info("",...i)},debug:(...i)=>{!r?.disabled&&u.debug("",...i)},box:(...i)=>{!r?.disabled&&u.box("",...i)},success:(...i)=>{!r?.disabled&&u.success("",...i)},break:(...i)=>{!r?.disabled&&console.log(`
2
2
  `)}}),m=V();var k=r=>({id:"google",name:"Google",createAuthorizationURL({state:i,scopes:e,codeVerifier:t,redirectURI:o}){if(!r.clientId||!r.clientSecret)throw m.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new g("CLIENT_ID_AND_SECRET_REQUIRED");if(!t)throw new g("codeVerifier is required for Google");let n=r.scope||e||["email","profile"];return c({id:"google",options:r,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:n,state:i,codeVerifier:t,redirectURI:o})},validateAuthorizationCode:async({code:i,codeVerifier:e,redirectURI:t})=>a({code:i,codeVerifier:e,redirectURI:r.redirectURI||t,options:r,tokenEndpoint:"https://oauth2.googleapis.com/token"}),async getUserInfo(i){if(!i.idToken)return null;let e=F(i.idToken)?.payload;return{user:{id:e.sub,name:e.name,email:e.email,image:e.picture,emailVerified:e.email_verified},data:e}}});import{betterFetch as G}from"@better-fetch/fetch";import{parseJWT as j}from"oslo/jwt";var w=r=>{let i=r.tenantId||"common",e=`https://login.microsoftonline.com/${i}/oauth2/v2.0/authorize`,t=`https://login.microsoftonline.com/${i}/oauth2/v2.0/token`;return{id:"microsoft",name:"Microsoft EntraID",createAuthorizationURL(o){let n=r.scope||o.scopes||["openid","profile","email","User.Read"];return c({id:"microsoft",options:r,authorizationEndpoint:e,state:o.state,codeVerifier:o.codeVerifier,scopes:n,redirectURI:o.redirectURI})},validateAuthorizationCode({code:o,codeVerifier:n,redirectURI:s}){return a({code:o,codeVerifier:n,redirectURI:r.redirectURI||s,options:r,tokenEndpoint:t})},async getUserInfo(o){if(!o.idToken)return null;let n=j(o.idToken)?.payload,s=r.profilePhotoSize||48;return await G(`https://graph.microsoft.com/v1.0/me/photos/${s}x${s}/$value`,{headers:{Authorization:`Bearer ${o.accessToken}`},async onResponse(p){if(!(r.disableProfilePhoto||!p.response.ok))try{let d=await p.response.clone().arrayBuffer(),f=Buffer.from(d).toString("base64");n.picture=`data:image/jpeg;base64, ${f}`}catch(l){m.error(l)}}}),{user:{id:n.sub,name:n.name,email:n.email,image:n.picture,emailVerified:!0},data:n}}}};import{betterFetch as J}from"@better-fetch/fetch";var O=r=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:i,scopes:e,codeVerifier:t,redirectURI:o}){let n=r.scope||e||["user-read-email"];return c({id:"spotify",options:r,authorizationEndpoint:"https://accounts.spotify.com/authorize",scopes:n,state:i,codeVerifier:t,redirectURI:o})},validateAuthorizationCode:async({code:i,codeVerifier:e,redirectURI:t})=>a({code:i,codeVerifier:e,redirectURI:r.redirectURI||t,options:r,tokenEndpoint:"https://accounts.spotify.com/api/token"}),async getUserInfo(i){let{data:e,error:t}=await J("https://api.spotify.com/v1/me",{method:"GET",headers:{Authorization:`Bearer ${i.accessToken}`}});return t?null:{user:{id:e.id,name:e.display_name,email:e.email,image:e.images[0]?.url,emailVerified:!1},data:e}}});import"@better-fetch/fetch";import{nanoid as ir}from"nanoid";import{parseJWT as M}from"oslo/jwt";var U=r=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:i,scopes:e,redirectURI:t}){let o=r.scope||e||["user:read:email","openid"];return c({id:"twitch",redirectURI:t,options:r,authorizationEndpoint:"https://id.twitch.tv/oauth2/authorize",scopes:o,state:i,claims:r.claims||["email","email_verified","preferred_username","picture"]})},validateAuthorizationCode:async({code:i,redirectURI:e})=>a({code:i,redirectURI:r.redirectURI||e,options:r,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(i){let e=i.idToken;if(!e)return m.error("No idToken found in token"),null;let t=M(e)?.payload;return{user:{id:t.sub,name:t.preferred_username,email:t.email,image:t.picture,emailVerified:!1},data:t}}});import{betterFetch as N}from"@better-fetch/fetch";var z=r=>({id:"twitter",name:"Twitter",createAuthorizationURL(i){let e=r.scope||i.scopes||["account_info.read"];return c({id:"twitter",options:r,authorizationEndpoint:"https://twitter.com/i/oauth2/authorize",scopes:e,state:i.state,codeVerifier:i.codeVerifier,redirectURI:i.redirectURI})},validateAuthorizationCode:async({code:i,codeVerifier:e,redirectURI:t})=>a({code:i,codeVerifier:e,redirectURI:r.redirectURI||t,options:r,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(i){let{data:e,error:t}=await N("https://api.x.com/2/users/me?user.fields=profile_image_url",{method:"GET",headers:{Authorization:`Bearer ${i.accessToken}`}});return t||!e.data.email?null:{user:{id:e.data.id,name:e.data.name,email:e.data.email,image:e.data.profile_image_url,emailVerified:e.data.verified||!1},data:e}}});import{betterFetch as q}from"@better-fetch/fetch";var T=r=>{let i="https://api.dropboxapi.com/oauth2/token";return{id:"dropbox",name:"Dropbox",createAuthorizationURL:async({state:e,scopes:t,codeVerifier:o,redirectURI:n})=>{let s=r.scope||t||["account_info.read"];return await c({id:"dropbox",options:r,authorizationEndpoint:"https://www.dropbox.com/oauth2/authorize",scopes:s,state:e,redirectURI:n,codeVerifier:o})},validateAuthorizationCode:async({code:e,codeVerifier:t,redirectURI:o})=>await a({code:e,codeVerifier:t,redirectURI:r.redirectURI||o,options:r,tokenEndpoint:i}),async getUserInfo(e){let{data:t,error:o}=await q("https://api.dropboxapi.com/2/users/get_current_account",{method:"POST",headers:{Authorization:`Bearer ${e.accessToken}`}});return o?null:{user:{id:t.account_id,name:t.name?.display_name,email:t.email,emailVerified:t.email_verified||!1,image:t.profile_photo_url},data:t}}}};import{betterFetch as W}from"@better-fetch/fetch";var R=r=>{let i="https://www.linkedin.com/oauth/v2/authorization",e="https://www.linkedin.com/oauth/v2/accessToken";return{id:"linkedin",name:"Linkedin",createAuthorizationURL:async({state:t,scopes:o,redirectURI:n})=>{let s=r.scope||o||["profile","email","openid"];return await c({id:"linkedin",options:r,authorizationEndpoint:i,scopes:s,state:t,redirectURI:n})},validateAuthorizationCode:async({code:t,redirectURI:o})=>await a({code:t,redirectURI:r.redirectURI||o,options:r,tokenEndpoint:e}),async getUserInfo(t){let{data:o,error:n}=await W("https://api.linkedin.com/v2/userinfo",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});return n?null:{user:{id:o.sub,name:o.name,email:o.email,emailVerified:o.email_verified||!1,image:o.picture},data:o}}}};var H={apple:y,discord:v,facebook:x,github:P,microsoft:w,google:k,spotify:O,twitch:U,twitter:z,dropbox:T,linkedin:R},Dr=Object.keys(H);export{y as apple,v as discord,T as dropbox,x as facebook,P as github,k as google,R as linkedin,w as microsoft,Dr as socialProviderList,H as socialProviders,O as spotify,U as twitch,z as twitter};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-auth",
3
- "version": "0.5.3-beta.13",
3
+ "version": "0.5.3-beta.14",
4
4
  "description": "The most comprehensive authentication library for TypeScript.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -213,7 +213,7 @@
213
213
  "@noble/hashes": "^1.5.0",
214
214
  "@simplewebauthn/browser": "^10.0.0",
215
215
  "@simplewebauthn/server": "^10.0.1",
216
- "better-call": "0.2.9",
216
+ "better-call": "0.2.11",
217
217
  "consola": "^3.2.3",
218
218
  "defu": "^6.1.4",
219
219
  "jose": "^5.9.4",