better-auth 0.5.3-beta.6 → 0.5.3-beta.8
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/access.js +0 -1
- package/dist/adapters/drizzle.d.ts +1 -1
- package/dist/adapters/drizzle.js +0 -1
- package/dist/adapters/kysely.d.ts +1 -1
- package/dist/adapters/kysely.js +0 -1
- package/dist/adapters/mongodb.d.ts +1 -1
- package/dist/adapters/mongodb.js +0 -1
- package/dist/adapters/prisma.d.ts +1 -1
- package/dist/adapters/prisma.js +0 -1
- package/dist/api.d.ts +1 -1
- package/dist/api.js +1 -2
- package/dist/{auth-ChOWHZz7.d.ts → auth-B9t_YkMU.d.ts} +65 -19
- package/dist/client/plugins.d.ts +3 -3
- package/dist/client/plugins.js +0 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +0 -1
- package/dist/cookies.d.ts +1 -1
- package/dist/cookies.js +0 -1
- package/dist/crypto.js +0 -1
- package/dist/db.d.ts +2 -2
- package/dist/db.js +0 -1
- package/dist/{index-BwCQ9u_T.d.ts → index-ny_c9jGl.d.ts} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -4
- package/dist/next-js.js +0 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +0 -1
- package/dist/oauth2.js +0 -1
- package/dist/plugins.d.ts +3 -3
- package/dist/plugins.js +1 -2
- package/dist/react.d.ts +1 -1
- package/dist/react.js +0 -1
- package/dist/social.d.ts +2 -0
- package/dist/social.js +1 -2
- package/dist/solid-start.d.ts +1 -1
- package/dist/solid-start.js +0 -1
- package/dist/solid.d.ts +1 -1
- package/dist/solid.js +0 -1
- package/dist/svelte-kit.d.ts +1 -1
- package/dist/svelte-kit.js +0 -1
- package/dist/svelte.d.ts +1 -1
- package/dist/svelte.js +0 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.js +0 -1
- package/dist/vue.d.ts +1 -1
- package/dist/vue.js +0 -1
- package/package.json +1 -1
- package/dist/access.js.map +0 -1
- package/dist/adapters/drizzle.js.map +0 -1
- package/dist/adapters/kysely.js.map +0 -1
- package/dist/adapters/mongodb.js.map +0 -1
- package/dist/adapters/prisma.js.map +0 -1
- package/dist/api.js.map +0 -1
- package/dist/client/plugins.js.map +0 -1
- package/dist/client.js.map +0 -1
- package/dist/cookies.js.map +0 -1
- package/dist/crypto.js.map +0 -1
- package/dist/db.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/next-js.js.map +0 -1
- package/dist/node.js.map +0 -1
- package/dist/oauth2.js.map +0 -1
- package/dist/plugins.js.map +0 -1
- package/dist/react.js.map +0 -1
- package/dist/social.js.map +0 -1
- package/dist/solid-start.js.map +0 -1
- package/dist/solid.js.map +0 -1
- package/dist/svelte-kit.js.map +0 -1
- package/dist/svelte.js.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/vue.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{APIError as
|
|
2
|
-
`)}}),b=de();var x=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 Xt("FORBIDDEN",{message:`Invalid ${l}`})};s(n,"callbackURL"),s(a,"currentURL")});import{parseJWT as or}from"oslo/jwt";import{sha256 as er}from"oslo/crypto";import{base64url as tr}from"oslo/encoding";async function Ve(e){let t=await er(new TextEncoder().encode(e));return tr.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 E({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 rr}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 rr(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 je=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=or(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 nr}from"@better-fetch/fetch";var ze=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 nr("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 ir}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 E({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 ir("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,picture: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 E({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 sr}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 k("CLIENT_ID_AND_SECRET_REQUIRED");if(!o)throw new k("codeVerifier is required for Google");let n=e.scope||r||["email","profile"];return E({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=sr(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 ar}from"@better-fetch/fetch";import{parseJWT as dr}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 E({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=dr(i.idToken)?.payload,a=e.profilePhotoSize||48;return await ar(`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 cr}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 E({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 cr("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 Un(e){return e.charAt(0).toUpperCase()+e.slice(1)}var F={isAction:!1};import{nanoid as lr}from"nanoid";var v=e=>lr(e);import{parseJWT as ur}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 E({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=ur(r)?.payload;return{user:{id:o.sub,name:o.preferred_username,email:o.email,image:o.picture,emailVerified:!1},data:o}}});import{betterFetch as pr}from"@better-fetch/fetch";var Je=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(t){let r=e.scope||t.scopes||["account_info.read"];return E({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 pr("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}}});var le={apple:je,discord:ze,facebook:Me,github:Ke,microsoft:Ge,google:Ze,spotify:Qe,twitch:We,twitter:Je},Ye=Object.keys(le);import{TimeSpan as fr}from"oslo";import{createJWT as mr,validateJWT as gr}from"oslo/jwt";import{z as S}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 Xe}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}}),et=()=>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)}),tt=y("/user/revoke-session",{method:"POST",body:Xe.object({id:Xe.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})}),rt=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 mr("HS256",Buffer.from(e),{email:t.toLowerCase(),updateTo:r},{expiresIn:new fr(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}var ot=y("/send-verification-email",{method:"POST",query:S.object({currentURL:S.string().optional()}).optional(),body:S.object({email:S.string().email(),callbackURL:S.string().optional()}),use:[x]},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})}),nt=y("/verify-email",{method:"GET",query:S.object({token:S.string(),callbackURL:S.string().optional()}),use:[x]},async e=>{let{token:t}=e.query,r;try{r=await gr("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=S.object({email:S.string().email(),updateTo:S.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 it=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(Ye)}),use:[x]},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 P("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=hr();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})}),st=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:[x]},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:t,password:r}=e.body;if(!I.string().email().safeParse(t).success)throw new P("BAD_REQUEST",{message:"Invalid email"});if(!I.string().email().safeParse(t).success)throw new P("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 P("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 P("UNAUTHORIZED",{message:"Invalid email or password"});let c=a?.password;if(!c)throw e.context.logger.error("Password not found",{email:t}),new P("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(c,r))throw e.context.logger.error("Invalid password"),new P("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 P("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 P("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 P("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 Di=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()}),at=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)}),Ni=w.object({id:w.string(),userId:w.string(),expiresAt:w.date(),ipAddress:w.string().optional(),userAgent:w.string().optional()}),Fi=w.object({id:w.string(),value:w.string(),expiresAt:w.date(),identifier:w.string()});function dt(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 ct(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 lt(e,t){let r=dt(e,"user");return ct(t||{},{fields:r})}function ut(e,t){let r=dt(e,"user");return ct(t||{},{fields:r})}var pt=y("/callback/:id",{method:"GET",query:re.object({state:re.string(),code:re.string().optional(),error:re.string().optional()}),metadata:F},async e=>{if(e.query.error||!e.query.code){let U=ae(e.query.state).data?.callbackURL||`${e.context.baseURL}/error`;throw e.context.logger.error(e.query.error,e.params.id),e.redirect(`${U}?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=at.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.
|
|
1
|
+
import{APIError as It,createRouter as Er,statusCode as vr}from"better-call";import{APIError as se}from"better-call";import{z as Se}from"zod";import{xchacha20poly1305 as zr}from"@noble/ciphers/chacha";import{bytesToHex as Hr,hexToBytes as Kr,utf8ToBytes as Zr}from"@noble/ciphers/utils";import{managedNonce as Qr}from"@noble/ciphers/webcrypto";import{sha256 as Jr}from"oslo/crypto";import ve 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 $t,encodeHex as be}from"oslo/encoding";import{scryptAsync as jt}from"@noble/hashes/scrypt";import{getRandomValues as zt}from"uncrypto";var z={N:16384,r:16,p:1,dkLen:64};async function Ae(e,t){return await jt(e.normalize("NFKC"),t,{N:z.N,p:z.p,r:z.r,dkLen:z.dkLen,maxmem:128*z.N*z.r*2})}var ke=async e=>{let t=be(zt(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,$t(o))};import Ue from"uncrypto";function Mt(e){return e.toString(2).padStart(8,"0")}function Ht(e){return[...e].map(t=>Mt(t)).join("")}function Te(e){return parseInt(Ht(e),2)}function Kt(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));Ue.getRandomValues(o),r!==0&&(o[0]&=(1<<r)-1);let i=Te(o);for(;i>=e;)Ue.getRandomValues(o),r!==0&&(o[0]&=(1<<r)-1),i=Te(o);return i}function xe(e,t){let r="";for(let o=0;o<e;o++)r+=t[Kt(t.length)];return r}function Ee(...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 ve.subtle.importKey("raw",r.encode(e),o,!1,["sign","verify"]),n=await ve.subtle.sign(o.name,i,r.encode(t));return btoa(String.fromCharCode(...new Uint8Array(n)))}import{createEndpointCreator as Zt,createMiddleware as Ie,createMiddlewareCreator as Gt}from"better-call";var Oe=Ie(async()=>({})),M=Gt({use:[Oe,Ie(async()=>({}))]}),y=Zt({use:[Oe]});var Pe=M({body:Se.object({csrfToken:Se.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 P}from"better-call";import{generateCodeVerifier as hr}from"oslo/oauth2";import{z as O}from"zod";import{generateState as Qt}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=Qt(),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 Wt}from"oslo";var k=class extends Error{constructor(t,r){super(t),this.name="BetterAuthError",this.message=t,this.cause=r,this.stack=""}},De=class extends k{constructor(t){super(`The package "${t}" is required. Make sure it is installed.`,t)}};import{env as Jt,isProduction as Ne}from"std-env";function Fe(e){let r=(e.advanced?.useSecureCookies!==void 0?e.advanced?.useSecureCookies:e.baseURL!==void 0?!!e.baseURL.startsWith("https://"):Ne)?"__Secure-":"",o="better-auth",i=e.session?.expiresIn||new Wt(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 k("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://")||Ne)?"__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:Jt.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 Eo(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 vo(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 Xt}from"better-call";import{createConsola as Yt}from"consola";var V=Yt({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 x=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 Xt("FORBIDDEN",{message:`Invalid ${l}`})};s(n,"callbackURL"),s(a,"currentURL")});import{parseJWT as or}from"oslo/jwt";import{sha256 as er}from"oslo/crypto";import{base64url as tr}from"oslo/encoding";async function Ve(e){let t=await er(new TextEncoder().encode(e));return tr.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 E({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 rr}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 rr(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 je=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=or(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 nr}from"@better-fetch/fetch";var ze=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 nr("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 ir}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 E({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 ir("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 E({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 sr}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 k("CLIENT_ID_AND_SECRET_REQUIRED");if(!o)throw new k("codeVerifier is required for Google");let n=e.scope||r||["email","profile"];return E({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=sr(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 ar}from"@better-fetch/fetch";import{parseJWT as dr}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 E({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=dr(i.idToken)?.payload,a=e.profilePhotoSize||48;return await ar(`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 cr}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 E({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 cr("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 Un(e){return e.charAt(0).toUpperCase()+e.slice(1)}var F={isAction:!1};import{nanoid as lr}from"nanoid";var v=e=>lr(e);import{parseJWT as ur}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 E({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=ur(r)?.payload;return{user:{id:o.sub,name:o.preferred_username,email:o.email,image:o.picture,emailVerified:!1},data:o}}});import{betterFetch as pr}from"@better-fetch/fetch";var Je=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(t){let r=e.scope||t.scopes||["account_info.read"];return E({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 pr("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}}});var le={apple:je,discord:ze,facebook:Me,github:Ke,microsoft:Ge,google:Ze,spotify:Qe,twitch:We,twitter:Je},Ye=Object.keys(le);import{TimeSpan as fr}from"oslo";import{createJWT as mr,validateJWT as gr}from"oslo/jwt";import{z as S}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 Xe}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}}),et=()=>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)}),tt=y("/user/revoke-session",{method:"POST",body:Xe.object({id:Xe.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})}),rt=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 mr("HS256",Buffer.from(e),{email:t.toLowerCase(),updateTo:r},{expiresIn:new fr(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}var ot=y("/send-verification-email",{method:"POST",query:S.object({currentURL:S.string().optional()}).optional(),body:S.object({email:S.string().email(),callbackURL:S.string().optional()}),use:[x]},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})}),nt=y("/verify-email",{method:"GET",query:S.object({token:S.string(),callbackURL:S.string().optional()}),use:[x]},async e=>{let{token:t}=e.query,r;try{r=await gr("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=S.object({email:S.string().email(),updateTo:S.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 it=y("/sign-in/social",{method:"POST",requireHeaders:!0,query:O.object({currentURL:O.string().optional()}).optional(),body:O.object({callbackURL:O.string().optional(),provider:O.enum(Ye)}),use:[x]},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 P("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=hr();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})}),st=y("/sign-in/email",{method:"POST",body:O.object({email:O.string(),password:O.string(),callbackURL:O.string().optional(),dontRememberMe:O.boolean().default(!1).optional()}),use:[x]},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:t,password:r}=e.body;if(!O.string().email().safeParse(t).success)throw new P("BAD_REQUEST",{message:"Invalid email"});if(!O.string().email().safeParse(t).success)throw new P("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 P("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 P("UNAUTHORIZED",{message:"Invalid email or password"});let c=a?.password;if(!c)throw e.context.logger.error("Password not found",{email:t}),new P("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(c,r))throw e.context.logger.error("Invalid password"),new P("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 P("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 P("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 P("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 Di=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()}),at=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)}),Ni=w.object({id:w.string(),userId:w.string(),expiresAt:w.date(),ipAddress:w.string().optional(),userAgent:w.string().optional()}),Fi=w.object({id:w.string(),value:w.string(),expiresAt:w.date(),identifier:w.string()});function dt(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 ct(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 lt(e,t){let r=dt(e,"user");return ct(t||{},{fields:r})}function ut(e,t){let r=dt(e,"user");return ct(t||{},{fields:r})}var pt=y("/callback/:id",{method:"GET",query:re.object({state:re.string(),code:re.string().optional(),error:re.string().optional()}),metadata:F},async e=>{if(e.query.error||!e.query.code){let U=ae(e.query.state).data?.callbackURL||`${e.context.baseURL}/error`;throw e.context.logger.error(e.query.error,e.params.id),e.redirect(`${U}?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=at.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(U=>U.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,U=await e.context.internalAdapter.createOAuthUser({...f.data,emailVerified:m},{...ce(s),providerId:t.id,accountId:d.id.toString()});if(g=U?.user.id,!m&&U&&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?.(U.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 yr}from"better-call";var ft=y("/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),G(e),e.json({success:!0})});import{z as L}from"zod";import{APIError as oe}from"better-call";var mt=y("/forget-password",{method:"POST",body:L.object({email:L.string().email(),redirectTo:L.string()}),use:[x]},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})}),gt=y("/reset-password/:token",{method:"GET",query:L.object({callbackURL:L.string()}),use:[x]},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}`)}),ht=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 T}from"better-call";var yt=()=>y("/user/update",{method:"POST",body:R.record(R.string(),R.any()),use:[C,x]},async e=>{let t=e.body;if(t.email)throw new T("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=lt(e.context.options,i),c=await e.context.internalAdapter.updateUserByEmail(n.user.email,{name:r,image:o,...a});return e.json({user:c})}),wt=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 T("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 T("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 T("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 T("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 T("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});await _(e,f.id)}return e.json(i.user)}),bt=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 T("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 T("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 T("BAD_REQUEST",{message:"user already has a password"})}),At=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 T("BAD_REQUEST",{message:"User does not have a password"});if(!await e.context.password.verify(i.password,t))throw new T("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)}),kt=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,x]},async e=>{if(!e.context.options.user?.changeEmail?.enabled)throw e.context.logger.error("Change email is disabled."),new T("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 T("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 T("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 T("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 Rt=y("/csrf",{method:"GET",metadata:F},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=xe(32,Ee("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 wr=(e="Unknown")=>`<!DOCTYPE html>
|
|
4
4
|
<html lang="en">
|
|
5
5
|
<head>
|
|
@@ -80,5 +80,4 @@ Error: `,m),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)
|
|
|
80
80
|
<div class="error-code">Error Code: <span id="errorCode">${e}</span></div>
|
|
81
81
|
</div>
|
|
82
82
|
</body>
|
|
83
|
-
</html>`,Ut=y("/error",{method:"GET",metadata:F},async e=>{let t=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(wr(t),{headers:{"Content-Type":"text/html"}})});var Tt=y("/ok",{method:"GET",metadata:F},async e=>e.json({ok:!0}));import{z as K}from"zod";import{APIError as D}from"better-call";var xt=()=>y("/sign-up/email",{method:"POST",query:K.object({currentURL:K.string().optional()}).optional(),body:K.record(K.string(),K.any()),use:[x]},async e=>{if(!e.context.options.emailAndPassword?.enabled)throw new D("BAD_REQUEST",{message:"Email and password sign up is not enabled"});let t=e.body,{name:r,email:o,password:i,image:n,callbackURL:a,...c}=t;if(!K.string().email().safeParse(o).success)throw new D("BAD_REQUEST",{message:"Invalid email"});let d=e.context.password.config.minPasswordLength;if(i.length<d)throw e.context.logger.error("Password is too short"),new D("BAD_REQUEST",{message:"Password is too short"});let l=e.context.password.config.maxPasswordLength;if(i.length>l)throw e.context.logger.error("Password is too long"),new D("BAD_REQUEST",{message:"Password is too long"});if((await e.context.internalAdapter.findUserByEmail(o))?.user)throw e.context.logger.info(`Sign-up attempt for existing email: ${o}`),new D("UNPROCESSABLE_ENTITY",{message:"Failed to create user"});let u=ut(e.context.options,c),p;try{if(p=await e.context.internalAdapter.createUser({email:o.toLowerCase(),name:r,image:n,...u,emailVerified:!1}),!p)throw new D("BAD_REQUEST",{message:"Failed to create user"})}catch(m){throw new D("UNPROCESSABLE_ENTITY",{message:"Failed to create user",details:m})}if(!p)throw new D("UNPROCESSABLE_ENTITY",{message:"Failed to create user"});let g=await e.context.password.hash(i);if(await e.context.internalAdapter.linkAccount({userId:p.id,providerId:"credential",accountId:p.id,password:g,expiresAt:$(60*60*24*30,"sec")}),e.context.options.emailVerification?.sendOnSignUp){let m=await B(e.context.secret,p.email),U=`${e.context.baseURL}/verify-email?token=${m}&callbackURL=${t.callbackURL||e.query?.currentURL||"/"}`;await e.context.options.emailVerification?.sendVerificationEmail?.(p,U,m)}if(!e.context.options.emailAndPassword.autoSignIn||e.context.options.emailAndPassword.requireEmailVerification)return e.json({user:p,session:null},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:p,session:null}});let h=await e.context.internalAdapter.createSession(p.id,e.request);if(!h)throw new D("BAD_REQUEST",{message:"Failed to create session"});return await _(e,h.id),e.json({user:p,session:h},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:p,session:h}})});import{isTest as br}from"std-env";function ne(e){let t="127.0.0.1";if(br)return t;let r=["x-client-ip","x-forwarded-for","cf-connecting-ip","fastly-client-ip","x-real-ip","x-cluster-client-ip","x-forwarded","forwarded-for","forwarded"],o=e instanceof Request?e.headers:e;for(let i of r){let n=o.get(i);if(typeof n=="string"){let a=n.split(",")[0].trim();if(a)return a}}return null}function Ar(e,t,r){let o=Date.now(),i=t*1e3;return o-r.lastRequest<i&&r.count>=e}function kr(e){return new Response(JSON.stringify({message:"Too many requests. Please try again later."}),{status:429,statusText:"Too Many Requests",headers:{"X-Retry-After":e.toString()}})}function Rr(e,t){let r=Date.now(),o=t*1e3;return Math.ceil((e+o-r)/1e3)}function Ur(e,t){let r=t??"rateLimit",o=e.adapter;return{get:async i=>await o.findOne({model:r,where:[{field:"key",value:i}]}),set:async(i,n,a)=>{try{a?await o.update({model:t??"rateLimit",where:[{field:"key",value:i}],update:{count:n.count,lastRequest:n.lastRequest}}):await o.create({model:t??"rateLimit",data:{key:i,count:n.count,lastRequest:n.lastRequest}})}catch(c){b.error("Error setting rate limit",c)}}}}var Et=new Map;function Tr(e){return e.rateLimit.storage==="secondary-storage"?{get:async r=>{let o=await e.options.secondaryStorage?.get(r);return o?JSON.parse(o):void 0},set:async(r,o)=>{await e.options.secondaryStorage?.set?.(r,JSON.stringify(o))}}:e.rateLimit.storage==="memory"?{async get(r){return Et.get(r)},async set(r,o,i){Et.set(r,o)}}:Ur(e,e.rateLimit.tableName)}async function vt(e,t){if(!t.rateLimit.enabled)return;let r=t.baseURL,o=e.url.replace(r,""),i=t.rateLimit.window,n=t.rateLimit.max,a=ne(e)+o,s=xr().find(u=>u.pathMatcher(o));s&&(i=s.window,n=s.max);for(let u of t.options.plugins||[])if(u.rateLimit){let p=u.rateLimit.find(g=>g.pathMatcher(o));if(p){i=p.window,n=p.max;break}}if(t.rateLimit.customRules){let u=t.rateLimit.customRules[o];u&&(i=u.window,n=u.max)}let d=Tr(t),l=await d.get(a),f=Date.now();if(!l)await d.set(a,{key:a,count:1,lastRequest:f});else{let u=f-l.lastRequest;if(Ar(n,i,l)){let p=Rr(l.lastRequest,i);return kr(p)}else u>i*1e3?await d.set(a,{...l,count:1,lastRequest:f}):await d.set(a,{...l,count:l.count+1,lastRequest:f})}}function xr(){return[{pathMatcher(t){return t.startsWith("/sign-in")||t.startsWith("/sign-up")},window:10,max:3}]}import{APIError as Ia}from"better-call";function fe(e,t){let r=t.plugins?.reduce((c,s)=>({...c,...s.endpoints}),{}),o=t.plugins?.map(c=>c.middlewares?.map(s=>{let d=async l=>s.middleware({...l,context:{...e,...l.context}});return d.path=s.path,d.options=s.middleware.options,d.headers=s.middleware.headers,{path:s.path,middleware:d}})).filter(c=>c!==void 0).flat()||[],n={...{signInOAuth:it,callbackOAuth:pt,getCSRFToken:Rt,getSession:ue(),signOut:ft,signUpEmail:xt(),signInEmail:st,forgetPassword:mt,resetPassword:ht,verifyEmail:nt,sendVerificationEmail:ot,changeEmail:kt,changePassword:wt,setPassword:bt,updateUser:yt(),deleteUser:At,forgetPasswordCallback:gt,listSessions:et(),revokeSession:tt,revokeSessions:rt},...r,ok:Tt,error:Ut},a={};for(let[c,s]of Object.entries(n))a[c]=async(d={})=>{let l=await e;for(let p of t.plugins||[])if(p.hooks?.before){for(let g of p.hooks.before)if(g.matcher({...s,...d,context:l})){let m=await g.handler({...d,context:{...l,...d?.context}});m&&"context"in m&&(l={...l,...m.context})}}let f;try{f=await s({...d,context:{...l,...d.context}})}catch(p){if(p instanceof Ot){let g=t.plugins?.map(m=>{if(m.hooks?.after)return m.hooks.after}).filter(m=>m!==void 0).flat();if(!g?.length)throw p;let h=new Response(JSON.stringify(p.body),{status:vr[p.status],headers:p.headers});for(let m of g||[])if(m.matcher(d)){let Z=Object.assign(d,{context:{...e,returned:h}}),q=await m.handler(Z);q&&"response"in q&&(h=q.response)}return h}throw p}let u=f;for(let p of t.plugins||[])if(p.hooks?.after){for(let g of p.hooks.after)if(g.matcher(d)){let m=Object.assign(d,{context:{...e,returned:u}}),U=await g.handler(m);U&&"response"in U&&(u=U.response)}}return u},a[c].path=s.path,a[c].method=s.method,a[c].options=s.options,a[c].headers=s.headers;return{api:a,middlewares:o}}var It=(e,t)=>{let{api:r,middlewares:o}=fe(e,t),i=new URL(e.baseURL).pathname;return Er(r,{extraContext:e,basePath:i,routerMiddleware:[{path:"/**",middleware:Pe},...o],async onRequest(n){for(let a of e.options.plugins||[])if(a.onRequest){let c=await a.onRequest(n,e);if(c)return c}return vt(n,e)},async onResponse(n){for(let a of e.options.plugins||[])if(a.onResponse){let c=await a.onResponse(n,e);if(c)return c.response}return n},onError(n){if(t.onAPIError?.throw)throw n;if(t.onAPIError?.onError){t.onAPIError.onError(n,e);return}let a=t.logger?.verboseLogging?b:void 0;t.logger?.disabled!==!0&&(n instanceof Ot?(n.status==="INTERNAL_SERVER_ERROR"&&b.error(n),a?.error(n.message)):b?.error(n))}})};var N=e=>{let t=e.plugins?.reduce((s,d)=>{let l=d.schema;if(!l)return s;for(let[f,u]of Object.entries(l))s[f]={fields:{...s[f]?.fields,...u.fields},tableName:u.tableName||f};return s},{}),r=e.rateLimit?.storage==="database",o={rateLimit:{tableName:e.rateLimit?.tableName||"rateLimit",fields:{key:{type:"string",fieldName:e.rateLimit?.fields?.key||"key"},count:{type:"number",fieldName:e.rateLimit?.fields?.count||"count"},lastRequest:{type:"number",fieldName:e.rateLimit?.fields?.lastRequest||"lastRequest"}}}},{user:i,session:n,account:a,...c}=t||{};return{user:{tableName:e.user?.modelName||"user",fields:{name:{type:"string",required:!0,fieldName:e.user?.fields?.name||"name"},email:{type:"string",unique:!0,required:!0,fieldName:e.user?.fields?.email||"email"},emailVerified:{type:"boolean",defaultValue:()=>!1,required:!0,fieldName:e.user?.fields?.emailVerified||"emailVerified"},image:{type:"string",required:!1,fieldName:e.user?.fields?.image||"image"},createdAt:{type:"date",defaultValue:()=>new Date,required:!0,fieldName:e.user?.fields?.createdAt||"createdAt"},updatedAt:{type:"date",defaultValue:()=>new Date,required:!0,fieldName:e.user?.fields?.updatedAt||"updatedAt"},...i?.fields,...e.user?.additionalFields},order:1},session:{tableName:e.session?.modelName||"session",fields:{expiresAt:{type:"date",required:!0,fieldName:e.session?.fields?.expiresAt||"expiresAt"},ipAddress:{type:"string",required:!1,fieldName:e.session?.fields?.ipAddress||"ipAddress"},userAgent:{type:"string",required:!1,fieldName:e.session?.fields?.userAgent||"userAgent"},userId:{type:"string",fieldName:e.session?.fields?.userId||"userId",references:{model:e.user?.modelName||"user",field:"id",onDelete:"cascade"},required:!0},...n?.fields,...e.session?.additionalFields},order:2},account:{tableName:e.account?.modelName||"account",fields:{accountId:{type:"string",required:!0,fieldName:e.account?.fields?.accountId||"accountId"},providerId:{type:"string",required:!0,fieldName:e.account?.fields?.providerId||"providerId"},userId:{type:"string",references:{model:e.user?.modelName||"user",field:"id",onDelete:"cascade"},required:!0,fieldName:e.account?.fields?.userId||"userId"},accessToken:{type:"string",required:!1,fieldName:e.account?.fields?.accessToken||"accessToken"},refreshToken:{type:"string",required:!1,fieldName:e.account?.fields?.refreshToken||"refreshToken"},idToken:{type:"string",required:!1,fieldName:e.account?.fields?.idToken||"idToken"},expiresAt:{type:"date",required:!1,fieldName:e.account?.fields?.expiresAt||"expiresAt"},password:{type:"string",required:!1,fieldName:e.account?.fields?.password||"password"},...a?.fields},order:3},verification:{tableName:e.verification?.modelName||"verification",fields:{identifier:{type:"string",required:!0,fieldName:e.verification?.fields?.identifier||"identifier"},value:{type:"string",required:!0,fieldName:e.verification?.fields?.value||"value"},expiresAt:{type:"date",required:!0,fieldName:e.verification?.fields?.expiresAt||"expiresAt"}},order:4},...c,...r?o:{}}};import{Kysely as St,MssqlDialect as Or}from"kysely";import{MysqlDialect as Pt,PostgresDialect as Lt,SqliteDialect as _t}from"kysely";function Ct(e){if("dialect"in e)return Ct(e.dialect);if("createDriver"in e){if(e instanceof _t)return"sqlite";if(e instanceof Pt)return"mysql";if(e instanceof Lt)return"postgres";if(e instanceof Or)return"mssql"}return"aggregate"in e?"sqlite":"getConnection"in e?"mysql":"connect"in e?"postgres":null}var W=async e=>{let t=e.database;if("db"in t)return{kysely:t.db,databaseType:t.type};if("dialect"in t)return{kysely:new St({dialect:t.dialect}),databaseType:t.type};let r,o=Ct(t);return"createDriver"in t&&(r=t),"aggregate"in t&&(r=new _t({database:t})),"getConnection"in t&&(r=new Pt({pool:t})),"connect"in t&&(r=new Lt({pool:t})),{kysely:r?new St({dialect:r}):null,databaseType:o}};function J(e){if(!e)return{and:null,or:null};let t={and:[],or:[]};return e.forEach(r=>{let{field:o,value:i,operator:n="=",connector:a="AND"}=r,c=s=>n.toLowerCase()==="in"?s(o,"in",Array.isArray(i)?i:[i]):n==="contains"?s(o,"like",`%${i}%`):n==="starts_with"?s(o,"like",`${i}%`):n==="ends_with"?s(o,"like",`%${i}`):s(o,n,i);a==="OR"?t.or.push(c):t.and.push(c)}),{and:t.and.length?t.and:null,or:t.or.length?t.or:null}}function ie(e,t,r){for(let o in e){let i=t[o]||Object.values(t).find(n=>n.fieldName===o);e[o]===0&&i.type==="boolean"&&r?.boolean&&(e[o]=!1),e[o]===1&&i?.type==="boolean"&&r?.boolean&&(e[o]=!0),i?.type==="date"&&(e[o]instanceof Date||(e[o]=new Date(e[o])))}return e}function Bt(e,t){for(let r in e)typeof e[r]=="boolean"&&t?.boolean&&(e[r]=e[r]?1:0),e[r]instanceof Date&&(e[r]=e[r].toISOString());return e}var Dt=(e,t)=>({id:"kysely",async create(r){let{model:o,data:i,select:n}=r;t?.transform&&(i=Bt(i,t.transform)),t?.generateId!==void 0&&(i.id=t.generateId?t.generateId():void 0);let a=await e.insertInto(o).values(i).returningAll().executeTakeFirst();if(t?.transform){let c=t.transform.schema[o];a=c?ie(i,c,t.transform):a}return n?.length&&(a=a?n.reduce((s,d)=>a?.[d]?{...s,[d]:a[d]}:s,{}):null),a},async findOne(r){let{model:o,where:i,select:n}=r,{and:a,or:c}=J(i),s=e.selectFrom(o).selectAll();a&&(s=s.where(l=>l.and(a.map(f=>f(l))))),c&&(s=s.where(l=>l.or(c.map(f=>f(l)))));let d=await s.executeTakeFirst();if(n?.length&&(d=d?n.reduce((f,u)=>d?.[u]?{...f,[u]:d[u]}:f,{}):null),t?.transform){let l=t.transform.schema[o];return d=d&&l?ie(d,l,t.transform):d,d||null}return d||null},async findMany(r){let{model:o,where:i,limit:n,offset:a,sortBy:c}=r,s=e.selectFrom(o),{and:d,or:l}=J(i);d&&(s=s.where(u=>u.and(d.map(p=>p(u))))),l&&(s=s.where(u=>u.or(l.map(p=>p(u))))),s=s.limit(n||100),a&&(s=s.offset(a)),c&&(s=s.orderBy(c.field,c.direction));let f=await s.selectAll().execute();if(t?.transform){let u=t.transform.schema[o];return u?f.map(p=>ie(p,u,t.transform)):f}return f},async update(r){let{model:o,where:i,update:n}=r,{and:a,or:c}=J(i);t?.transform&&(n=Bt(n,t.transform)),n.id&&(n.id=void 0);let s=e.updateTable(o).set(n);a&&(s=s.where(l=>l.and(a.map(f=>f(l))))),c&&(s=s.where(l=>l.or(c.map(f=>f(l)))));let d=await s.returningAll().executeTakeFirst()||null;if(t?.transform){let l=t.transform.schema[o];return l?ie(d,l,t.transform):d}return d},async delete(r){let{model:o,where:i}=r,{and:n,or:a}=J(i),c=e.deleteFrom(o);n&&(c=c.where(s=>s.and(n.map(d=>d(s))))),a&&(c=c.where(s=>s.or(a.map(d=>d(s))))),await c.execute()},async deleteMany(r){let{model:o,where:i}=r,{and:n,or:a}=J(i),c=e.deleteFrom(o);n&&(c=c.where(s=>s.and(n.map(d=>d(s))))),a&&(c=c.where(s=>s.or(a.map(d=>d(s))))),await c.execute()}});async function Nt(e){if(!e.database)throw new k("Database configuration is required");if("create"in e.database)return e.database;let{kysely:t,databaseType:r}=await W(e);if(!t)throw new k("Failed to initialize database adapter");let o=N(e),i={};for(let n of Object.values(o))i[n.tableName]=n.fields;return Dt(t,{transform:{schema:i,date:!0,boolean:r==="sqlite"},generateId:"generateId"in e.database?e.database.generateId:void 0})}function me(e,t){let r={id:t.id};for(let o in e){let i=e[o],n=t[o];r[i.fieldName||o]=n}return r}function O(e,t){if(!t)return null;let r={id:t.id};for(let[o,i]of Object.entries(e))r[o]=t[i.fieldName||o];return r}function Ft(e,t){let r=t.hooks,o=N(t.options);async function i(a,c,s){let d=a,l=o[c];for(let p of r||[]){let g=p[c]?.create?.before;if(g){let h=await g(a);if(h===!1)return null;typeof h=="object"&&"data"in h&&(d=h.data)}}let f=s?await s.fn(d):null,u=!s||s.executeMainFn?await e.create({model:l.tableName,data:{...me(l.fields,d),id:d.id||v()}}):f;for(let p of r||[]){let g=p[c]?.create?.after;g&&await g(u)}return O(l.fields,u)}async function n(a,c,s,d){let l=a;for(let p of r||[]){let g=p[s]?.update?.before;if(g){let h=await g(a);if(h===!1)return null;l=typeof h=="object"?h.data:h}}let f=d?await d.fn(l):null,u=!d||d.executeMainFn?await e.update({model:o[s].tableName,update:me(o[s].fields,l),where:c}):f;for(let p of r||[]){let g=p[s]?.update?.after;g&&await g(u)}return O(o[s].fields,u)}return{createWithHooks:i,updateWithHooks:n}}var ge=(e,t)=>{let r=t.options,o=r.secondaryStorage,i=r.session?.expiresIn||60*60*24*7,n=N(r),{createWithHooks:a,updateWithHooks:c}=Ft(e,t);return{createOAuthUser:async(s,d)=>{try{let l=await a({id:v(),createdAt:new Date,updatedAt:new Date,...s},"user"),f=await a({id:v(),...d,userId:l.id||s.id},"account");return{user:l,account:f}}catch(l){return console.log(l),null}},createUser:async s=>await a({id:v(),createdAt:new Date,updatedAt:new Date,emailVerified:!1,...s},"user"),createAccount:async s=>await a({id:v(),createdAt:new Date,updatedAt:new Date,...s},"account"),listSessions:async s=>await e.findMany({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]}),listUsers:async(s,d,l,f)=>(await e.findMany({model:n.user.tableName,limit:s,offset:d,sortBy:l,where:f})).map(p=>O(n.user.fields,p)),deleteUser:async s=>{await e.delete({model:n.account.tableName,where:[{field:n.account.fields.userId.fieldName||"userId",value:s}]}),await e.deleteMany({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]}),await e.deleteMany({model:n.user.tableName,where:[{field:"id",value:s}]})},createSession:async(s,d,l,f)=>{let u=d instanceof Request?d.headers:d,p={id:v(),userId:s,expiresAt:l?$(60*60*24,"sec"):$(i,"sec"),ipAddress:d&&ne(d)||"",userAgent:u?.get("user-agent")||"",...f};return await a(p,"session",o?{fn:async h=>{let m=await e.findOne({model:n.user.tableName,where:[{field:"id",value:s}]});return o.set(h.id,JSON.stringify({session:h,user:m}),i),h},executeMainFn:r.session?.storeSessionInDatabase}:void 0)},findSession:async s=>{if(o){let f=await o.get(s);if(f){let u=JSON.parse(f);return{session:{...u.session,expiresAt:new Date(u.session.expiresAt)},user:{...u.user,createdAt:new Date(u.user.createdAt),updatedAt:new Date(u.user.updatedAt)}}}}let d=await e.findOne({model:n.session.tableName,where:[{value:s,field:"id"}]});if(!d)return null;let l=await e.findOne({model:n.user.tableName,where:[{value:d.userId,field:"id"}]});return l?{session:O(n.session.fields,d),user:O(n.user.fields,l)}:null},findSessions:async s=>{if(o){let u=[];for(let p of s){let g=await o.get(p);if(g){let h=JSON.parse(g),m={session:{...h.session,expiresAt:new Date(h.session.expiresAt)},user:{...h.user,createdAt:new Date(h.user.createdAt),updatedAt:new Date(h.user.updatedAt)}};u.push(m)}}return u}let d=await e.findMany({model:n.session.tableName,where:[{field:"id",value:s,operator:"in"}]}),l=d.map(u=>u.userId);if(!l.length)return[];let f=await e.findMany({model:n.user.tableName,where:[{field:"id",value:l,operator:"in"}]});return d.map(u=>{let p=f.find(g=>g.id===u.userId);return p?{session:O(n.session.fields,u),user:O(n.user.fields,p)}:null})},updateSession:async(s,d)=>await c(d,[{field:"id",value:s}],"session",o?{async fn(f){let u=await o.get(s),p=null;if(u){let g=JSON.parse(u);p={...g.session,...f},await o.set(s,JSON.stringify({session:p,user:g.user}),g.session.expiresAt?new Date(g.session.expiresAt).getTime():void 0)}else return null},executeMainFn:r.session?.storeSessionInDatabase}:void 0),deleteSession:async s=>{if(o){await o.delete(s),r.session?.storeSessionInDatabase&&await e.delete({model:n.session.tableName,where:[{field:"id",value:s}]});return}await e.delete({model:n.session.tableName,where:[{field:"id",value:s}]})},deleteSessions:async s=>{if(o){let d=await e.findMany({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]});for(let l of d)await o.delete(l.id);r.session?.storeSessionInDatabase&&await e.delete({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]});return}await e.deleteMany({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]})},findUserByEmail:async(s,d)=>{let l=await e.findOne({model:n.user.tableName,where:[{value:s.toLowerCase(),field:n.user.fields.email.fieldName||"email"}]});if(!l)return null;if(d?.includeAccounts){let f=await e.findMany({model:n.account.tableName,where:[{value:l.id,field:n.account.fields.userId.fieldName||"userId"}]});return{user:O(n.user.fields,l),accounts:f.map(u=>O(n.account.fields,u))}}return{user:O(n.user.fields,l),accounts:[]}},findUserById:async s=>await e.findOne({model:n.user.tableName,where:[{field:"id",value:s}]}),linkAccount:async s=>await a({id:v(),...s},"account"),updateUser:async(s,d)=>await c(d,[{field:"id",value:s}],"user"),updateUserByEmail:async(s,d)=>await c(d,[{field:n.user.fields.email.fieldName||"email",value:s}],"user"),updatePassword:async(s,d)=>await c({password:d},[{field:n.account.fields.userId.fieldName||"userId",value:s},{field:n.account.fields.providerId.fieldName||"providerId",value:"credential"}],"account"),findAccounts:async s=>(await e.findMany({model:n.account.tableName,where:[{field:n.account.fields.userId.fieldName||"userId",value:s}]})).map(l=>O(n.account.fields,l)),updateAccount:async(s,d)=>await c(d,[{field:"id",value:s}],"account"),createVerificationValue:async s=>await a({id:v(),...s},"verification"),findVerificationValue:async s=>{let d=await e.findOne({model:n.verification.tableName,where:[{field:n.verification.fields.identifier.fieldName||"identifier",value:s}]});return O(n.verification.fields,d)},deleteVerificationValue:async s=>{await e.delete({model:n.verification.tableName,where:[{field:"id",value:s}]})},updateVerificationValue:async(s,d)=>await c(d,[{field:"id",value:s}],"verification")}};import{z as td}from"zod";import"kysely";import{env as we,isProduction as qt}from"std-env";import{defu as Sr}from"defu";import{env as j}from"std-env";function Ir(e){try{return new URL(e).pathname!=="/"}catch{throw new k(`Invalid base URL: ${e}. Please provide a valid base URL.`)}}function he(e,t="/api/auth"){return Ir(e)?e:(t=t.startsWith("/")?t:`/${t}`,`${e}${t}`)}function Y(e,t){if(e)return he(e,t);let r=j.BETTER_AUTH_URL||j.NEXT_PUBLIC_BETTER_AUTH_URL||j.PUBLIC_BETTER_AUTH_URL||j.NUXT_PUBLIC_BETTER_AUTH_URL||j.NUXT_PUBLIC_AUTH_URL||(j.BASE_URL!=="/"?j.BASE_URL:void 0);if(r)return he(r,t);if(typeof window<"u")return he(window.location.origin,t)}var ye="better-auth-secret-123456789";var Vt=async e=>{let t=await Nt(e),r=e.plugins||[],o=Lr(e),{kysely:i}=await W(e),n=Y(e.baseURL,e.basePath);if(!n)throw new k("Base URL can not be empty. Please add `BETTER_AUTH_URL` in your environment variables or pass it your auth config.");let a=e.secret||we.BETTER_AUTH_SECRET||we.AUTH_SECRET||ye;if(a===ye&&qt)throw new k("You are using the default secret. Please set `BETTER_AUTH_SECRET` or `AUTH_SECRET` in your environment variables or pass `secret` in your auth config.");e={...e,secret:a,baseURL:n?new URL(n).origin:"",basePath:e.basePath||"/api/auth",plugins:r.concat(o),emailAndPassword:{...e.emailAndPassword,enabled:e.emailAndPassword?.enabled??!1,autoSignIn:e.emailAndPassword?.autoSignIn??!0}};let c=Fe(e),s=N(e),d=Object.keys(e.socialProviders||{}).map(u=>{let p=e.socialProviders?.[u];return p.enabled===!1?null:((!p.clientId||!p.clientSecret)&&b.warn(`Social provider ${u} is missing clientId or clientSecret`),le[u](p))}).filter(u=>u!==null),l={appName:e.appName||"Better Auth",socialProviders:d,options:e,tables:s,trustedOrigins:_r(e),baseURL:n,sessionConfig:{updateAge:e.session?.updateAge||24*60*60,expiresIn:e.session?.expiresIn||60*60*24*7},secret:a,rateLimit:{...e.rateLimit,enabled:e.rateLimit?.enabled??qt,window:e.rateLimit?.window||10,max:e.rateLimit?.max||100,storage:e.rateLimit?.storage||e.secondaryStorage?"secondary-storage":"memory"},authCookies:c,logger:de({disabled:e.logger?.disabled||!1}),db:i,uuid:v,secondaryStorage:e.secondaryStorage,password:{hash:e.emailAndPassword?.password?.hash||ke,verify:e.emailAndPassword?.password?.verify||Re,config:{minPasswordLength:e.emailAndPassword?.minPasswordLength||8,maxPasswordLength:e.emailAndPassword?.maxPasswordLength||128}},adapter:t,internalAdapter:ge(t,{options:e,hooks:e.databaseHooks?[e.databaseHooks]:[]}),createAuthCookie:qe(e)},{context:f}=Pr(l);return f};function Pr(e){let t=e.options,r=t.plugins||[],o=e,i=[];for(let n of r)if(n.init){let a=n.init(e);typeof a=="object"&&(a.options&&(a.options.databaseHooks&&i.push(a.options.databaseHooks),t=Sr(t,a.options)),a.context&&(o={...o,...a.context}))}return i.push(t.databaseHooks),o.internalAdapter=ge(e.adapter,{options:t,hooks:i.filter(n=>n!==void 0)}),o.options=t,{context:o}}function Lr(e){let t=[];return e.advanced?.crossSubDomainCookies?.enabled,t}function _r(e){let t=Y(e.baseURL,e.basePath);if(!t)throw new k("Base URL can not be empty. Please add `BETTER_AUTH_URL` in your environment variables or pass it in your auth config.");let r=[new URL(t).origin];e.trustedOrigins&&r.push(...e.trustedOrigins);let o=we.BETTER_AUTH_TRUSTED_ORIGINS;return o&&r.push(...o.split(",")),r}var zd=e=>{let t=Vt(e),{api:r}=fe(t,e);return{handler:async o=>{let i=await t,n=i.options.basePath||"/api/auth",a=new URL(o.url);if(!i.options.baseURL){let s=Y(void 0,n)||`${a.origin}${n}`;i.options.baseURL=s,i.baseURL=s}if(!i.options.baseURL)return new Response("Base URL not set",{status:400});if(a.pathname===n||a.pathname===`${n}/`)return new Response("Welcome to BetterAuth",{status:200});let{handler:c}=It(i,e);return c(o)},api:r,options:e,$Infer:{}}};export{k as BetterAuthError,F as HIDE_METADATA,De as MissingDependencyError,zd as betterAuth,Un as capitalizeFirstLetter,qe as createCookieGetter,de as createLogger,G as deleteSessionCookie,v as generateId,Be as generateState,Fe as getCookies,b as logger,vo as parseCookies,Eo as parseSetCookieHeader,ae as parseState,_ as setSessionCookie};
|
|
84
|
-
//# sourceMappingURL=index.js.map
|
|
83
|
+
</html>`,Ut=y("/error",{method:"GET",metadata:F},async e=>{let t=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(wr(t),{headers:{"Content-Type":"text/html"}})});var Tt=y("/ok",{method:"GET",metadata:F},async e=>e.json({ok:!0}));import{z as K}from"zod";import{APIError as D}from"better-call";var xt=()=>y("/sign-up/email",{method:"POST",query:K.object({currentURL:K.string().optional()}).optional(),body:K.record(K.string(),K.any()),use:[x]},async e=>{if(!e.context.options.emailAndPassword?.enabled)throw new D("BAD_REQUEST",{message:"Email and password sign up is not enabled"});let t=e.body,{name:r,email:o,password:i,image:n,callbackURL:a,...c}=t;if(!K.string().email().safeParse(o).success)throw new D("BAD_REQUEST",{message:"Invalid email"});let d=e.context.password.config.minPasswordLength;if(i.length<d)throw e.context.logger.error("Password is too short"),new D("BAD_REQUEST",{message:"Password is too short"});let l=e.context.password.config.maxPasswordLength;if(i.length>l)throw e.context.logger.error("Password is too long"),new D("BAD_REQUEST",{message:"Password is too long"});if((await e.context.internalAdapter.findUserByEmail(o))?.user)throw e.context.logger.info(`Sign-up attempt for existing email: ${o}`),new D("UNPROCESSABLE_ENTITY",{message:"Failed to create user"});let u=ut(e.context.options,c),p;try{if(p=await e.context.internalAdapter.createUser({email:o.toLowerCase(),name:r,image:n,...u,emailVerified:!1}),!p)throw new D("BAD_REQUEST",{message:"Failed to create user"})}catch(m){throw new D("UNPROCESSABLE_ENTITY",{message:"Failed to create user",details:m})}if(!p)throw new D("UNPROCESSABLE_ENTITY",{message:"Failed to create user"});let g=await e.context.password.hash(i);if(await e.context.internalAdapter.linkAccount({userId:p.id,providerId:"credential",accountId:p.id,password:g,expiresAt:$(60*60*24*30,"sec")}),e.context.options.emailVerification?.sendOnSignUp){let m=await B(e.context.secret,p.email),U=`${e.context.baseURL}/verify-email?token=${m}&callbackURL=${t.callbackURL||e.query?.currentURL||"/"}`;await e.context.options.emailVerification?.sendVerificationEmail?.(p,U,m)}if(!e.context.options.emailAndPassword.autoSignIn||e.context.options.emailAndPassword.requireEmailVerification)return e.json({user:p,session:null},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:p,session:null}});let h=await e.context.internalAdapter.createSession(p.id,e.request);if(!h)throw new D("BAD_REQUEST",{message:"Failed to create session"});return await _(e,h.id),e.json({user:p,session:h},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:p,session:h}})});import{isTest as br}from"std-env";function ne(e){let t="127.0.0.1";if(br)return t;let r=["x-client-ip","x-forwarded-for","cf-connecting-ip","fastly-client-ip","x-real-ip","x-cluster-client-ip","x-forwarded","forwarded-for","forwarded"],o=e instanceof Request?e.headers:e;for(let i of r){let n=o.get(i);if(typeof n=="string"){let a=n.split(",")[0].trim();if(a)return a}}return null}function Ar(e,t,r){let o=Date.now(),i=t*1e3;return o-r.lastRequest<i&&r.count>=e}function kr(e){return new Response(JSON.stringify({message:"Too many requests. Please try again later."}),{status:429,statusText:"Too Many Requests",headers:{"X-Retry-After":e.toString()}})}function Rr(e,t){let r=Date.now(),o=t*1e3;return Math.ceil((e+o-r)/1e3)}function Ur(e,t){let r=t??"rateLimit",o=e.adapter;return{get:async i=>await o.findOne({model:r,where:[{field:"key",value:i}]}),set:async(i,n,a)=>{try{a?await o.update({model:t??"rateLimit",where:[{field:"key",value:i}],update:{count:n.count,lastRequest:n.lastRequest}}):await o.create({model:t??"rateLimit",data:{key:i,count:n.count,lastRequest:n.lastRequest}})}catch(c){b.error("Error setting rate limit",c)}}}}var Et=new Map;function Tr(e){return e.rateLimit.storage==="secondary-storage"?{get:async r=>{let o=await e.options.secondaryStorage?.get(r);return o?JSON.parse(o):void 0},set:async(r,o)=>{await e.options.secondaryStorage?.set?.(r,JSON.stringify(o))}}:e.rateLimit.storage==="memory"?{async get(r){return Et.get(r)},async set(r,o,i){Et.set(r,o)}}:Ur(e,e.rateLimit.tableName)}async function vt(e,t){if(!t.rateLimit.enabled)return;let r=t.baseURL,o=e.url.replace(r,""),i=t.rateLimit.window,n=t.rateLimit.max,a=ne(e)+o,s=xr().find(u=>u.pathMatcher(o));s&&(i=s.window,n=s.max);for(let u of t.options.plugins||[])if(u.rateLimit){let p=u.rateLimit.find(g=>g.pathMatcher(o));if(p){i=p.window,n=p.max;break}}if(t.rateLimit.customRules){let u=t.rateLimit.customRules[o];u&&(i=u.window,n=u.max)}let d=Tr(t),l=await d.get(a),f=Date.now();if(!l)await d.set(a,{key:a,count:1,lastRequest:f});else{let u=f-l.lastRequest;if(Ar(n,i,l)){let p=Rr(l.lastRequest,i);return kr(p)}else u>i*1e3?await d.set(a,{...l,count:1,lastRequest:f}):await d.set(a,{...l,count:l.count+1,lastRequest:f})}}function xr(){return[{pathMatcher(t){return t.startsWith("/sign-in")||t.startsWith("/sign-up")},window:10,max:3}]}import{APIError as Oa}from"better-call";function fe(e,t){let r=t.plugins?.reduce((c,s)=>({...c,...s.endpoints}),{}),o=t.plugins?.map(c=>c.middlewares?.map(s=>{let d=async l=>s.middleware({...l,context:{...e,...l.context}});return d.path=s.path,d.options=s.middleware.options,d.headers=s.middleware.headers,{path:s.path,middleware:d}})).filter(c=>c!==void 0).flat()||[],n={...{signInOAuth:it,callbackOAuth:pt,getCSRFToken:Rt,getSession:ue(),signOut:ft,signUpEmail:xt(),signInEmail:st,forgetPassword:mt,resetPassword:ht,verifyEmail:nt,sendVerificationEmail:ot,changeEmail:kt,changePassword:wt,setPassword:bt,updateUser:yt(),deleteUser:At,forgetPasswordCallback:gt,listSessions:et(),revokeSession:tt,revokeSessions:rt},...r,ok:Tt,error:Ut},a={};for(let[c,s]of Object.entries(n))a[c]=async(d={})=>{let l=await e;for(let p of t.plugins||[])if(p.hooks?.before){for(let g of p.hooks.before)if(g.matcher({...s,...d,context:l})){let m=await g.handler({...d,context:{...l,...d?.context}});m&&"context"in m&&(l={...l,...m.context})}}let f;try{f=await s({...d,context:{...l,...d.context}})}catch(p){if(p instanceof It){let g=t.plugins?.map(m=>{if(m.hooks?.after)return m.hooks.after}).filter(m=>m!==void 0).flat();if(!g?.length)throw p;let h=new Response(JSON.stringify(p.body),{status:vr[p.status],headers:p.headers});for(let m of g||[])if(m.matcher(d)){let Z=Object.assign(d,{context:{...e,returned:h}}),q=await m.handler(Z);q&&"response"in q&&(h=q.response)}return h}throw p}let u=f;for(let p of t.plugins||[])if(p.hooks?.after){for(let g of p.hooks.after)if(g.matcher(d)){let m=Object.assign(d,{context:{...e,returned:u}}),U=await g.handler(m);U&&"response"in U&&(u=U.response)}}return u},a[c].path=s.path,a[c].method=s.method,a[c].options=s.options,a[c].headers=s.headers;return{api:a,middlewares:o}}var Ot=(e,t)=>{let{api:r,middlewares:o}=fe(e,t),i=new URL(e.baseURL).pathname;return Er(r,{extraContext:e,basePath:i,routerMiddleware:[{path:"/**",middleware:Pe},...o],async onRequest(n){for(let a of e.options.plugins||[])if(a.onRequest){let c=await a.onRequest(n,e);if(c)return c}return vt(n,e)},async onResponse(n){for(let a of e.options.plugins||[])if(a.onResponse){let c=await a.onResponse(n,e);if(c)return c.response}return n},onError(n){if(t.onAPIError?.throw)throw n;if(t.onAPIError?.onError){t.onAPIError.onError(n,e);return}let a=t.logger?.verboseLogging?b:void 0;t.logger?.disabled!==!0&&(n instanceof It?(n.status==="INTERNAL_SERVER_ERROR"&&b.error(n),a?.error(n.message)):b?.error(n))}})};var N=e=>{let t=e.plugins?.reduce((s,d)=>{let l=d.schema;if(!l)return s;for(let[f,u]of Object.entries(l))s[f]={fields:{...s[f]?.fields,...u.fields},tableName:u.tableName||f};return s},{}),r=e.rateLimit?.storage==="database",o={rateLimit:{tableName:e.rateLimit?.tableName||"rateLimit",fields:{key:{type:"string",fieldName:e.rateLimit?.fields?.key||"key"},count:{type:"number",fieldName:e.rateLimit?.fields?.count||"count"},lastRequest:{type:"number",fieldName:e.rateLimit?.fields?.lastRequest||"lastRequest"}}}},{user:i,session:n,account:a,...c}=t||{};return{user:{tableName:e.user?.modelName||"user",fields:{name:{type:"string",required:!0,fieldName:e.user?.fields?.name||"name"},email:{type:"string",unique:!0,required:!0,fieldName:e.user?.fields?.email||"email"},emailVerified:{type:"boolean",defaultValue:()=>!1,required:!0,fieldName:e.user?.fields?.emailVerified||"emailVerified"},image:{type:"string",required:!1,fieldName:e.user?.fields?.image||"image"},createdAt:{type:"date",defaultValue:()=>new Date,required:!0,fieldName:e.user?.fields?.createdAt||"createdAt"},updatedAt:{type:"date",defaultValue:()=>new Date,required:!0,fieldName:e.user?.fields?.updatedAt||"updatedAt"},...i?.fields,...e.user?.additionalFields},order:1},session:{tableName:e.session?.modelName||"session",fields:{expiresAt:{type:"date",required:!0,fieldName:e.session?.fields?.expiresAt||"expiresAt"},ipAddress:{type:"string",required:!1,fieldName:e.session?.fields?.ipAddress||"ipAddress"},userAgent:{type:"string",required:!1,fieldName:e.session?.fields?.userAgent||"userAgent"},userId:{type:"string",fieldName:e.session?.fields?.userId||"userId",references:{model:e.user?.modelName||"user",field:"id",onDelete:"cascade"},required:!0},...n?.fields,...e.session?.additionalFields},order:2},account:{tableName:e.account?.modelName||"account",fields:{accountId:{type:"string",required:!0,fieldName:e.account?.fields?.accountId||"accountId"},providerId:{type:"string",required:!0,fieldName:e.account?.fields?.providerId||"providerId"},userId:{type:"string",references:{model:e.user?.modelName||"user",field:"id",onDelete:"cascade"},required:!0,fieldName:e.account?.fields?.userId||"userId"},accessToken:{type:"string",required:!1,fieldName:e.account?.fields?.accessToken||"accessToken"},refreshToken:{type:"string",required:!1,fieldName:e.account?.fields?.refreshToken||"refreshToken"},idToken:{type:"string",required:!1,fieldName:e.account?.fields?.idToken||"idToken"},expiresAt:{type:"date",required:!1,fieldName:e.account?.fields?.expiresAt||"expiresAt"},password:{type:"string",required:!1,fieldName:e.account?.fields?.password||"password"},...a?.fields},order:3},verification:{tableName:e.verification?.modelName||"verification",fields:{identifier:{type:"string",required:!0,fieldName:e.verification?.fields?.identifier||"identifier"},value:{type:"string",required:!0,fieldName:e.verification?.fields?.value||"value"},expiresAt:{type:"date",required:!0,fieldName:e.verification?.fields?.expiresAt||"expiresAt"}},order:4},...c,...r?o:{}}};import{Kysely as St,MssqlDialect as Ir}from"kysely";import{MysqlDialect as Pt,PostgresDialect as Lt,SqliteDialect as _t}from"kysely";function Ct(e){if("dialect"in e)return Ct(e.dialect);if("createDriver"in e){if(e instanceof _t)return"sqlite";if(e instanceof Pt)return"mysql";if(e instanceof Lt)return"postgres";if(e instanceof Ir)return"mssql"}return"aggregate"in e?"sqlite":"getConnection"in e?"mysql":"connect"in e?"postgres":null}var W=async e=>{let t=e.database;if("db"in t)return{kysely:t.db,databaseType:t.type};if("dialect"in t)return{kysely:new St({dialect:t.dialect}),databaseType:t.type};let r,o=Ct(t);return"createDriver"in t&&(r=t),"aggregate"in t&&(r=new _t({database:t})),"getConnection"in t&&(r=new Pt({pool:t})),"connect"in t&&(r=new Lt({pool:t})),{kysely:r?new St({dialect:r}):null,databaseType:o}};function J(e){if(!e)return{and:null,or:null};let t={and:[],or:[]};return e.forEach(r=>{let{field:o,value:i,operator:n="=",connector:a="AND"}=r,c=s=>n.toLowerCase()==="in"?s(o,"in",Array.isArray(i)?i:[i]):n==="contains"?s(o,"like",`%${i}%`):n==="starts_with"?s(o,"like",`${i}%`):n==="ends_with"?s(o,"like",`%${i}`):s(o,n,i);a==="OR"?t.or.push(c):t.and.push(c)}),{and:t.and.length?t.and:null,or:t.or.length?t.or:null}}function ie(e,t,r){for(let o in e){let i=t[o]||Object.values(t).find(n=>n.fieldName===o);e[o]===0&&i.type==="boolean"&&r?.boolean&&(e[o]=!1),e[o]===1&&i?.type==="boolean"&&r?.boolean&&(e[o]=!0),i?.type==="date"&&(e[o]instanceof Date||(e[o]=new Date(e[o])))}return e}function Bt(e,t){for(let r in e)typeof e[r]=="boolean"&&t?.boolean&&(e[r]=e[r]?1:0),e[r]instanceof Date&&(e[r]=e[r].toISOString());return e}var Dt=(e,t)=>({id:"kysely",async create(r){let{model:o,data:i,select:n}=r;t?.transform&&(i=Bt(i,t.transform)),t?.generateId!==void 0&&(i.id=t.generateId?t.generateId():void 0);let a=await e.insertInto(o).values(i).returningAll().executeTakeFirst();if(t?.transform){let c=t.transform.schema[o];a=c?ie(i,c,t.transform):a}return n?.length&&(a=a?n.reduce((s,d)=>a?.[d]?{...s,[d]:a[d]}:s,{}):null),a},async findOne(r){let{model:o,where:i,select:n}=r,{and:a,or:c}=J(i),s=e.selectFrom(o).selectAll();a&&(s=s.where(l=>l.and(a.map(f=>f(l))))),c&&(s=s.where(l=>l.or(c.map(f=>f(l)))));let d=await s.executeTakeFirst();if(n?.length&&(d=d?n.reduce((f,u)=>d?.[u]?{...f,[u]:d[u]}:f,{}):null),t?.transform){let l=t.transform.schema[o];return d=d&&l?ie(d,l,t.transform):d,d||null}return d||null},async findMany(r){let{model:o,where:i,limit:n,offset:a,sortBy:c}=r,s=e.selectFrom(o),{and:d,or:l}=J(i);d&&(s=s.where(u=>u.and(d.map(p=>p(u))))),l&&(s=s.where(u=>u.or(l.map(p=>p(u))))),s=s.limit(n||100),a&&(s=s.offset(a)),c&&(s=s.orderBy(c.field,c.direction));let f=await s.selectAll().execute();if(t?.transform){let u=t.transform.schema[o];return u?f.map(p=>ie(p,u,t.transform)):f}return f},async update(r){let{model:o,where:i,update:n}=r,{and:a,or:c}=J(i);t?.transform&&(n=Bt(n,t.transform)),n.id&&(n.id=void 0);let s=e.updateTable(o).set(n);a&&(s=s.where(l=>l.and(a.map(f=>f(l))))),c&&(s=s.where(l=>l.or(c.map(f=>f(l)))));let d=await s.returningAll().executeTakeFirst()||null;if(t?.transform){let l=t.transform.schema[o];return l?ie(d,l,t.transform):d}return d},async delete(r){let{model:o,where:i}=r,{and:n,or:a}=J(i),c=e.deleteFrom(o);n&&(c=c.where(s=>s.and(n.map(d=>d(s))))),a&&(c=c.where(s=>s.or(a.map(d=>d(s))))),await c.execute()},async deleteMany(r){let{model:o,where:i}=r,{and:n,or:a}=J(i),c=e.deleteFrom(o);n&&(c=c.where(s=>s.and(n.map(d=>d(s))))),a&&(c=c.where(s=>s.or(a.map(d=>d(s))))),await c.execute()}});async function Nt(e){if(!e.database)throw new k("Database configuration is required");if("create"in e.database)return e.database;let{kysely:t,databaseType:r}=await W(e);if(!t)throw new k("Failed to initialize database adapter");let o=N(e),i={};for(let n of Object.values(o))i[n.tableName]=n.fields;return Dt(t,{transform:{schema:i,date:!0,boolean:r==="sqlite"},generateId:"generateId"in e.database?e.database.generateId:void 0})}function me(e,t){let r={id:t.id};for(let o in e){let i=e[o],n=t[o];r[i.fieldName||o]=n}return r}function I(e,t){if(!t)return null;let r={id:t.id};for(let[o,i]of Object.entries(e))r[o]=t[i.fieldName||o];return r}function Ft(e,t){let r=t.hooks,o=N(t.options);async function i(a,c,s){let d=a,l=o[c];for(let p of r||[]){let g=p[c]?.create?.before;if(g){let h=await g(a);if(h===!1)return null;typeof h=="object"&&"data"in h&&(d=h.data)}}let f=s?await s.fn(d):null,u=!s||s.executeMainFn?await e.create({model:l.tableName,data:{...me(l.fields,d),id:d.id||v()}}):f;for(let p of r||[]){let g=p[c]?.create?.after;g&&await g(u)}return I(l.fields,u)}async function n(a,c,s,d){let l=a;for(let p of r||[]){let g=p[s]?.update?.before;if(g){let h=await g(a);if(h===!1)return null;l=typeof h=="object"?h.data:h}}let f=d?await d.fn(l):null,u=!d||d.executeMainFn?await e.update({model:o[s].tableName,update:me(o[s].fields,l),where:c}):f;for(let p of r||[]){let g=p[s]?.update?.after;g&&await g(u)}return I(o[s].fields,u)}return{createWithHooks:i,updateWithHooks:n}}var ge=(e,t)=>{let r=t.options,o=r.secondaryStorage,i=r.session?.expiresIn||60*60*24*7,n=N(r),{createWithHooks:a,updateWithHooks:c}=Ft(e,t);return{createOAuthUser:async(s,d)=>{try{let l=await a({id:v(),createdAt:new Date,updatedAt:new Date,...s},"user"),f=await a({id:v(),...d,userId:l.id||s.id},"account");return{user:l,account:f}}catch(l){return console.log(l),null}},createUser:async s=>await a({id:v(),createdAt:new Date,updatedAt:new Date,emailVerified:!1,...s},"user"),createAccount:async s=>await a({id:v(),createdAt:new Date,updatedAt:new Date,...s},"account"),listSessions:async s=>await e.findMany({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]}),listUsers:async(s,d,l,f)=>(await e.findMany({model:n.user.tableName,limit:s,offset:d,sortBy:l,where:f})).map(p=>I(n.user.fields,p)),deleteUser:async s=>{await e.delete({model:n.account.tableName,where:[{field:n.account.fields.userId.fieldName||"userId",value:s}]}),await e.deleteMany({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]}),await e.deleteMany({model:n.user.tableName,where:[{field:"id",value:s}]})},createSession:async(s,d,l,f)=>{let u=d instanceof Request?d.headers:d,p={id:v(),userId:s,expiresAt:l?$(60*60*24,"sec"):$(i,"sec"),ipAddress:d&&ne(d)||"",userAgent:u?.get("user-agent")||"",...f};return await a(p,"session",o?{fn:async h=>{let m=await e.findOne({model:n.user.tableName,where:[{field:"id",value:s}]});return o.set(h.id,JSON.stringify({session:h,user:m}),i),h},executeMainFn:r.session?.storeSessionInDatabase}:void 0)},findSession:async s=>{if(o){let f=await o.get(s);if(f){let u=JSON.parse(f);return{session:{...u.session,expiresAt:new Date(u.session.expiresAt)},user:{...u.user,createdAt:new Date(u.user.createdAt),updatedAt:new Date(u.user.updatedAt)}}}}let d=await e.findOne({model:n.session.tableName,where:[{value:s,field:"id"}]});if(!d)return null;let l=await e.findOne({model:n.user.tableName,where:[{value:d.userId,field:"id"}]});return l?{session:I(n.session.fields,d),user:I(n.user.fields,l)}:null},findSessions:async s=>{if(o){let u=[];for(let p of s){let g=await o.get(p);if(g){let h=JSON.parse(g),m={session:{...h.session,expiresAt:new Date(h.session.expiresAt)},user:{...h.user,createdAt:new Date(h.user.createdAt),updatedAt:new Date(h.user.updatedAt)}};u.push(m)}}return u}let d=await e.findMany({model:n.session.tableName,where:[{field:"id",value:s,operator:"in"}]}),l=d.map(u=>u.userId);if(!l.length)return[];let f=await e.findMany({model:n.user.tableName,where:[{field:"id",value:l,operator:"in"}]});return d.map(u=>{let p=f.find(g=>g.id===u.userId);return p?{session:I(n.session.fields,u),user:I(n.user.fields,p)}:null})},updateSession:async(s,d)=>await c(d,[{field:"id",value:s}],"session",o?{async fn(f){let u=await o.get(s),p=null;if(u){let g=JSON.parse(u);p={...g.session,...f},await o.set(s,JSON.stringify({session:p,user:g.user}),g.session.expiresAt?new Date(g.session.expiresAt).getTime():void 0)}else return null},executeMainFn:r.session?.storeSessionInDatabase}:void 0),deleteSession:async s=>{if(o){await o.delete(s),r.session?.storeSessionInDatabase&&await e.delete({model:n.session.tableName,where:[{field:"id",value:s}]});return}await e.delete({model:n.session.tableName,where:[{field:"id",value:s}]})},deleteSessions:async s=>{if(o){let d=await e.findMany({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]});for(let l of d)await o.delete(l.id);r.session?.storeSessionInDatabase&&await e.delete({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]});return}await e.deleteMany({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]})},findUserByEmail:async(s,d)=>{let l=await e.findOne({model:n.user.tableName,where:[{value:s.toLowerCase(),field:n.user.fields.email.fieldName||"email"}]});if(!l)return null;if(d?.includeAccounts){let f=await e.findMany({model:n.account.tableName,where:[{value:l.id,field:n.account.fields.userId.fieldName||"userId"}]});return{user:I(n.user.fields,l),accounts:f.map(u=>I(n.account.fields,u))}}return{user:I(n.user.fields,l),accounts:[]}},findUserById:async s=>await e.findOne({model:n.user.tableName,where:[{field:"id",value:s}]}),linkAccount:async s=>await a({id:v(),...s},"account"),updateUser:async(s,d)=>await c(d,[{field:"id",value:s}],"user"),updateUserByEmail:async(s,d)=>await c(d,[{field:n.user.fields.email.fieldName||"email",value:s}],"user"),updatePassword:async(s,d)=>await c({password:d},[{field:n.account.fields.userId.fieldName||"userId",value:s},{field:n.account.fields.providerId.fieldName||"providerId",value:"credential"}],"account"),findAccounts:async s=>(await e.findMany({model:n.account.tableName,where:[{field:n.account.fields.userId.fieldName||"userId",value:s}]})).map(l=>I(n.account.fields,l)),updateAccount:async(s,d)=>await c(d,[{field:"id",value:s}],"account"),createVerificationValue:async s=>await a({id:v(),...s},"verification"),findVerificationValue:async s=>{let d=await e.findOne({model:n.verification.tableName,where:[{field:n.verification.fields.identifier.fieldName||"identifier",value:s}]});return I(n.verification.fields,d)},deleteVerificationValue:async s=>{await e.delete({model:n.verification.tableName,where:[{field:"id",value:s}]})},updateVerificationValue:async(s,d)=>await c(d,[{field:"id",value:s}],"verification")}};import{z as td}from"zod";import"kysely";import{env as we,isProduction as qt}from"std-env";import{defu as Sr}from"defu";import{env as j}from"std-env";function Or(e){try{return new URL(e).pathname!=="/"}catch{throw new k(`Invalid base URL: ${e}. Please provide a valid base URL.`)}}function he(e,t="/api/auth"){return Or(e)?e:(t=t.startsWith("/")?t:`/${t}`,`${e}${t}`)}function Y(e,t){if(e)return he(e,t);let r=j.BETTER_AUTH_URL||j.NEXT_PUBLIC_BETTER_AUTH_URL||j.PUBLIC_BETTER_AUTH_URL||j.NUXT_PUBLIC_BETTER_AUTH_URL||j.NUXT_PUBLIC_AUTH_URL||(j.BASE_URL!=="/"?j.BASE_URL:void 0);if(r)return he(r,t);if(typeof window<"u")return he(window.location.origin,t)}var ye="better-auth-secret-123456789";var Vt=async e=>{let t=await Nt(e),r=e.plugins||[],o=Lr(e),{kysely:i}=await W(e),n=Y(e.baseURL,e.basePath);if(!n)throw new k("Base URL can not be empty. Please add `BETTER_AUTH_URL` in your environment variables or pass it your auth config.");let a=e.secret||we.BETTER_AUTH_SECRET||we.AUTH_SECRET||ye;if(a===ye&&qt)throw new k("You are using the default secret. Please set `BETTER_AUTH_SECRET` or `AUTH_SECRET` in your environment variables or pass `secret` in your auth config.");e={...e,secret:a,baseURL:n?new URL(n).origin:"",basePath:e.basePath||"/api/auth",plugins:r.concat(o),emailAndPassword:{...e.emailAndPassword,enabled:e.emailAndPassword?.enabled??!1,autoSignIn:e.emailAndPassword?.autoSignIn??!0}};let c=Fe(e),s=N(e),d=Object.keys(e.socialProviders||{}).map(u=>{let p=e.socialProviders?.[u];return p.enabled===!1?null:((!p.clientId||!p.clientSecret)&&b.warn(`Social provider ${u} is missing clientId or clientSecret`),le[u](p))}).filter(u=>u!==null),l={appName:e.appName||"Better Auth",socialProviders:d,options:e,tables:s,trustedOrigins:_r(e),baseURL:n,sessionConfig:{updateAge:e.session?.updateAge||24*60*60,expiresIn:e.session?.expiresIn||60*60*24*7},secret:a,rateLimit:{...e.rateLimit,enabled:e.rateLimit?.enabled??qt,window:e.rateLimit?.window||10,max:e.rateLimit?.max||100,storage:e.rateLimit?.storage||e.secondaryStorage?"secondary-storage":"memory"},authCookies:c,logger:de({disabled:e.logger?.disabled||!1}),db:i,uuid:v,secondaryStorage:e.secondaryStorage,password:{hash:e.emailAndPassword?.password?.hash||ke,verify:e.emailAndPassword?.password?.verify||Re,config:{minPasswordLength:e.emailAndPassword?.minPasswordLength||8,maxPasswordLength:e.emailAndPassword?.maxPasswordLength||128}},adapter:t,internalAdapter:ge(t,{options:e,hooks:e.databaseHooks?[e.databaseHooks]:[]}),createAuthCookie:qe(e)},{context:f}=Pr(l);return f};function Pr(e){let t=e.options,r=t.plugins||[],o=e,i=[];for(let n of r)if(n.init){let a=n.init(e);typeof a=="object"&&(a.options&&(a.options.databaseHooks&&i.push(a.options.databaseHooks),t=Sr(t,a.options)),a.context&&(o={...o,...a.context}))}return i.push(t.databaseHooks),o.internalAdapter=ge(e.adapter,{options:t,hooks:i.filter(n=>n!==void 0)}),o.options=t,{context:o}}function Lr(e){let t=[];return e.advanced?.crossSubDomainCookies?.enabled,t}function _r(e){let t=Y(e.baseURL,e.basePath);if(!t)throw new k("Base URL can not be empty. Please add `BETTER_AUTH_URL` in your environment variables or pass it in your auth config.");let r=[new URL(t).origin];e.trustedOrigins&&r.push(...e.trustedOrigins);let o=we.BETTER_AUTH_TRUSTED_ORIGINS;return o&&r.push(...o.split(",")),r}var zd=e=>{let t=Vt(e),{api:r}=fe(t,e);return{handler:async o=>{let i=await t,n=i.options.basePath||"/api/auth",a=new URL(o.url);if(!i.options.baseURL){let s=Y(void 0,n)||`${a.origin}${n}`;i.options.baseURL=s,i.baseURL=s}if(!i.options.baseURL)return new Response("Base URL not set",{status:400});if(a.pathname===n||a.pathname===`${n}/`)return new Response("Welcome to BetterAuth",{status:200});let{handler:c}=Ot(i,e);return c(o)},api:r,options:e,$Infer:{}}};export{k as BetterAuthError,F as HIDE_METADATA,De as MissingDependencyError,zd as betterAuth,Un as capitalizeFirstLetter,qe as createCookieGetter,de as createLogger,G as deleteSessionCookie,v as generateId,Be as generateState,Fe as getCookies,b as logger,vo as parseCookies,Eo as parseSetCookieHeader,ae as parseState,_ as setSessionCookie};
|
package/dist/next-js.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
1
|
import{betterFetch as a}from"@better-fetch/fetch";import{NextResponse as n}from"next/server";import{env as u}from"std-env";function f(e){let s=async r=>"handler"in e?e.handler(r):e(r);return{GET:s,POST:s}}function p(e){return async s=>{let r=u.BETTER_AUTH_URL||new URL(s.url).origin,o=e?.basePath||"/api/auth",i=`${r}${o}/session`,t=(await a(i,{headers:{cookie:s.headers.get("cookie")||""}}).catch(d=>({data:null}))).data||null;return e.customRedirect?e.customRedirect(t,s):t?n.next():n.redirect(new URL(e.redirectTo||"/",r))}}export{p as authMiddleware,f as toNextJsHandler};
|
|
2
|
-
//# sourceMappingURL=next-js.js.map
|
package/dist/node.d.ts
CHANGED
package/dist/node.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
1
|
import{toNodeHandler as n}from"better-call";var s=e=>"handler"in e?n(e.handler):n(e);function i(e){let t=new Headers;for(let[o,r]of Object.entries(e))r!==void 0&&(Array.isArray(r)?r.forEach(d=>t.append(o,d)):t.set(o,r));return t}export{i as fromNodeHeaders,s as toNodeHandler};
|
|
2
|
-
//# sourceMappingURL=node.js.map
|
package/dist/oauth2.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
1
|
import{sha256 as y}from"oslo/crypto";import{base64url as k}from"oslo/encoding";async function l(e){let t=await y(new TextEncoder().encode(e));return k.encode(new Uint8Array(t),{includePadding:!1})}function d(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 O({id:e,options:t,authorizationEndpoint:s,state:r,codeVerifier:i,scopes:n,claims:c,disablePkce:a,redirectURI:u}){let o=new URL(s);if(o.searchParams.set("response_type","code"),o.searchParams.set("client_id",t.clientId),o.searchParams.set("state",r),o.searchParams.set("scope",n.join(" ")),o.searchParams.set("redirect_uri",t.redirectURI||u),!a&&i){let p=await l(i);o.searchParams.set("code_challenge_method","S256"),o.searchParams.set("code_challenge",p)}if(c){let p=c.reduce((m,g)=>(m[g]=null,m),{});o.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...p}}))}return o}import{betterFetch as x}from"@better-fetch/fetch";async function E({code:e,codeVerifier:t,redirectURI:s,options:r,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",s),n.set("client_id",r.clientId),n.set("client_secret",r.clientSecret);let{data:c,error:a}=await x(i,{method:"POST",body:n,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(a)throw a;return d(c)}import{generateState as A}from"oslo/oauth2";import{z as f}from"zod";import{sha256 as T}from"oslo/crypto";async function h(e){let t=await T(typeof e=="string"?new TextEncoder().encode(e):e);return Buffer.from(t).toString("base64")}import"better-call";async function F(e){let t=A(),s=JSON.stringify({code:t,callbackURL:e}),r=await h(s);return{raw:s,hash:r}}function H(e){return f.object({code:f.string(),callbackURL:f.string().optional(),currentURL:f.string().optional()}).safeParse(JSON.parse(e))}function K(e){let t=e.accessToken,s=e.refreshToken,r;try{r=e.accessTokenExpiresAt}catch{}return{accessToken:t,refreshToken:s,expiresAt:r}}export{O as createAuthorizationURL,l as generateCodeChallenge,F as generateState,K as getAccountTokens,d as getOAuth2Tokens,H as parseState,E as validateAuthorizationCode};
|
|
2
|
-
//# sourceMappingURL=oauth2.js.map
|
package/dist/plugins.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { A as AnonymousOptions, O as OrganizationOptions, b as Passkey, P as PasskeyOptions, U as UserWithPhoneNumber, f as UserWithRole, i as admin, h as adminMiddleware, e as anonymous, j as genericOAuth, g as getPasskeyActions, m as magicLink, k as multiSession, o as organization, p as passkey, c as passkeyClient, d as phoneNumber, t as twoFactor, a as twoFactorClient, u as username } from './index-
|
|
1
|
+
export { A as AnonymousOptions, O as OrganizationOptions, b as Passkey, P as PasskeyOptions, U as UserWithPhoneNumber, f as UserWithRole, i as admin, h as adminMiddleware, e as anonymous, j as genericOAuth, g as getPasskeyActions, m as magicLink, k as multiSession, o as organization, p as passkey, c as passkeyClient, d as phoneNumber, t as twoFactor, a as twoFactorClient, u as username } from './index-ny_c9jGl.js';
|
|
2
2
|
export { i as ac } from './index-DfAHOgpj.js';
|
|
3
|
-
import { H as HookEndpointContext, P as PluginSchema } from './auth-
|
|
4
|
-
export { e as AuthEndpoint, f as AuthMiddleware, b as BetterAuthPlugin, d as createAuthEndpoint, c as createAuthMiddleware, o as optionsMiddleware } from './auth-
|
|
3
|
+
import { H as HookEndpointContext, P as PluginSchema } from './auth-B9t_YkMU.js';
|
|
4
|
+
export { e as AuthEndpoint, f as AuthMiddleware, b as BetterAuthPlugin, d as createAuthEndpoint, c as createAuthMiddleware, o as optionsMiddleware } from './auth-B9t_YkMU.js';
|
|
5
5
|
export { H as HIDE_METADATA } from './hide-metadata-DEHJp1rk.js';
|
|
6
6
|
import { U as User } from './schema-Dkt0LqYs.js';
|
|
7
7
|
import * as better_call from 'better-call';
|