better-auth 0.5.2-beta.11 → 0.5.2-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.cjs +4 -4
- package/dist/api.js +3 -3
- package/dist/client/plugins.cjs +1 -1
- package/dist/client/plugins.js +1 -1
- package/dist/client.cjs +1 -1
- package/dist/client.d.cts +2 -2
- package/dist/client.d.ts +2 -2
- package/dist/client.js +1 -1
- package/dist/cookies.cjs +1 -1
- package/dist/cookies.js +1 -1
- package/dist/db.cjs +3 -3
- package/dist/db.js +3 -3
- package/dist/index.cjs +4 -4
- package/dist/index.js +4 -4
- package/dist/next-js.cjs +1 -1
- package/dist/next-js.js +1 -1
- package/dist/oauth2.cjs +1 -1
- package/dist/oauth2.js +1 -1
- package/dist/plugins.cjs +5 -5
- package/dist/plugins.js +5 -5
- package/dist/react.cjs +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +1 -1
- package/dist/social.cjs +2 -2
- package/dist/social.js +2 -2
- package/dist/solid.cjs +1 -1
- package/dist/solid.d.cts +2 -2
- package/dist/solid.d.ts +2 -2
- package/dist/solid.js +1 -1
- package/dist/svelte.cjs +1 -1
- package/dist/svelte.d.cts +2 -2
- package/dist/svelte.d.ts +2 -2
- package/dist/svelte.js +1 -1
- package/dist/types.d.cts +0 -1
- package/dist/types.d.ts +0 -1
- package/dist/vue.cjs +1 -1
- package/dist/vue.d.cts +2 -2
- package/dist/vue.d.ts +2 -2
- package/dist/vue.js +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{APIError as
|
|
2
|
-
`)}}),b=ae();var x=z(async e=>{let t=e.body?.callbackURL||e.query?.callbackURL||e.query?.redirectTo||e.body?.redirectTo,r=e.headers?.get("referer"),o=e.query?.currentURL||r||e.context.baseURL,i=e.context.trustedOrigins;if(t?.includes("http")){let n=new URL(t).origin;if(!i.includes(n))throw b.error("Invalid callback URL",{callbackURL:t,trustedOrigins:i}),new Be("FORBIDDEN",{message:"Invalid callback URL"})}if(o!==e.context.baseURL){let n=new URL(o).origin;if(!i.includes(n))throw b.error("Invalid current URL",{currentURL:o,trustedOrigins:i}),new Be("FORBIDDEN",{message:"Invalid callback URL"})}});import{parseJWT as Gt}from"oslo/jwt";import{sha256 as Mt}from"oslo/crypto";function zt(e){try{return new URL(e).pathname!=="/"}catch{throw new k(`Invalid base URL: ${e}. Please provide a valid base URL.`)}}function de(e,t="/api/auth"){return zt(e)?e:(t=t.startsWith("/")?t:`/${t}`,`${e}${t}`)}function Q(e,t){if(e)return de(e,t);let r=typeof process<"u"?process.env:{},o=r.BETTER_AUTH_URL||r.NEXT_PUBLIC_BETTER_AUTH_URL||r.PUBLIC_BETTER_AUTH_URL||r.NUXT_PUBLIC_BETTER_AUTH_URL||r.NUXT_PUBLIC_AUTH_URL||(r.BASE_URL!=="/"?r.BASE_URL:void 0);if(o)return de(o,t);if(typeof window<"u")return de(window.location.origin,t)}import{base64url as Ht}from"oslo/encoding";async function De(e){let t=await Mt(new TextEncoder().encode(e));return Ht.encode(new Uint8Array(t),{includePadding:!1})}function Ne(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 T({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 De(i);d.searchParams.set("code_challenge_method","S256"),d.searchParams.set("code_challenge",l)}if(a){let l=a.reduce((p,u)=>(p[u]=null,p),{});d.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...l}}))}return d}import{betterFetch as Kt}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 Kt(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 Ne(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 Fe=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=Gt(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 Qt}from"@better-fetch/fetch";var qe=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 Qt("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 Wt}from"@better-fetch/fetch";var Ve=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=e.scope||r||["email","public_profile"];return await T({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 Wt("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,emailVerified:r.email_verified},data:r}}});import{betterFetch as $e}from"@better-fetch/fetch";var je=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 T({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 $e("https://api.github.com/user",{headers:{"User-Agent":"better-auth",authorization:`Bearer ${r.accessToken}`}});if(i)return null;let n=!1;if(!o.email){let{data:a,error:c}=await $e("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 Zt}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 T({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=Zt(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 Jt}from"@better-fetch/fetch";import{parseJWT as Xt}from"oslo/jwt";var Me=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 T({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=Xt(i.idToken)?.payload,a=e.profilePhotoSize||48;return await Jt(`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 Yt}from"@better-fetch/fetch";var He=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:i}){let n=e.scope||r||["user-read-email"];return T({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 Yt("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 pn(e){return e.charAt(0).toUpperCase()+e.slice(1)}var N={isAction:!1};import{nanoid as er}from"nanoid";var E=e=>er(e);import{parseJWT as tr}from"oslo/jwt";var Ke=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=e.scope||r||["user:read:email","openid"];return T({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=tr(r)?.payload;return{user:{id:o.sub,name:o.preferred_username,email:o.email,image:o.picture,emailVerified:!1},data:o}}});import{betterFetch as rr}from"@better-fetch/fetch";var Ge=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(t){let r=e.scope||t.scopes||["account_info.read"];return T({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 rr("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:Fe,discord:qe,facebook:Ve,github:je,microsoft:Me,google:ze,spotify:He,twitch:Ke,twitter:Ge},Qe=Object.keys(le);import{TimeSpan as or}from"oslo";import{createJWT as nr,validateJWT as ir}from"oslo/jwt";import{z as S}from"zod";import{APIError as M}from"better-call";import{APIError as W}from"better-call";var V=(e,t="ms")=>new Date(Date.now()+(t==="sec"?e*1e3:e));import{z as We}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:V(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 L(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=z(async e=>{let t=await pe(e);if(!t?.session)throw new W("UNAUTHORIZED");return{session:t}}),Ze=()=>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)}),Je=y("/user/revoke-session",{method:"POST",body:We.object({id:We.string()}),use:[C],requireHeaders:!0},async e=>{let t=e.body.id,r=await e.context.internalAdapter.findSession(t);if(!r)throw new W("BAD_REQUEST",{message:"Session not found"});if(r.session.userId!==e.context.session.user.id)throw new W("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(t)}catch(o){throw e.context.logger.error(o),new W("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),Xe=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 W("INTERNAL_SERVER_ERROR")}return e.json({status:!0})});async function B(e,t,r){return await nr("HS256",Buffer.from(e),{email:t.toLowerCase(),updateTo:r},{expiresIn:new or(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}var Ye=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 M("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:t}=e.body,r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw new M("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})}),et=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 ir("HS256",Buffer.from(e.context.secret),t)}catch(a){throw e.context.logger.error("Failed to verify email",a),new M("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 M("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 M("UNAUTHORIZED",{message:"Session not found"});if(a.user.email!==i.email)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new M("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 tt=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(Qe)}),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 Pe(i||o?.origin||e.context.options.baseURL);await e.setSignedCookie(r.state.name,n.hash,e.context.secret,r.state.options);let a=sr();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})}),rt=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),p=`${e.context.options.baseURL}/verify-email?token=${l}`;throw await e.context.options.emailVerification.sendVerificationEmail(n.user,p,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 L(e,d.id,e.body.dontRememberMe),e.json({user:n.user,session:d,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});import{z as te}from"zod";import{z as w}from"zod";var Ii=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()}),ot=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)}),Oi=w.object({id:w.string(),userId:w.string(),expiresAt:w.date(),ipAddress:w.string().optional(),userAgent:w.string().optional()}),Si=w.object({id:w.string(),value:w.string(),expiresAt:w.date(),identifier:w.string()});function ar(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 nt(e,t){let r={...e.user?.additionalFields};return ar(t||{},{fields:r})}var it=y("/callback/:id",{method:"GET",query:te.object({state:te.string(),code:te.string().optional(),error:te.string().optional()}),metadata:N},async e=>{if(e.query.error||!e.query.code){let U=se(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(g=>g.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=se(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 Se(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(g){throw e.context.logger.error(g),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let d=await t.getUserInfo(s).then(g=>g?.user),l=E(),p=ot.safeParse({...d,id:l});if(!d||p.success===!1)throw b.error("Unable to get user info",p.error),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!o)throw e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);function u(g){throw e.redirect(`${i||o||`${e.context.baseURL}/error`}?error=${g}`)}let f=await e.context.internalAdapter.findUserByEmail(d.email,{includeAccounts:!0}).catch(g=>{throw b.error(`Better auth was unable to query your database.
|
|
3
|
-
Error: `,g),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)}),m=f?.user.id;if(f){if(!f.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:f.user.id,...
|
|
1
|
+
import{APIError as xt,createRouter as Rr,statusCode as Ur}from"better-call";import{APIError as se}from"better-call";import{z as Ie}from"zod";import{xchacha20poly1305 as Dr}from"@noble/ciphers/chacha";import{bytesToHex as Fr,hexToBytes as qr,utf8ToBytes as Vr}from"@noble/ciphers/utils";import{managedNonce as jr}from"@noble/ciphers/webcrypto";import{sha256 as Mr}from"oslo/crypto";function Y(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 Nt,encodeHex as be}from"oslo/encoding";import{scryptAsync as Ft}from"@noble/hashes/scrypt";var z={N:16384,r:16,p:1,dkLen:64};async function Ae(e,t){return await Ft(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(crypto.getRandomValues(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 Y(i,Nt(o))};function qt(e){return e.toString(2).padStart(8,"0")}function Vt(e){return[...e].map(t=>qt(t)).join("")}function Ue(e){return parseInt(Vt(e),2)}function $t(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));crypto.getRandomValues(o),r!==0&&(o[0]&=(1<<r)-1);let i=Ue(o);for(;i>=e;)crypto.getRandomValues(o),r!==0&&(o[0]&=(1<<r)-1),i=Ue(o);return i}function xe(e,t){let r="";for(let o=0;o<e;o++)r+=t[$t(t.length)];return r}function Te(...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 crypto.subtle.importKey("raw",r.encode(e),o,!1,["sign","verify"]),n=await crypto.subtle.sign(o.name,i,r.encode(t));return btoa(String.fromCharCode(...new Uint8Array(n)))}import{createEndpointCreator as jt,createMiddleware as ve,createMiddlewareCreator as zt}from"better-call";var Ee=ve(async()=>({})),M=zt({use:[Ee,ve(async()=>({}))]}),y=jt({use:[Ee]});var Pe=M({body:Ie.object({csrfToken:Ie.string().optional()}).optional()},async e=>{if(e.request?.method!=="POST"||e.context.options.advanced?.disableCSRFCheck)return;let t=e.headers?.get("origin")||"";if(e.context.trustedOrigins.includes(t))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 O}from"better-call";import{generateCodeVerifier as ur}from"oslo/oauth2";import{z as P}from"zod";import{generateState as Mt}from"oslo/oauth2";import{z as te}from"zod";import{sha256 as Se}from"oslo/crypto";async function Oe(e){let t=await Se(typeof e=="string"?new TextEncoder().encode(e):e);return Buffer.from(t).toString("base64")}async function Le(e,t){let r=await Se(typeof e=="string"?new TextEncoder().encode(e):e),o=Buffer.from(t,"base64");return Y(r,o)}import"better-call";async function _e(e){let t=Mt(),r=JSON.stringify({code:t,callbackURL:e}),o=await Oe(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 Ht}from"oslo";var k=class extends Error{constructor(t,r){super(t),this.name="BetterAuthError",this.message=t,this.cause=r,this.stack=""}},Ce=class extends k{constructor(t){super(`The package "${t}" is required. Make sure it is installed.`,t)}};import{env as Kt,isProduction as Be}from"std-env";function De(e){let r=(e.advanced?.useSecureCookies!==void 0?e.advanced?.useSecureCookies:e.baseURL!==void 0?!!e.baseURL.startsWith("https://"):Be)?"__Secure-":"",o="better-auth",i=e.session?.expiresIn||new Ht(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 Ne(e){let r=(e.advanced?.useSecureCookies!==void 0?e.advanced?.useSecureCookies:e.baseURL?.startsWith("https://")||Be)?"__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:Kt.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 L(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 Q(e){e.setCookie(e.context.authCookies.sessionToken.name,"",{maxAge:0}),e.setCookie(e.context.authCookies.dontRememberToken.name,"",{maxAge:0})}function wo(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,p]=d.split("=");s[l.toLowerCase()]=p||!0}),t.set(a,s)}),t}function bo(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 Fe}from"better-call";import{createConsola as Gt}from"consola";var q=Gt({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),de=e=>({log:(...t)=>{!e?.disabled&&q.log("",...t)},error:(...t)=>{!e?.disabled&&q.error("",...t)},warn:(...t)=>{!e?.disabled&&q.warn("",...t)},info:(...t)=>{!e?.disabled&&q.info("",...t)},debug:(...t)=>{!e?.disabled&&q.debug("",...t)},box:(...t)=>{!e?.disabled&&q.box("",...t)},success:(...t)=>{!e?.disabled&&q.success("",...t)},break:(...t)=>{!e?.disabled&&console.log(`
|
|
2
|
+
`)}}),b=de();var x=M(async e=>{let t=e.body?.callbackURL||e.query?.callbackURL||e.query?.redirectTo||e.body?.redirectTo,r=e.headers?.get("referer"),o=e.query?.currentURL||r||e.context.baseURL,i=e.context.trustedOrigins;if(t?.includes("http")){let n=new URL(t).origin;if(!i.includes(n))throw b.error("Invalid callback URL",{callbackURL:t,trustedOrigins:i}),new Fe("FORBIDDEN",{message:"Invalid callback URL"})}if(o!==e.context.baseURL){let n=new URL(o).origin;if(!i.includes(n))throw b.error("Invalid current URL",{currentURL:o,trustedOrigins:i}),new Fe("FORBIDDEN",{message:"Invalid callback URL"})}});import{parseJWT as Xt}from"oslo/jwt";import{sha256 as Wt}from"oslo/crypto";import{env as V}from"std-env";function Qt(e){try{return new URL(e).pathname!=="/"}catch{throw new k(`Invalid base URL: ${e}. Please provide a valid base URL.`)}}function ce(e,t="/api/auth"){return Qt(e)?e:(t=t.startsWith("/")?t:`/${t}`,`${e}${t}`)}function W(e,t){if(e)return ce(e,t);let r=V.BETTER_AUTH_URL||V.NEXT_PUBLIC_BETTER_AUTH_URL||V.PUBLIC_BETTER_AUTH_URL||V.NUXT_PUBLIC_BETTER_AUTH_URL||V.NUXT_PUBLIC_AUTH_URL||(V.BASE_URL!=="/"?V.BASE_URL:void 0);if(r)return ce(r,t);if(typeof window<"u")return ce(window.location.origin,t)}import{base64url as Zt}from"oslo/encoding";async function qe(e){let t=await Wt(new TextEncoder().encode(e));return Zt.encode(new Uint8Array(t),{includePadding:!1})}function Ve(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 T({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 qe(i);d.searchParams.set("code_challenge_method","S256"),d.searchParams.set("code_challenge",l)}if(a){let l=a.reduce((p,u)=>(p[u]=null,p),{});d.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...l}}))}return d}import{betterFetch as Jt}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 Jt(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 Ve(a)}function le(e){let t=e.accessToken,r=e.refreshToken,o;try{o=e.accessTokenExpiresAt}catch{}return{accessToken:t,refreshToken:r,expiresAt:o}}var $e=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=Xt(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 Yt}from"@better-fetch/fetch";var je=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=e.scope||r||["identify","email"];return new URL(`https://discord.com/api/oauth2/authorize?scope=${i.join("+")}&response_type=code&client_id=${e.clientId}&redirect_uri=${encodeURIComponent(e.redirectURI||o)}&state=${t}`)},validateAuthorizationCode:async({code:t,redirectURI:r})=>A({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await Yt("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 er}from"@better-fetch/fetch";var ze=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let i=e.scope||r||["email","public_profile"];return await T({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 er("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,emailVerified:r.email_verified},data:r}}});import{betterFetch as Me}from"@better-fetch/fetch";var He=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 T({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 Me("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 Me("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 tr}from"oslo/jwt";var Ke=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 T({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=tr(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 rr}from"@better-fetch/fetch";import{parseJWT as or}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 T({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=or(i.idToken)?.payload,a=e.profilePhotoSize||48;return await rr(`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 nr}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 T({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 nr("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 An(e){return e.charAt(0).toUpperCase()+e.slice(1)}var N={isAction:!1};import{nanoid as ir}from"nanoid";var v=e=>ir(e);import{parseJWT as sr}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 T({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=sr(r)?.payload;return{user:{id:o.sub,name:o.preferred_username,email:o.email,image:o.picture,emailVerified:!1},data:o}}});import{betterFetch as ar}from"@better-fetch/fetch";var Ze=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(t){let r=e.scope||t.scopes||["account_info.read"];return T({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 ar("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 ue={apple:$e,discord:je,facebook:ze,github:He,microsoft:Ge,google:Ke,spotify:Qe,twitch:We,twitter:Ze},Je=Object.keys(ue);import{TimeSpan as dr}from"oslo";import{createJWT as cr,validateJWT as lr}from"oslo/jwt";import{z as S}from"zod";import{APIError as H}from"better-call";import{APIError as Z}from"better-call";var $=(e,t="ms")=>new Date(Date.now()+(t==="sec"?e*1e3:e));import{z as Xe}from"zod";var pe=()=>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 Q(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 Q(e),e.json(null,{status:401});let d=(s.expiresAt.valueOf()-Date.now())/1e3;return await L(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})}}),fe=async e=>await pe()({...e,_flag:"json",headers:e.headers}),C=M(async e=>{let t=await fe(e);if(!t?.session)throw new Z("UNAUTHORIZED");return{session:t}}),Ye=()=>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)}),et=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 Z("BAD_REQUEST",{message:"Session not found"});if(r.session.userId!==e.context.session.user.id)throw new Z("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(t)}catch(o){throw e.context.logger.error(o),new Z("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),tt=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 Z("INTERNAL_SERVER_ERROR")}return e.json({status:!0})});async function B(e,t,r){return await cr("HS256",Buffer.from(e),{email:t.toLowerCase(),updateTo:r},{expiresIn:new dr(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}var rt=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})}),ot=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 lr("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 fe(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 nt=y("/sign-in/social",{method:"POST",requireHeaders:!0,query:P.object({currentURL:P.string().optional()}).optional(),body:P.object({callbackURL:P.string().optional(),provider:P.enum(Je)}),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 O("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 _e(i||o?.origin||e.context.options.baseURL);await e.setSignedCookie(r.state.name,n.hash,e.context.secret,r.state.options);let a=ur();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})}),it=y("/sign-in/email",{method:"POST",body:P.object({email:P.string(),password:P.string(),callbackURL:P.string().optional(),dontRememberMe:P.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 O("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:t,password:r}=e.body;if(!P.string().email().safeParse(t).success)throw new O("BAD_REQUEST",{message:"Invalid email"});if(!P.string().email().safeParse(t).success)throw new O("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 O("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 O("UNAUTHORIZED",{message:"Invalid email or password"});let c=a?.password;if(!c)throw e.context.logger.error("Password not found",{email:t}),new O("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(c,r))throw e.context.logger.error("Invalid password"),new O("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 O("INTERNAL_SERVER_ERROR",{message:"Email is not verified."});let l=await B(e.context.secret,n.user.email),p=`${e.context.options.baseURL}/verify-email?token=${l}`;throw await e.context.options.emailVerification.sendVerificationEmail(n.user,p,l),e.context.logger.error("Email not verified",{email:t}),new O("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 O("UNAUTHORIZED",{message:"Failed to create session"});return await L(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()}),st=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 pr(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 at(e,t){let r={...e.user?.additionalFields};return pr(t||{},{fields:r})}var dt=y("/callback/:id",{method:"GET",query:re.object({state:re.string(),code:re.string().optional(),error:re.string().optional()}),metadata:N},async e=>{if(e.query.error||!e.query.code){let 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(g=>g.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 Le(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(g){throw e.context.logger.error(g),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let d=await t.getUserInfo(s).then(g=>g?.user),l=v(),p=st.safeParse({...d,id:l});if(!d||p.success===!1)throw b.error("Unable to get user info",p.error),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!o)throw e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);function u(g){throw e.redirect(`${i||o||`${e.context.baseURL}/error`}?error=${g}`)}let f=await e.context.internalAdapter.findUserByEmail(d.email,{includeAccounts:!0}).catch(g=>{throw b.error(`Better auth was unable to query your database.
|
|
3
|
+
Error: `,g),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)}),m=f?.user.id;if(f){if(!f.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:f.user.id,...le(s)})}catch(F){b.error("Unable to link account",F),u("unable_to_link_account")}}}else try{let g=d.emailVerified||!1,U=await e.context.internalAdapter.createOAuthUser({...p.data,emailVerified:g},{...le(s),providerId:t.id,accountId:d.id.toString()});if(m=U?.user.id,!g&&U&&e.context.options.emailVerification?.sendOnSignUp){let G=await B(e.context.secret,d.email),F=`${e.context.baseURL}/verify-email?token=${G}&callbackURL=${o}`;await e.context.options.emailVerification?.sendVerificationEmail?.(U.user,F,G)}}catch(g){b.error("Unable to create user",g),u("unable_to_create_user")}m||u("unable_to_create_user");let h=await e.context.internalAdapter.createSession(m,e.request);throw h||u("unable_to_create_session"),await L(e,h.id),e.redirect(o)});import"zod";import{APIError as fr}from"better-call";var ct=y("/sign-out",{method:"POST"},async e=>{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)throw new fr("BAD_REQUEST",{message:"Session not found"});return await e.context.internalAdapter.deleteSession(t),Q(e),e.json({success:!0})});import{z as _}from"zod";import{APIError as oe}from"better-call";var lt=y("/forget-password",{method:"POST",body:_.object({email:_.string().email(),redirectTo:_.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})}),ut=y("/reset-password/:token",{method:"GET",query:_.object({callbackURL:_.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}`)}),pt=y("/reset-password",{query:_.optional(_.object({token:_.string()})),method:"POST",body:_.object({newPassword:_.string()})},async e=>{let t=e.query?.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 E}from"better-call";var ft=y("/user/update",{method:"POST",body:R.object({name:R.string().optional(),image:R.string().optional()}),use:[C,x]},async e=>{let{name:t,image:r}=e.body,o=e.context.session;if(!r&&!t)return e.json({user:o.user});let i=await e.context.internalAdapter.updateUserByEmail(o.user.email,{name:t,image:r});return e.json({user:i})}),mt=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 E("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 E("BAD_REQUEST",{message:"Password too long"});let s=(await e.context.internalAdapter.findAccounts(i.user.id)).find(p=>p.providerId==="credential"&&p.password);if(!s||!s.password)throw new E("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 E("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 p=await e.context.internalAdapter.createSession(i.user.id,e.headers);if(!p)throw new E("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});await L(e,p.id)}return e.json(i.user)}),gt=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 E("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 E("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 E("BAD_REQUEST",{message:"user already has a password"})}),ht=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(a=>a.providerId==="credential"&&a.password);if(!i||!i.password)throw new E("BAD_REQUEST",{message:"User does not have a password"});if(!await e.context.password.verify(i.password,t))throw new E("BAD_REQUEST",{message:"Incorrect password"});return await e.context.internalAdapter.deleteUser(r.user.id),await e.context.internalAdapter.deleteSessions(r.user.id),e.json(null)}),yt=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 E("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 E("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 E("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.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new E("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.emailVerification.sendVerificationEmail(e.context.session.user,o,r),e.json({user:null,status:!0})});var wt=y("/csrf",{method:"GET",metadata:N},async e=>{let t=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret);if(t){let[n,a]=t.split("!")||[null,null];return e.json({csrfToken:n})}let r=xe(32,Te("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 mr=(e="Unknown")=>`<!DOCTYPE html>
|
|
4
4
|
<html lang="en">
|
|
5
5
|
<head>
|
|
6
6
|
<meta charset="UTF-8">
|
|
@@ -80,4 +80,4 @@ Error: `,g),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>`,ht=y("/error",{method:"GET",metadata:N},async e=>{let t=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(cr(t),{headers:{"Content-Type":"text/html"}})});var yt=y("/ok",{method:"GET",metadata:N},async e=>e.json({ok:!0}));import{z as H}from"zod";import{APIError as $}from"better-call";var wt=()=>y("/sign-up/email",{method:"POST",query:H.object({currentURL:H.string().optional()}).optional(),body:H.record(H.string(),H.any()),use:[x]},async e=>{if(!e.context.options.emailAndPassword?.enabled)throw new $("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(!H.string().email().safeParse(o).success)throw new $("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 $("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 $("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 $("UNPROCESSABLE_ENTITY",{message:"Failed to create user"});let u=nt(e.context.options,c),f=await e.context.internalAdapter.createUser({email:o.toLowerCase(),name:r,image:n,...u,emailVerified:!1});if(!f)throw new $("BAD_REQUEST",{message:"Failed to create user"});let m=await e.context.password.hash(i);if(await e.context.internalAdapter.linkAccount({userId:f.id,providerId:"credential",accountId:f.id,password:m,expiresAt:V(60*60*24*30,"sec")}),e.context.options.emailVerification?.sendOnSignUp){let g=await B(e.context.secret,f.email),U=`${e.context.baseURL}/verify-email?token=${g}&callbackURL=${t.callbackURL||e.query?.currentURL||"/"}`;await e.context.options.emailVerification?.sendVerificationEmail?.(f,U,g)}if(!e.context.options.emailAndPassword.autoSignIn||e.context.options.emailAndPassword.requireEmailVerification)return e.json({user:f,session:null},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:f,session:null}});let h=await e.context.internalAdapter.createSession(f.id,e.request);if(!h)throw new $("BAD_REQUEST",{message:"Failed to create session"});return await L(e,h.id),e.json({user:f,session:h},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:f,session:h}})});function oe(e){let t="127.0.0.1";if(process.env.NODE_ENV==="test")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 lr(e,t,r){let o=Date.now(),i=t*1e3;return o-r.lastRequest<i&&r.count>=e}function ur(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 pr(e,t){let r=Date.now(),o=t*1e3;return Math.ceil((e+o-r)/1e3)}function fr(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 bt=new Map;function mr(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 bt.get(r)},async set(r,o,i){bt.set(r,o)}}:fr(e,e.rateLimit.tableName)}async function At(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=oe(e)+o,s=gr().find(u=>u.pathMatcher(o));s&&(i=s.window,n=s.max);for(let u of t.options.plugins||[])if(u.rateLimit){let f=u.rateLimit.find(m=>m.pathMatcher(o));if(f){i=f.window,n=f.max;break}}if(t.rateLimit.customRules){let u=t.rateLimit.customRules[o];u&&(i=u.window,n=u.max)}let d=mr(t),l=await d.get(a),p=Date.now();if(!l)await d.set(a,{key:a,count:1,lastRequest:p});else{let u=p-l.lastRequest;if(lr(n,i,l)){let f=pr(l.lastRequest,i);return ur(f)}else u>i*1e3?await d.set(a,{...l,count:1,lastRequest:p}):await d.set(a,{...l,count:l.count+1,lastRequest:p})}}function gr(){return[{pathMatcher(t){return t.startsWith("/sign-in")||t.startsWith("/sign-up")},window:10,max:7}]}import{APIError as ha}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:tt,callbackOAuth:it,getCSRFToken:gt,getSession:ue(),signOut:st,signUpEmail:wt(),signInEmail:rt,forgetPassword:at,resetPassword:ct,verifyEmail:et,sendVerificationEmail:Ye,changeEmail:mt,changePassword:ut,setPassword:pt,updateUser:lt,deleteUser:ft,forgetPasswordCallback:dt,listSessions:Ze(),revokeSession:Je,revokeSessions:Xe},...r,ok:yt,error:ht},a={};for(let[c,s]of Object.entries(n))a[c]=async(d={})=>{let l=await e;for(let f of t.plugins||[])if(f.hooks?.before){for(let m of f.hooks.before)if(m.matcher({...s,...d,context:l})){let g=await m.handler({...d,context:{...l,...d?.context}});g&&"context"in g&&(l={...l,...g.context})}}let p;try{p=await s({...d,context:{...l,...d.context}})}catch(f){if(f instanceof kt){let m=t.plugins?.map(g=>{if(g.hooks?.after)return g.hooks.after}).filter(g=>g!==void 0).flat();if(!m?.length)throw f;let h=new Response(JSON.stringify(f.body),{status:yr[f.status],headers:f.headers});for(let g of m||[])if(g.matcher(d)){let K=Object.assign(d,{context:{...e,returned:h}}),F=await g.handler(K);F&&"response"in F&&(h=F.response)}return h}throw f}let u=p;for(let f of t.plugins||[])if(f.hooks?.after){for(let m of f.hooks.after)if(m.matcher(d)){let g=Object.assign(d,{context:{...e,returned:u}}),U=await m.handler(g);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 Rt=(e,t)=>{let{api:r,middlewares:o}=fe(e,t),i=new URL(e.baseURL).pathname;return hr(r,{extraContext:e,basePath:i,routerMiddleware:[{path:"/**",middleware:ve},...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 At(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 kt?(n.status==="INTERNAL_SERVER_ERROR"&&b.error(n),a?.error(n.message)):b?.error(n))}})};var D=e=>{let t=e.plugins?.reduce((s,d)=>{let l=d.schema;if(!l)return s;for(let[p,u]of Object.entries(l))s[p]={fields:{...s[p]?.fields,...u.fields},tableName:u.tableName||p};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 Ut,MssqlDialect as wr}from"kysely";import{MysqlDialect as xt,PostgresDialect as Tt,SqliteDialect as Et}from"kysely";function vt(e){if("dialect"in e)return vt(e.dialect);if("createDriver"in e){if(e instanceof Et)return"sqlite";if(e instanceof xt)return"mysql";if(e instanceof Tt)return"postgres";if(e instanceof wr)return"mssql"}return"aggregate"in e?"sqlite":"getConnection"in e?"mysql":"connect"in e?"postgres":null}var Z=async e=>{let t=e.database;if("db"in t)return{kysely:t.db,databaseType:t.type};if("dialect"in t)return{kysely:new Ut({dialect:t.dialect}),databaseType:t.type};let r,o=vt(t);return"createDriver"in t&&(r=t),"aggregate"in t&&(r=new Et({database:t})),"getConnection"in t&&(r=new xt({pool:t})),"connect"in t&&(r=new Tt({pool:t})),{kysely:r?new Ut({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 ne(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 It(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 Ot=(e,t)=>({id:"kysely",async create(r){let{model:o,data:i,select:n}=r;t?.transform&&(i=It(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?ne(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(p=>p(l))))),c&&(s=s.where(l=>l.or(c.map(p=>p(l)))));let d=await s.executeTakeFirst();if(n?.length&&(d=d?n.reduce((p,u)=>d?.[u]?{...p,[u]:d[u]}:p,{}):null),t?.transform){let l=t.transform.schema[o];return d=d&&l?ne(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(f=>f(u))))),l&&(s=s.where(u=>u.or(l.map(f=>f(u))))),s=s.limit(n||100),a&&(s=s.offset(a)),c&&(s=s.orderBy(c.field,c.direction));let p=await s.selectAll().execute();if(t?.transform){let u=t.transform.schema[o];return u?p.map(f=>ne(f,u,t.transform)):p}return p},async update(r){let{model:o,where:i,update:n}=r,{and:a,or:c}=J(i);t?.transform&&(n=It(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(p=>p(l))))),c&&(s=s.where(l=>l.or(c.map(p=>p(l)))));let d=await s.returningAll().executeTakeFirst()||null;if(t?.transform){let l=t.transform.schema[o];return l?ne(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 St(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 Z(e);if(!t)throw new k("Failed to initialize database adapter");let o=D(e),i={};for(let n of Object.values(o))i[n.tableName]=n.fields;return Ot(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 Pt(e,t){let r=t.hooks,o=D(t.options);async function i(a,c,s){let d=a,l=o[c];for(let f of r||[]){let m=f[c]?.create?.before;if(m){let h=await m(a);if(h===!1)return null;typeof h=="object"&&"data"in h&&(d=h.data)}}let p=s?await s.fn(d):null,u=!s||s.executeMainFn?await e.create({model:l.tableName,data:{...me(l.fields,d),id:d.id||E()}}):p;for(let f of r||[]){let m=f[c]?.create?.after;m&&await m(u)}return I(l.fields,u)}async function n(a,c,s,d){let l=a;for(let f of r||[]){let m=f[s]?.update?.before;if(m){let h=await m(a);if(h===!1)return null;l=typeof h=="object"?h.data:h}}let p=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}):p;for(let f of r||[]){let m=f[s]?.update?.after;m&&await m(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=D(r),{createWithHooks:a,updateWithHooks:c}=Pt(e,t);return{createOAuthUser:async(s,d)=>{try{let l=await a({id:E(),createdAt:new Date,updatedAt:new Date,...s},"user"),p=await a({id:E(),...d,userId:l.id||s.id},"account");return{user:l,account:p}}catch(l){return console.log(l),null}},createUser:async s=>await a({id:E(),createdAt:new Date,updatedAt:new Date,emailVerified:!1,...s},"user"),createAccount:async s=>await a({id:E(),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,p)=>(await e.findMany({model:n.user.tableName,limit:s,offset:d,sortBy:l,where:p})).map(f=>I(n.user.fields,f)),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,p)=>{let u=d instanceof Request?d.headers:d,f={id:E(),userId:s,expiresAt:l?V(60*60*24,"sec"):V(i,"sec"),ipAddress:d&&oe(d)||"",userAgent:u?.get("user-agent")||"",...p};return await a(f,"session",o?{fn:async h=>{let g=await e.findOne({model:n.user.tableName,where:[{field:"id",value:s}]});return o.set(h.id,JSON.stringify({session:h,user:g}),i),h},executeMainFn:r.session?.storeSessionInDatabase}:void 0)},findSession:async s=>{if(o){let p=await o.get(s);if(p){let u=JSON.parse(p);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 f of s){let m=await o.get(f);if(m){let h=JSON.parse(m),g={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(g)}}return u}let d=await e.findMany({model:n.session.tableName,where:[{field:"id",value:s,operator:"in"}]}),l=d.map(u=>u.userId),p=await e.findMany({model:n.user.tableName,where:[{field:"id",value:l,operator:"in"}]});return d.map(u=>{let f=p.find(m=>m.id===u.userId);return f?{session:I(n.session.fields,u),user:I(n.user.fields,f)}:null})},updateSession:async(s,d)=>await c(d,[{field:"id",value:s}],"session",o?{async fn(p){let u=await o.get(s),f=null;if(u){let m=JSON.parse(u);f={...m.session,...p},await o.set(s,JSON.stringify({session:f,user:m.user}),m.session.expiresAt?new Date(m.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.delete({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 p=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:p.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:E(),...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:E(),...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 ja}from"zod";import"kysely";import{defu as br}from"defu";var he="better-auth-secret-123456789";var Lt=async e=>{let t=await St(e),r=e.plugins||[],o=kr(e),{kysely:i}=await Z(e),n=Q(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||process.env.BETTER_AUTH_SECRET||process.env.AUTH_SECRET||he;if(a===he&&process.env.NODE_ENV==="production")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=_e(e),s=D(e),d=Object.keys(e.socialProviders||{}).map(u=>{let f=e.socialProviders?.[u];return f.enabled===!1?null:((!f.clientId||!f.clientSecret)&&b.warn(`Social provider ${u} is missing clientId or clientSecret`),le[u](f))}).filter(u=>u!==null),l={appName:e.appName||"Better Auth",socialProviders:d,options:e,tables:s,trustedOrigins:Rr(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??process.env.NODE_ENV!=="development",window:e.rateLimit?.window||60,max:e.rateLimit?.max||100,storage:e.rateLimit?.storage||e.secondaryStorage?"secondary-storage":"memory"},authCookies:c,logger:ae({disabled:e.logger?.disabled||!1}),db:i,uuid:E,secondaryStorage:e.secondaryStorage,password:{hash:e.emailAndPassword?.password?.hash||be,verify:e.emailAndPassword?.password?.verify||Ae,config:{minPasswordLength:e.emailAndPassword?.minPasswordLength||8,maxPasswordLength:e.emailAndPassword?.maxPasswordLength||128}},adapter:t,internalAdapter:ge(t,{options:e,hooks:e.databaseHooks?[e.databaseHooks]:[]}),createAuthCookie:Ce(e)},{context:p}=Ar(l);return p};function Ar(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=br(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 kr(e){let t=[];return e.advanced?.crossSubDomainCookies?.enabled,t}function Rr(e){let t=Q(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=process.env.BETTER_AUTH_TRUSTED_ORIGINS;return o&&r.push(...o.split(",")),r}var Ed=e=>{let t=Lt(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=Q(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}=Rt(i,e);return c(o)},api:r,options:e,$Infer:{}}};export{k as BetterAuthError,N as HIDE_METADATA,Le as MissingDependencyError,Ed as betterAuth,pn as capitalizeFirstLetter,Ce as createCookieGetter,ae as createLogger,G as deleteSessionCookie,E as generateId,Pe as generateState,_e as getCookies,b as logger,po as parseCookies,uo as parseSetCookieHeader,se as parseState,L as setSessionCookie};
|
|
83
|
+
</html>`,bt=y("/error",{method:"GET",metadata:N},async e=>{let t=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(mr(t),{headers:{"Content-Type":"text/html"}})});var At=y("/ok",{method:"GET",metadata:N},async e=>e.json({ok:!0}));import{z as K}from"zod";import{APIError as j}from"better-call";var kt=()=>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 j("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 j("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 j("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 j("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 j("UNPROCESSABLE_ENTITY",{message:"Failed to create user"});let u=at(e.context.options,c),f=await e.context.internalAdapter.createUser({email:o.toLowerCase(),name:r,image:n,...u,emailVerified:!1});if(!f)throw new j("BAD_REQUEST",{message:"Failed to create user"});let m=await e.context.password.hash(i);if(await e.context.internalAdapter.linkAccount({userId:f.id,providerId:"credential",accountId:f.id,password:m,expiresAt:$(60*60*24*30,"sec")}),e.context.options.emailVerification?.sendOnSignUp){let g=await B(e.context.secret,f.email),U=`${e.context.baseURL}/verify-email?token=${g}&callbackURL=${t.callbackURL||e.query?.currentURL||"/"}`;await e.context.options.emailVerification?.sendVerificationEmail?.(f,U,g)}if(!e.context.options.emailAndPassword.autoSignIn||e.context.options.emailAndPassword.requireEmailVerification)return e.json({user:f,session:null},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:f,session:null}});let h=await e.context.internalAdapter.createSession(f.id,e.request);if(!h)throw new j("BAD_REQUEST",{message:"Failed to create session"});return await L(e,h.id),e.json({user:f,session:h},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:f,session:h}})});import{isTest as gr}from"std-env";function ne(e){let t="127.0.0.1";if(gr)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 hr(e,t,r){let o=Date.now(),i=t*1e3;return o-r.lastRequest<i&&r.count>=e}function yr(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 wr(e,t){let r=Date.now(),o=t*1e3;return Math.ceil((e+o-r)/1e3)}function br(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 Rt=new Map;function Ar(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 Rt.get(r)},async set(r,o,i){Rt.set(r,o)}}:br(e,e.rateLimit.tableName)}async function Ut(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=kr().find(u=>u.pathMatcher(o));s&&(i=s.window,n=s.max);for(let u of t.options.plugins||[])if(u.rateLimit){let f=u.rateLimit.find(m=>m.pathMatcher(o));if(f){i=f.window,n=f.max;break}}if(t.rateLimit.customRules){let u=t.rateLimit.customRules[o];u&&(i=u.window,n=u.max)}let d=Ar(t),l=await d.get(a),p=Date.now();if(!l)await d.set(a,{key:a,count:1,lastRequest:p});else{let u=p-l.lastRequest;if(hr(n,i,l)){let f=wr(l.lastRequest,i);return yr(f)}else u>i*1e3?await d.set(a,{...l,count:1,lastRequest:p}):await d.set(a,{...l,count:l.count+1,lastRequest:p})}}function kr(){return[{pathMatcher(t){return t.startsWith("/sign-in")||t.startsWith("/sign-up")},window:10,max:7}]}import{APIError as Ta}from"better-call";function me(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:nt,callbackOAuth:dt,getCSRFToken:wt,getSession:pe(),signOut:ct,signUpEmail:kt(),signInEmail:it,forgetPassword:lt,resetPassword:pt,verifyEmail:ot,sendVerificationEmail:rt,changeEmail:yt,changePassword:mt,setPassword:gt,updateUser:ft,deleteUser:ht,forgetPasswordCallback:ut,listSessions:Ye(),revokeSession:et,revokeSessions:tt},...r,ok:At,error:bt},a={};for(let[c,s]of Object.entries(n))a[c]=async(d={})=>{let l=await e;for(let f of t.plugins||[])if(f.hooks?.before){for(let m of f.hooks.before)if(m.matcher({...s,...d,context:l})){let g=await m.handler({...d,context:{...l,...d?.context}});g&&"context"in g&&(l={...l,...g.context})}}let p;try{p=await s({...d,context:{...l,...d.context}})}catch(f){if(f instanceof xt){let m=t.plugins?.map(g=>{if(g.hooks?.after)return g.hooks.after}).filter(g=>g!==void 0).flat();if(!m?.length)throw f;let h=new Response(JSON.stringify(f.body),{status:Ur[f.status],headers:f.headers});for(let g of m||[])if(g.matcher(d)){let G=Object.assign(d,{context:{...e,returned:h}}),F=await g.handler(G);F&&"response"in F&&(h=F.response)}return h}throw f}let u=p;for(let f of t.plugins||[])if(f.hooks?.after){for(let m of f.hooks.after)if(m.matcher(d)){let g=Object.assign(d,{context:{...e,returned:u}}),U=await m.handler(g);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 Tt=(e,t)=>{let{api:r,middlewares:o}=me(e,t),i=new URL(e.baseURL).pathname;return Rr(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 Ut(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 xt?(n.status==="INTERNAL_SERVER_ERROR"&&b.error(n),a?.error(n.message)):b?.error(n))}})};var D=e=>{let t=e.plugins?.reduce((s,d)=>{let l=d.schema;if(!l)return s;for(let[p,u]of Object.entries(l))s[p]={fields:{...s[p]?.fields,...u.fields},tableName:u.tableName||p};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 vt,MssqlDialect as xr}from"kysely";import{MysqlDialect as Et,PostgresDialect as It,SqliteDialect as Pt}from"kysely";function St(e){if("dialect"in e)return St(e.dialect);if("createDriver"in e){if(e instanceof Pt)return"sqlite";if(e instanceof Et)return"mysql";if(e instanceof It)return"postgres";if(e instanceof xr)return"mssql"}return"aggregate"in e?"sqlite":"getConnection"in e?"mysql":"connect"in e?"postgres":null}var J=async e=>{let t=e.database;if("db"in t)return{kysely:t.db,databaseType:t.type};if("dialect"in t)return{kysely:new vt({dialect:t.dialect}),databaseType:t.type};let r,o=St(t);return"createDriver"in t&&(r=t),"aggregate"in t&&(r=new Pt({database:t})),"getConnection"in t&&(r=new Et({pool:t})),"connect"in t&&(r=new It({pool:t})),{kysely:r?new vt({dialect:r}):null,databaseType:o}};function X(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 Ot(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 Lt=(e,t)=>({id:"kysely",async create(r){let{model:o,data:i,select:n}=r;t?.transform&&(i=Ot(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}=X(i),s=e.selectFrom(o).selectAll();a&&(s=s.where(l=>l.and(a.map(p=>p(l))))),c&&(s=s.where(l=>l.or(c.map(p=>p(l)))));let d=await s.executeTakeFirst();if(n?.length&&(d=d?n.reduce((p,u)=>d?.[u]?{...p,[u]:d[u]}:p,{}):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}=X(i);d&&(s=s.where(u=>u.and(d.map(f=>f(u))))),l&&(s=s.where(u=>u.or(l.map(f=>f(u))))),s=s.limit(n||100),a&&(s=s.offset(a)),c&&(s=s.orderBy(c.field,c.direction));let p=await s.selectAll().execute();if(t?.transform){let u=t.transform.schema[o];return u?p.map(f=>ie(f,u,t.transform)):p}return p},async update(r){let{model:o,where:i,update:n}=r,{and:a,or:c}=X(i);t?.transform&&(n=Ot(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(p=>p(l))))),c&&(s=s.where(l=>l.or(c.map(p=>p(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}=X(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}=X(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 _t(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 J(e);if(!t)throw new k("Failed to initialize database adapter");let o=D(e),i={};for(let n of Object.values(o))i[n.tableName]=n.fields;return Lt(t,{transform:{schema:i,date:!0,boolean:r==="sqlite"},generateId:"generateId"in e.database?e.database.generateId:void 0})}function ge(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 Ct(e,t){let r=t.hooks,o=D(t.options);async function i(a,c,s){let d=a,l=o[c];for(let f of r||[]){let m=f[c]?.create?.before;if(m){let h=await m(a);if(h===!1)return null;typeof h=="object"&&"data"in h&&(d=h.data)}}let p=s?await s.fn(d):null,u=!s||s.executeMainFn?await e.create({model:l.tableName,data:{...ge(l.fields,d),id:d.id||v()}}):p;for(let f of r||[]){let m=f[c]?.create?.after;m&&await m(u)}return I(l.fields,u)}async function n(a,c,s,d){let l=a;for(let f of r||[]){let m=f[s]?.update?.before;if(m){let h=await m(a);if(h===!1)return null;l=typeof h=="object"?h.data:h}}let p=d?await d.fn(l):null,u=!d||d.executeMainFn?await e.update({model:o[s].tableName,update:ge(o[s].fields,l),where:c}):p;for(let f of r||[]){let m=f[s]?.update?.after;m&&await m(u)}return I(o[s].fields,u)}return{createWithHooks:i,updateWithHooks:n}}var he=(e,t)=>{let r=t.options,o=r.secondaryStorage,i=r.session?.expiresIn||60*60*24*7,n=D(r),{createWithHooks:a,updateWithHooks:c}=Ct(e,t);return{createOAuthUser:async(s,d)=>{try{let l=await a({id:v(),createdAt:new Date,updatedAt:new Date,...s},"user"),p=await a({id:v(),...d,userId:l.id||s.id},"account");return{user:l,account:p}}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,p)=>(await e.findMany({model:n.user.tableName,limit:s,offset:d,sortBy:l,where:p})).map(f=>I(n.user.fields,f)),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,p)=>{let u=d instanceof Request?d.headers:d,f={id:v(),userId:s,expiresAt:l?$(60*60*24,"sec"):$(i,"sec"),ipAddress:d&&ne(d)||"",userAgent:u?.get("user-agent")||"",...p};return await a(f,"session",o?{fn:async h=>{let g=await e.findOne({model:n.user.tableName,where:[{field:"id",value:s}]});return o.set(h.id,JSON.stringify({session:h,user:g}),i),h},executeMainFn:r.session?.storeSessionInDatabase}:void 0)},findSession:async s=>{if(o){let p=await o.get(s);if(p){let u=JSON.parse(p);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 f of s){let m=await o.get(f);if(m){let h=JSON.parse(m),g={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(g)}}return u}let d=await e.findMany({model:n.session.tableName,where:[{field:"id",value:s,operator:"in"}]}),l=d.map(u=>u.userId),p=await e.findMany({model:n.user.tableName,where:[{field:"id",value:l,operator:"in"}]});return d.map(u=>{let f=p.find(m=>m.id===u.userId);return f?{session:I(n.session.fields,u),user:I(n.user.fields,f)}:null})},updateSession:async(s,d)=>await c(d,[{field:"id",value:s}],"session",o?{async fn(p){let u=await o.get(s),f=null;if(u){let m=JSON.parse(u);f={...m.session,...p},await o.set(s,JSON.stringify({session:f,user:m.user}),m.session.expiresAt?new Date(m.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.delete({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 p=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:p.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 Ja}from"zod";import"kysely";import{env as we,isProduction as Bt}from"std-env";import{defu as Tr}from"defu";var ye="better-auth-secret-123456789";var Dt=async e=>{let t=await _t(e),r=e.plugins||[],o=Er(e),{kysely:i}=await J(e),n=W(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&&Bt)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=De(e),s=D(e),d=Object.keys(e.socialProviders||{}).map(u=>{let f=e.socialProviders?.[u];return f.enabled===!1?null:((!f.clientId||!f.clientSecret)&&b.warn(`Social provider ${u} is missing clientId or clientSecret`),ue[u](f))}).filter(u=>u!==null),l={appName:e.appName||"Better Auth",socialProviders:d,options:e,tables:s,trustedOrigins:Ir(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??Bt,window:e.rateLimit?.window||60,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:he(t,{options:e,hooks:e.databaseHooks?[e.databaseHooks]:[]}),createAuthCookie:Ne(e)},{context:p}=vr(l);return p};function vr(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=Tr(t,a.options)),a.context&&(o={...o,...a.context}))}return i.push(t.databaseHooks),o.internalAdapter=he(e.adapter,{options:t,hooks:i.filter(n=>n!==void 0)}),o.options=t,{context:o}}function Er(e){let t=[];return e.advanced?.crossSubDomainCookies?.enabled,t}function Ir(e){let t=W(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 Dd=e=>{let t=Dt(e),{api:r}=me(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=W(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}=Tt(i,e);return c(o)},api:r,options:e,$Infer:{}}};export{k as BetterAuthError,N as HIDE_METADATA,Ce as MissingDependencyError,Dd as betterAuth,An as capitalizeFirstLetter,Ne as createCookieGetter,de as createLogger,Q as deleteSessionCookie,v as generateId,_e as generateState,De as getCookies,b as logger,bo as parseCookies,wo as parseSetCookieHeader,ae as parseState,L as setSessionCookie};
|
package/dist/next-js.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var o=Object.defineProperty;var
|
|
1
|
+
"use strict";var o=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var l=(e,s)=>{for(var r in s)o(e,r,{get:s[r],enumerable:!0})},h=(e,s,r,n)=>{if(s&&typeof s=="object"||typeof s=="function")for(let t of m(s))!R.call(e,t)&&t!==r&&o(e,t,{get:()=>s[t],enumerable:!(n=d(s,t))||n.enumerable});return e};var f=e=>h(o({},"__esModule",{value:!0}),e);var x={};l(x,{authMiddleware:()=>U,toNextJsHandler:()=>p});module.exports=f(x);var u=require("@better-fetch/fetch"),i=require("next/server"),c=require("std-env");function p(e){let s=async r=>"handler"in e?e.handler(r):e(r);return{GET:s,POST:s}}function U(e){return async s=>{let r=c.env.BETTER_AUTH_URL||new URL(s.url).origin,n=e?.basePath||"/api/auth",t=`${r}${n}/session`,a=(await(0,u.betterFetch)(t,{headers:{cookie:s.headers.get("cookie")||""}}).catch(T=>({data:null}))).data||null;return e.customRedirect?e.customRedirect(a,s):a?i.NextResponse.next():i.NextResponse.redirect(new URL(e.redirectTo||"/",r))}}0&&(module.exports={authMiddleware,toNextJsHandler});
|
package/dist/next-js.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{betterFetch as a}from"@better-fetch/fetch";import{NextResponse as n}from"next/server";function
|
|
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};
|
package/dist/oauth2.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var u=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var P=Object.prototype.hasOwnProperty;var R=(e,t)=>{for(var r in t)u(e,r,{get:t[r],enumerable:!0})},B=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of k(t))!P.call(e,o)&&o!==r&&u(e,o,{get:()=>t[o],enumerable:!(n=w(t,o))||n.enumerable});return e};var E=e=>B(u({},"__esModule",{value:!0}),e);var
|
|
1
|
+
"use strict";var u=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var P=Object.prototype.hasOwnProperty;var R=(e,t)=>{for(var r in t)u(e,r,{get:t[r],enumerable:!0})},B=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of k(t))!P.call(e,o)&&o!==r&&u(e,o,{get:()=>t[o],enumerable:!(n=w(t,o))||n.enumerable});return e};var E=e=>B(u({},"__esModule",{value:!0}),e);var I={};R(I,{createAuthorizationURL:()=>b,generateCodeChallenge:()=>d,generateState:()=>S,getAccountTokens:()=>C,getOAuth2Tokens:()=>l,parseState:()=>v,validateAuthorizationCode:()=>O});module.exports=E(I);var g=require("oslo/crypto");var L=require("std-env");var T=require("oslo/encoding");async function d(e){let t=await(0,g.sha256)(new TextEncoder().encode(e));return T.base64url.encode(new Uint8Array(t),{includePadding:!1})}function l(e){return{tokenType:e.token_type,accessToken:e.access_token,refreshToken:e.refresh_token,accessTokenExpiresAt:e.expires_at?new Date((Date.now()+e.expires_in)*1e3):void 0,scopes:e?.scope?typeof e.scope=="string"?e.scope.split(" "):e.scope:[],idToken:e.id_token}}async function b({id:e,options:t,authorizationEndpoint:r,state:n,codeVerifier:o,scopes:s,claims:c,disablePkce:f,redirectURI:m}){let i=new URL(r);if(i.searchParams.set("response_type","code"),i.searchParams.set("client_id",t.clientId),i.searchParams.set("state",n),i.searchParams.set("scope",s.join(" ")),i.searchParams.set("redirect_uri",t.redirectURI||m),!f&&o){let p=await d(o);i.searchParams.set("code_challenge_method","S256"),i.searchParams.set("code_challenge",p)}if(c){let p=c.reduce((h,A)=>(h[A]=null,h),{});i.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...p}}))}return i}var U=require("@better-fetch/fetch");async function O({code:e,codeVerifier:t,redirectURI:r,options:n,tokenEndpoint:o}){let s=new URLSearchParams;s.set("grant_type","authorization_code"),s.set("code",e),t&&s.set("code_verifier",t),s.set("redirect_uri",r),s.set("client_id",n.clientId),s.set("client_secret",n.clientSecret);let{data:c,error:f}=await(0,U.betterFetch)(o,{method:"POST",body:s,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(f)throw f;return l(c)}var x=require("oslo/oauth2"),a=require("zod");var y=require("oslo/crypto");async function _(e){let t=await(0,y.sha256)(typeof e=="string"?new TextEncoder().encode(e):e);return Buffer.from(t).toString("base64")}var Z=require("better-call");async function S(e){let t=(0,x.generateState)(),r=JSON.stringify({code:t,callbackURL:e}),n=await _(r);return{raw:r,hash:n}}function v(e){return a.z.object({code:a.z.string(),callbackURL:a.z.string().optional(),currentURL:a.z.string().optional()}).safeParse(JSON.parse(e))}function C(e){let t=e.accessToken,r=e.refreshToken,n;try{n=e.accessTokenExpiresAt}catch{}return{accessToken:t,refreshToken:r,expiresAt:n}}0&&(module.exports={createAuthorizationURL,generateCodeChallenge,generateState,getAccountTokens,getOAuth2Tokens,parseState,validateAuthorizationCode});
|
package/dist/oauth2.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{sha256 as T}from"oslo/crypto";import{base64url as U}from"oslo/encoding";async function l(e){let t=await T(new TextEncoder().encode(e));return U.encode(new Uint8Array(t),{includePadding:!1})}function
|
|
1
|
+
import{sha256 as T}from"oslo/crypto";import{env as P}from"std-env";import{base64url as U}from"oslo/encoding";async function l(e){let t=await T(new TextEncoder().encode(e));return U.encode(new Uint8Array(t),{includePadding:!1})}function m(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 C({id:e,options:t,authorizationEndpoint:s,state:r,codeVerifier:i,scopes:n,claims:a,disablePkce:c,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),!c&&i){let p=await l(i);o.searchParams.set("code_challenge_method","S256"),o.searchParams.set("code_challenge",p)}if(a){let p=a.reduce((d,g)=>(d[g]=null,d),{});o.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...p}}))}return o}import{betterFetch as y}from"@better-fetch/fetch";async function z({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:a,error:c}=await y(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 m(a)}import{generateState as x}from"oslo/oauth2";import{z as f}from"zod";import{sha256 as _}from"oslo/crypto";async function h(e){let t=await _(typeof e=="string"?new TextEncoder().encode(e):e);return Buffer.from(t).toString("base64")}import"better-call";async function Q(e){let t=x(),s=JSON.stringify({code:t,callbackURL:e}),r=await h(s);return{raw:s,hash:r}}function V(e){return f.object({code:f.string(),callbackURL:f.string().optional(),currentURL:f.string().optional()}).safeParse(JSON.parse(e))}function Z(e){let t=e.accessToken,s=e.refreshToken,r;try{r=e.accessTokenExpiresAt}catch{}return{accessToken:t,refreshToken:s,expiresAt:r}}export{C as createAuthorizationURL,l as generateCodeChallenge,Q as generateState,Z as getAccountTokens,m as getOAuth2Tokens,V as parseState,z as validateAuthorizationCode};
|