better-auth 0.5.2-beta.16 → 0.5.2-beta.18
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/adapters/drizzle.d.ts +1 -1
- package/dist/adapters/kysely.d.ts +1 -1
- package/dist/adapters/mongodb.d.ts +1 -1
- package/dist/adapters/prisma.d.ts +1 -1
- package/dist/adapters/prisma.js +1 -1
- package/dist/api.d.ts +1 -1
- package/dist/api.js +4 -4
- package/dist/{auth-SMzIERpz.d.ts → auth-DhjJVba-.d.ts} +294 -46
- package/dist/client/plugins.d.ts +3 -3
- package/dist/client.d.ts +1 -1
- package/dist/cookies.d.ts +1 -1
- package/dist/db.d.ts +2 -2
- package/dist/{index-DOKc35nY.d.ts → index-BVMUzWqf.d.ts} +7 -56
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -4
- package/dist/node.d.ts +4 -2
- package/dist/node.js +1 -1
- package/dist/plugins.d.ts +3 -3
- package/dist/plugins.js +5 -5
- package/dist/react.d.ts +1 -1
- package/dist/solid-start.d.ts +1 -1
- package/dist/solid.d.ts +1 -1
- package/dist/svelte-kit.d.ts +1 -1
- package/dist/svelte.d.ts +1 -1
- package/dist/types.d.ts +8 -3
- package/dist/vue.d.ts +1 -1
- package/package.json +24 -47
- package/dist/access.cjs +0 -1
- package/dist/access.d.cts +0 -4
- package/dist/adapters/drizzle.cjs +0 -1
- package/dist/adapters/drizzle.d.cts +0 -36
- package/dist/adapters/kysely.cjs +0 -1
- package/dist/adapters/kysely.d.cts +0 -43
- package/dist/adapters/mongodb.cjs +0 -1
- package/dist/adapters/mongodb.d.cts +0 -63
- package/dist/adapters/prisma.cjs +0 -1
- package/dist/adapters/prisma.d.cts +0 -25
- package/dist/api.cjs +0 -83
- package/dist/api.d.cts +0 -10
- package/dist/auth-kXZUEU5B.d.cts +0 -6117
- package/dist/client/plugins.cjs +0 -1
- package/dist/client/plugins.d.cts +0 -280
- package/dist/client.cjs +0 -1
- package/dist/client.d.cts +0 -276
- package/dist/cookies.cjs +0 -1
- package/dist/cookies.d.cts +0 -10
- package/dist/crypto.cjs +0 -1
- package/dist/crypto.d.cts +0 -30
- package/dist/db.cjs +0 -4
- package/dist/db.d.cts +0 -54
- package/dist/helper-DPDj8Nix.d.cts +0 -21
- package/dist/hide-metadata-DEHJp1rk.d.cts +0 -5
- package/dist/index-BkNFhk9A.d.cts +0 -24
- package/dist/index-R4tR6ojQ.d.cts +0 -5860
- package/dist/index.cjs +0 -83
- package/dist/index.d.cts +0 -28
- package/dist/next-js.cjs +0 -1
- package/dist/next-js.d.cts +0 -35
- package/dist/node.cjs +0 -1
- package/dist/node.d.cts +0 -15
- package/dist/oauth2.cjs +0 -1
- package/dist/oauth2.d.cts +0 -37
- package/dist/plugins.cjs +0 -84
- package/dist/plugins.d.cts +0 -182
- package/dist/react.cjs +0 -1
- package/dist/react.d.cts +0 -296
- package/dist/schema-Dkt0LqYs.d.cts +0 -105
- package/dist/social.cjs +0 -2
- package/dist/social.d.cts +0 -824
- package/dist/solid-start.cjs +0 -1
- package/dist/solid-start.d.cts +0 -21
- package/dist/solid.cjs +0 -1
- package/dist/solid.d.cts +0 -277
- package/dist/state-BUSdcdLW.d.cts +0 -17
- package/dist/statement-Da_cxgTI.d.cts +0 -81
- package/dist/svelte-kit.cjs +0 -1
- package/dist/svelte-kit.d.cts +0 -25
- package/dist/svelte.cjs +0 -1
- package/dist/svelte.d.cts +0 -276
- package/dist/types-BVIhbXRu.d.cts +0 -55
- package/dist/types.cjs +0 -1
- package/dist/types.d.cts +0 -133
- package/dist/vue.cjs +0 -1
- package/dist/vue.d.cts +0 -327
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Kysely } from 'kysely';
|
|
2
|
-
import { B as BetterAuthOptions, K as KyselyDatabaseType, F as FieldAttribute, A as Adapter } from '../auth-
|
|
2
|
+
import { B as BetterAuthOptions, K as KyselyDatabaseType, F as FieldAttribute, A as Adapter } from '../auth-DhjJVba-.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
import '../schema-Dkt0LqYs.js';
|
|
5
5
|
import 'better-call';
|
package/dist/adapters/prisma.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function f(a){switch(a){case"starts_with":return"startsWith";case"ends_with":return"endsWith";default:return a}}function c(a){if(!a)return{};if(a.length===1){let e=a[0];return e?{[e.field]:e.operator==="eq"||!e.operator?e.value:{[f(e.operator)]:e.value}}:void 0}let l=a.filter(e=>e.connector==="AND"||!e.connector),s=a.filter(e=>e.connector==="OR"),o=l.map(e=>({[e.field]:e.operator==="eq"||!e.operator?e.value:{[f(e.operator)]:e.value}})),r=s.map(e=>({[e.field]:{[e.operator||"eq"]:e.value}}));return{AND:o.length?o:void 0,OR:r.length?r:void 0}}var y=(a,l)=>{let s=a,o=l.generateId;return{id:"prisma",async create(r){let{model:e,data:n,select:t}=r;return o!==void 0&&(n.id=o?o():void 0),await s[e].create({data:n,...t?.length?{select:t.reduce((d,i)=>({...d,[i]:!0}),{})}:{}})},async findOne(r){let{model:e,where:n,select:t}=r,d=c(n);return await s[e].findFirst({where:d,...t?.length?{select:t.reduce((i,u)=>({...i,[u]:!0}),{})}:{}})},async findMany(r){let{model:e,where:n,limit:t,offset:d,sortBy:i}=r,u=c(n);return await s[e].findMany({where:u,take:t||100,skip:d||0,orderBy:i?.field?{[i.field]:i.direction==="desc"?"desc":"asc"}:void 0})},async update(r){let{model:e,where:n,update:t}=r;t.id&&(t.id=void 0);let d=c(n);return n.length===1?await s[e].update({where:d,data:t}):await s[e].updateMany({where:d,data:t})},async delete(r){let{model:e,where:n}=r,t=c(n);return await s[e].delete({where:t})},async deleteMany(r){let{model:e,where:n}=r,t=c(n);return await s[e].deleteMany({where:t})},options:l}};export{y as prismaAdapter};
|
|
1
|
+
function f(a){switch(a){case"starts_with":return"startsWith";case"ends_with":return"endsWith";default:return a}}function c(a){if(!a)return{};if(a.length===1){let e=a[0];return e?{[e.field]:e.operator==="eq"||!e.operator?e.value:{[f(e.operator)]:e.value}}:void 0}let l=a.filter(e=>e.connector==="AND"||!e.connector),s=a.filter(e=>e.connector==="OR"),o=l.map(e=>({[e.field]:e.operator==="eq"||!e.operator?e.value:{[f(e.operator)]:e.value}})),r=s.map(e=>({[e.field]:{[e.operator||"eq"]:e.value}}));return{AND:o.length?o:void 0,OR:r.length?r:void 0}}var y=(a,l)=>{let s=a,o=l.generateId;return{id:"prisma",async create(r){let{model:e,data:n,select:t}=r;return o!==void 0&&(n.id=o?o():void 0),await s[e].create({data:n,...t?.length?{select:t.reduce((d,i)=>({...d,[i]:!0}),{})}:{}})},async findOne(r){let{model:e,where:n,select:t}=r,d=c(n);return await s[e].findFirst({where:d,...t?.length?{select:t.reduce((i,u)=>({...i,[u]:!0}),{})}:{}})},async findMany(r){let{model:e,where:n,limit:t,offset:d,sortBy:i}=r,u=c(n);return await s[e].findMany({where:u,take:t||100,skip:d||0,orderBy:i?.field?{[i.field]:i.direction==="desc"?"desc":"asc"}:void 0})},async update(r){let{model:e,where:n,update:t}=r;t.id&&(t.id=void 0);let d=c(n);return n.length===1?await s[e].update({where:d,data:t}):await s[e].updateMany({where:d,data:t})},async delete(r){let{model:e,where:n}=r,t=c(n);return await s[e].delete({where:t}).catch(d=>{})},async deleteMany(r){let{model:e,where:n}=r,t=c(n);return await s[e].deleteMany({where:t})},options:l}};export{y as prismaAdapter};
|
package/dist/api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { e as AuthEndpoint, f as AuthMiddleware, a1 as callbackOAuth, aj as changeEmail, ag as changePassword, d as createAuthEndpoint, c as createAuthMiddleware, ac as createEmailVerificationToken, ao as csrfMiddleware, ai as deleteUser, al as error, a9 as forgetPassword, aa as forgetPasswordCallback, ak as getCSRFToken, Z as getEndpoints, a2 as getSession, a3 as getSessionFromCtx, a5 as listSessions, am as ok, o as optionsMiddleware, ab as resetPassword, a6 as revokeSession, a7 as revokeSessions, _ as router, ad as sendVerificationEmail, a4 as sessionMiddleware, ah as setPassword, a0 as signInEmail, $ as signInOAuth, a8 as signOut, an as signUpEmail, af as updateUser, ae as verifyEmail } from './auth-
|
|
1
|
+
export { e as AuthEndpoint, f as AuthMiddleware, a1 as callbackOAuth, aj as changeEmail, ag as changePassword, d as createAuthEndpoint, c as createAuthMiddleware, ac as createEmailVerificationToken, ao as csrfMiddleware, ai as deleteUser, al as error, a9 as forgetPassword, aa as forgetPasswordCallback, ak as getCSRFToken, Z as getEndpoints, a2 as getSession, a3 as getSessionFromCtx, a5 as listSessions, am as ok, o as optionsMiddleware, ab as resetPassword, a6 as revokeSession, a7 as revokeSessions, _ as router, ad as sendVerificationEmail, a4 as sessionMiddleware, ah as setPassword, a0 as signInEmail, $ as signInOAuth, a8 as signOut, an as signUpEmail, af as updateUser, ae as verifyEmail } from './auth-DhjJVba-.js';
|
|
2
2
|
import './helper-DPDj8Nix.js';
|
|
3
3
|
export { APIError } from 'better-call';
|
|
4
4
|
import 'zod';
|
package/dist/api.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{APIError as
|
|
2
|
-
`)}}),w=at();var R=V(async e=>{let{body:t,query:r,headers:o,context:n}=e,i=t?.callbackURL||r?.callbackURL||r?.redirectTo||t?.redirectTo,s=r?.currentURL||o?.get("referer")||n.baseURL,c=n.trustedOrigins,d=(a,l)=>{if(a?.startsWith("http")&&!c.some(g=>a.startsWith(g)))throw w.error(`Invalid ${l}`,{[l]:a,trustedOrigins:c}),new ct("FORBIDDEN",{message:`Invalid ${l}`})};d(i,"callbackURL"),d(s,"currentURL")});import{parseJWT as pt}from"oslo/jwt";import{sha256 as dt}from"oslo/crypto";import{env as Mr}from"std-env";import{base64url as lt}from"oslo/encoding";async function pe(e){let t=await dt(new TextEncoder().encode(e));return lt.encode(new Uint8Array(t),{includePadding:!1})}function me(e){return{tokenType:e.token_type,accessToken:e.access_token,refreshToken:e.refresh_token,accessTokenExpiresAt:e.expires_at?new Date((Date.now()+e.expires_in)*1e3):void 0,scopes:e?.scope?typeof e.scope=="string"?e.scope.split(" "):e.scope:[],idToken:e.id_token}}async function U({id:e,options:t,authorizationEndpoint:r,state:o,codeVerifier:n,scopes:i,claims:s,disablePkce:c,redirectURI:d}){let a=new URL(r);if(a.searchParams.set("response_type","code"),a.searchParams.set("client_id",t.clientId),a.searchParams.set("state",o),a.searchParams.set("scope",i.join(" ")),a.searchParams.set("redirect_uri",t.redirectURI||d),!c&&n){let l=await pe(n);a.searchParams.set("code_challenge_method","S256"),a.searchParams.set("code_challenge",l)}if(s){let l=s.reduce((h,g)=>(h[g]=null,h),{});a.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...l}}))}return a}import{betterFetch as ut}from"@better-fetch/fetch";async function y({code:e,codeVerifier:t,redirectURI:r,options:o,tokenEndpoint:n}){let i=new URLSearchParams;i.set("grant_type","authorization_code"),i.set("code",e),t&&i.set("code_verifier",t),i.set("redirect_uri",r),i.set("client_id",o.clientId),i.set("client_secret",o.clientSecret);let{data:s,error:c}=await ut(n,{method:"POST",body:i,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(c)throw c;return me(s)}function X(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:n}){let i=e.scope||o||["email","name","openid"];return new URL(`https://appleid.apple.com/auth/authorize?client_id=${e.clientId}&response_type=code&redirect_uri=${n||e.redirectURI}&scope=${i.join(" ")}&state=${r}`)},validateAuthorizationCode:async({code:r,codeVerifier:o,redirectURI:n})=>y({code:r,codeVerifier:o,redirectURI:e.redirectURI||n,options:e,tokenEndpoint:t}),async getUserInfo(r){if(!r.idToken)return null;let o=pt(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 mt}from"@better-fetch/fetch";var ge=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let n=e.scope||r||["identify","email"];return new URL(`https://discord.com/api/oauth2/authorize?scope=${n.join("+")}&response_type=code&client_id=${e.clientId}&redirect_uri=${encodeURIComponent(e.redirectURI||o)}&state=${t}`)},validateAuthorizationCode:async({code:t,redirectURI:r})=>y({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await mt("https://discord.com/api/users/@me",{headers:{authorization:`Bearer ${t.accessToken}`}});if(o)return null;if(r.avatar===null){let n=r.discriminator==="0"?Number(BigInt(r.id)>>BigInt(22))%6:parseInt(r.discriminator)%5;r.image_url=`https://cdn.discordapp.com/embed/avatars/${n}.png`}else{let n=r.avatar.startsWith("a_")?"gif":"png";r.image_url=`https://cdn.discordapp.com/avatars/${r.id}/${r.avatar}.${n}`}return{user:{id:r.id,name:r.display_name||r.username||"",email:r.email,emailVerified:r.verified,image:r.image_url},data:r}}});import{betterFetch as ft}from"@better-fetch/fetch";var he=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let n=e.scope||r||["email","public_profile"];return await U({id:"facebook",options:e,authorizationEndpoint:"https://www.facebook.com/v21.0/dialog/oauth",scopes:n,state:t,redirectURI:o})},validateAuthorizationCode:async({code:t,redirectURI:r})=>y({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 ft("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 we}from"@better-fetch/fetch";var ye=e=>{let t="https://github.com/login/oauth/access_token";return{id:"github",name:"Github",createAuthorizationURL({state:r,scopes:o,codeVerifier:n,redirectURI:i}){let s=e.scope||o||["user:email"];return U({id:"github",options:e,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:s,state:r,redirectURI:i,codeVerifier:n})},validateAuthorizationCode:async({code:r,redirectURI:o})=>y({code:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:t}),async getUserInfo(r){let{data:o,error:n}=await we("https://api.github.com/user",{headers:{"User-Agent":"better-auth",authorization:`Bearer ${r.accessToken}`}});if(n)return null;let i=!1;if(!o.email){let{data:s,error:c}=await we("https://api.github.com/user/emails",{headers:{authorization:`Bearer ${r.accessToken}`,"User-Agent":"better-auth"}});c||(o.email=(s.find(d=>d.primary)??s[0])?.email,i=s.find(d=>d.email===o.email)?.verified??!1)}return{user:{id:o.id.toString(),name:o.name||o.login,email:o.email,image:o.avatar_url,emailVerified:i},data:o}}}};import{parseJWT as gt}from"oslo/jwt";var be=e=>({id:"google",name:"Google",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:n}){if(!e.clientId||!e.clientSecret)throw w.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new B("CLIENT_ID_AND_SECRET_REQUIRED");if(!o)throw new B("codeVerifier is required for Google");let i=e.scope||r||["email","profile"];return U({id:"google",options:e,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:i,state:t,codeVerifier:o,redirectURI:n})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>y({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=gt(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 ht}from"@better-fetch/fetch";import{parseJWT as wt}from"oslo/jwt";var Ae=e=>{let t=e.tenantId||"common",r=`https://login.microsoftonline.com/${t}/oauth2/v2.0/authorize`,o=`https://login.microsoftonline.com/${t}/oauth2/v2.0/token`;return{id:"microsoft",name:"Microsoft EntraID",createAuthorizationURL(n){let i=e.scope||n.scopes||["openid","profile","email","User.Read"];return U({id:"microsoft",options:e,authorizationEndpoint:r,state:n.state,codeVerifier:n.codeVerifier,scopes:i,redirectURI:n.redirectURI})},validateAuthorizationCode({code:n,codeVerifier:i,redirectURI:s}){return y({code:n,codeVerifier:i,redirectURI:e.redirectURI||s,options:e,tokenEndpoint:o})},async getUserInfo(n){if(!n.idToken)return null;let i=wt(n.idToken)?.payload,s=e.profilePhotoSize||48;return await ht(`https://graph.microsoft.com/v1.0/me/photos/${s}x${s}/$value`,{headers:{Authorization:`Bearer ${n.accessToken}`},async onResponse(c){if(!(e.disableProfilePhoto||!c.response.ok))try{let a=await c.response.clone().arrayBuffer(),l=Buffer.from(a).toString("base64");i.picture=`data:image/jpeg;base64, ${l}`}catch(d){w.error(d)}}}),{user:{id:i.sub,name:i.name,email:i.email,image:i.picture,emailVerified:!0},data:i}}}};import{betterFetch as yt}from"@better-fetch/fetch";var ke=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:n}){let i=e.scope||r||["user-read-email"];return U({id:"spotify",options:e,authorizationEndpoint:"https://accounts.spotify.com/authorize",scopes:i,state:t,codeVerifier:o,redirectURI:n})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>y({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";var I={isAction:!1};import{nanoid as bt}from"nanoid";var Re=e=>bt(e);import{parseJWT as At}from"oslo/jwt";var Ue=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let n=e.scope||r||["user:read:email","openid"];return U({id:"twitch",redirectURI:o,options:e,authorizationEndpoint:"https://id.twitch.tv/oauth2/authorize",scopes:n,state:t,claims:e.claims||["email","email_verified","preferred_username","picture"]})},validateAuthorizationCode:async({code:t,redirectURI:r})=>y({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 w.error("No idToken found in token"),null;let o=At(r)?.payload;return{user:{id:o.sub,name:o.preferred_username,email:o.email,image:o.picture,emailVerified:!1},data:o}}});import{betterFetch as kt}from"@better-fetch/fetch";var Ee=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(t){let r=e.scope||t.scopes||["account_info.read"];return U({id:"twitter",options:e,authorizationEndpoint:"https://twitter.com/i/oauth2/authorize",scopes:r,state:t.state,codeVerifier:t.codeVerifier,redirectURI:t.redirectURI})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>y({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 kt("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 Rt={apple:fe,discord:ge,facebook:he,github:ye,microsoft:Ae,google:be,spotify:ke,twitch:Ue,twitter:Ee},Te=Object.keys(Rt);import{TimeSpan as Ut}from"oslo";import{createJWT as Et,validateJWT as Tt}from"oslo/jwt";import{z as v}from"zod";import{APIError as z}from"better-call";import{APIError as N}from"better-call";var Q=(e,t="ms")=>new Date(Date.now()+(t==="sec"?e*1e3:e));import{z as xe}from"zod";var Y=()=>m("/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 M(e),r&&await e.context.internalAdapter.deleteSession(r.session.id),e.json(null,{status:401});if(await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret))return e.json(r);let n=e.context.sessionConfig.expiresIn,i=e.context.sessionConfig.updateAge;if(r.session.expiresAt.valueOf()-n*1e3+i*1e3<=Date.now()){let d=await e.context.internalAdapter.updateSession(r.session.id,{expiresAt:Q(e.context.sessionConfig.expiresIn,"sec")});if(!d)return M(e),e.json(null,{status:401});let a=(d.expiresAt.valueOf()-Date.now())/1e3;return await _(e,d.id,!1,{maxAge:a}),e.json({session:d,user:r.user})}return e.json(r)}catch(t){return e.context.logger.error(t),e.json(null,{status:500})}}),ee=async e=>await Y()({...e,_flag:"json",headers:e.headers}),L=V(async e=>{let t=await ee(e);if(!t?.session)throw new N("UNAUTHORIZED");return{session:t}}),ve=()=>m("/user/list-sessions",{method:"GET",use:[L],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)}),Pe=m("/user/revoke-session",{method:"POST",body:xe.object({id:xe.string()}),use:[L],requireHeaders:!0},async e=>{let t=e.body.id,r=await e.context.internalAdapter.findSession(t);if(!r)throw new N("BAD_REQUEST",{message:"Session not found"});if(r.session.userId!==e.context.session.user.id)throw new N("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(t)}catch(o){throw e.context.logger.error(o),new N("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),_e=m("/user/revoke-sessions",{method:"POST",use:[L],requireHeaders:!0},async e=>{try{await e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(t){throw e.context.logger.error(t),new N("INTERNAL_SERVER_ERROR")}return e.json({status:!0})});async function O(e,t,r){return await Et("HS256",Buffer.from(e),{email:t.toLowerCase(),updateTo:r},{expiresIn:new Ut(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}var Se=m("/send-verification-email",{method:"POST",query:v.object({currentURL:v.string().optional()}).optional(),body:v.object({email:v.string().email(),callbackURL:v.string().optional()}),use:[R]},async e=>{if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new z("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:t}=e.body,r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw new z("BAD_REQUEST",{message:"User not found"});let o=await O(e.context.secret,t),n=`${e.context.baseURL}/verify-email?token=${o}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.emailVerification.sendVerificationEmail(r.user,n,o),e.json({status:!0})}),Le=m("/verify-email",{method:"GET",query:v.object({token:v.string(),callbackURL:v.string().optional()}),use:[R]},async e=>{let{token:t}=e.query,r;try{r=await Tt("HS256",Buffer.from(e.context.secret),t)}catch(s){throw e.context.logger.error("Failed to verify email",s),new z("BAD_REQUEST",{message:"Invalid token"})}let n=v.object({email:v.string().email(),updateTo:v.string().optional()}).parse(r.payload);if(!await e.context.internalAdapter.findUserByEmail(n.email))throw new z("BAD_REQUEST",{message:"User not found"});if(n.updateTo){let s=await ee(e);if(!s)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new z("UNAUTHORIZED",{message:"Session not found"});if(s.user.email!==n.email)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new z("UNAUTHORIZED",{message:"Invalid session"});let c=await e.context.internalAdapter.updateUserByEmail(n.email,{email:n.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(n.email,{emailVerified:!0}),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:null,status:!0})});var Oe=m("/sign-in/social",{method:"POST",requireHeaders:!0,query:x.object({currentURL:x.string().optional()}).optional(),body:x.object({callbackURL:x.string().optional(),provider:x.enum(Te)}),use:[R]},async e=>{let t=e.context.socialProviders.find(d=>d.id===e.body.provider);if(!t)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new P("NOT_FOUND",{message:"Provider not found"});let r=e.context.authCookies,o=e.query?.currentURL?new URL(e.query?.currentURL):null,n=e.body.callbackURL?.startsWith("http")?e.body.callbackURL:`${o?.origin}${e.body.callbackURL||""}`,i=await ue(n||o?.origin||e.context.options.baseURL);await e.setSignedCookie(r.state.name,i.hash,e.context.secret,r.state.options);let s=xt();await e.setSignedCookie(r.pkCodeVerifier.name,s,e.context.secret,r.pkCodeVerifier.options);let c=await t.createAuthorizationURL({state:i.raw,codeVerifier:s,redirectURI:`${e.context.baseURL}/callback/${t.id}`});return e.json({url:c.toString(),state:i,codeVerifier:s,redirect:!0})}),Ie=m("/sign-in/email",{method:"POST",body:x.object({email:x.string(),password:x.string(),callbackURL:x.string().optional(),dontRememberMe:x.boolean().default(!1).optional()}),use:[R]},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(!x.string().email().safeParse(t).success)throw new P("BAD_REQUEST",{message:"Invalid email"});if(!x.string().email().safeParse(t).success)throw new P("BAD_REQUEST",{message:"Invalid email"});let i=await e.context.internalAdapter.findUserByEmail(t,{includeAccounts:!0});if(!i)throw await e.context.password.hash(r),e.context.logger.error("User not found",{email:t}),new P("UNAUTHORIZED",{message:"Invalid email or password"});let s=i.accounts.find(l=>l.providerId==="credential");if(!s)throw e.context.logger.error("Credential account not found",{email:t}),new P("UNAUTHORIZED",{message:"Invalid email or password"});let c=s?.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&&!i.user.emailVerified){if(!e.context.options?.emailVerification?.sendVerificationEmail)throw w.error("Email verification is required but no email verification handler is provided"),new P("INTERNAL_SERVER_ERROR",{message:"Email is not verified."});let l=await O(e.context.secret,i.user.email),h=`${e.context.options.baseURL}/verify-email?token=${l}`;throw await e.context.options.emailVerification.sendVerificationEmail(i.user,h,l),e.context.logger.error("Email not verified",{email:t}),new P("FORBIDDEN",{message:"Email is not verified. Check your email for a verification link"})}let a=await e.context.internalAdapter.createSession(i.user.id,e.headers,e.body.dontRememberMe);if(!a)throw e.context.logger.error("Failed to create session"),new P("UNAUTHORIZED",{message:"Failed to create session"});return await _(e,a.id,e.body.dontRememberMe),e.json({user:i.user,session:a,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});import{z as G}from"zod";import{z as f}from"zod";var Kn=f.object({id:f.string(),providerId:f.string(),accountId:f.string(),userId:f.string(),accessToken:f.string().nullable().optional(),refreshToken:f.string().nullable().optional(),idToken:f.string().nullable().optional(),expiresAt:f.date().nullable().optional(),password:f.string().optional().nullable()}),Ce=f.object({id:f.string(),email:f.string().transform(e=>e.toLowerCase()),emailVerified:f.boolean().default(!1),name:f.string(),image:f.string().optional(),createdAt:f.date().default(new Date),updatedAt:f.date().default(new Date)}),Xn=f.object({id:f.string(),userId:f.string(),expiresAt:f.date(),ipAddress:f.string().optional(),userAgent:f.string().optional()}),Yn=f.object({id:f.string(),value:f.string(),expiresAt:f.date(),identifier:f.string()});function vt(e,t){let r=t.fields,o={};for(let n in r){if(n in e){if(r[n].input===!1){if(r[n].defaultValue){o[n]=r[n].defaultValue;continue}continue}o[n]=e[n];continue}if(r[n].defaultValue){o[n]=r[n].defaultValue;continue}}return o}function Be(e,t){let r={...e.user?.additionalFields};return vt(t||{},{fields:r})}var De=m("/callback/:id",{method:"GET",query:G.object({state:G.string(),code:G.string().optional(),error:G.string().optional()}),metadata:I},async e=>{if(e.query.error||!e.query.code){let k=K(e.query.state).data?.callbackURL||`${e.context.baseURL}/error`;throw e.context.logger.error(e.query.error,e.params.id),e.redirect(`${k}?error=${e.query.error||"oAuth_code_missing"}`)}let t=e.context.socialProviders.find(p=>p.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=K(e.query.state);if(!r.success)throw e.context.logger.error("Unable to parse state"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let{data:{callbackURL:o,currentURL:n}}=r,i=await e.getSignedCookie(e.context.authCookies.state.name,e.context.secret);if(!i)throw w.error("No stored state found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!await le(e.query.state,i))throw w.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),d;try{d=await t.validateAuthorizationCode({code:e.query.code,codeVerifier:c,redirectURI:`${e.context.baseURL}/callback/${t.id}`})}catch(p){throw e.context.logger.error(p),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let a=await t.getUserInfo(d).then(p=>p?.user),l=Re(),h=Ce.safeParse({...a,id:l});if(!a||h.success===!1)throw w.error("Unable to get user info",h.error),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!o)throw e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);function g(p){throw e.redirect(`${n||o||`${e.context.baseURL}/error`}?error=${p}`)}let u=await e.context.internalAdapter.findUserByEmail(a.email,{includeAccounts:!0}).catch(p=>{throw w.error(`Better auth was unable to query your database.
|
|
3
|
-
Error: `,p),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)}),b=u?.user.id;if(u){if(!u.accounts.find(k=>k.providerId===t.id)){(!e.context.options.account?.accountLinking?.trustedProviders?.includes(t.id)&&!
|
|
1
|
+
import{APIError as rt,createRouter as zt,statusCode as jt}from"better-call";import{APIError as J}from"better-call";import{z as se}from"zod";import{xchacha20poly1305 as Xt}from"@noble/ciphers/chacha";import{bytesToHex as er,hexToBytes as tr,utf8ToBytes as rr}from"@noble/ciphers/utils";import{managedNonce as nr}from"@noble/ciphers/webcrypto";import{sha256 as sr}from"oslo/crypto";function W(e,t){let r=new Uint8Array(e),o=new Uint8Array(t);if(r.length!==o.length)return!1;let n=0;for(let i=0;i<r.length;i++)n|=r[i]^o[i];return n===0}import{decodeHex as Ft,encodeHex as Ht}from"oslo/encoding";import{scryptAsync as Gt}from"@noble/hashes/scrypt";function ot(e){return e.toString(2).padStart(8,"0")}function nt(e){return[...e].map(t=>ot(t)).join("")}function te(e){return parseInt(nt(e),2)}function it(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 n=te(o);for(;n>=e;)crypto.getRandomValues(o),r!==0&&(o[0]&=(1<<r)-1),n=te(o);return n}function re(e,t){let r="";for(let o=0;o<e;o++)r+=t[it(t.length)];return r}function oe(...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 F(e,t){let r=new TextEncoder,o={name:"HMAC",hash:"SHA-256"},n=await crypto.subtle.importKey("raw",r.encode(e),o,!1,["sign","verify"]),i=await crypto.subtle.sign(o.name,n,r.encode(t));return btoa(String.fromCharCode(...new Uint8Array(i)))}import{createEndpointCreator as st,createMiddleware as ne,createMiddlewareCreator as at}from"better-call";var ie=ne(async()=>({})),V=at({use:[ie,ne(async()=>({}))]}),m=st({use:[ie]});var ae=V({body:se.object({csrfToken:se.string().optional()}).optional()},async e=>{if(e.request?.method!=="POST"||e.context.options.advanced?.disableCSRFCheck)return;let t=e.headers?.get("origin")||"";if(t){let a=new URL(t).origin;if(e.context.trustedOrigins.includes(a))return}let r=e.body?.csrfToken;if(!r)throw new J("UNAUTHORIZED",{message:"CSRF Token is required"});let o=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret),[n,i]=o?.split("!")||[null,null];if(!r||!n||!i||n!==r)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new J("UNAUTHORIZED",{message:"Invalid CSRF Token"});let s=await F(e.context.secret,n);if(i!==s)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new J("UNAUTHORIZED",{message:"Invalid CSRF Token"})});import{APIError as P}from"better-call";import{generateCodeVerifier as St}from"oslo/oauth2";import{z as x}from"zod";import{generateState as dt}from"oslo/oauth2";import{z as H}from"zod";import{sha256 as de}from"oslo/crypto";async function ce(e){let t=await de(typeof e=="string"?new TextEncoder().encode(e):e);return Buffer.from(t).toString("base64")}async function le(e,t){let r=await de(typeof e=="string"?new TextEncoder().encode(e):e),o=Buffer.from(t,"base64");return W(r,o)}import"better-call";async function ue(e){let t=dt(),r=JSON.stringify({code:t,callbackURL:e}),o=await ce(r);return{raw:r,hash:o}}function K(e){return H.object({code:H.string(),callbackURL:H.string().optional(),currentURL:H.string().optional()}).safeParse(JSON.parse(e))}import{TimeSpan as Or}from"oslo";var B=class extends Error{constructor(t,r){super(t),this.name="BetterAuthError",this.message=t,this.cause=r,this.stack=""}};import{env as Cr,isProduction as Br}from"std-env";async function S(e,t,r,o){let n=e.context.authCookies.sessionToken.options;n.maxAge=r?void 0:e.context.sessionConfig.expiresIn,await e.setSignedCookie(e.context.authCookies.sessionToken.name,t,e.context.secret,{...n,...o}),r&&await e.setSignedCookie(e.context.authCookies.dontRememberToken.name,"true",e.context.secret,e.context.authCookies.dontRememberToken.options)}function M(e){e.setCookie(e.context.authCookies.sessionToken.name,"",{maxAge:0}),e.setCookie(e.context.authCookies.dontRememberToken.name,"",{maxAge:0})}import{APIError as ut}from"better-call";import{createConsola as ct}from"consola";var D=ct({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),lt=e=>({log:(...t)=>{!e?.disabled&&D.log("",...t)},error:(...t)=>{!e?.disabled&&D.error("",...t)},warn:(...t)=>{!e?.disabled&&D.warn("",...t)},info:(...t)=>{!e?.disabled&&D.info("",...t)},debug:(...t)=>{!e?.disabled&&D.debug("",...t)},box:(...t)=>{!e?.disabled&&D.box("",...t)},success:(...t)=>{!e?.disabled&&D.success("",...t)},break:(...t)=>{!e?.disabled&&console.log(`
|
|
2
|
+
`)}}),w=lt();var U=V(async e=>{let{body:t,query:r,headers:o,context:n}=e,i=t?.callbackURL||r?.callbackURL||r?.redirectTo||t?.redirectTo,s=r?.currentURL||o?.get("referer")||n.baseURL,a=n.trustedOrigins,c=(d,l)=>{if(d?.startsWith("http")&&!a.some(g=>d.startsWith(g)))throw w.error(`Invalid ${l}`,{[l]:d,trustedOrigins:a}),new ut("FORBIDDEN",{message:`Invalid ${l}`})};c(i,"callbackURL"),c(s,"currentURL")});import{parseJWT as gt}from"oslo/jwt";import{sha256 as pt}from"oslo/crypto";import{env as Fr}from"std-env";import{base64url as mt}from"oslo/encoding";async function pe(e){let t=await pt(new TextEncoder().encode(e));return mt.encode(new Uint8Array(t),{includePadding:!1})}function me(e){return{tokenType:e.token_type,accessToken:e.access_token,refreshToken:e.refresh_token,accessTokenExpiresAt:e.expires_at?new Date((Date.now()+e.expires_in)*1e3):void 0,scopes:e?.scope?typeof e.scope=="string"?e.scope.split(" "):e.scope:[],idToken:e.id_token}}async function E({id:e,options:t,authorizationEndpoint:r,state:o,codeVerifier:n,scopes:i,claims:s,disablePkce:a,redirectURI:c}){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",i.join(" ")),d.searchParams.set("redirect_uri",t.redirectURI||c),!a&&n){let l=await pe(n);d.searchParams.set("code_challenge_method","S256"),d.searchParams.set("code_challenge",l)}if(s){let l=s.reduce((h,g)=>(h[g]=null,h),{});d.searchParams.set("claims",JSON.stringify({id_token:{email:null,email_verified:null,...l}}))}return d}import{betterFetch as ft}from"@better-fetch/fetch";async function y({code:e,codeVerifier:t,redirectURI:r,options:o,tokenEndpoint:n}){let i=new URLSearchParams;i.set("grant_type","authorization_code"),i.set("code",e),t&&i.set("code_verifier",t),i.set("redirect_uri",r),i.set("client_id",o.clientId),i.set("client_secret",o.clientSecret);let{data:s,error:a}=await ft(n,{method:"POST",body:i,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(a)throw a;return me(s)}function X(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:n}){let i=e.scope||o||["email","name","openid"];return new URL(`https://appleid.apple.com/auth/authorize?client_id=${e.clientId}&response_type=code&redirect_uri=${n||e.redirectURI}&scope=${i.join(" ")}&state=${r}`)},validateAuthorizationCode:async({code:r,codeVerifier:o,redirectURI:n})=>y({code:r,codeVerifier:o,redirectURI:e.redirectURI||n,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 ht}from"@better-fetch/fetch";var ge=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let n=e.scope||r||["identify","email"];return new URL(`https://discord.com/api/oauth2/authorize?scope=${n.join("+")}&response_type=code&client_id=${e.clientId}&redirect_uri=${encodeURIComponent(e.redirectURI||o)}&state=${t}`)},validateAuthorizationCode:async({code:t,redirectURI:r})=>y({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await ht("https://discord.com/api/users/@me",{headers:{authorization:`Bearer ${t.accessToken}`}});if(o)return null;if(r.avatar===null){let n=r.discriminator==="0"?Number(BigInt(r.id)>>BigInt(22))%6:parseInt(r.discriminator)%5;r.image_url=`https://cdn.discordapp.com/embed/avatars/${n}.png`}else{let n=r.avatar.startsWith("a_")?"gif":"png";r.image_url=`https://cdn.discordapp.com/avatars/${r.id}/${r.avatar}.${n}`}return{user:{id:r.id,name:r.display_name||r.username||"",email:r.email,emailVerified:r.verified,image:r.image_url},data:r}}});import{betterFetch as wt}from"@better-fetch/fetch";var he=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let n=e.scope||r||["email","public_profile"];return await E({id:"facebook",options:e,authorizationEndpoint:"https://www.facebook.com/v21.0/dialog/oauth",scopes:n,state:t,redirectURI:o})},validateAuthorizationCode:async({code:t,redirectURI:r})=>y({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 we}from"@better-fetch/fetch";var ye=e=>{let t="https://github.com/login/oauth/access_token";return{id:"github",name:"Github",createAuthorizationURL({state:r,scopes:o,codeVerifier:n,redirectURI:i}){let s=e.scope||o||["user:email"];return E({id:"github",options:e,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:s,state:r,redirectURI:i,codeVerifier:n})},validateAuthorizationCode:async({code:r,redirectURI:o})=>y({code:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:t}),async getUserInfo(r){let{data:o,error:n}=await we("https://api.github.com/user",{headers:{"User-Agent":"better-auth",authorization:`Bearer ${r.accessToken}`}});if(n)return null;let i=!1;if(!o.email){let{data:s,error:a}=await we("https://api.github.com/user/emails",{headers:{authorization:`Bearer ${r.accessToken}`,"User-Agent":"better-auth"}});a||(o.email=(s.find(c=>c.primary)??s[0])?.email,i=s.find(c=>c.email===o.email)?.verified??!1)}return{user:{id:o.id.toString(),name:o.name||o.login,email:o.email,image:o.avatar_url,emailVerified:i},data:o}}}};import{parseJWT as yt}from"oslo/jwt";var be=e=>({id:"google",name:"Google",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:n}){if(!e.clientId||!e.clientSecret)throw w.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new B("CLIENT_ID_AND_SECRET_REQUIRED");if(!o)throw new B("codeVerifier is required for Google");let i=e.scope||r||["email","profile"];return E({id:"google",options:e,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:i,state:t,codeVerifier:o,redirectURI:n})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>y({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=yt(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 bt}from"@better-fetch/fetch";import{parseJWT as At}from"oslo/jwt";var Ae=e=>{let t=e.tenantId||"common",r=`https://login.microsoftonline.com/${t}/oauth2/v2.0/authorize`,o=`https://login.microsoftonline.com/${t}/oauth2/v2.0/token`;return{id:"microsoft",name:"Microsoft EntraID",createAuthorizationURL(n){let i=e.scope||n.scopes||["openid","profile","email","User.Read"];return E({id:"microsoft",options:e,authorizationEndpoint:r,state:n.state,codeVerifier:n.codeVerifier,scopes:i,redirectURI:n.redirectURI})},validateAuthorizationCode({code:n,codeVerifier:i,redirectURI:s}){return y({code:n,codeVerifier:i,redirectURI:e.redirectURI||s,options:e,tokenEndpoint:o})},async getUserInfo(n){if(!n.idToken)return null;let i=At(n.idToken)?.payload,s=e.profilePhotoSize||48;return await bt(`https://graph.microsoft.com/v1.0/me/photos/${s}x${s}/$value`,{headers:{Authorization:`Bearer ${n.accessToken}`},async onResponse(a){if(!(e.disableProfilePhoto||!a.response.ok))try{let d=await a.response.clone().arrayBuffer(),l=Buffer.from(d).toString("base64");i.picture=`data:image/jpeg;base64, ${l}`}catch(c){w.error(c)}}}),{user:{id:i.sub,name:i.name,email:i.email,image:i.picture,emailVerified:!0},data:i}}}};import{betterFetch as kt}from"@better-fetch/fetch";var ke=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:n}){let i=e.scope||r||["user-read-email"];return E({id:"spotify",options:e,authorizationEndpoint:"https://accounts.spotify.com/authorize",scopes:i,state:t,codeVerifier:o,redirectURI:n})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>y({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 kt("https://api.spotify.com/v1/me",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});return o?null:{user:{id:r.id,name:r.display_name,email:r.email,image:r.images[0]?.url,emailVerified:!1},data:r}}});import"@better-fetch/fetch";var I={isAction:!1};import{nanoid as Rt}from"nanoid";var Re=e=>Rt(e);import{parseJWT as Ut}from"oslo/jwt";var Ue=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let n=e.scope||r||["user:read:email","openid"];return E({id:"twitch",redirectURI:o,options:e,authorizationEndpoint:"https://id.twitch.tv/oauth2/authorize",scopes:n,state:t,claims:e.claims||["email","email_verified","preferred_username","picture"]})},validateAuthorizationCode:async({code:t,redirectURI:r})=>y({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 w.error("No idToken found in token"),null;let o=Ut(r)?.payload;return{user:{id:o.sub,name:o.preferred_username,email:o.email,image:o.picture,emailVerified:!1},data:o}}});import{betterFetch as Et}from"@better-fetch/fetch";var Ee=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(t){let r=e.scope||t.scopes||["account_info.read"];return E({id:"twitter",options:e,authorizationEndpoint:"https://twitter.com/i/oauth2/authorize",scopes:r,state:t.state,codeVerifier:t.codeVerifier,redirectURI:t.redirectURI})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>y({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 Et("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 Tt={apple:fe,discord:ge,facebook:he,github:ye,microsoft:Ae,google:be,spotify:ke,twitch:Ue,twitter:Ee},Te=Object.keys(Tt);import{TimeSpan as xt}from"oslo";import{createJWT as vt,validateJWT as Pt}from"oslo/jwt";import{z as v}from"zod";import{APIError as z}from"better-call";import{APIError as N}from"better-call";var Z=(e,t="ms")=>new Date(Date.now()+(t==="sec"?e*1e3:e));import{z as xe}from"zod";var Y=()=>m("/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 M(e),r&&await e.context.internalAdapter.deleteSession(r.session.id),e.json(null,{status:401});if(await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret))return e.json(r);let n=e.context.sessionConfig.expiresIn,i=e.context.sessionConfig.updateAge;if(r.session.expiresAt.valueOf()-n*1e3+i*1e3<=Date.now()){let c=await e.context.internalAdapter.updateSession(r.session.id,{expiresAt:Z(e.context.sessionConfig.expiresIn,"sec")});if(!c)return M(e),e.json(null,{status:401});let d=(c.expiresAt.valueOf()-Date.now())/1e3;return await S(e,c.id,!1,{maxAge:d}),e.json({session:c,user:r.user})}return e.json(r)}catch(t){return e.context.logger.error(t),e.json(null,{status:500})}}),ee=async e=>await Y()({...e,_flag:"json",headers:e.headers}),O=V(async e=>{let t=await ee(e);if(!t?.session)throw new N("UNAUTHORIZED");return{session:t}}),ve=()=>m("/user/list-sessions",{method:"GET",use:[O],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)}),Pe=m("/user/revoke-session",{method:"POST",body:xe.object({id:xe.string()}),use:[O],requireHeaders:!0},async e=>{let t=e.body.id,r=await e.context.internalAdapter.findSession(t);if(!r)throw new N("BAD_REQUEST",{message:"Session not found"});if(r.session.userId!==e.context.session.user.id)throw new N("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(t)}catch(o){throw e.context.logger.error(o),new N("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),Se=m("/user/revoke-sessions",{method:"POST",use:[O],requireHeaders:!0},async e=>{try{await e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(t){throw e.context.logger.error(t),new N("INTERNAL_SERVER_ERROR")}return e.json({status:!0})});async function L(e,t,r){return await vt("HS256",Buffer.from(e),{email:t.toLowerCase(),updateTo:r},{expiresIn:new xt(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}var _e=m("/send-verification-email",{method:"POST",query:v.object({currentURL:v.string().optional()}).optional(),body:v.object({email:v.string().email(),callbackURL:v.string().optional()}),use:[U]},async e=>{if(!e.context.options.emailVerification?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled."),new z("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:t}=e.body,r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw new z("BAD_REQUEST",{message:"User not found"});let o=await L(e.context.secret,t),n=`${e.context.baseURL}/verify-email?token=${o}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.emailVerification.sendVerificationEmail(r.user,n,o),e.json({status:!0})}),Oe=m("/verify-email",{method:"GET",query:v.object({token:v.string(),callbackURL:v.string().optional()}),use:[U]},async e=>{let{token:t}=e.query,r;try{r=await Pt("HS256",Buffer.from(e.context.secret),t)}catch(s){throw e.context.logger.error("Failed to verify email",s),new z("BAD_REQUEST",{message:"Invalid token"})}let n=v.object({email:v.string().email(),updateTo:v.string().optional()}).parse(r.payload);if(!await e.context.internalAdapter.findUserByEmail(n.email))throw new z("BAD_REQUEST",{message:"User not found"});if(n.updateTo){let s=await ee(e);if(!s)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new z("UNAUTHORIZED",{message:"Session not found"});if(s.user.email!==n.email)throw e.query.callbackURL?e.redirect(`${e.query.callbackURL}?error=unauthorized`):new z("UNAUTHORIZED",{message:"Invalid session"});let a=await e.context.internalAdapter.updateUserByEmail(n.email,{email:n.updateTo});if(await e.context.options.emailVerification?.sendVerificationEmail?.(a,`${e.context.baseURL}/verify-email?token=${t}`,t),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:a,status:!0})}if(await e.context.internalAdapter.updateUserByEmail(n.email,{emailVerified:!0}),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({user:null,status:!0})});var Le=m("/sign-in/social",{method:"POST",requireHeaders:!0,query:x.object({currentURL:x.string().optional()}).optional(),body:x.object({callbackURL:x.string().optional(),provider:x.enum(Te)}),use:[U]},async e=>{let t=e.context.socialProviders.find(c=>c.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,n=e.body.callbackURL?.startsWith("http")?e.body.callbackURL:`${o?.origin}${e.body.callbackURL||""}`,i=await ue(n||o?.origin||e.context.options.baseURL);await e.setSignedCookie(r.state.name,i.hash,e.context.secret,r.state.options);let s=St();await e.setSignedCookie(r.pkCodeVerifier.name,s,e.context.secret,r.pkCodeVerifier.options);let a=await t.createAuthorizationURL({state:i.raw,codeVerifier:s,redirectURI:`${e.context.baseURL}/callback/${t.id}`});return e.json({url:a.toString(),state:i,codeVerifier:s,redirect:!0})}),Ie=m("/sign-in/email",{method:"POST",body:x.object({email:x.string(),password:x.string(),callbackURL:x.string().optional(),dontRememberMe:x.boolean().default(!1).optional()}),use:[U]},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(!x.string().email().safeParse(t).success)throw new P("BAD_REQUEST",{message:"Invalid email"});if(!x.string().email().safeParse(t).success)throw new P("BAD_REQUEST",{message:"Invalid email"});let i=await e.context.internalAdapter.findUserByEmail(t,{includeAccounts:!0});if(!i)throw await e.context.password.hash(r),e.context.logger.error("User not found",{email:t}),new P("UNAUTHORIZED",{message:"Invalid email or password"});let s=i.accounts.find(l=>l.providerId==="credential");if(!s)throw e.context.logger.error("Credential account not found",{email:t}),new P("UNAUTHORIZED",{message:"Invalid email or password"});let a=s?.password;if(!a)throw e.context.logger.error("Password not found",{email:t}),new P("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(a,r))throw e.context.logger.error("Invalid password"),new P("UNAUTHORIZED",{message:"Invalid email or password"});if(e.context.options?.emailAndPassword?.requireEmailVerification&&!i.user.emailVerified){if(!e.context.options?.emailVerification?.sendVerificationEmail)throw w.error("Email verification is required but no email verification handler is provided"),new P("INTERNAL_SERVER_ERROR",{message:"Email is not verified."});let l=await L(e.context.secret,i.user.email),h=`${e.context.options.baseURL}/verify-email?token=${l}`;throw await e.context.options.emailVerification.sendVerificationEmail(i.user,h,l),e.context.logger.error("Email not verified",{email:t}),new P("FORBIDDEN",{message:"Email is not verified. Check your email for a verification link"})}let d=await e.context.internalAdapter.createSession(i.user.id,e.headers,e.body.dontRememberMe);if(!d)throw e.context.logger.error("Failed to create session"),new P("UNAUTHORIZED",{message:"Failed to create session"});return await S(e,d.id,e.body.dontRememberMe),e.json({user:i.user,session:d,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});import{z as Q}from"zod";import{z as f}from"zod";var Yn=f.object({id:f.string(),providerId:f.string(),accountId:f.string(),userId:f.string(),accessToken:f.string().nullable().optional(),refreshToken:f.string().nullable().optional(),idToken:f.string().nullable().optional(),expiresAt:f.date().nullable().optional(),password:f.string().optional().nullable()}),Ce=f.object({id:f.string(),email:f.string().transform(e=>e.toLowerCase()),emailVerified:f.boolean().default(!1),name:f.string(),image:f.string().optional(),createdAt:f.date().default(new Date),updatedAt:f.date().default(new Date)}),ei=f.object({id:f.string(),userId:f.string(),expiresAt:f.date(),ipAddress:f.string().optional(),userAgent:f.string().optional()}),ti=f.object({id:f.string(),value:f.string(),expiresAt:f.date(),identifier:f.string()});function Be(e,t){let r={...t==="user"?e.user?.additionalFields:{},...t==="session"?e.session?.additionalFields:{}};for(let o of e.plugins||[])o.schema&&o.schema[t]&&(r={...r,...o.schema[t].fields});return r}function De(e,t){let r=t.fields,o={};for(let n in r){if(n in e){if(r[n].input===!1){if(r[n].defaultValue){o[n]=r[n].defaultValue;continue}continue}o[n]=e[n];continue}if(r[n].defaultValue){o[n]=r[n].defaultValue;continue}}return o}function $e(e,t){let r=Be(e,"user");return De(t||{},{fields:r})}function Ve(e,t){let r=Be(e,"user");return De(t||{},{fields:r})}var ze=m("/callback/:id",{method:"GET",query:Q.object({state:Q.string(),code:Q.string().optional(),error:Q.string().optional()}),metadata:I},async e=>{if(e.query.error||!e.query.code){let k=K(e.query.state).data?.callbackURL||`${e.context.baseURL}/error`;throw e.context.logger.error(e.query.error,e.params.id),e.redirect(`${k}?error=${e.query.error||"oAuth_code_missing"}`)}let t=e.context.socialProviders.find(p=>p.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=K(e.query.state);if(!r.success)throw e.context.logger.error("Unable to parse state"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let{data:{callbackURL:o,currentURL:n}}=r,i=await e.getSignedCookie(e.context.authCookies.state.name,e.context.secret);if(!i)throw w.error("No stored state found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!await le(e.query.state,i))throw w.error("OAuth state mismatch"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let a=await e.getSignedCookie(e.context.authCookies.pkCodeVerifier.name,e.context.secret),c;try{c=await t.validateAuthorizationCode({code:e.query.code,codeVerifier:a,redirectURI:`${e.context.baseURL}/callback/${t.id}`})}catch(p){throw e.context.logger.error(p),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let d=await t.getUserInfo(c).then(p=>p?.user),l=Re(),h=Ce.safeParse({...d,id:l});if(!d||h.success===!1)throw w.error("Unable to get user info",h.error),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!o)throw e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);function g(p){throw e.redirect(`${n||o||`${e.context.baseURL}/error`}?error=${p}`)}let u=await e.context.internalAdapter.findUserByEmail(d.email,{includeAccounts:!0}).catch(p=>{throw w.error(`Better auth was unable to query your database.
|
|
3
|
+
Error: `,p),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)}),b=u?.user.id;if(u){if(!u.accounts.find(k=>k.providerId===t.id)){(!e.context.options.account?.accountLinking?.trustedProviders?.includes(t.id)&&!d.emailVerified||!e.context.options.account?.accountLinking?.enabled)&&g("account_not_linked");try{await e.context.internalAdapter.linkAccount({providerId:t.id,accountId:d.id.toString(),id:`${t.id}:${d.id}`,userId:u.user.id,...X(c)})}catch(C){w.error("Unable to link account",C),g("unable_to_link_account")}}}else try{let p=d.emailVerified||!1,k=await e.context.internalAdapter.createOAuthUser({...h.data,emailVerified:p},{...X(c),providerId:t.id,accountId:d.id.toString()});if(b=k?.user.id,!p&&k&&e.context.options.emailVerification?.sendOnSignUp){let q=await L(e.context.secret,d.email),C=`${e.context.baseURL}/verify-email?token=${q}&callbackURL=${o}`;await e.context.options.emailVerification?.sendVerificationEmail?.(k.user,C,q)}}catch(p){w.error("Unable to create user",p),g("unable_to_create_user")}b||g("unable_to_create_user");let T=await e.context.internalAdapter.createSession(b,e.request);throw T||g("unable_to_create_session"),await S(e,T.id),e.redirect(o)});import"zod";import{APIError as _t}from"better-call";var je=m("/sign-out",{method:"POST"},async e=>{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)throw new _t("BAD_REQUEST",{message:"Session not found"});return await e.context.internalAdapter.deleteSession(t),M(e),e.json({success:!0})});import{z as _}from"zod";import{APIError as G}from"better-call";var qe=m("/forget-password",{method:"POST",body:_.object({email:_.string().email(),redirectTo:_.string()}),use:[U]},async e=>{if(!e.context.options.emailAndPassword?.sendResetPassword)throw e.context.logger.error("Reset password isn't enabled.Please pass an emailAndPassword.sendResetPasswordToken function in your auth config!"),new G("BAD_REQUEST",{message:"Reset password isn't enabled"});let{email:t,redirectTo:r}=e.body,o=await e.context.internalAdapter.findUserByEmail(t,{includeAccounts:!0});if(!o)return e.context.logger.error("Reset Password: User not found",{email:t}),e.json({status:!1},{body:{status:!0}});let n=60*60*1,i=new Date(Date.now()+1e3*(e.context.options.emailAndPassword.resetPasswordTokenExpiresIn||n)),s=e.context.uuid();await e.context.internalAdapter.createVerificationValue({value:o.user.id,identifier:`reset-password:${s}`,expiresAt:i});let a=`${e.context.baseURL}/reset-password/${s}?callbackURL=${r}`;return await e.context.options.emailAndPassword.sendResetPassword(o.user,a),e.json({status:!0})}),Me=m("/reset-password/:token",{method:"GET",query:_.object({callbackURL:_.string()}),use:[U]},async e=>{let{token:t}=e.params,r=e.query.callbackURL,o=r.startsWith("http")?r:`${e.context.options.baseURL}${r}`;if(!t||!r)throw e.redirect(`${e.context.baseURL}/error?error=INVALID_TOKEN`);let n=await e.context.internalAdapter.findVerificationValue(`reset-password:${t}`);throw!n||n.expiresAt<new Date?e.redirect(`${o}?error=INVALID_TOKEN`):e.redirect(`${o}?token=${t}`)}),Ne=m("/reset-password",{query:_.optional(_.object({token:_.string()})),method:"POST",body:_.object({newPassword:_.string()})},async e=>{let t=e.query?.token;if(!t)throw new G("BAD_REQUEST",{message:"Token not found"});let{newPassword:r}=e.body,o=`reset-password:${t}`,n=await e.context.internalAdapter.findVerificationValue(o);if(!n||n.expiresAt<new Date)throw new G("BAD_REQUEST",{message:"Invalid token"});await e.context.internalAdapter.deleteVerificationValue(n.id);let i=n.value,s=await e.context.password.hash(r);if(!(await e.context.internalAdapter.findAccounts(i)).find(l=>l.providerId==="credential"))return await e.context.internalAdapter.createAccount({userId:i,providerId:"credential",password:s,accountId:e.context.uuid()}),e.json({status:!0});if(!await e.context.internalAdapter.updatePassword(i,s))throw new G("BAD_REQUEST",{message:"Failed to update password"});return e.json({status:!0})});import{z as A}from"zod";import{APIError as R}from"better-call";var Fe=()=>m("/user/update",{method:"POST",body:A.record(A.string(),A.any()),use:[O,U]},async e=>{let t=e.body;if(t.email)throw new R("BAD_REQUEST",{message:"You can't update email"});let{name:r,image:o,...n}=t,i=e.context.session;if(!o&&!r&&Object.keys(n).length===0)return e.json({user:i.user});let s=$e(e.context.options,n);console.log({additionalFields:s});let a=await e.context.internalAdapter.updateUserByEmail(i.user.email,{name:r,image:o,...s});return e.json({user:a})}),He=m("/user/change-password",{method:"POST",body:A.object({newPassword:A.string(),currentPassword:A.string(),revokeOtherSessions:A.boolean().optional()}),use:[O]},async e=>{let{newPassword:t,currentPassword:r,revokeOtherSessions:o}=e.body,n=e.context.session,i=e.context.password.config.minPasswordLength;if(t.length<i)throw e.context.logger.error("Password is too short"),new R("BAD_REQUEST",{message:"Password is too short"});let s=e.context.password.config.maxPasswordLength;if(t.length>s)throw e.context.logger.error("Password is too long"),new R("BAD_REQUEST",{message:"Password too long"});let c=(await e.context.internalAdapter.findAccounts(n.user.id)).find(h=>h.providerId==="credential"&&h.password);if(!c||!c.password)throw new R("BAD_REQUEST",{message:"User does not have a password"});let d=await e.context.password.hash(t);if(!await e.context.password.verify(c.password,r))throw new R("BAD_REQUEST",{message:"Incorrect password"});if(await e.context.internalAdapter.updateAccount(c.id,{password:d}),o){await e.context.internalAdapter.deleteSessions(n.user.id);let h=await e.context.internalAdapter.createSession(n.user.id,e.headers);if(!h)throw new R("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});await S(e,h.id)}return e.json(n.user)}),Ze=m("/user/set-password",{method:"POST",body:A.object({newPassword:A.string()}),use:[O]},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 R("BAD_REQUEST",{message:"Password is too short"});let n=e.context.password.config.maxPasswordLength;if(t.length>n)throw e.context.logger.error("Password is too long"),new R("BAD_REQUEST",{message:"Password too long"});let s=(await e.context.internalAdapter.findAccounts(r.user.id)).find(c=>c.providerId==="credential"&&c.password),a=await e.context.password.hash(t);if(!s)return await e.context.internalAdapter.linkAccount({userId:r.user.id,providerId:"credential",accountId:r.user.id,password:a}),e.json(r.user);throw new R("BAD_REQUEST",{message:"user already has a password"})}),Qe=m("/user/delete",{method:"POST",body:A.object({password:A.string()}),use:[O]},async e=>{let{password:t}=e.body,r=e.context.session,n=(await e.context.internalAdapter.findAccounts(r.user.id)).find(s=>s.providerId==="credential"&&s.password);if(!n||!n.password)throw new R("BAD_REQUEST",{message:"User does not have a password"});if(!await e.context.password.verify(n.password,t))throw new R("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)}),Ge=m("/user/change-email",{method:"POST",query:A.object({currentURL:A.string().optional()}).optional(),body:A.object({newEmail:A.string().email(),callbackURL:A.string().optional()}),use:[O,U]},async e=>{if(!e.context.options.user?.changeEmail?.enabled)throw e.context.logger.error("Change email is disabled."),new R("BAD_REQUEST",{message:"Change email is disabled"});if(e.body.newEmail===e.context.session.user.email)throw e.context.logger.error("Email is the same"),new R("BAD_REQUEST",{message:"Email is the same"});if(await e.context.internalAdapter.findUserByEmail(e.body.newEmail))throw e.context.logger.error("Email already exists"),new R("BAD_REQUEST",{message:"Couldn't update your email"});if(e.context.session.user.emailVerified!==!0){let n=await e.context.internalAdapter.updateUserByEmail(e.context.session.user.email,{email:e.body.newEmail});return e.json({user:n,status:!0})}if(!e.context.options.user.changeEmail.sendChangeEmailVerification)throw e.context.logger.error("Verification email isn't enabled."),new R("BAD_REQUEST",{message:"Verification email isn't enabled"});let r=await L(e.context.secret,e.context.session.user.email,e.body.newEmail),o=`${e.context.baseURL}/verify-email?token=${r}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.user.changeEmail.sendChangeEmailVerification(e.context.session.user,e.body.newEmail,o,r),e.json({user:null,status:!0})});var We=m("/csrf",{method:"GET",metadata:I},async e=>{let t=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret);if(t){let[i,s]=t.split("!")||[null,null];return e.json({csrfToken:i})}let r=re(32,oe("a-z","0-9","A-Z")),o=await F(e.context.secret,r),n=`${r}!${o}`;return await e.setSignedCookie(e.context.authCookies.csrfToken.name,n,e.context.secret,e.context.authCookies.csrfToken.options),e.json({csrfToken:r})});var Ot=(e="Unknown")=>`<!DOCTYPE html>
|
|
4
4
|
<html lang="en">
|
|
5
5
|
<head>
|
|
6
6
|
<meta charset="UTF-8">
|
|
@@ -80,4 +80,4 @@ Error: `,p),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>`,
|
|
83
|
+
</html>`,Je=m("/error",{method:"GET",metadata:I},async e=>{let t=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(Ot(t),{headers:{"Content-Type":"text/html"}})});var Ke=m("/ok",{method:"GET",metadata:I},async e=>e.json({ok:!0}));import{z as j}from"zod";import{APIError as $}from"better-call";var Xe=()=>m("/sign-up/email",{method:"POST",query:j.object({currentURL:j.string().optional()}).optional(),body:j.record(j.string(),j.any()),use:[U]},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:n,image:i,callbackURL:s,...a}=t;if(!j.string().email().safeParse(o).success)throw new $("BAD_REQUEST",{message:"Invalid email"});let d=e.context.password.config.minPasswordLength;if(n.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(n.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 g=Ve(e.context.options,a),u=await e.context.internalAdapter.createUser({email:o.toLowerCase(),name:r,image:i,...g,emailVerified:!1});if(!u)throw new $("BAD_REQUEST",{message:"Failed to create user"});let b=await e.context.password.hash(n);if(await e.context.internalAdapter.linkAccount({userId:u.id,providerId:"credential",accountId:u.id,password:b,expiresAt:Z(60*60*24*30,"sec")}),e.context.options.emailVerification?.sendOnSignUp){let p=await L(e.context.secret,u.email),k=`${e.context.baseURL}/verify-email?token=${p}&callbackURL=${t.callbackURL||e.query?.currentURL||"/"}`;await e.context.options.emailVerification?.sendVerificationEmail?.(u,k,p)}if(!e.context.options.emailAndPassword.autoSignIn||e.context.options.emailAndPassword.requireEmailVerification)return e.json({user:u,session:null},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:u,session:null}});let T=await e.context.internalAdapter.createSession(u.id,e.request);if(!T)throw new $("BAD_REQUEST",{message:"Failed to create session"});return await S(e,T.id),e.json({user:u,session:T},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:u,session:T}})});import{isTest as Lt}from"std-env";function Ye(e){let t="127.0.0.1";if(Lt)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 n of r){let i=o.get(n);if(typeof i=="string"){let s=i.split(",")[0].trim();if(s)return s}}return null}function It(e,t,r){let o=Date.now(),n=t*1e3;return o-r.lastRequest<n&&r.count>=e}function Ct(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 Bt(e,t){let r=Date.now(),o=t*1e3;return Math.ceil((e+o-r)/1e3)}function Dt(e,t){let r=t??"rateLimit",o=e.adapter;return{get:async n=>await o.findOne({model:r,where:[{field:"key",value:n}]}),set:async(n,i,s)=>{try{s?await o.update({model:t??"rateLimit",where:[{field:"key",value:n}],update:{count:i.count,lastRequest:i.lastRequest}}):await o.create({model:t??"rateLimit",data:{key:n,count:i.count,lastRequest:i.lastRequest}})}catch(a){w.error("Error setting rate limit",a)}}}}var et=new Map;function $t(e){return e.rateLimit.storage==="secondary-storage"?{get:async r=>{let o=await e.options.secondaryStorage?.get(r);return o?JSON.parse(o):void 0},set:async(r,o)=>{await e.options.secondaryStorage?.set?.(r,JSON.stringify(o))}}:e.rateLimit.storage==="memory"?{async get(r){return et.get(r)},async set(r,o,n){et.set(r,o)}}:Dt(e,e.rateLimit.tableName)}async function tt(e,t){if(!t.rateLimit.enabled)return;let r=t.baseURL,o=e.url.replace(r,""),n=t.rateLimit.window,i=t.rateLimit.max,s=Ye(e)+o,c=Vt().find(g=>g.pathMatcher(o));c&&(n=c.window,i=c.max);for(let g of t.options.plugins||[])if(g.rateLimit){let u=g.rateLimit.find(b=>b.pathMatcher(o));if(u){n=u.window,i=u.max;break}}if(t.rateLimit.customRules){let g=t.rateLimit.customRules[o];g&&(n=g.window,i=g.max)}let d=$t(t),l=await d.get(s),h=Date.now();if(!l)await d.set(s,{key:s,count:1,lastRequest:h});else{let g=h-l.lastRequest;if(It(i,n,l)){let u=Bt(l.lastRequest,n);return Ct(u)}else g>n*1e3?await d.set(s,{...l,count:1,lastRequest:h}):await d.set(s,{...l,count:l.count+1,lastRequest:h})}}function Vt(){return[{pathMatcher(t){return t.startsWith("/sign-in")||t.startsWith("/sign-up")},window:10,max:3}]}import{APIError as Qs}from"better-call";function qt(e,t){let r=t.plugins?.reduce((a,c)=>({...a,...c.endpoints}),{}),o=t.plugins?.map(a=>a.middlewares?.map(c=>{let d=async l=>c.middleware({...l,context:{...e,...l.context}});return d.path=c.path,d.options=c.middleware.options,d.headers=c.middleware.headers,{path:c.path,middleware:d}})).filter(a=>a!==void 0).flat()||[],i={...{signInOAuth:Le,callbackOAuth:ze,getCSRFToken:We,getSession:Y(),signOut:je,signUpEmail:Xe(),signInEmail:Ie,forgetPassword:qe,resetPassword:Ne,verifyEmail:Oe,sendVerificationEmail:_e,changeEmail:Ge,changePassword:He,setPassword:Ze,updateUser:Fe(),deleteUser:Qe,forgetPasswordCallback:Me,listSessions:ve(),revokeSession:Pe,revokeSessions:Se},...r,ok:Ke,error:Je},s={};for(let[a,c]of Object.entries(i))s[a]=async(d={})=>{let l=await e;for(let u of t.plugins||[])if(u.hooks?.before){for(let b of u.hooks.before)if(b.matcher({...c,...d,context:l})){let p=await b.handler({...d,context:{...l,...d?.context}});p&&"context"in p&&(l={...l,...p.context})}}let h;try{h=await c({...d,context:{...l,...d.context}})}catch(u){if(u instanceof rt){let b=t.plugins?.map(p=>{if(p.hooks?.after)return p.hooks.after}).filter(p=>p!==void 0).flat();if(!b?.length)throw u;let T=new Response(JSON.stringify(u.body),{status:jt[u.status],headers:u.headers});for(let p of b||[])if(p.matcher(d)){let q=Object.assign(d,{context:{...e,returned:T}}),C=await p.handler(q);C&&"response"in C&&(T=C.response)}return T}throw u}let g=h;for(let u of t.plugins||[])if(u.hooks?.after){for(let b of u.hooks.after)if(b.matcher(d)){let p=Object.assign(d,{context:{...e,returned:g}}),k=await b.handler(p);k&&"response"in k&&(g=k.response)}}return g},s[a].path=c.path,s[a].method=c.method,s[a].options=c.options,s[a].headers=c.headers;return{api:s,middlewares:o}}var qs=(e,t)=>{let{api:r,middlewares:o}=qt(e,t),n=new URL(e.baseURL).pathname;return zt(r,{extraContext:e,basePath:n,routerMiddleware:[{path:"/**",middleware:ae},...o],async onRequest(i){for(let s of e.options.plugins||[])if(s.onRequest){let a=await s.onRequest(i,e);if(a)return a}return tt(i,e)},async onResponse(i){for(let s of e.options.plugins||[])if(s.onResponse){let a=await s.onResponse(i,e);if(a)return a.response}return i},onError(i){if(t.onAPIError?.throw)throw i;if(t.onAPIError?.onError){t.onAPIError.onError(i,e);return}let s=t.logger?.verboseLogging?w:void 0;t.logger?.disabled!==!0&&(i instanceof rt?(i.status==="INTERNAL_SERVER_ERROR"&&w.error(i),s?.error(i.message)):w?.error(i))}})};export{Qs as APIError,ze as callbackOAuth,Ge as changeEmail,He as changePassword,m as createAuthEndpoint,V as createAuthMiddleware,L as createEmailVerificationToken,ae as csrfMiddleware,Qe as deleteUser,Je as error,qe as forgetPassword,Me as forgetPasswordCallback,We as getCSRFToken,qt as getEndpoints,Y as getSession,ee as getSessionFromCtx,ve as listSessions,Ke as ok,ie as optionsMiddleware,Ne as resetPassword,Pe as revokeSession,Se as revokeSessions,qs as router,_e as sendVerificationEmail,O as sessionMiddleware,Ze as setPassword,Ie as signInEmail,Le as signInOAuth,je as signOut,Xe as signUpEmail,Fe as updateUser,Oe as verifyEmail};
|