better-auth 0.8.3-beta.7 → 0.8.3

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/plugins.cjs CHANGED
@@ -81,4 +81,4 @@
81
81
  </div>
82
82
  </body>
83
83
  </html>`,Vo=c("/error",{method:"GET",metadata:ge},async e=>{let o=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(No(o),{headers:{"Content-Type":"text/html"}})});var v=require("better-call");async function Ue(e,{userInfo:o,account:r,callbackURL:t}){let n=await e.context.internalAdapter.findUserByEmail(o.email.toLowerCase(),{includeAccounts:!0}).catch(a=>{throw y.error(`Better auth was unable to query your database.
84
- Error: `,a),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)}),i=n?.user;if(n){let a=n.accounts.find(d=>d.providerId===r.providerId);if(a)await e.context.internalAdapter.updateAccount(a.id,{accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,expiresAt:r.expiresAt});else{if(!e.context.options.account?.accountLinking?.trustedProviders?.includes(r.providerId)&&!o.emailVerified||e.context.options.account?.accountLinking?.enabled===!1)return Vt&&y.warn(`User already exist but account isn't linked to ${r.providerId}. To read more about how account linking works in Better Auth see https://www.better-auth.com/docs/concepts/users-accounts#account-linking.`),{error:"account not linked",data:null};try{await e.context.internalAdapter.linkAccount({providerId:r.providerId,accountId:o.id.toString(),id:e.context.uuid(),userId:n.user.id,accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,expiresAt:r.expiresAt})}catch(l){return y.error("Unable to link account",l),{error:"unable to link account",data:null}}}}else try{let a=o.emailVerified||!1;if(i=await e.context.internalAdapter.createOAuthUser({...o,id:e.context.uuid(),emailVerified:a,email:o.email.toLowerCase()},{accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,expiresAt:r.expiresAt,providerId:r.providerId,accountId:o.id.toString()}).then(d=>d?.user),!a&&i&&e.context.options.emailVerification?.sendOnSignUp){let d=await ae(e.context.secret,i.email),u=`${e.context.baseURL}/verify-email?token=${d}&callbackURL=${t}`;await e.context.options.emailVerification?.sendVerificationEmail?.({user:i,url:u,token:d},e.request)}}catch(a){return y.error("Unable to create user",a),{error:"unable to create user",data:null}}if(!i)return{error:"unable to create user",data:null};let s=await e.context.internalAdapter.createSession(i.id,e.request);return s?{data:{session:s,user:i},error:null}:{error:"unable to create session",data:null}}var Fo=c("/sign-in/social",{method:"POST",query:_.z.object({currentURL:_.z.string().optional()}).optional(),body:_.z.object({callbackURL:_.z.string().optional(),provider:_.z.enum(rt),idToken:_.z.optional(_.z.object({token:_.z.string(),nonce:_.z.string().optional(),accessToken:_.z.string().optional(),refreshToken:_.z.string().optional(),expiresAt:_.z.number().optional()}))})},async e=>{let o=e.context.socialProviders.find(i=>i.id===e.body.provider);if(!o)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new L.APIError("NOT_FOUND",{message:"Provider not found"});if(e.body.idToken){if(!o.verifyIdToken)throw e.context.logger.error("Provider does not support id token verification",{provider:e.body.provider}),new L.APIError("NOT_FOUND",{message:"Provider does not support id token verification"});let{token:i,nonce:s}=e.body.idToken;if(!await o.verifyIdToken(i,s))throw e.context.logger.error("Invalid id token",{provider:e.body.provider}),new L.APIError("UNAUTHORIZED",{message:"Invalid id token"});let d=await o.getUserInfo({idToken:i,accessToken:e.body.idToken.accessToken,refreshToken:e.body.idToken.refreshToken});if(!d||!d?.user)throw e.context.logger.error("Failed to get user info",{provider:e.body.provider}),new L.APIError("UNAUTHORIZED",{message:"Failed to get user info"});if(!d.user.email)throw e.context.logger.error("User email not found",{provider:e.body.provider}),new L.APIError("UNAUTHORIZED",{message:"User email not found"});let u=await Ue(e,{userInfo:{email:d.user.email,id:d.user.id,name:d.user.name||"",image:d.user.image,emailVerified:d.user.emailVerified||!1},account:{providerId:o.id,accountId:d.user.id,accessToken:e.body.idToken.accessToken}});if(u.error)throw new L.APIError("UNAUTHORIZED",{message:u.error});return await w(e,u.data),e.json({session:u.data.session,user:u.data.user,url:`${e.body.callbackURL||e.query?.currentURL||e.context.options.baseURL}`,redirect:!0})}let{codeVerifier:r,state:t}=await ve(e),n=await o.createAuthorizationURL({state:t,codeVerifier:r,redirectURI:`${e.context.baseURL}/callback/${o.id}`});return e.json({url:n.toString(),redirect:!0})}),qo=c("/sign-in/email",{method:"POST",body:_.z.object({email:_.z.string(),password:_.z.string(),callbackURL:_.z.string().optional(),rememberMe:_.z.boolean().default(!1).optional()})},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 L.APIError("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:o,password:r}=e.body;if(!_.z.string().email().safeParse(o).success)throw new L.APIError("BAD_REQUEST",{message:"Invalid email"});let n=await e.context.internalAdapter.findUserByEmail(o,{includeAccounts:!0});if(!n)throw await e.context.password.hash(r),e.context.logger.error("User not found",{email:o}),new L.APIError("UNAUTHORIZED",{message:"Invalid email or password"});let i=n.accounts.find(u=>u.providerId==="credential");if(!i)throw e.context.logger.error("Credential account not found",{email:o}),new L.APIError("UNAUTHORIZED",{message:"Invalid email or password"});let s=i?.password;if(!s)throw e.context.logger.error("Password not found",{email:o}),new L.APIError("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(s,r))throw e.context.logger.error("Invalid password"),new L.APIError("UNAUTHORIZED",{message:"Invalid email or password"});if(e.context.options?.emailAndPassword?.requireEmailVerification&&!n.user.emailVerified){if(!e.context.options?.emailVerification?.sendVerificationEmail)throw y.error("Email verification is required but no email verification handler is provided"),new L.APIError("INTERNAL_SERVER_ERROR",{message:"Email is not verified."});let u=await ae(e.context.secret,n.user.email),l=`${e.context.baseURL}/verify-email?token=${u}`;throw await e.context.options.emailVerification.sendVerificationEmail({user:n.user,url:l,token:u},e.request),e.context.logger.error("Email not verified",{email:o}),new L.APIError("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.rememberMe===!1);if(!d)throw e.context.logger.error("Failed to create session"),new L.APIError("UNAUTHORIZED",{message:"Failed to create session"});return await w(e,{session:d,user:n.user},e.body.rememberMe===!1),e.json({user:n.user,session:d,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});var je=require("zod");var Mo=c("/callback/:id",{method:["GET","POST"],query:je.z.object({state:je.z.string(),code:je.z.string().optional(),error:je.z.string().optional()}),metadata:ge},async e=>{if(!e.query.code)throw e.redirect(`${e.context.baseURL}/error?error=${e.query.error||"no_code"}`);let o=e.context.socialProviders.find(k=>k.id===e.params.id);if(!o)throw e.context.logger.error("Oauth provider with id",e.params.id,"not found"),e.redirect(`${e.context.baseURL}/error?error=oauth_provider_not_found`);let{codeVerifier:r,callbackURL:t,link:n,errorURL:i}=await tt(e),s;try{s=await o.validateAuthorizationCode({code:e.query.code,codeVerifier:r,redirectURI:`${e.context.baseURL}/callback/${o.id}`})}catch(k){throw e.context.logger.error(k),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let a=await o.getUserInfo(s).then(k=>k?.user),u={id:B(),...a};function l(k){let E=i||t||`${e.context.baseURL}/error`;throw E.includes("?")?E=`${E}&error=${k}`:E=`${E}?error=${k}`,e.redirect(E)}if(!a)return y.error("Unable to get user info"),l("unable_to_get_user_info");if(!u.email)return e.context.logger.error("Provider did not return email. This could be due to misconfiguration in the provider settings."),l("email_not_found");if(!t)throw y.error("No callback URL found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(n){if(n.email!==u.email.toLowerCase())return l("email_doesn't_match");if(!await e.context.internalAdapter.createAccount({userId:n.userId,providerId:o.id,accountId:a.id}))return l("unable_to_link_account");let E;try{E=new URL(t).toString()}catch{E=t}throw e.redirect(E)}let m=await Ue(e,{userInfo:{email:u.email,id:u.id,name:u.name||"",image:u.image,emailVerified:u.emailVerified||!1},account:{providerId:o.id,accountId:a.id,accessToken:s.accessToken,refreshToken:s.refreshToken,expiresAt:s.accessTokenExpiresAt},callbackURL:t});if(m.error)return l(m.error.split(" ").join("_"));let{session:f,user:p}=m.data;await w(e,{session:f,user:p});let h;try{h=new URL(t).toString()}catch{h=t}throw e.redirect(h)});var od=require("zod");var Ir=require("better-call"),$o=c("/sign-out",{method:"POST",requireHeaders:!0},async e=>{let o=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!o)throw new Ir.APIError("BAD_REQUEST",{message:"Session not found"});return await e.context.internalAdapter.deleteSession(o),J(e),e.json({success:!0})});var Q=require("zod");var Ne=require("better-call");function Tr(e,o,r){let t=o?new URL(o,e.baseURL):new URL(`${e.baseURL}/error`);return r&&Object.entries(r).forEach(([n,i])=>t.searchParams.set(n,i)),t.href}function en(e,o,r){let t=new URL(o,e.baseURL);return r&&Object.entries(r).forEach(([n,i])=>t.searchParams.set(n,i)),t.href}var Qo=c("/forget-password",{method:"POST",body:Q.z.object({email:Q.z.string().email(),redirectTo:Q.z.string()})},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 Ne.APIError("BAD_REQUEST",{message:"Reset password isn't enabled"});let{email:o,redirectTo:r}=e.body,t=await e.context.internalAdapter.findUserByEmail(o,{includeAccounts:!0});if(!t)return e.context.logger.error("Reset Password: User not found",{email:o}),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:t.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({user:t.user,url:a},e.request),e.json({status:!0})}),Ho=c("/reset-password/:token",{method:"GET",query:Q.z.object({callbackURL:Q.z.string()})},async e=>{let{token:o}=e.params,{callbackURL:r}=e.query;if(!o||!r)throw e.redirect(Tr(e.context,r,{error:"INVALID_TOKEN"}));let t=await e.context.internalAdapter.findVerificationValue(`reset-password:${o}`);throw!t||t.expiresAt<new Date?e.redirect(Tr(e.context,r,{error:"INVALID_TOKEN"})):e.redirect(en(e.context,r,{token:o}))}),Wo=c("/reset-password",{query:Q.z.optional(Q.z.object({token:Q.z.string().optional(),currentURL:Q.z.string().optional()})),method:"POST",body:Q.z.object({newPassword:Q.z.string()})},async e=>{let o=e.query?.token||(e.query?.currentURL?new URL(e.query.currentURL).searchParams.get("token"):"");if(!o)throw new Ne.APIError("BAD_REQUEST",{message:"Token not found"});let{newPassword:r}=e.body,t=`reset-password:${o}`,n=await e.context.internalAdapter.findVerificationValue(t);if(!n||n.expiresAt<new Date)throw new Ne.APIError("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 Ne.APIError("BAD_REQUEST",{message:"Failed to update password"});return e.json({status:!0})});var V=require("zod");var j=require("better-call");var Go=c("/change-password",{method:"POST",body:V.z.object({newPassword:V.z.string(),currentPassword:V.z.string(),revokeOtherSessions:V.z.boolean().optional()}),use:[b]},async e=>{let{newPassword:o,currentPassword:r,revokeOtherSessions:t}=e.body,n=e.context.session,i=e.context.password.config.minPasswordLength;if(o.length<i)throw e.context.logger.error("Password is too short"),new j.APIError("BAD_REQUEST",{message:"Password is too short"});let s=e.context.password.config.maxPasswordLength;if(o.length>s)throw e.context.logger.error("Password is too long"),new j.APIError("BAD_REQUEST",{message:"Password too long"});let d=(await e.context.internalAdapter.findAccounts(n.user.id)).find(m=>m.providerId==="credential"&&m.password);if(!d||!d.password)throw new j.APIError("BAD_REQUEST",{message:"User does not have a password"});let u=await e.context.password.hash(o);if(!await e.context.password.verify(d.password,r))throw new j.APIError("BAD_REQUEST",{message:"Incorrect password"});if(await e.context.internalAdapter.updateAccount(d.id,{password:u}),t){await e.context.internalAdapter.deleteSessions(n.user.id);let m=await e.context.internalAdapter.createSession(n.user.id,e.headers);if(!m)throw new j.APIError("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});await w(e,{session:m,user:n.user})}return e.json(n.user)}),Jo=c("/set-password",{method:"POST",body:V.z.object({newPassword:V.z.string()}),metadata:{SERVER_ONLY:!0},use:[b]},async e=>{let{newPassword:o}=e.body,r=e.context.session,t=e.context.password.config.minPasswordLength;if(o.length<t)throw e.context.logger.error("Password is too short"),new j.APIError("BAD_REQUEST",{message:"Password is too short"});let n=e.context.password.config.maxPasswordLength;if(o.length>n)throw e.context.logger.error("Password is too long"),new j.APIError("BAD_REQUEST",{message:"Password too long"});let s=(await e.context.internalAdapter.findAccounts(r.user.id)).find(d=>d.providerId==="credential"&&d.password),a=await e.context.password.hash(o);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 j.APIError("BAD_REQUEST",{message:"user already has a password"})}),Ko=c("/delete-user",{method:"POST",body:V.z.object({password:V.z.string()}),use:[b]},async e=>{let{password:o}=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 j.APIError("BAD_REQUEST",{message:"User does not have a password"});if(!await e.context.password.verify(n.password,o))throw new j.APIError("BAD_REQUEST",{message:"Incorrect password"});return await e.context.internalAdapter.deleteUser(r.user.id),await e.context.internalAdapter.deleteSessions(r.user.id),J(e),e.json(null)}),Zo=c("/change-email",{method:"POST",query:V.z.object({currentURL:V.z.string().optional()}).optional(),body:V.z.object({newEmail:V.z.string().email(),callbackURL:V.z.string().optional()}),use:[b]},async e=>{if(!e.context.options.user?.changeEmail?.enabled)throw e.context.logger.error("Change email is disabled."),new j.APIError("BAD_REQUEST",{message:"Change email is disabled"});if(e.body.newEmail===e.context.session.user.email)throw e.context.logger.error("Email is the same"),new j.APIError("BAD_REQUEST",{message:"Email is the same"});if(await e.context.internalAdapter.findUserByEmail(e.body.newEmail))throw e.context.logger.error("Email already exists"),new j.APIError("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 j.APIError("BAD_REQUEST",{message:"Verification email isn't enabled"});let r=await ae(e.context.secret,e.context.session.user.email,e.body.newEmail),t=`${e.context.baseURL}/verify-email?token=${r}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.user.changeEmail.sendChangeEmailVerification({user:e.context.session.user,newEmail:e.body.newEmail,url:t,token:r},e.request),e.json({user:null,status:!0})});var Ie=require("zod");var kt=require("better-call");var Yo=c("/list-accounts",{method:"GET",use:[b]},async e=>{let o=e.context.session,r=await e.context.internalAdapter.findAccounts(o.user.id);return e.json(r.map(t=>({id:t.id,provider:t.providerId})))}),Xo=c("/link-social",{method:"POST",requireHeaders:!0,query:Ie.z.object({currentURL:Ie.z.string().optional()}).optional(),body:Ie.z.object({callbackURL:Ie.z.string().optional(),provider:Ie.z.enum(rt)}),use:[b]},async e=>{let o=e.context.session;if((await e.context.internalAdapter.findAccounts(o.user.id)).find(a=>a.providerId===e.body.provider))throw new kt.APIError("BAD_REQUEST",{message:"Social Account is already linked."});let n=e.context.socialProviders.find(a=>a.id===e.body.provider);if(!n)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new kt.APIError("NOT_FOUND",{message:"Provider not found"});let i=await ve(e,{userId:o.user.id,email:o.user.email}),s=await n.createAuthorizationURL({state:i.state,codeVerifier:i.codeVerifier,redirectURI:`${e.context.baseURL}/callback/${n.id}`});return e.json({url:s.toString(),redirect:!0})});var Sr=(e,o)=>{let r={};for(let[t,n]of Object.entries(e))r[t]=i=>n({...i,context:{...o,...i.context}}),r[t].path=n.path,r[t].method=n.method,r[t].options=n.options,r[t].headers=n.headers;return r};var Te=class extends Error{path;constructor(o,r){super(o),this.path=r}},nt=class{constructor(o){this.s=o;this.statements=o}statements;newRole(o){return new it(o)}},it=class e{statements;constructor(o){this.statements=o}authorize(o,r){for(let[t,n]of Object.entries(o)){let i=this.statements[t];if(!i)return{success:!1,error:`You are not allowed to access resource: ${t}`};let s=r==="OR"?n.some(a=>i.includes(a)):n.every(a=>i.includes(a));return s?{success:s}:{success:!1,error:`unauthorized to access resource "${t}"`}}return{success:!1,error:"Not authorized"}}static fromString(o){let r=JSON.parse(o);if(typeof r!="object")throw new Te("statements is not an object",".");for(let[t,n]of Object.entries(r)){if(typeof t!="string")throw new Te("invalid resource identifier",t);if(!Array.isArray(n))throw new Te("actions is not an array",t);for(let i=0;i<n.length;i++)if(typeof n[i]!="string")throw new Te("action is not a string",`${t}[${i}]`)}return new e(r)}toString(){return JSON.stringify(this.statements)}};var tn=e=>new nt(e),rn={organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]},Ot=tn(rn),on=Ot.newRole({organization:["update"],invitation:["create","cancel"],member:["create","update","delete"]}),nn=Ot.newRole({organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]}),sn=Ot.newRole({organization:[],member:[],invitation:[]}),Pr={admin:on,owner:nn,member:sn};var C=(e,o)=>{let r=e.adapter;return{findOrganizationBySlug:async t=>await r.findOne({model:"organization",where:[{field:"slug",value:t}]}),createOrganization:async t=>{let n=await r.create({model:"organization",data:{...t.organization,metadata:t.organization.metadata?JSON.stringify(t.organization.metadata):void 0}}),i=await r.create({model:"member",data:{id:B(),organizationId:n.id,userId:t.user.id,createdAt:new Date,role:o?.creatorRole||"owner"}});return{...n,metadata:n.metadata?JSON.parse(n.metadata):void 0,members:[{...i,user:{id:t.user.id,name:t.user.name,email:t.user.email,image:t.user.image}}]}},findMemberByEmail:async t=>{let n=await r.findOne({model:e.tables.user.tableName,where:[{field:"email",value:t.email}]});if(!n)return null;let i=await r.findOne({model:"member",where:[{field:"organizationId",value:t.organizationId},{field:"userId",value:n.id}]});return i?{...i,user:{id:n.id,name:n.name,email:n.email,image:n.image}}:null},findMemberByOrgId:async t=>{let[n,i]=await Promise.all([await r.findOne({model:"member",where:[{field:"userId",value:t.userId},{field:"organizationId",value:t.organizationId}]}),await r.findOne({model:e.tables.user.tableName,where:[{field:"id",value:t.userId}]})]);return!i||!n?null:{...n,user:{id:i.id,name:i.name,email:i.email,image:i.image}}},findMemberById:async t=>{let n=await r.findOne({model:"member",where:[{field:"id",value:t}]});if(!n)return null;let i=await r.findOne({model:e.tables.user.tableName,where:[{field:"id",value:n.userId}]});return i?{...n,user:{id:i.id,name:i.name,email:i.email,image:i.image}}:null},createMember:async t=>await r.create({model:"member",data:t}),updateMember:async(t,n)=>await r.update({model:"member",where:[{field:"id",value:t}],update:{role:n}}),deleteMember:async t=>await r.delete({model:"member",where:[{field:"id",value:t}]}),updateOrganization:async(t,n)=>await r.update({model:"organization",where:[{field:"id",value:t}],update:n}),deleteOrganization:async t=>(await r.delete({model:"member",where:[{field:"organizationId",value:t}]}),await r.delete({model:"invitation",where:[{field:"organizationId",value:t}]}),await r.delete({model:"organization",where:[{field:"id",value:t}]}),t),setActiveOrganization:async(t,n)=>await r.update({model:e.tables.session.tableName,where:[{field:"id",value:t}],update:{activeOrganizationId:n}}),findOrganizationById:async t=>await r.findOne({model:"organization",where:[{field:"id",value:t}]}),findFullOrganization:async(t,n)=>{let[i,s,a]=await Promise.all([r.findOne({model:"organization",where:[{field:"id",value:t}]}),r.findMany({model:"invitation",where:[{field:"organizationId",value:t}]}),r.findMany({model:"member",where:[{field:"organizationId",value:t}]})]);if(!i)return null;let d=a.map(f=>f.userId),u=await r.findMany({model:e.tables.user.tableName,where:[{field:"id",value:d,operator:"in"}]}),l=new Map(u.map(f=>[f.id,f])),m=a.map(f=>{let p=l.get(f.userId);if(!p)throw new W("Unexpected error: User not found for member");return{...f,user:{id:p.id,name:p.name,email:p.email,image:p.image}}});return{...i,invitations:s,members:m}},listOrganizations:async t=>{let n=await r.findMany({model:"member",where:[{field:"userId",value:t}]});if(!n||n.length===0)return[];let i=n.map(a=>a.organizationId);return await r.findMany({model:"organization",where:[{field:"id",value:i,operator:"in"}]})},createInvitation:async({invitation:t,user:n})=>{let s=P(o?.invitationExpiresIn||1728e5);return await r.create({model:"invitation",data:{id:B(),email:t.email,role:t.role,organizationId:t.organizationId,status:"pending",expiresAt:s,inviterId:n.id}})},findInvitationById:async t=>await r.findOne({model:"invitation",where:[{field:"id",value:t}]}),findPendingInvitation:async t=>(await r.findMany({model:"invitation",where:[{field:"email",value:t.email},{field:"organizationId",value:t.organizationId},{field:"status",value:"pending"}]})).filter(i=>new Date(i.expiresAt)>new Date),updateInvitation:async t=>await r.update({model:"invitation",where:[{field:"id",value:t.invitationId}],update:{status:t.status}})}};var Zd=require("better-call");var x=S(async e=>({})),D=S({use:[b]},async e=>({session:e.context.session}));var F=require("zod");var R=require("zod"),st=R.z.enum(["admin","member","owner"]),an=R.z.enum(["pending","accepted","rejected","canceled"]).default("pending"),tu=R.z.object({id:R.z.string(),name:R.z.string(),slug:R.z.string(),logo:R.z.string().nullish(),metadata:R.z.record(R.z.string()).or(R.z.string().transform(e=>JSON.parse(e))).nullish(),createdAt:R.z.date()}),ru=R.z.object({id:R.z.string(),organizationId:R.z.string(),userId:R.z.string(),role:st,createdAt:R.z.date()}),ou=R.z.object({id:R.z.string(),organizationId:R.z.string(),email:R.z.string(),role:st,status:an,inviterId:R.z.string(),expiresAt:R.z.date()});var T=require("better-call"),_r=c("/organization/invite-member",{method:"POST",use:[x,D],body:F.z.object({email:F.z.string(),role:st,organizationId:F.z.string().optional(),resend:F.z.boolean().optional()})},async e=>{if(!e.context.orgOptions.sendInvitationEmail)throw y.warn("Invitation email is not enabled. Pass `sendInvitationEmail` to the plugin options to enable it."),new T.APIError("BAD_REQUEST",{message:"Invitation email is not enabled"});let o=e.context.session,r=e.body.organizationId||o.session.activeOrganizationId;if(!r)throw new T.APIError("BAD_REQUEST",{message:"Organization not found"});let t=C(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)throw new T.APIError("BAD_REQUEST",{message:"Member not found!"});let i=e.context.roles[n.role];if(!i)throw new T.APIError("BAD_REQUEST",{message:"Role not found!"});if(i.authorize({invitation:["create"]}).error)throw new T.APIError("FORBIDDEN",{message:"You are not allowed to invite members"});if(await t.findMemberByEmail({email:e.body.email,organizationId:r}))throw new T.APIError("BAD_REQUEST",{message:"User is already a member of this organization"});if((await t.findPendingInvitation({email:e.body.email,organizationId:r})).length&&!e.body.resend)throw new T.APIError("BAD_REQUEST",{message:"User is already invited to this organization"});let u=await t.createInvitation({invitation:{role:e.body.role,email:e.body.email,organizationId:r},user:o.user}),l=await t.findOrganizationById(r);if(!l)throw new T.APIError("BAD_REQUEST",{message:"Organization not found"});return await e.context.orgOptions.sendInvitationEmail?.({id:u.id,role:u.role,email:u.email,organization:l,inviter:{...n,user:o.user}},e.request),e.json(u)}),Cr=c("/organization/accept-invitation",{method:"POST",body:F.z.object({invitationId:F.z.string()}),use:[x,D]},async e=>{let o=e.context.session,r=C(e.context,e.context.orgOptions),t=await r.findInvitationById(e.body.invitationId);if(!t||t.expiresAt<new Date||t.status!=="pending")throw new T.APIError("BAD_REQUEST",{message:"Invitation not found!"});if(t.email!==o.user.email)throw new T.APIError("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.updateInvitation({invitationId:e.body.invitationId,status:"accepted"}),i=await r.createMember({id:B(),organizationId:t.organizationId,userId:o.user.id,role:t.role,createdAt:new Date});return await r.setActiveOrganization(o.session.id,t.organizationId),n?e.json({invitation:n,member:i}):e.json(null,{status:400,body:{message:"Invitation not found!"}})}),zr=c("/organization/reject-invitation",{method:"POST",body:F.z.object({invitationId:F.z.string()}),use:[x,D]},async e=>{let o=e.context.session,r=C(e.context,e.context.orgOptions),t=await r.findInvitationById(e.body.invitationId);if(!t||t.expiresAt<new Date||t.status!=="pending")throw new T.APIError("BAD_REQUEST",{message:"Invitation not found!"});if(t.email!==o.user.email)throw new T.APIError("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.updateInvitation({invitationId:e.body.invitationId,status:"rejected"});return e.json({invitation:n,member:null})}),Br=c("/organization/cancel-invitation",{method:"POST",body:F.z.object({invitationId:F.z.string()}),use:[x,D]},async e=>{let o=e.context.session,r=C(e.context,e.context.orgOptions),t=await r.findInvitationById(e.body.invitationId);if(!t)throw new T.APIError("BAD_REQUEST",{message:"Invitation not found!"});let n=await r.findMemberByOrgId({userId:o.user.id,organizationId:t.organizationId});if(!n)throw new T.APIError("BAD_REQUEST",{message:"Member not found!"});if(e.context.roles[n.role].authorize({invitation:["cancel"]}).error)throw new T.APIError("FORBIDDEN",{message:"You are not allowed to cancel this invitation"});let s=await r.updateInvitation({invitationId:e.body.invitationId,status:"canceled"});return e.json(s)}),xr=c("/organization/get-invitation",{method:"GET",use:[x],requireHeaders:!0,query:F.z.object({id:F.z.string()})},async e=>{let o=await z(e);if(!o)throw new T.APIError("UNAUTHORIZED",{message:"Not authenticated"});let r=C(e.context,e.context.orgOptions),t=await r.findInvitationById(e.query.id);if(!t||t.status!=="pending"||t.expiresAt<new Date)throw new T.APIError("BAD_REQUEST",{message:"Invitation not found!"});if(t.email!==o.user.email)throw new T.APIError("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.findOrganizationById(t.organizationId);if(!n)throw new T.APIError("BAD_REQUEST",{message:"Organization not found"});let i=await r.findMemberByOrgId({userId:t.inviterId,organizationId:t.organizationId});if(!i)throw new T.APIError("BAD_REQUEST",{message:"Inviter is no longer a member of the organization"});return e.json({...t,organizationName:n.name,organizationSlug:n.slug,inviterEmail:i.user.email})});var de=require("zod");var Se=require("better-call"),Lr=c("/organization/remove-member",{method:"POST",body:de.z.object({memberIdOrEmail:de.z.string(),organizationId:de.z.string().optional()}),use:[x,D]},async e=>{let o=e.context.session,r=e.body.organizationId||o.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"No active organization found!"}});let t=C(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)throw new Se.APIError("BAD_REQUEST",{message:"Member not found!"});let i=e.context.roles[n.role];if(!i)throw new Se.APIError("BAD_REQUEST",{message:"Role not found!"});let s=o.user.email===e.body.memberIdOrEmail||n.id===e.body.memberIdOrEmail;if(s&&n.role===(e.context.orgOptions?.creatorRole||"owner"))throw new Se.APIError("BAD_REQUEST",{message:"You cannot leave the organization as the owner"});if(!(s||i.authorize({member:["delete"]}).success))throw new Se.APIError("UNAUTHORIZED",{message:"You are not allowed to delete this member"});let u=null;if(e.body.memberIdOrEmail.includes("@")?u=await t.findMemberByEmail({email:e.body.memberIdOrEmail,organizationId:r}):u=await t.findMemberById(e.body.memberIdOrEmail),u?.organizationId!==r)throw new Se.APIError("BAD_REQUEST",{message:"Member not found!"});return await t.deleteMember(u.id),o.user.id===u.userId&&o.session.activeOrganizationId===u.organizationId&&await t.setActiveOrganization(o.session.id,null),e.json({member:u})}),Dr=c("/organization/update-member-role",{method:"POST",body:de.z.object({role:de.z.enum(["admin","member","owner"]),memberId:de.z.string(),organizationId:de.z.string().optional()}),use:[x,D]},async e=>{let o=e.context.session,r=e.body.organizationId||o.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"No active organization found!"}});let t=C(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)return e.json(null,{status:400,body:{message:"Member not found!"}});let i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({member:["update"]}).error||e.body.role==="owner"&&n.role!=="owner")return e.json(null,{body:{message:"You are not allowed to update this member"},status:403});let a=await t.updateMember(e.body.memberId,e.body.role);return a?e.json(a):e.json(null,{status:400,body:{message:"Member not found!"}})}),jr=c("/organization/get-active-member",{method:"GET",use:[x,D]},async e=>{let o=e.context.session,r=o.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"No active organization found!"}});let n=await C(e.context,e.context.orgOptions).findMemberByOrgId({userId:o.user.id,organizationId:r});return n?e.json(n):e.json(null,{status:400,body:{message:"Member not found!"}})});var I=require("zod");var ue=require("better-call"),Nr=c("/organization/create",{method:"POST",body:I.z.object({name:I.z.string(),slug:I.z.string(),userId:I.z.string().optional(),logo:I.z.string().optional(),metadata:I.z.record(I.z.string(),I.z.any()).optional()}),use:[x,D]},async e=>{let o=e.context.session.user;if(!o)return e.json(null,{status:401});let r=e.context.orgOptions;if(!(typeof r?.allowUserToCreateOrganization=="function"?await r.allowUserToCreateOrganization(o):r?.allowUserToCreateOrganization===void 0?!0:r.allowUserToCreateOrganization))throw new ue.APIError("FORBIDDEN",{message:"You are not allowed to create an organization"});let n=C(e.context,r),i=await n.listOrganizations(o.id);if(typeof r.organizationLimit=="number"?i.length>=r.organizationLimit:typeof r.organizationLimit=="function"?await r.organizationLimit(o):!1)throw new ue.APIError("FORBIDDEN",{message:"You have reached the organization limit"});if(await n.findOrganizationBySlug(e.body.slug))throw new ue.APIError("BAD_REQUEST",{message:"Organization with this slug already exists"});let d=await n.createOrganization({organization:{id:B(),slug:e.body.slug,name:e.body.name,logo:e.body.logo,createdAt:new Date,metadata:e.body.metadata},user:o});return e.json(d)}),Vr=c("/organization/update",{method:"POST",body:I.z.object({data:I.z.object({name:I.z.string().optional(),slug:I.z.string().optional(),logo:I.z.string().optional()}).partial(),organizationId:I.z.string().optional()}),requireHeaders:!0,use:[x]},async e=>{let o=await e.context.getSession(e);if(!o)throw new ue.APIError("UNAUTHORIZED",{message:"User not found"});let r=e.body.organizationId||o.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"Organization id not found!"}});let t=C(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)return e.json(null,{status:400,body:{message:"User is not a member of this organization!"}});let i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({organization:["update"]}).error)return e.json(null,{body:{message:"You are not allowed to update this organization"},status:403});let a=await t.updateOrganization(r,e.body.data);return e.json(a)}),Fr=c("/organization/delete",{method:"POST",body:I.z.object({organizationId:I.z.string()}),requireHeaders:!0,use:[x]},async e=>{let o=await e.context.getSession(e);if(!o)return e.json(null,{status:401});let r=e.body.organizationId;if(!r)return e.json(null,{status:400,body:{message:"Organization id not found!"}});let t=C(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)return e.json(null,{status:400,body:{message:"User is not a member of this organization!"}});let i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({organization:["delete"]}).error)throw new ue.APIError("FORBIDDEN",{message:"You are not allowed to delete this organization"});return r===o.session.activeOrganizationId&&await t.setActiveOrganization(o.session.id,null),await t.deleteOrganization(r),e.json(r)}),qr=c("/organization/get-full-organization",{method:"GET",query:I.z.optional(I.z.object({organizationId:I.z.string().optional()})),requireHeaders:!0,use:[x,D]},async e=>{let o=e.context.session,r=e.query?.organizationId||o.session.activeOrganizationId;if(!r)return e.json(null,{status:200});let n=await C(e.context,e.context.orgOptions).findFullOrganization(r,e.context.db||void 0);if(!n)throw new ue.APIError("BAD_REQUEST",{message:"Organization not found"});return e.json(n)}),Mr=c("/organization/set-active",{method:"POST",body:I.z.object({organizationId:I.z.string().nullable().optional()}),use:[D,x]},async e=>{let o=C(e.context,e.context.orgOptions),r=e.context.session,t=e.body.organizationId;if(t===null)return r.session.activeOrganizationId&&await o.setActiveOrganization(r.session.id,null),e.json(null);if(!t){let s=r.session.activeOrganizationId;if(!s)return e.json(null);t=s}if(!await o.findMemberByOrgId({userId:r.user.id,organizationId:t}))throw await o.setActiveOrganization(r.session.id,null),new ue.APIError("FORBIDDEN",{message:"You are not a member of this organization"});await o.setActiveOrganization(r.session.id,t);let i=await o.findFullOrganization(t,e.context.db||void 0);return e.json(i)}),$r=c("/organization/list",{method:"GET",use:[x,D]},async e=>{let r=await C(e.context,e.context.orgOptions).listOrganizations(e.context.session.user.id);return e.json(r)});var dn=e=>{let o={createOrganization:Nr,updateOrganization:Vr,deleteOrganization:Fr,setActiveOrganization:Mr,getFullOrganization:qr,listOrganization:$r,createInvitation:_r,cancelInvitation:Br,acceptInvitation:Cr,getInvitation:xr,rejectInvitation:zr,removeMember:Lr,updateMemberRole:Dr,getActiveMember:jr},r={...Pr,...e?.roles};return{id:"organization",endpoints:{...Sr(o,{orgOptions:e||{},roles:r,getSession:async n=>await z(n)}),hasPermission:c("/organization/has-permission",{method:"POST",requireHeaders:!0,body:Pe.z.object({permission:Pe.z.record(Pe.z.string(),Pe.z.array(Pe.z.string()))}),use:[D]},async n=>{if(!n.context.session.session.activeOrganizationId)throw new vt.APIError("BAD_REQUEST",{message:"No active organization"});let s=await C(n.context).findMemberByOrgId({userId:n.context.session.user.id,organizationId:n.context.session.session.activeOrganizationId||""});if(!s)throw new vt.APIError("UNAUTHORIZED",{message:"You are not a member of this organization"});let d=r[s.role].authorize(n.body.permission);return d.error?n.json({error:d.error,success:!1},{status:403}):n.json({error:null,success:!0})})},schema:{session:{fields:{activeOrganizationId:{type:"string",required:!1,fieldName:e?.schema?.session?.fields?.activeOrganizationId}}},organization:{fields:{name:{type:"string",required:!0,fieldName:e?.schema?.organization?.fields?.name},slug:{type:"string",unique:!0,fieldName:e?.schema?.organization?.fields?.slug},logo:{type:"string",required:!1,fieldName:e?.schema?.organization?.fields?.logo},createdAt:{type:"date",required:!0,fieldName:e?.schema?.organization?.fields?.createdAt},metadata:{type:"string",required:!1,fieldName:e?.schema?.organization?.fields?.metadata}}},member:{fields:{organizationId:{type:"string",required:!0,references:{model:"organization",field:"id"},fieldName:e?.schema?.member?.fields?.organizationId},userId:{type:"string",required:!0,fieldName:e?.schema?.member?.fields?.userId},role:{type:"string",required:!0,defaultValue:"member",fieldName:e?.schema?.member?.fields?.role},createdAt:{type:"date",required:!0,fieldName:e?.schema?.member?.fields?.createdAt}}},invitation:{fields:{organizationId:{type:"string",required:!0,references:{model:"organization",field:"id"},fieldName:e?.schema?.invitation?.fields?.organizationId},email:{type:"string",required:!0,fieldName:e?.schema?.invitation?.fields?.email},role:{type:"string",required:!1,fieldName:e?.schema?.invitation?.fields?.role},status:{type:"string",required:!0,defaultValue:"pending",fieldName:e?.schema?.invitation?.fields?.status},expiresAt:{type:"date",required:!0,fieldName:e?.schema?.invitation?.fields?.expiresAt},inviterId:{type:"string",references:{model:"user",field:"id"},fieldName:e?.schema?.invitation?.fields?.inviterId,required:!0}}}},$Infer:{Organization:{},Invitation:{},Member:{},ActiveOrganization:{}}}};var Rt=Nt(require("uncrypto"),1);function un(e){return e.toString(2).padStart(8,"0")}function cn(e){return[...e].map(o=>un(o)).join("")}function Qr(e){return parseInt(cn(e),2)}function ln(e){if(e<0||!Number.isInteger(e))throw new Error("Argument 'max' must be an integer greater than or equal to 0");let o=(e-1).toString(2).length,r=o%8,t=new Uint8Array(Math.ceil(o/8));Rt.default.getRandomValues(t),r!==0&&(t[0]&=(1<<r)-1);let n=Qr(t);for(;n>=e;)Rt.default.getRandomValues(t),r!==0&&(t[0]&=(1<<r)-1),n=Qr(t);return n}function q(e,o){let r="";for(let t=0;t<e;t++)r+=o[ln(o.length)];return r}function M(...e){let o=new Set(e),r="";for(let t of o)t==="a-z"?r+="abcdefghijklmnopqrstuvwxyz":t==="A-Z"?r+="ABCDEFGHIJKLMNOPQRSTUVWXYZ":t==="0-9"?r+="0123456789":r+=t;return r}var $e=require("zod");var Ut=require("@noble/ciphers/chacha"),_e=require("@noble/ciphers/utils"),It=require("@noble/ciphers/webcrypto"),Tt=require("oslo/crypto"),Et=Nt(require("uncrypto"),1);var Hr=require("oslo/encoding");var mn=require("@noble/hashes/scrypt"),pn=require("uncrypto");async function Ve(e,o){let r=new TextEncoder,t={name:"HMAC",hash:"SHA-256"},n=await Et.default.subtle.importKey("raw",r.encode(e),t,!1,["sign","verify"]),i=await Et.default.subtle.sign(t.name,n,r.encode(o));return btoa(String.fromCharCode(...new Uint8Array(i)))}var re=async({key:e,data:o})=>{let r=await(0,Tt.sha256)(new TextEncoder().encode(e)),t=(0,_e.utf8ToBytes)(o),n=(0,It.managedNonce)(Ut.xchacha20poly1305)(new Uint8Array(r));return(0,_e.bytesToHex)(n.encrypt(t))},ce=async({key:e,data:o})=>{let r=await(0,Tt.sha256)(new TextEncoder().encode(e)),t=(0,_e.hexToBytes)(o),n=(0,It.managedNonce)(Ut.xchacha20poly1305)(new Uint8Array(r));return new TextDecoder().decode(n.decrypt(t))};var K=require("zod");var Ce=require("better-call");var at="two_factor";var dt="trust_device";var St=require("zod");var we=S({body:St.z.object({trustDevice:St.z.boolean().optional()})},async e=>{let o=await z(e);if(!o){let r=e.context.createAuthCookie(at),t=await e.getSignedCookie(r.name,e.context.secret);if(!t)throw new Ce.APIError("UNAUTHORIZED",{message:"invalid two factor cookie"});let n=await e.context.internalAdapter.findUserById(t);if(!n)throw new Ce.APIError("UNAUTHORIZED",{message:"invalid two factor cookie"});let i=await e.context.internalAdapter.createSession(t,e.request);if(!i)throw new Ce.APIError("INTERNAL_SERVER_ERROR",{message:"failed to create session"});return{valid:async()=>{if(await w(e,{session:i,user:n}),e.body.trustDevice){let s=e.context.createAuthCookie(dt,{maxAge:2592e3}),a=await Ve(e.context.secret,`${n.id}!${i.id}`);await e.setSignedCookie(s.name,`${a}!${i.id}`,e.context.secret,s.attributes)}return e.json({session:i,user:n})},invalid:async()=>{throw new Ce.APIError("UNAUTHORIZED",{message:"invalid two factor authentication"})},session:{id:i.id,userId:i.userId,expiresAt:i.expiresAt,user:n}}}return{valid:async()=>e.json({session:o,user:o.user}),invalid:async()=>{throw new Ce.APIError("UNAUTHORIZED",{message:"invalid two factor authentication"})},session:o}});var ze=require("better-call");function fn(e){return Array.from({length:e?.amount??10}).fill(null).map(()=>q(e?.length??10,M("a-z","0-9"))).map(o=>`${o.slice(0,5)}-${o.slice(5)}`)}async function Pt(e,o){let r=e,t=o?.customBackupCodesGenerate?o.customBackupCodesGenerate():fn(),n=await re({data:JSON.stringify(t),key:r});return{backupCodes:t,encryptedBackupCodes:n}}async function gn(e,o){let r=await Wr(e.backupCodes,o);return r?{status:r.includes(e.code),updated:r.filter(t=>t!==e.code)}:{status:!1,updated:null}}async function Wr(e,o){let r=Buffer.from(await ce({key:o,data:e})).toString("utf-8"),t=JSON.parse(r),n=K.z.array(K.z.string()).safeParse(t);return n.success?n.data:null}var Gr=(e,o)=>({id:"backup_code",endpoints:{verifyBackupCode:c("/two-factor/verify-backup-code",{method:"POST",body:K.z.object({code:K.z.string(),disableSession:K.z.boolean().optional()}),use:[we]},async r=>{let t=r.context.session.user,n=await r.context.adapter.findOne({model:o,where:[{field:"userId",value:t.id}]});if(!n)throw new ze.APIError("BAD_REQUEST",{message:"Backup codes aren't enabled"});let i=await gn({backupCodes:n.backupCodes,code:r.body.code},r.context.secret);if(!i.status)throw new ze.APIError("UNAUTHORIZED",{message:"Invalid backup code"});let s=await re({key:r.context.secret,data:JSON.stringify(i.updated)});return await r.context.adapter.update({model:o,update:{backupCodes:s},where:[{field:"userId",value:t.id}]}),r.body.disableSession||await w(r,{session:r.context.session,user:t}),r.json({user:t,session:r.context.session})}),generateBackupCodes:c("/two-factor/generate-backup-codes",{method:"POST",body:K.z.object({password:K.z.string()}),use:[b]},async r=>{let t=r.context.session.user;if(!t.twoFactorEnabled)throw new ze.APIError("BAD_REQUEST",{message:"Two factor isn't enabled"});await r.context.password.checkPassword(t.id,r);let n=await Pt(r.context.secret,e);return await r.context.adapter.update({model:o,update:{backupCodes:n.encryptedBackupCodes},where:[{field:"userId",value:r.context.session.user.id}]}),r.json({status:!0,backupCodes:n.backupCodes})}),viewBackupCodes:c("/two-factor/view-backup-codes",{method:"GET",body:K.z.object({userId:K.z.string()}),metadata:{SERVER_ONLY:!0}},async r=>{let t=await r.context.adapter.findOne({model:o,where:[{field:"userId",value:r.body.userId}]});if(!t)throw new ze.APIError("BAD_REQUEST",{message:"Backup codes aren't enabled"});let n=await Wr(t.backupCodes,r.context.secret);if(!n)throw new ze.APIError("BAD_REQUEST",{message:"Backup codes aren't enabled"});return r.json({status:!0,backupCodes:n})})}});var Fe=require("better-call"),Jr=require("oslo/otp"),_t=require("zod");var Kr=require("oslo"),Zr=(e,o)=>{let r={...e,period:new Kr.TimeSpan(e?.period||3,"m")},t=new Jr.TOTPController({digits:6,period:r.period}),n=c("/two-factor/send-otp",{method:"POST",use:[we]},async s=>{if(!e||!e.sendOTP)throw s.context.logger.error("send otp isn't configured. Please configure the send otp function on otp options."),new Fe.APIError("BAD_REQUEST",{message:"otp isn't configured"});let a=s.context.session.user,d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d)throw new Fe.APIError("BAD_REQUEST",{message:"OTP isn't enabled"});let u=await t.generate(Buffer.from(d.secret));return await e.sendOTP({user:a,otp:u},s.request),s.json({status:!0})}),i=c("/two-factor/verify-otp",{method:"POST",body:_t.z.object({code:_t.z.string()}),use:[we]},async s=>{let a=s.context.session.user;if(!a.twoFactorEnabled)throw new Fe.APIError("BAD_REQUEST",{message:"two factor isn't enabled"});let d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d)throw new Fe.APIError("BAD_REQUEST",{message:"OTP isn't enabled"});return await t.generate(Buffer.from(d.secret))===s.body.code?s.context.valid():s.context.invalid()});return{id:"otp",endpoints:{send2FaOTP:n,verifyOTP:i}}};var ye=require("better-call"),Yr=require("oslo"),Me=require("oslo/otp"),qe=require("zod");var Xr=(e,o)=>{let r={...e,digits:6,period:new Yr.TimeSpan(e?.period||30,"s")},t=c("/totp/generate",{method:"POST",use:[b]},async s=>{if(!e)throw s.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp"),new ye.APIError("BAD_REQUEST",{message:"totp isn't configured"});let a=s.context.session.user,d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d)throw new ye.APIError("BAD_REQUEST",{message:"totp isn't enabled"});return{code:await new Me.TOTPController(r).generate(Buffer.from(d.secret))}}),n=c("/two-factor/get-totp-uri",{method:"POST",use:[b],body:qe.z.object({password:qe.z.string()})},async s=>{if(!e)throw s.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp"),new ye.APIError("BAD_REQUEST",{message:"totp isn't configured"});let a=s.context.session.user,d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d||!a.twoFactorEnabled)throw new ye.APIError("BAD_REQUEST",{message:"totp isn't enabled"});return await s.context.password.checkPassword(a.id,s),{totpURI:(0,Me.createTOTPKeyURI)(e.issuer||s.context.appName,a.email,Buffer.from(d.secret),r)}}),i=c("/two-factor/verify-totp",{method:"POST",body:qe.z.object({code:qe.z.string()}),use:[we]},async s=>{if(!e)throw s.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp"),new ye.APIError("BAD_REQUEST",{message:"totp isn't configured"});let a=s.context.session.user,d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d)throw new ye.APIError("BAD_REQUEST",{message:"totp isn't enabled"});let u=new Me.TOTPController(r),l=await ce({key:s.context.secret,data:d.secret}),m=Buffer.from(l);if(!await u.verify(s.body.code,m))return s.context.invalid();if(!a.twoFactorEnabled){let p=await s.context.internalAdapter.updateUser(a.id,{twoFactorEnabled:!0}),h=await s.context.internalAdapter.createSession(a.id,s.request);await w(s,{session:h,user:p})}return s.context.valid()});return{id:"totp",endpoints:{generateTOTP:t,viewTOTPURI:n,verifyTOTP:i}}};var hn=require("better-call");async function Ct(e,o){let t=(await e.context.internalAdapter.findAccounts(o.userId))?.find(s=>s.providerId==="credential"),n=t?.password;return!t||!n?!1:await e.context.password.verify(n,o.password)}var ut=require("better-call"),eo=require("oslo/otp"),to=require("oslo");var wn=(e={redirect:!0,twoFactorPage:"/"})=>({id:"two-factor",$InferServerPlugin:{},atomListeners:[{matcher:o=>o.startsWith("/two-factor/"),signal:"$sessionSignal"}],pathMethods:{"/two-factor/disable":"POST","/two-factor/enable":"POST","/two-factor/send-otp":"POST","/two-factor/generate-backup-codes":"POST"},fetchPlugins:[{id:"two-factor",name:"two-factor",hooks:{async onSuccess(o){o.data?.twoFactorRedirect&&(e.redirect||e.twoFactorPage)&&typeof window<"u"&&(window.location.href=e.twoFactorPage)}}}]});var yn=e=>{let o={twoFactorTable:e?.twoFactorTable||"twoFactor"},r=Xr({issuer:e?.issuer,...e?.totpOptions},o.twoFactorTable),t=Gr({...e?.backupCodeOptions},o.twoFactorTable),n=Zr({...e?.otpOptions},o.twoFactorTable);return{id:"two-factor",endpoints:{...r.endpoints,...n.endpoints,...t.endpoints,enableTwoFactor:c("/two-factor/enable",{method:"POST",body:$e.z.object({password:$e.z.string().min(8)}),use:[b]},async i=>{let s=i.context.session.user,{password:a}=i.body;if(!await Ct(i,{password:a,userId:s.id}))throw new ut.APIError("BAD_REQUEST",{message:"Invalid password"});let u=q(16,M("a-z","0-9","-")),l=await re({key:i.context.secret,data:u}),m=await Pt(i.context.secret,e?.backupCodeOptions);if(e?.skipVerificationOnEnable){let p=await i.context.internalAdapter.updateUser(s.id,{twoFactorEnabled:!0}),h=await i.context.internalAdapter.createSession(p.id,i.request);await w(i,{session:h,user:s})}await i.context.adapter.deleteMany({model:o.twoFactorTable,where:[{field:"userId",value:s.id}]}),await i.context.adapter.create({model:o.twoFactorTable,data:{id:i.context.uuid(),secret:l,backupCodes:m.encryptedBackupCodes,userId:s.id}});let f=(0,eo.createTOTPKeyURI)(e?.issuer||"BetterAuth",s.email,Buffer.from(u),{digits:e?.totpOptions?.digits||6,period:new to.TimeSpan(e?.totpOptions?.period||30,"s")});return i.json({totpURI:f,backupCodes:m.backupCodes})}),disableTwoFactor:c("/two-factor/disable",{method:"POST",body:$e.z.object({password:$e.z.string().min(8)}),use:[b]},async i=>{let s=i.context.session.user,{password:a}=i.body;if(!await Ct(i,{password:a,userId:s.id}))throw new ut.APIError("BAD_REQUEST",{message:"Invalid password"});return await i.context.internalAdapter.updateUser(s.id,{twoFactorEnabled:!1}),await i.context.adapter.delete({model:o.twoFactorTable,where:[{field:"userId",value:s.id}]}),i.json({status:!0})})},options:e,hooks:{after:[{matcher(i){return i.path==="/sign-in/email"||i.path==="/sign-in/username"},handler:S(async i=>{let s=i.context.returned;if(s instanceof Response&&s?.status!==200||s instanceof ut.APIError)return;let a=s instanceof Response?await s.clone().json():s;if(!a.user.twoFactorEnabled)return;let d=i.context.createAuthCookie(dt,{maxAge:30*24*60*60}),u=await i.getSignedCookie(d.name,i.context.secret);if(u){let[f,p]=u.split("!"),h=await Ve(i.context.secret,`${a.user.id}!${p}`);if(f===h){let k=await Ve(i.context.secret,`${a.user.id}!${a.session.id}`);await i.setSignedCookie(d.name,`${k}!${a.session.id}`,i.context.secret,d.attributes);return}}J(i),await i.context.internalAdapter.deleteSession(a.session.id);let l=i.context.createAuthCookie(at,{maxAge:60*10});return await i.setSignedCookie(l.name,a.user.id,i.context.secret,l.attributes),{response:new Response(JSON.stringify({twoFactorRedirect:!0}),{headers:i.responseHeader})}})}]},schema:{user:{fields:{twoFactorEnabled:{type:"boolean",required:!1,defaultValue:!1,input:!1}}},twoFactor:{tableName:o.twoFactorTable,fields:{secret:{type:"string",required:!0,returned:!1},backupCodes:{type:"string",required:!0,returned:!1},userId:{type:"string",required:!0,returned:!1,references:{model:"user",field:"id"}}}}},rateLimit:[{pathMatcher(i){return i.startsWith("/two-factor/")},window:10,max:3}]}};var le=require("@simplewebauthn/server"),H=require("better-call");var Z=require("zod");var Be=require("@simplewebauthn/browser");var An=require("@better-fetch/fetch");var Dc=require("nanostores");var Ec=require("@better-fetch/fetch");var bn=require("nanostores");var Ic=require("@better-fetch/fetch"),ct=require("nanostores"),zt=(e,o,r,t)=>{let n=(0,ct.atom)({data:null,error:null,isPending:!0,isRefetching:!1}),i=()=>{let a=typeof t=="function"?t({data:n.get().data,error:n.get().error,isPending:n.get().isPending}):t;return r(o,{...a,onSuccess:async d=>{n.set({data:d.data,error:null,isPending:!1,isRefetching:!1}),await a?.onSuccess?.(d)},async onError(d){n.set({error:d.error,data:null,isPending:!1,isRefetching:!1}),await a?.onError?.(d)},async onRequest(d){let u=n.get();n.set({isPending:u.data===null,data:u.data,error:null,isRefetching:!0}),await a?.onRequest?.(d)}})};e=Array.isArray(e)?e:[e];let s=!1;for(let a of e)a.subscribe(()=>{s?i():(0,ct.onMount)(n,()=>(i(),s=!0,()=>{n.off(),a.off()}))});return n};var ro=require("nanostores"),oo=(e,{$listPasskeys:o})=>({signIn:{passkey:async(n,i)=>{let s=await e("/passkey/generate-authenticate-options",{method:"POST",body:{email:n?.email}});if(!s.data)return s;try{let a=await(0,Be.startAuthentication)(s.data,n?.autoFill||!1),d=await e("/passkey/verify-authentication",{body:{response:a},...n?.fetchOptions,...i,method:"POST"});if(!d.data)return d}catch{return{data:null,error:{message:"auth cancelled",status:400,statusText:"BAD_REQUEST"}}}}},passkey:{addPasskey:async(n,i)=>{let s=await e("/passkey/generate-register-options",{method:"GET"});if(!s.data)return s;try{let a=await(0,Be.startRegistration)(s.data),d=await e("/passkey/verify-registration",{...n?.fetchOptions,...i,body:{response:a,name:n?.name},method:"POST"});if(!d.data)return d;o.set(Math.random())}catch(a){return a instanceof Be.WebAuthnError?a.code==="ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED"?{data:null,error:{message:"previously registered",status:400,statusText:"BAD_REQUEST"}}:a.code==="ERROR_CEREMONY_ABORTED"?{data:null,error:{message:"registration cancelled",status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:a.message,status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:a instanceof Error?a.message:"unknown error",status:500,statusText:"INTERNAL_SERVER_ERROR"}}}}},$Infer:{}}),kn=()=>{let e=(0,ro.atom)();return{id:"passkey",$InferServerPlugin:{},getActions:o=>oo(o,{$listPasskeys:e}),getAtoms(o){return{listPasskeys:zt(e,"/passkey/list-user-passkeys",o,{method:"GET"}),$listPasskeys:e}},pathMethods:{"/passkey/register":"POST","/passkey/authenticate":"POST"},atomListeners:[{matcher(o){return o==="/passkey/verify-registration"||o==="/passkey/delete-passkey"},signal:"_listPasskeys"}]}};var On=e=>{let o=G.BETTER_AUTH_URL,r=e?.rpID||o?.replace("http://","").replace("https://","").split(":")[0]||"localhost";if(!r)throw new W("passkey rpID not found. Please provide a rpID in the options or set the BETTER_AUTH_URL environment variable.");let t={origin:null,...e,rpID:r,advanced:{webAuthnChallengeCookie:"better-auth-passkey",...e?.advanced}},n=new Date(Date.now()+1e3*60*5),i=new Date,s=Math.floor((n.getTime()-i.getTime())/1e3);return{id:"passkey",endpoints:{generatePasskeyRegistrationOptions:c("/passkey/generate-register-options",{method:"GET",use:[b],metadata:{client:!1}},async a=>{let d=a.context.session,u=await a.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}),l=new Uint8Array(Buffer.from(q(32,M("a-z","0-9")))),m;m=await(0,le.generateRegistrationOptions)({rpName:t.rpName||a.context.appName,rpID:t.rpID,userID:l,userName:d.user.email||d.user.id,attestationType:"none",excludeCredentials:u.map(p=>({id:p.id,transports:p.transports?.split(",")})),authenticatorSelection:{residentKey:"preferred",userVerification:"preferred",authenticatorAttachment:"platform"}});let f=B();return await a.setSignedCookie(t.advanced.webAuthnChallengeCookie,f,a.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:s}),await a.context.internalAdapter.createVerificationValue({identifier:f,value:JSON.stringify({expectedChallenge:m.challenge,userData:{id:d.user.id}}),expiresAt:n}),a.json(m,{status:200})}),generatePasskeyAuthenticationOptions:c("/passkey/generate-authenticate-options",{method:"POST",body:Z.z.object({email:Z.z.string().optional()}).optional()},async a=>{let d=await z(a),u=[];d&&(u=await a.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}));let l=await(0,le.generateAuthenticationOptions)({rpID:t.rpID,userVerification:"preferred",...u.length?{allowCredentials:u.map(p=>({id:p.id,transports:p.transports?.split(",")}))}:{}}),m={expectedChallenge:l.challenge,userData:{id:d?.user.id||""}},f=B();return await a.setSignedCookie(t.advanced.webAuthnChallengeCookie,f,a.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:s}),await a.context.internalAdapter.createVerificationValue({identifier:f,value:JSON.stringify(m),expiresAt:n}),a.json(l,{status:200})}),verifyPasskeyRegistration:c("/passkey/verify-registration",{method:"POST",body:Z.z.object({response:Z.z.any(),name:Z.z.string().optional()}),use:[b]},async a=>{let d=e?.origin||a.headers?.get("origin")||"";if(!d)return a.json(null,{status:400});let u=a.body.response,l=await a.getSignedCookie(t.advanced.webAuthnChallengeCookie,a.context.secret);if(!l)throw new H.APIError("BAD_REQUEST",{message:"Challenge not found"});let m=await a.context.internalAdapter.findVerificationValue(l);if(!m)return a.json(null,{status:400});let{expectedChallenge:f,userData:p}=JSON.parse(m.value);if(p.id!==a.context.session.user.id)throw new H.APIError("UNAUTHORIZED",{message:"You are not authorized to register this passkey"});try{let h=await(0,le.verifyRegistrationResponse)({response:u,expectedChallenge:f,expectedOrigin:d,expectedRPID:e?.rpID}),{verified:k,registrationInfo:E}=h;if(!k||!E)return a.json(null,{status:400});let{credentialID:ee,credentialPublicKey:Ae,counter:N,credentialDeviceType:pt,credentialBackedUp:ke}=E,pe=Buffer.from(Ae).toString("base64"),ft=B(),co={name:a.body.name,userId:p.id,webauthnUserID:ft,id:ee,publicKey:pe,counter:N,deviceType:pt,transports:u.response.transports.join(","),backedUp:ke,createdAt:new Date},lo=await a.context.adapter.create({model:"passkey",data:co});return a.json(lo,{status:200})}catch(h){throw console.log(h),new H.APIError("INTERNAL_SERVER_ERROR",{message:"Failed to verify registration"})}}),verifyPasskeyAuthentication:c("/passkey/verify-authentication",{method:"POST",body:Z.z.object({response:Z.z.any()})},async a=>{let d=e?.origin||a.headers?.get("origin")||"";if(!d)throw new H.APIError("BAD_REQUEST",{message:"origin missing"});let u=a.body.response,l=await a.getSignedCookie(t.advanced.webAuthnChallengeCookie,a.context.secret);if(!l)throw new H.APIError("BAD_REQUEST",{message:"Challenge not found"});let m=await a.context.internalAdapter.findVerificationValue(l);if(!m)throw new H.APIError("BAD_REQUEST",{message:"Challenge not found"});let{expectedChallenge:f}=JSON.parse(m.value),p=await a.context.adapter.findOne({model:"passkey",where:[{field:"id",value:u.id}]});if(!p)throw new H.APIError("UNAUTHORIZED",{message:"Passkey not found"});try{let h=await(0,le.verifyAuthenticationResponse)({response:u,expectedChallenge:f,expectedOrigin:d,expectedRPID:t.rpID,authenticator:{credentialID:p.id,credentialPublicKey:new Uint8Array(Buffer.from(p.publicKey,"base64")),counter:p.counter,transports:p.transports?.split(",")}}),{verified:k}=h;if(!k)throw new H.APIError("UNAUTHORIZED",{message:"Authentication failed"});await a.context.adapter.update({model:"passkey",where:[{field:"id",value:p.id}],update:{counter:h.authenticationInfo.newCounter}});let E=await a.context.internalAdapter.createSession(p.userId,a.request);if(!E)throw new H.APIError("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});let ee=await a.context.internalAdapter.findUserById(p.userId);if(!ee)throw new H.APIError("INTERNAL_SERVER_ERROR",{message:"User not found"});return await w(a,{session:E,user:ee}),a.json({session:E},{status:200})}catch(h){throw a.context.logger.error(h),new H.APIError("BAD_REQUEST",{message:"Failed to verify authentication"})}}),listPasskeys:c("/passkey/list-user-passkeys",{method:"GET",use:[b]},async a=>{let d=await a.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:a.context.session.user.id}]});return a.json(d,{status:200})}),deletePasskey:c("/passkey/delete-passkey",{method:"POST",body:Z.z.object({id:Z.z.string()}),use:[b]},async a=>(await a.context.adapter.delete({model:"passkey",where:[{field:"id",value:a.body.id}]}),a.json(null,{status:200})))},schema:{passkey:{fields:{name:{type:"string",required:!1},publicKey:{type:"string",required:!0},userId:{type:"string",references:{model:"user",field:"id"},required:!0},webauthnUserID:{type:"string",required:!0},counter:{type:"number",required:!0},deviceType:{type:"string",required:!0},backedUp:{type:"boolean",required:!0},transports:{type:"string",required:!1},createdAt:{type:"date",defaultValue:new Date,required:!1}}}}}};var Qe=require("zod");var He=require("better-call"),Bt=()=>({id:"username",endpoints:{signInUsername:c("/sign-in/username",{method:"POST",body:Qe.z.object({username:Qe.z.string(),password:Qe.z.string(),rememberMe:Qe.z.boolean().optional()})},async e=>{let o=await e.context.adapter.findOne({model:e.context.tables.user.tableName,where:[{field:"username",value:e.body.username}]});if(!o)throw await e.context.password.hash(e.body.password),e.context.logger.error("User not found",{username:Bt}),new He.APIError("UNAUTHORIZED",{message:"Invalid username or password"});let r=await e.context.adapter.findOne({model:e.context.tables.account.tableName,where:[{field:e.context.tables.account.fields.userId.fieldName||"userId",value:o.id},{field:e.context.tables.account.fields.providerId.fieldName||"providerId",value:"credential"}]});if(!r)throw new He.APIError("UNAUTHORIZED",{message:"Invalid username or password"});let t=r?.password;if(!t)throw e.context.logger.error("Password not found",{username:Bt}),new He.APIError("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(t,e.body.password))throw e.context.logger.error("Invalid password"),new He.APIError("UNAUTHORIZED",{message:"Invalid username or password"});let i=await e.context.internalAdapter.createSession(o.id,e.request,e.body.rememberMe===!1);return i?(await e.setSignedCookie(e.context.authCookies.sessionToken.name,i.id,e.context.secret,e.body.rememberMe===!1?{...e.context.authCookies.sessionToken.options,maxAge:void 0}:e.context.authCookies.sessionToken.options),e.json({user:o,session:i})):e.json(null,{status:500,body:{message:"Failed to create session",status:500}})})},schema:{user:{fields:{username:{type:"string",required:!1,unique:!0,returned:!0}}}}});var no=require("better-call"),vn=()=>({id:"bearer",hooks:{before:[{matcher(e){return!!(e.request?.headers.get("authorization")||e.headers?.get("authorization"))},handler:async e=>{let o=e.request?.headers.get("authorization")?.replace("Bearer ","")||e.headers?.get("authorization")?.replace("Bearer ","");if(!o)return;let r="";return o.includes(".")?r=o:r=await(0,no.serializeSigned)("",o,e.context.secret),e.request&&e.request.headers.set("cookie",`${e.context.authCookies.sessionToken.name}=${r.replace("=","")}`),e.headers&&e.headers.set("cookie",`${e.context.authCookies.sessionToken.name}=${r.replace("=","")}`),{context:e}}}]}});var be=require("zod");var xt=require("better-call");var Rn=e=>({id:"magic-link",endpoints:{signInMagicLink:c("/sign-in/magic-link",{method:"POST",requireHeaders:!0,body:be.z.object({email:be.z.string().email(),callbackURL:be.z.string().optional()})},async o=>{let{email:r}=o.body;if(e.disableSignUp&&!await o.context.internalAdapter.findUserByEmail(r))throw new xt.APIError("BAD_REQUEST",{message:"User not found"});let t=q(32,M("a-z","A-Z"));await o.context.internalAdapter.createVerificationValue({identifier:t,value:r,expiresAt:new Date(Date.now()+(e.expiresIn||60*5)*1e3)});let n=`${o.context.baseURL}/magic-link/verify?token=${t}&callbackURL=${o.body.callbackURL||"/"}`;try{await e.sendMagicLink({email:r,url:n,token:t},o.request)}catch(i){throw o.context.logger.error("Failed to send magic link",i),new xt.APIError("INTERNAL_SERVER_ERROR",{message:"Failed to send magic link"})}return o.json({status:!0})}),magicLinkVerify:c("/magic-link/verify",{method:"GET",query:be.z.object({token:be.z.string(),callbackURL:be.z.string().optional()}),requireHeaders:!0},async o=>{let{token:r,callbackURL:t}=o.query,n=t?.startsWith("http")?t:t?`${o.context.options.baseURL}${t}`:o.context.options.baseURL,i=await o.context.internalAdapter.findVerificationValue(r);if(!i)throw o.redirect(`${n}?error=INVALID_TOKEN`);if(i.expiresAt<new Date)throw await o.context.internalAdapter.deleteVerificationValue(i.id),o.redirect(`${n}?error=EXPIRED_TOKEN`);await o.context.internalAdapter.deleteVerificationValue(i.id);let s=i.value,a=await o.context.internalAdapter.findUserByEmail(s),d=a?.user.id||"";if(!a){if(e.disableSignUp)throw o.redirect(`${n}?error=USER_NOT_FOUND`);if(d=(await o.context.internalAdapter.createUser({email:s,emailVerified:!0,name:s})).id,!d)throw o.redirect(`${n}?error=USER_NOT_CREATED`)}let u=await o.context.internalAdapter.createSession(d,o.headers);if(!u)throw o.redirect(`${n}?error=SESSION_NOT_CREATED`);if(await w(o,{session:u,user:a?.user}),!t)return o.json({status:!0});throw o.redirect(t)})},rateLimit:[{pathMatcher(o){return o.startsWith("/sign-in/magic-link")||o.startsWith("/magic-link/verify")},window:e.rateLimit?.window||60,max:e.rateLimit?.max||5}]});var me=require("zod");var oe=require("better-call");function En(e){return q(e,M("0-9"))}var Un=e=>{let o={phoneNumber:"phoneNumber",phoneNumberVerified:"phoneNumberVerified",code:"code",createdAt:"createdAt",expiresIn:e?.expiresIn||300,otpLength:e?.otpLength||6};return{id:"phone-number",endpoints:{sendPhoneNumberOTP:c("/phone-number/send-otp",{method:"POST",body:me.z.object({phoneNumber:me.z.string()})},async r=>{if(!e?.sendOTP)throw y.warn("sendOTP not implemented"),new oe.APIError("NOT_IMPLEMENTED",{message:"sendOTP not implemented"});let t=En(o.otpLength);return await r.context.internalAdapter.createVerificationValue({value:t,identifier:r.body.phoneNumber,expiresAt:P(o.expiresIn,"sec")}),await e.sendOTP({phoneNumber:r.body.phoneNumber,code:t},r.request),r.json({code:t},{body:{message:"Code sent"}})}),verifyPhoneNumber:c("/phone-number/verify",{method:"POST",body:me.z.object({phoneNumber:me.z.string(),code:me.z.string(),disableSession:me.z.boolean().optional(),updatePhoneNumber:me.z.boolean().optional()})},async r=>{let t=await r.context.internalAdapter.findVerificationValue(r.body.phoneNumber);if(!t||t.expiresAt<new Date)throw t&&t.expiresAt<new Date?(await r.context.internalAdapter.deleteVerificationValue(t.id),new oe.APIError("BAD_REQUEST",{message:"OTP expired"})):new oe.APIError("BAD_REQUEST",{message:"OTP not found"});if(t.value!==r.body.code)throw new oe.APIError("BAD_REQUEST",{message:"Invalid OTP"});if(await r.context.internalAdapter.deleteVerificationValue(t.id),r.body.updatePhoneNumber){let i=await z(r);if(!i)throw new oe.APIError("UNAUTHORIZED",{message:"Session not found"});let s=await r.context.internalAdapter.updateUser(i.user.id,{[o.phoneNumber]:r.body.phoneNumber,[o.phoneNumberVerified]:!0});return r.json({user:s,session:i.session})}let n=await r.context.adapter.findOne({model:r.context.tables.user.tableName,where:[{value:r.body.phoneNumber,field:o.phoneNumber}]});if(await e?.callbackOnVerification?.({phoneNumber:r.body.phoneNumber,user:n},r.request),n)n=await r.context.internalAdapter.updateUser(n.id,{[o.phoneNumberVerified]:!0});else if(e?.signUpOnVerification){if(n=await r.context.internalAdapter.createUser({email:e.signUpOnVerification.getTempEmail(r.body.phoneNumber),name:e.signUpOnVerification.getTempName?e.signUpOnVerification.getTempName(r.body.phoneNumber):r.body.phoneNumber,[o.phoneNumber]:r.body.phoneNumber,[o.phoneNumberVerified]:!0}),!n)throw new oe.APIError("INTERNAL_SERVER_ERROR",{message:"Failed to create user"})}else return r.json(null);if(!n)throw new oe.APIError("INTERNAL_SERVER_ERROR",{message:"Failed to update user"});if(!r.body.disableSession){let i=await r.context.internalAdapter.createSession(n.id,r.request);if(!i)throw new oe.APIError("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await w(r,{session:i,user:n}),r.json({user:n,session:i})}return r.json({user:n,session:null})})},schema:{user:{fields:{phoneNumber:{type:"string",required:!1,unique:!0,returned:!0},phoneNumberVerified:{type:"boolean",required:!1,returned:!0,input:!1}}}}}};var Tl=require("zod");var In=e=>({id:"anonymous",endpoints:{signInAnonymous:c("/sign-in/anonymous",{method:"POST"},async o=>{let{emailDomainName:r=Oe(o.context.baseURL)}=e||{},t=B(),n=`temp-${t}@${r}`,i=await o.context.internalAdapter.createUser({id:t,email:n,emailVerified:!1,isAnonymous:!0,name:"Anonymous",createdAt:new Date,updatedAt:new Date});if(!i)return o.json(null,{status:500,body:{message:"Failed to create user",status:500}});let s=await o.context.internalAdapter.createSession(i.id,o.request);return s?(await w(o,{session:s,user:i}),o.json({user:i,session:s})):o.json(null,{status:400,body:{message:"Could not create session"}})})},hooks:{after:[{matcher(o){return o.path?.startsWith("/sign-in")||o.path?.startsWith("/sign-up")},async handler(o){let r=o.context.returned;if(!(r instanceof Response))return;let t=r.headers.get("set-cookie"),n=o.context.authCookies.sessionToken.name,i=Ye(t||"").get(n)?.value.split(".")[0];if(!i)return;let s=await z(o);if(!(!s||!s.user.isAnonymous)){if(o.path==="/sign-in/anonymous")throw new v.APIError("BAD_REQUEST",{message:"Anonymous users cannot sign in again anonymously"});if(e?.onLinkAccount){let a=await o.context.internalAdapter.findSession(i);if(!a)return;await e?.onLinkAccount?.({anonymousUser:s,newUser:a})}e?.disableDeleteAnonymousUser||await o.context.internalAdapter.deleteUser(s.user.id)}}}]},schema:{user:{fields:{isAnonymous:{type:"boolean",required:!1}}}}});var g=require("zod");var Tn=e=>{let o={defaultRole:"user",adminRole:"admin",...e},r=S(async t=>{let n=await z(t);if(!n?.session)throw new v.APIError("UNAUTHORIZED");let i=n.user;if(!i.role||(Array.isArray(o.adminRole)?!o.adminRole.includes(i.role):i.role!==o.adminRole))throw new v.APIError("FORBIDDEN",{message:"Only admins can access this endpoint"});return{session:{user:i,session:n.session}}});return{id:"admin",init(t){return{options:{databaseHooks:{user:{create:{async before(n){if(e?.defaultRole!==!1)return{data:{role:e?.defaultRole??"user",...n}}}}},session:{create:{async before(n){let i=await t.internalAdapter.findUserById(n.userId);if(i.banned){if(i.banExpires&&i.banExpires<Date.now()){await t.internalAdapter.updateUser(n.userId,{banned:!1,banReason:null,banExpires:null});return}return!1}}}}}}}},hooks:{after:[{matcher(t){return t.path==="/list-sessions"},handler:S(async t=>{let n=t.context.returned;if(n instanceof Response){let s=(await n.clone().json()).filter(d=>!d.impersonatedBy),a=new Response(JSON.stringify(s),{status:200,statusText:"OK",headers:n.headers});return t.json({response:a})}})}]},endpoints:{setRole:c("/admin/set-role",{method:"POST",body:g.z.object({userId:g.z.string(),role:g.z.string()}),use:[r]},async t=>{let n=await t.context.internalAdapter.updateUser(t.body.userId,{role:t.body.role});return t.json({user:n})}),createUser:c("/admin/create-user",{method:"POST",body:g.z.object({email:g.z.string(),password:g.z.string(),name:g.z.string(),role:g.z.string(),data:g.z.optional(g.z.record(g.z.any()))}),use:[r]},async t=>{if(await t.context.internalAdapter.findUserByEmail(t.body.email))throw new v.APIError("BAD_REQUEST",{message:"User already exists"});let i=await t.context.internalAdapter.createUser({email:t.body.email,name:t.body.name,role:t.body.role,...t.body.data});if(!i)throw new v.APIError("INTERNAL_SERVER_ERROR",{message:"Failed to create user"});let s=await t.context.password.hash(t.body.password);return await t.context.internalAdapter.linkAccount({accountId:i.id,providerId:"credential",password:s,userId:i.id}),t.json({user:i})}),listUsers:c("/admin/list-users",{method:"GET",use:[r],query:g.z.object({searchValue:g.z.string().optional(),searchField:g.z.enum(["email","name"]).optional(),searchOperator:g.z.enum(["contains","starts_with","ends_with"]).optional(),limit:g.z.string().or(g.z.number()).optional(),offset:g.z.string().or(g.z.number()).optional(),sortBy:g.z.string().optional(),sortDirection:g.z.enum(["asc","desc"]).optional(),filterField:g.z.string().optional(),filterValue:g.z.string().or(g.z.number()).or(g.z.boolean()).optional(),filterOperator:g.z.enum(["eq","ne","lt","lte","gt","gte"]).optional()})},async t=>{let n=[];t.query?.searchValue&&n.push({field:t.query.searchField||"email",operator:t.query.searchOperator||"contains",value:t.query.searchValue}),t.query?.filterValue&&n.push({field:t.query.filterField||"email",operator:t.query.filterOperator||"eq",value:t.query.filterValue});try{let i=await t.context.internalAdapter.listUsers(Number(t.query?.limit)||void 0,Number(t.query?.offset)||void 0,t.query?.sortBy?{field:t.query.sortBy,direction:t.query.sortDirection||"asc"}:void 0,n.length?n:void 0);return t.json({users:i})}catch(i){return console.log(i),t.json({users:[]})}}),listUserSessions:c("/admin/list-user-sessions",{method:"POST",use:[r],body:g.z.object({userId:g.z.string()})},async t=>({sessions:await t.context.internalAdapter.listSessions(t.body.userId)})),unbanUser:c("/admin/unban-user",{method:"POST",body:g.z.object({userId:g.z.string()}),use:[r]},async t=>{let n=await t.context.internalAdapter.updateUser(t.body.userId,{banned:!1});return t.json({user:n})}),banUser:c("/admin/ban-user",{method:"POST",body:g.z.object({userId:g.z.string(),banReason:g.z.string().optional(),banExpiresIn:g.z.number().optional()}),use:[r]},async t=>{if(t.body.userId===t.context.session.user.id)throw new v.APIError("BAD_REQUEST",{message:"You cannot ban yourself"});let n=await t.context.internalAdapter.updateUser(t.body.userId,{banned:!0,banReason:t.body.banReason||e?.defaultBanReason||"No reason",banExpires:t.body.banExpiresIn?P(t.body.banExpiresIn,"sec"):e?.defaultBanExpiresIn?P(e.defaultBanExpiresIn,"sec"):void 0});return await t.context.internalAdapter.deleteSessions(t.body.userId),t.json({user:n})}),impersonateUser:c("/admin/impersonate-user",{method:"POST",body:g.z.object({userId:g.z.string()}),use:[r]},async t=>{let n=await t.context.internalAdapter.findUserById(t.body.userId);if(!n)throw new v.APIError("NOT_FOUND",{message:"User not found"});let i=await t.context.internalAdapter.createSession(n.id,void 0,!0,{impersonatedBy:t.context.session.user.id,expiresAt:e?.impersonationSessionDuration?P(e.impersonationSessionDuration,"sec"):P(60*60,"sec")});if(!i)throw new v.APIError("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await w(t,{session:i,user:n},!0),t.json({session:i,user:n})}),revokeUserSession:c("/admin/revoke-user-session",{method:"POST",body:g.z.object({sessionId:g.z.string()}),use:[r]},async t=>(await t.context.internalAdapter.deleteSession(t.body.sessionId),t.json({success:!0}))),revokeUserSessions:c("/admin/revoke-user-sessions",{method:"POST",body:g.z.object({userId:g.z.string()}),use:[r]},async t=>(await t.context.internalAdapter.deleteSessions(t.body.userId),t.json({success:!0}))),removeUser:c("/admin/remove-user",{method:"POST",body:g.z.object({userId:g.z.string()}),use:[r]},async t=>(await t.context.internalAdapter.deleteUser(t.body.userId),t.json({success:!0})))},schema:{user:{fields:{role:{type:"string",required:!1,input:!1},banned:{type:"boolean",defaultValue:!1,required:!1,input:!1},banReason:{type:"string",required:!1,input:!1},banExpires:{type:"date",required:!1,input:!1}}},session:{fields:{impersonatedBy:{type:"string",required:!1}}}}}};var Y=require("zod"),xe=require("better-call");var lt=require("@better-fetch/fetch");var io=require("oslo/jwt");async function Sn(e,o,r){if(o==="oidc"&&e.idToken){let n=(0,io.parseJWT)(e.idToken);if(n?.payload)return n.payload}return r?(await(0,lt.betterFetch)(r,{method:"GET",headers:{Authorization:`Bearer ${e.accessToken}`}})).data:null}var Pn=e=>({id:"generic-oauth",endpoints:{signInWithOAuth2:c("/sign-in/oauth2",{method:"POST",query:Y.z.object({currentURL:Y.z.string().optional()}).optional(),body:Y.z.object({providerId:Y.z.string(),callbackURL:Y.z.string().optional()})},async o=>{let{providerId:r}=o.body,t=e.config.find(pe=>pe.providerId===r);if(!t)throw new xe.APIError("BAD_REQUEST",{message:`No config found for provider ${r}`});let{discoveryUrl:n,authorizationUrl:i,tokenUrl:s,clientId:a,clientSecret:d,scopes:u,redirectURI:l,responseType:m,pkce:f,prompt:p,accessType:h}=t,k=i,E=s;if(n){let pe=await(0,lt.betterFetch)(n,{onError(ft){y.error(ft.error,{discoveryUrl:n})}});pe.data&&(k=pe.data.authorization_endpoint,E=pe.data.token_endpoint)}if(!k||!E)throw new xe.APIError("BAD_REQUEST",{message:"Invalid OAuth configuration."});let ee=o.query?.currentURL?new URL(o.query?.currentURL):null,Ae=o.body.callbackURL?.startsWith("http")?o.body.callbackURL:`${ee?.origin}${o.body.callbackURL||""}`,{state:N,codeVerifier:pt}=await ve(o),ke=await U({id:r,options:{clientId:a,clientSecret:d,redirectURI:l},authorizationEndpoint:k,state:N,codeVerifier:f?pt:void 0,scopes:u||[],redirectURI:`${o.context.baseURL}/oauth2/callback/${r}`});return m&&m!=="code"&&ke.searchParams.set("response_type",m),p&&ke.searchParams.set("prompt",p),h&&ke.searchParams.set("access_type",h),o.json({url:ke.toString(),redirect:!0})}),oAuth2Callback:c("/oauth2/callback/:providerId",{method:"GET",query:Y.z.object({code:Y.z.string().optional(),error:Y.z.string().optional(),state:Y.z.string()})},async o=>{if(o.query.error||!o.query.code)throw o.redirect(`${o.context.baseURL}?error=${o.query.error||"oAuth_code_missing"}`);let r=e.config.find(N=>N.providerId===o.params.providerId);if(!r)throw new xe.APIError("BAD_REQUEST",{message:`No config found for provider ${o.params.providerId}`});let t,n=await tt(o),{callbackURL:i,codeVerifier:s,errorURL:a}=n,d=o.query.code,u=r.tokenUrl,l=r.userInfoUrl;if(r.discoveryUrl){let N=await(0,lt.betterFetch)(r.discoveryUrl,{method:"GET"});N.data&&(u=N.data.token_endpoint,l=N.data.userinfo_endpoint)}try{if(!u)throw new xe.APIError("BAD_REQUEST",{message:"Invalid OAuth configuration."});t=await O({code:d,codeVerifier:s,redirectURI:`${o.context.baseURL}/oauth2/callback/${r.providerId}`,options:{clientId:r.clientId,clientSecret:r.clientSecret},tokenEndpoint:u})}catch(N){throw o.context.logger.error(N),o.redirect(`${a}?error=oauth_code_verification_failed`)}if(!t)throw new xe.APIError("BAD_REQUEST",{message:"Invalid OAuth configuration."});let m=r.getUserInfo?await r.getUserInfo(t):await Sn(t,r.type||"oauth2",l),f=B(),p=Ur.safeParse({...m,id:f});if(!m||p.success===!1)throw y.error("Unable to get user info",p.error),o.redirect(`${o.context.baseURL}/error?error=please_restart_the_process`);let h=await Ue(o,{userInfo:p.data,account:{providerId:r.providerId,accountId:m.id,accessToken:t.accessToken}});function k(N){throw o.redirect(`${a||i||`${o.context.baseURL}/error`}?error=${N}`)}if(h.error)return k(h.error.split(" ").join("_"));let{session:E,user:ee}=h.data;await w(o,{session:E,user:ee});let Ae;try{Ae=new URL(i).toString()}catch{Ae=i}throw o.redirect(Ae)})}});var Le=require("zod"),so={jwks:{fields:{publicKey:{type:"string",required:!0},privateKey:{type:"string",required:!0},createdAt:{type:"date",required:!0}}}},Hl=Le.z.object({id:Le.z.string(),publicKey:Le.z.string(),privateKey:Le.z.string(),createdAt:Le.z.date()});var Lt=e=>({getAllKeys:async()=>await e.findMany({model:"jwks"}),getLatestKey:async()=>(await e.findMany({model:"jwks",sortBy:{field:"createdAt",direction:"desc"},limit:1}))[0],createJwk:async o=>await e.create({model:"jwks",data:{...o,createdAt:new Date}})});var ne=require("jose");var _n=e=>({id:"jwt",endpoints:{getJwks:c("/jwks",{method:"GET"},async o=>{let t=await Lt(o.context.adapter).getAllKeys();return o.json({keys:t.map(n=>({...JSON.parse(n.publicKey),kid:n.id}))})}),getToken:c("/token",{method:"GET",requireHeaders:!0,use:[b]},async o=>{let r=Lt(o.context.adapter),t=await r.getLatestKey(),n=!e?.jwks?.disablePrivateKeyEncryption;if(t===void 0){let{publicKey:u,privateKey:l}=await(0,ne.generateKeyPair)(e?.jwks?.keyPairConfig?.alg??"EdDSA",e?.jwks?.keyPairConfig??{crv:"Ed25519"}),m=await(0,ne.exportJWK)(u),f=await(0,ne.exportJWK)(l),p=JSON.stringify(f),h={id:crypto.randomUUID(),publicKey:JSON.stringify(m),privateKey:n?JSON.stringify(await re({key:o.context.options.secret,data:p})):p,createdAt:new Date};t=await r.createJwk(h)}let i=n?await ce({key:o.context.options.secret,data:JSON.parse(t.privateKey)}):t.privateKey,s=await(0,ne.importJWK)(JSON.parse(i)),a=e?.jwt?.definePayload?await e?.jwt.definePayload(o.context.session.user):o.context.session.user,d=await new ne.SignJWT({...a,...o.context.session.session.impersonatedBy?{impersonatedBy:o.context.session.session.impersonatedBy}:{}}).setProtectedHeader({alg:e?.jwks?.keyPairConfig?.alg??"EdDSA",kid:t.id}).setIssuedAt().setIssuer(e?.jwt?.issuer??o.context.options.baseURL).setAudience(e?.jwt?.audience??o.context.options.baseURL).setExpirationTime(e?.jwt?.expirationTime??"15m").setSubject(o.context.session.user.id).sign(s);return o.json({token:d})})},schema:so});var We=require("zod");var Cn=e=>{let o={maximumSessions:5,...e},r=t=>t.includes("_multi-");return{id:"multi-session",endpoints:{listDeviceSessions:c("/multi-session/list-device-sessions",{method:"GET",requireHeaders:!0},async t=>{let n=t.headers?.get("cookie");if(!n)return t.json([]);let i=Object.fromEntries(Xe(n)),s=(await Promise.all(Object.entries(i).filter(([u])=>r(u)).map(async([u])=>await t.getSignedCookie(u,t.context.secret)))).filter(u=>u!==void 0);if(!s.length)return t.json([]);let d=(await t.context.internalAdapter.findSessions(s)).filter(u=>u&&u.session.expiresAt>new Date).filter((u,l,m)=>l===m.findIndex(f=>f.user.id===u.user.id));return t.json(d)}),setActiveSession:c("/multi-session/set-active",{method:"POST",body:We.z.object({sessionId:We.z.string()}),requireHeaders:!0,use:[b]},async t=>{let n=t.body.sessionId,i=`${t.context.authCookies.sessionToken.name}_multi-${n}`;if(!await t.getSignedCookie(i,t.context.secret))throw new v.APIError("UNAUTHORIZED",{message:"Invalid session id"});let a=await t.context.internalAdapter.findSession(n);if(!a||a.session.expiresAt<new Date)throw t.setCookie(i,"",{...t.context.authCookies.sessionToken.options,maxAge:0}),new v.APIError("UNAUTHORIZED",{message:"Invalid session id"});return await t.setSignedCookie(t.context.authCookies.sessionToken.name,n,t.context.secret,t.context.authCookies.sessionToken.options),t.json(a)}),revokeDeviceSession:c("/multi-session/revoke",{method:"POST",body:We.z.object({sessionId:We.z.string()}),requireHeaders:!0,use:[b]},async t=>{let n=t.body.sessionId,i=`${t.context.authCookies.sessionToken.name}_multi-${n}`;if(!await t.getSignedCookie(i,t.context.secret))throw new v.APIError("UNAUTHORIZED",{message:"Invalid session id"});let a=await t.context.internalAdapter.findSession(n);return t.setCookie(i,"",{...t.context.authCookies.sessionToken.options,maxAge:0}),a?(await t.context.internalAdapter.deleteSession(n),t.json({success:!0})):t.json({success:!0})})},hooks:{after:[{matcher:()=>!0,handler:S(async t=>{if(!t.context.returned||!(t.context.returned instanceof Response))return;let n=t.context.returned.headers.get("set-cookie");if(!n)return;let i=Ye(n),s=t.context.authCookies.sessionToken,a=i.get(s.name)?.value;if(!a)return;let d=Xe(t.headers?.get("cookie")||""),u=a.split(".")[0],l=`${s.name}_multi-${u}`;if(i.get(l)||d.get(l)||Object.keys(Object.fromEntries(d)).filter(r).length+(n.includes("session_token")?1:0)>o.maximumSessions)return;await t.setSignedCookie(l,u,t.context.secret,s.options);let f=t.context.returned;return f.headers.append("Set-Cookie",t.responseHeader.get("set-cookie")),{response:f}})},{matcher:t=>t.path==="/sign-out",handler:S(async t=>{if(!(t.context.returned instanceof Response))return;let n=t.headers?.get("cookie");if(!n)return;let i=Object.fromEntries(Xe(n));await Promise.all(Object.entries(i).map(async([a,d])=>{if(r(a)){t.setCookie(a,"",{maxAge:0});let u=a.split("_multi-")[1];await t.context.internalAdapter.deleteSession(u)}}));let s=t.context.returned;return s.headers.append("Set-Cookie",t.responseHeader.get("set-cookie")),{response:s}})}]}}};var X=require("zod");var zn=e=>{let o={expireIn:300,otpLength:6,...e};return{id:"email-otp",endpoints:{sendVerificationOTP:c("/email-otp/send-verification-otp",{method:"POST",body:X.z.object({email:X.z.string(),type:X.z.enum(["email-verification","sign-in"])})},async r=>{if(!e?.sendVerificationOTP)throw y.error("send email verification is not implemented"),new v.APIError("BAD_REQUEST",{message:"send email verification is not implemented"});let t=r.body.email,n=q(o.otpLength,M("0-9"));return await r.context.internalAdapter.createVerificationValue({value:n,identifier:`${r.body.type}-otp-${t}`,expiresAt:P(o.expireIn,"sec")}),await e.sendVerificationOTP({email:t,otp:n,type:r.body.type},r.request),r.json({success:!0})}),verifyEmailOTP:c("/email-otp/verify-email",{method:"POST",body:X.z.object({email:X.z.string(),otp:X.z.string()})},async r=>{let t=r.body.email,n=await r.context.internalAdapter.findVerificationValue(`email-verification-otp-${t}`);if(!n||n.expiresAt<new Date)throw n&&await r.context.internalAdapter.deleteVerificationValue(n.id),new v.APIError("BAD_REQUEST",{message:"Invalid OTP"});let i=r.body.otp;if(n.value!==i)throw new v.APIError("BAD_REQUEST",{message:"Invalid OTP"});await r.context.internalAdapter.deleteVerificationValue(n.id);let s=await r.context.internalAdapter.findUserByEmail(t);if(!s)throw new v.APIError("BAD_REQUEST",{message:"User not found"});let a=await r.context.internalAdapter.updateUser(s.user.id,{email:t,emailVerified:!0});return r.json({user:a})}),signInEmailOTP:c("/sign-in/email-otp",{method:"POST",body:X.z.object({email:X.z.string(),otp:X.z.string()})},async r=>{let t=r.body.email,n=await r.context.internalAdapter.findVerificationValue(`sign-in-otp-${t}`);if(!n||n.expiresAt<new Date)throw n&&await r.context.internalAdapter.deleteVerificationValue(n.id),new v.APIError("BAD_REQUEST",{message:"Invalid OTP"});let i=r.body.otp;if(n.value!==i)throw new v.APIError("BAD_REQUEST",{message:"Invalid OTP"});await r.context.internalAdapter.deleteVerificationValue(n.id);let s=await r.context.internalAdapter.findUserByEmail(t);if(!s){if(o.disableSignUp)throw new v.APIError("BAD_REQUEST",{message:"User not found"});let d=await r.context.internalAdapter.createUser({email:t,emailVerified:!0,name:t}),u=await r.context.internalAdapter.createSession(d.id,r.request);return await w(r,{session:u,user:d}),r.json({user:d,session:u})}let a=await r.context.internalAdapter.createSession(s.user.id,r.request);return await w(r,{session:a,user:s.user}),r.json({session:a,user:s})})},hooks:{after:[{matcher(r){return!!(r.path?.startsWith("/sign-up")&&o.sendVerificationOnSignUp)},async handler(r){let t=r.context.returned;if(t?.status!==200)return;let n=await t.clone().json();if(n.user.email&&n.user.emailVerified===!1){let i=q(o.otpLength,M("0-9"));await r.context.internalAdapter.createVerificationValue({value:i,identifier:`email-verification-otp-${n.user.email}`,expiresAt:P(o.expireIn,"sec")}),await e.sendVerificationOTP({email:n.user.email,otp:i,type:"email-verification"},r.request)}}}]}}};var Dt=require("zod");var uo=require("@better-fetch/fetch");function ao(e){return e==="true"||e===!0}var Bn=e=>({id:"one-tap",endpoints:{oneTapCallback:c("/one-tap/callback",{method:"POST",body:Dt.z.object({idToken:Dt.z.string()})},async o=>{let{idToken:r}=o.body,{data:t,error:n}=await(0,uo.betterFetch)("https://oauth2.googleapis.com/tokeninfo?id_token="+r);if(n)return o.json({error:"Invalid token"});let i=await o.context.internalAdapter.findUserByEmail(t.email);if(!i){if(e?.disableSignup)throw new v.APIError("BAD_GATEWAY",{message:"User not found"});let a=await o.context.internalAdapter.createOAuthUser({email:t.email,emailVerified:ao(t.email_verified),name:t.name,image:t.picture},{providerId:"google",accountId:t.sub});if(!a)throw new v.APIError("INTERNAL_SERVER_ERROR",{message:"Could not create user"});let d=await o.context.internalAdapter.createSession(a?.user.id,o.request);return await w(o,{user:a.user,session:d}),o.json({session:d,user:a})}let s=await o.context.internalAdapter.createSession(i.user.id,o.request);return await w(o,{user:i.user,session:s}),o.json({session:s,user:i})})}});var mt=require("zod");function xn(){let e=G.VERCEL_URL,o=G.NETLIFY_URL,r=G.RENDER_URL,t=G.AWS_LAMBDA_FUNCTION_NAME,n=G.GOOGLE_CLOUD_FUNCTION_NAME,i=G.AZURE_FUNCTION_NAME;return e||o||r||t||n||i}var Ln=e=>({id:"oauth-proxy",endpoints:{oAuthProxy:c("/oauth-proxy-callback",{method:"GET",query:mt.z.object({callbackURL:mt.z.string(),cookies:mt.z.string()})},async o=>{let r=o.query.cookies,t=await ce({key:o.context.secret,data:r});throw o.setHeader("set-cookie",t),o.redirect(o.query.callbackURL)})},hooks:{after:[{matcher(o){return o.path?.startsWith("/callback")},handler:S(async o=>{let r=o.context.returned;if(!r||!(r instanceof Response))return;let t=r.headers.get("location");if(t?.includes("/oauth-proxy-callback?callbackURL")){if(!t.startsWith("http"))return;let n=new URL(t);if(n.origin===Oe(o.context.baseURL)){let u=n.searchParams.get("callbackURL");return u?(r.headers.set("location",u),{response:r}):void 0}let s=r.headers.get("set-cookie");if(!s)return;let a=await re({key:o.context.secret,data:s}),d=`${t}&cookies=${encodeURIComponent(a)}`;return r.headers.set("location",d),{response:r}}})}],before:[{matcher(o){return o.path?.startsWith("/sign-in/social")},async handler(o){let r=new URL(e?.currentURL||o.request?.url||xn()||o.context.baseURL);return o.body.callbackURL=`${r.origin}${o.context.options.basePath||"/api/auth"}/oauth-proxy-callback?callbackURL=${encodeURIComponent(o.body.callbackURL||o.context.baseURL)}`,{context:o}}}]}});0&&(module.exports={HIDE_METADATA,admin,anonymous,bearer,createAuthEndpoint,createAuthMiddleware,emailOTP,genericOAuth,getPasskeyActions,jwt,magicLink,multiSession,oAuthProxy,oneTap,optionsMiddleware,organization,passkey,passkeyClient,phoneNumber,twoFactor,twoFactorClient,username});
84
+ Error: `,a),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)}),i=n?.user;if(n){let a=n.accounts.find(d=>d.providerId===r.providerId);if(a)await e.context.internalAdapter.updateAccount(a.id,{accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,expiresAt:r.expiresAt});else{if(!e.context.options.account?.accountLinking?.trustedProviders?.includes(r.providerId)&&!o.emailVerified||e.context.options.account?.accountLinking?.enabled===!1)return Vt&&y.warn(`User already exist but account isn't linked to ${r.providerId}. To read more about how account linking works in Better Auth see https://www.better-auth.com/docs/concepts/users-accounts#account-linking.`),{error:"account not linked",data:null};try{await e.context.internalAdapter.linkAccount({providerId:r.providerId,accountId:o.id.toString(),id:e.context.uuid(),userId:n.user.id,accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,expiresAt:r.expiresAt})}catch(l){return y.error("Unable to link account",l),{error:"unable to link account",data:null}}}}else try{let a=o.emailVerified||!1;if(i=await e.context.internalAdapter.createOAuthUser({...o,id:e.context.uuid(),emailVerified:a,email:o.email.toLowerCase()},{accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,expiresAt:r.expiresAt,providerId:r.providerId,accountId:o.id.toString()}).then(d=>d?.user),!a&&i&&e.context.options.emailVerification?.sendOnSignUp){let d=await ae(e.context.secret,i.email),u=`${e.context.baseURL}/verify-email?token=${d}&callbackURL=${t}`;await e.context.options.emailVerification?.sendVerificationEmail?.({user:i,url:u,token:d},e.request)}}catch(a){return y.error("Unable to create user",a),{error:"unable to create user",data:null}}if(!i)return{error:"unable to create user",data:null};let s=await e.context.internalAdapter.createSession(i.id,e.request);return s?{data:{session:s,user:i},error:null}:{error:"unable to create session",data:null}}var Fo=c("/sign-in/social",{method:"POST",query:_.z.object({currentURL:_.z.string().optional()}).optional(),body:_.z.object({callbackURL:_.z.string().optional(),provider:_.z.enum(rt),idToken:_.z.optional(_.z.object({token:_.z.string(),nonce:_.z.string().optional(),accessToken:_.z.string().optional(),refreshToken:_.z.string().optional(),expiresAt:_.z.number().optional()}))})},async e=>{let o=e.context.socialProviders.find(i=>i.id===e.body.provider);if(!o)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new L.APIError("NOT_FOUND",{message:"Provider not found"});if(e.body.idToken){if(!o.verifyIdToken)throw e.context.logger.error("Provider does not support id token verification",{provider:e.body.provider}),new L.APIError("NOT_FOUND",{message:"Provider does not support id token verification"});let{token:i,nonce:s}=e.body.idToken;if(!await o.verifyIdToken(i,s))throw e.context.logger.error("Invalid id token",{provider:e.body.provider}),new L.APIError("UNAUTHORIZED",{message:"Invalid id token"});let d=await o.getUserInfo({idToken:i,accessToken:e.body.idToken.accessToken,refreshToken:e.body.idToken.refreshToken});if(!d||!d?.user)throw e.context.logger.error("Failed to get user info",{provider:e.body.provider}),new L.APIError("UNAUTHORIZED",{message:"Failed to get user info"});if(!d.user.email)throw e.context.logger.error("User email not found",{provider:e.body.provider}),new L.APIError("UNAUTHORIZED",{message:"User email not found"});let u=await Ue(e,{userInfo:{email:d.user.email,id:d.user.id,name:d.user.name||"",image:d.user.image,emailVerified:d.user.emailVerified||!1},account:{providerId:o.id,accountId:d.user.id,accessToken:e.body.idToken.accessToken}});if(u.error)throw new L.APIError("UNAUTHORIZED",{message:u.error});return await w(e,u.data),e.json({session:u.data.session,user:u.data.user,url:`${e.body.callbackURL||e.query?.currentURL||e.context.options.baseURL}`,redirect:!0})}let{codeVerifier:r,state:t}=await ve(e),n=await o.createAuthorizationURL({state:t,codeVerifier:r,redirectURI:`${e.context.baseURL}/callback/${o.id}`});return e.json({url:n.toString(),redirect:!0})}),qo=c("/sign-in/email",{method:"POST",body:_.z.object({email:_.z.string(),password:_.z.string(),callbackURL:_.z.string().optional(),rememberMe:_.z.boolean().default(!1).optional()})},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 L.APIError("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:o,password:r}=e.body;if(!_.z.string().email().safeParse(o).success)throw new L.APIError("BAD_REQUEST",{message:"Invalid email"});let n=await e.context.internalAdapter.findUserByEmail(o,{includeAccounts:!0});if(!n)throw await e.context.password.hash(r),e.context.logger.error("User not found",{email:o}),new L.APIError("UNAUTHORIZED",{message:"Invalid email or password"});let i=n.accounts.find(u=>u.providerId==="credential");if(!i)throw e.context.logger.error("Credential account not found",{email:o}),new L.APIError("UNAUTHORIZED",{message:"Invalid email or password"});let s=i?.password;if(!s)throw e.context.logger.error("Password not found",{email:o}),new L.APIError("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(s,r))throw e.context.logger.error("Invalid password"),new L.APIError("UNAUTHORIZED",{message:"Invalid email or password"});if(e.context.options?.emailAndPassword?.requireEmailVerification&&!n.user.emailVerified){if(!e.context.options?.emailVerification?.sendVerificationEmail)throw y.error("Email verification is required but no email verification handler is provided"),new L.APIError("INTERNAL_SERVER_ERROR",{message:"Email is not verified."});let u=await ae(e.context.secret,n.user.email),l=`${e.context.baseURL}/verify-email?token=${u}`;throw await e.context.options.emailVerification.sendVerificationEmail({user:n.user,url:l,token:u},e.request),e.context.logger.error("Email not verified",{email:o}),new L.APIError("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.rememberMe===!1);if(!d)throw e.context.logger.error("Failed to create session"),new L.APIError("UNAUTHORIZED",{message:"Failed to create session"});return await w(e,{session:d,user:n.user},e.body.rememberMe===!1),e.json({user:n.user,session:d,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});var je=require("zod");var Mo=c("/callback/:id",{method:["GET","POST"],query:je.z.object({state:je.z.string(),code:je.z.string().optional(),error:je.z.string().optional()}),metadata:ge},async e=>{if(!e.query.code)throw e.redirect(`${e.context.baseURL}/error?error=${e.query.error||"no_code"}`);let o=e.context.socialProviders.find(k=>k.id===e.params.id);if(!o)throw e.context.logger.error("Oauth provider with id",e.params.id,"not found"),e.redirect(`${e.context.baseURL}/error?error=oauth_provider_not_found`);let{codeVerifier:r,callbackURL:t,link:n,errorURL:i}=await tt(e),s;try{s=await o.validateAuthorizationCode({code:e.query.code,codeVerifier:r,redirectURI:`${e.context.baseURL}/callback/${o.id}`})}catch(k){throw e.context.logger.error(k),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let a=await o.getUserInfo(s).then(k=>k?.user),u={id:B(),...a};function l(k){let E=i||t||`${e.context.baseURL}/error`;throw E.includes("?")?E=`${E}&error=${k}`:E=`${E}?error=${k}`,e.redirect(E)}if(!a)return y.error("Unable to get user info"),l("unable_to_get_user_info");if(!u.email)return e.context.logger.error("Provider did not return email. This could be due to misconfiguration in the provider settings."),l("email_not_found");if(!t)throw y.error("No callback URL found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(n){if(n.email!==u.email.toLowerCase())return l("email_doesn't_match");if(!await e.context.internalAdapter.createAccount({userId:n.userId,providerId:o.id,accountId:a.id}))return l("unable_to_link_account");let E;try{E=new URL(t).toString()}catch{E=t}throw e.redirect(E)}let m=await Ue(e,{userInfo:{email:u.email,id:u.id,name:u.name||"",image:u.image,emailVerified:u.emailVerified||!1},account:{providerId:o.id,accountId:a.id,accessToken:s.accessToken,refreshToken:s.refreshToken,expiresAt:s.accessTokenExpiresAt},callbackURL:t});if(m.error)return l(m.error.split(" ").join("_"));let{session:f,user:p}=m.data;await w(e,{session:f,user:p});let h;try{h=new URL(t).toString()}catch{h=t}throw e.redirect(h)});var od=require("zod");var Ir=require("better-call"),$o=c("/sign-out",{method:"POST",requireHeaders:!0},async e=>{let o=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!o)throw new Ir.APIError("BAD_REQUEST",{message:"Session not found"});return await e.context.internalAdapter.deleteSession(o),J(e),e.json({success:!0})});var Q=require("zod");var Ne=require("better-call");function Tr(e,o,r){let t=o?new URL(o,e.baseURL):new URL(`${e.baseURL}/error`);return r&&Object.entries(r).forEach(([n,i])=>t.searchParams.set(n,i)),t.href}function en(e,o,r){let t=new URL(o,e.baseURL);return r&&Object.entries(r).forEach(([n,i])=>t.searchParams.set(n,i)),t.href}var Qo=c("/forget-password",{method:"POST",body:Q.z.object({email:Q.z.string().email(),redirectTo:Q.z.string()})},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 Ne.APIError("BAD_REQUEST",{message:"Reset password isn't enabled"});let{email:o,redirectTo:r}=e.body,t=await e.context.internalAdapter.findUserByEmail(o,{includeAccounts:!0});if(!t)return e.context.logger.error("Reset Password: User not found",{email:o}),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:t.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({user:t.user,url:a},e.request),e.json({status:!0})}),Ho=c("/reset-password/:token",{method:"GET",query:Q.z.object({callbackURL:Q.z.string()})},async e=>{let{token:o}=e.params,{callbackURL:r}=e.query;if(!o||!r)throw e.redirect(Tr(e.context,r,{error:"INVALID_TOKEN"}));let t=await e.context.internalAdapter.findVerificationValue(`reset-password:${o}`);throw!t||t.expiresAt<new Date?e.redirect(Tr(e.context,r,{error:"INVALID_TOKEN"})):e.redirect(en(e.context,r,{token:o}))}),Wo=c("/reset-password",{query:Q.z.optional(Q.z.object({token:Q.z.string().optional(),currentURL:Q.z.string().optional()})),method:"POST",body:Q.z.object({newPassword:Q.z.string()})},async e=>{let o=e.query?.token||(e.query?.currentURL?new URL(e.query.currentURL).searchParams.get("token"):"");if(!o)throw new Ne.APIError("BAD_REQUEST",{message:"Token not found"});let{newPassword:r}=e.body,t=`reset-password:${o}`,n=await e.context.internalAdapter.findVerificationValue(t);if(!n||n.expiresAt<new Date)throw new Ne.APIError("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 Ne.APIError("BAD_REQUEST",{message:"Failed to update password"});return e.json({status:!0})});var V=require("zod");var j=require("better-call");var Go=c("/change-password",{method:"POST",body:V.z.object({newPassword:V.z.string(),currentPassword:V.z.string(),revokeOtherSessions:V.z.boolean().optional()}),use:[b]},async e=>{let{newPassword:o,currentPassword:r,revokeOtherSessions:t}=e.body,n=e.context.session,i=e.context.password.config.minPasswordLength;if(o.length<i)throw e.context.logger.error("Password is too short"),new j.APIError("BAD_REQUEST",{message:"Password is too short"});let s=e.context.password.config.maxPasswordLength;if(o.length>s)throw e.context.logger.error("Password is too long"),new j.APIError("BAD_REQUEST",{message:"Password too long"});let d=(await e.context.internalAdapter.findAccounts(n.user.id)).find(m=>m.providerId==="credential"&&m.password);if(!d||!d.password)throw new j.APIError("BAD_REQUEST",{message:"User does not have a password"});let u=await e.context.password.hash(o);if(!await e.context.password.verify(d.password,r))throw new j.APIError("BAD_REQUEST",{message:"Incorrect password"});if(await e.context.internalAdapter.updateAccount(d.id,{password:u}),t){await e.context.internalAdapter.deleteSessions(n.user.id);let m=await e.context.internalAdapter.createSession(n.user.id,e.headers);if(!m)throw new j.APIError("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});await w(e,{session:m,user:n.user})}return e.json(n.user)}),Jo=c("/set-password",{method:"POST",body:V.z.object({newPassword:V.z.string()}),metadata:{SERVER_ONLY:!0},use:[b]},async e=>{let{newPassword:o}=e.body,r=e.context.session,t=e.context.password.config.minPasswordLength;if(o.length<t)throw e.context.logger.error("Password is too short"),new j.APIError("BAD_REQUEST",{message:"Password is too short"});let n=e.context.password.config.maxPasswordLength;if(o.length>n)throw e.context.logger.error("Password is too long"),new j.APIError("BAD_REQUEST",{message:"Password too long"});let s=(await e.context.internalAdapter.findAccounts(r.user.id)).find(d=>d.providerId==="credential"&&d.password),a=await e.context.password.hash(o);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 j.APIError("BAD_REQUEST",{message:"user already has a password"})}),Ko=c("/delete-user",{method:"POST",body:V.z.object({password:V.z.string()}),use:[b]},async e=>{let{password:o}=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 j.APIError("BAD_REQUEST",{message:"User does not have a password"});if(!await e.context.password.verify(n.password,o))throw new j.APIError("BAD_REQUEST",{message:"Incorrect password"});return await e.context.internalAdapter.deleteUser(r.user.id),await e.context.internalAdapter.deleteSessions(r.user.id),J(e),e.json(null)}),Zo=c("/change-email",{method:"POST",query:V.z.object({currentURL:V.z.string().optional()}).optional(),body:V.z.object({newEmail:V.z.string().email(),callbackURL:V.z.string().optional()}),use:[b]},async e=>{if(!e.context.options.user?.changeEmail?.enabled)throw e.context.logger.error("Change email is disabled."),new j.APIError("BAD_REQUEST",{message:"Change email is disabled"});if(e.body.newEmail===e.context.session.user.email)throw e.context.logger.error("Email is the same"),new j.APIError("BAD_REQUEST",{message:"Email is the same"});if(await e.context.internalAdapter.findUserByEmail(e.body.newEmail))throw e.context.logger.error("Email already exists"),new j.APIError("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 j.APIError("BAD_REQUEST",{message:"Verification email isn't enabled"});let r=await ae(e.context.secret,e.context.session.user.email,e.body.newEmail),t=`${e.context.baseURL}/verify-email?token=${r}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.user.changeEmail.sendChangeEmailVerification({user:e.context.session.user,newEmail:e.body.newEmail,url:t,token:r},e.request),e.json({user:null,status:!0})});var Ie=require("zod");var kt=require("better-call");var Yo=c("/list-accounts",{method:"GET",use:[b]},async e=>{let o=e.context.session,r=await e.context.internalAdapter.findAccounts(o.user.id);return e.json(r.map(t=>({id:t.id,provider:t.providerId})))}),Xo=c("/link-social",{method:"POST",requireHeaders:!0,query:Ie.z.object({currentURL:Ie.z.string().optional()}).optional(),body:Ie.z.object({callbackURL:Ie.z.string().optional(),provider:Ie.z.enum(rt)}),use:[b]},async e=>{let o=e.context.session;if((await e.context.internalAdapter.findAccounts(o.user.id)).find(a=>a.providerId===e.body.provider))throw new kt.APIError("BAD_REQUEST",{message:"Social Account is already linked."});let n=e.context.socialProviders.find(a=>a.id===e.body.provider);if(!n)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new kt.APIError("NOT_FOUND",{message:"Provider not found"});let i=await ve(e,{userId:o.user.id,email:o.user.email}),s=await n.createAuthorizationURL({state:i.state,codeVerifier:i.codeVerifier,redirectURI:`${e.context.baseURL}/callback/${n.id}`});return e.json({url:s.toString(),redirect:!0})});var Sr=(e,o)=>{let r={};for(let[t,n]of Object.entries(e))r[t]=i=>n({...i,context:{...o,...i.context}}),r[t].path=n.path,r[t].method=n.method,r[t].options=n.options,r[t].headers=n.headers;return r};var Te=class extends Error{path;constructor(o,r){super(o),this.path=r}},nt=class{constructor(o){this.s=o;this.statements=o}statements;newRole(o){return new it(o)}},it=class e{statements;constructor(o){this.statements=o}authorize(o,r){for(let[t,n]of Object.entries(o)){let i=this.statements[t];if(!i)return{success:!1,error:`You are not allowed to access resource: ${t}`};let s=r==="OR"?n.some(a=>i.includes(a)):n.every(a=>i.includes(a));return s?{success:s}:{success:!1,error:`unauthorized to access resource "${t}"`}}return{success:!1,error:"Not authorized"}}static fromString(o){let r=JSON.parse(o);if(typeof r!="object")throw new Te("statements is not an object",".");for(let[t,n]of Object.entries(r)){if(typeof t!="string")throw new Te("invalid resource identifier",t);if(!Array.isArray(n))throw new Te("actions is not an array",t);for(let i=0;i<n.length;i++)if(typeof n[i]!="string")throw new Te("action is not a string",`${t}[${i}]`)}return new e(r)}toString(){return JSON.stringify(this.statements)}};var tn=e=>new nt(e),rn={organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]},Ot=tn(rn),on=Ot.newRole({organization:["update"],invitation:["create","cancel"],member:["create","update","delete"]}),nn=Ot.newRole({organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]}),sn=Ot.newRole({organization:[],member:[],invitation:[]}),Pr={admin:on,owner:nn,member:sn};var C=(e,o)=>{let r=e.adapter;return{findOrganizationBySlug:async t=>await r.findOne({model:"organization",where:[{field:"slug",value:t}]}),createOrganization:async t=>{let n=await r.create({model:"organization",data:{...t.organization,metadata:t.organization.metadata?JSON.stringify(t.organization.metadata):void 0}}),i=await r.create({model:"member",data:{id:B(),organizationId:n.id,userId:t.user.id,createdAt:new Date,role:o?.creatorRole||"owner"}});return{...n,metadata:n.metadata?JSON.parse(n.metadata):void 0,members:[{...i,user:{id:t.user.id,name:t.user.name,email:t.user.email,image:t.user.image}}]}},findMemberByEmail:async t=>{let n=await r.findOne({model:e.tables.user.tableName,where:[{field:"email",value:t.email}]});if(!n)return null;let i=await r.findOne({model:"member",where:[{field:"organizationId",value:t.organizationId},{field:"userId",value:n.id}]});return i?{...i,user:{id:n.id,name:n.name,email:n.email,image:n.image}}:null},findMemberByOrgId:async t=>{let[n,i]=await Promise.all([await r.findOne({model:"member",where:[{field:"userId",value:t.userId},{field:"organizationId",value:t.organizationId}]}),await r.findOne({model:e.tables.user.tableName,where:[{field:"id",value:t.userId}]})]);return!i||!n?null:{...n,user:{id:i.id,name:i.name,email:i.email,image:i.image}}},findMemberById:async t=>{let n=await r.findOne({model:"member",where:[{field:"id",value:t}]});if(!n)return null;let i=await r.findOne({model:e.tables.user.tableName,where:[{field:"id",value:n.userId}]});return i?{...n,user:{id:i.id,name:i.name,email:i.email,image:i.image}}:null},createMember:async t=>await r.create({model:"member",data:t}),updateMember:async(t,n)=>await r.update({model:"member",where:[{field:"id",value:t}],update:{role:n}}),deleteMember:async t=>await r.delete({model:"member",where:[{field:"id",value:t}]}),updateOrganization:async(t,n)=>await r.update({model:"organization",where:[{field:"id",value:t}],update:n}),deleteOrganization:async t=>(await r.delete({model:"member",where:[{field:"organizationId",value:t}]}),await r.delete({model:"invitation",where:[{field:"organizationId",value:t}]}),await r.delete({model:"organization",where:[{field:"id",value:t}]}),t),setActiveOrganization:async(t,n)=>await r.update({model:e.tables.session.tableName,where:[{field:"id",value:t}],update:{activeOrganizationId:n}}),findOrganizationById:async t=>await r.findOne({model:"organization",where:[{field:"id",value:t}]}),findFullOrganization:async(t,n)=>{let[i,s,a]=await Promise.all([r.findOne({model:"organization",where:[{field:"id",value:t}]}),r.findMany({model:"invitation",where:[{field:"organizationId",value:t}]}),r.findMany({model:"member",where:[{field:"organizationId",value:t}]})]);if(!i)return null;let d=a.map(f=>f.userId),u=await r.findMany({model:e.tables.user.tableName,where:[{field:"id",value:d,operator:"in"}]}),l=new Map(u.map(f=>[f.id,f])),m=a.map(f=>{let p=l.get(f.userId);if(!p)throw new W("Unexpected error: User not found for member");return{...f,user:{id:p.id,name:p.name,email:p.email,image:p.image}}});return{...i,invitations:s,members:m}},listOrganizations:async t=>{let n=await r.findMany({model:"member",where:[{field:"userId",value:t}]});if(!n||n.length===0)return[];let i=n.map(a=>a.organizationId);return await r.findMany({model:"organization",where:[{field:"id",value:i,operator:"in"}]})},createInvitation:async({invitation:t,user:n})=>{let s=P(o?.invitationExpiresIn||1728e5);return await r.create({model:"invitation",data:{id:B(),email:t.email,role:t.role,organizationId:t.organizationId,status:"pending",expiresAt:s,inviterId:n.id}})},findInvitationById:async t=>await r.findOne({model:"invitation",where:[{field:"id",value:t}]}),findPendingInvitation:async t=>(await r.findMany({model:"invitation",where:[{field:"email",value:t.email},{field:"organizationId",value:t.organizationId},{field:"status",value:"pending"}]})).filter(i=>new Date(i.expiresAt)>new Date),updateInvitation:async t=>await r.update({model:"invitation",where:[{field:"id",value:t.invitationId}],update:{status:t.status}})}};var Zd=require("better-call");var x=S(async e=>({})),D=S({use:[b]},async e=>({session:e.context.session}));var F=require("zod");var R=require("zod"),st=R.z.enum(["admin","member","owner"]),an=R.z.enum(["pending","accepted","rejected","canceled"]).default("pending"),tu=R.z.object({id:R.z.string(),name:R.z.string(),slug:R.z.string(),logo:R.z.string().nullish(),metadata:R.z.record(R.z.string()).or(R.z.string().transform(e=>JSON.parse(e))).nullish(),createdAt:R.z.date()}),ru=R.z.object({id:R.z.string(),organizationId:R.z.string(),userId:R.z.string(),role:st,createdAt:R.z.date()}),ou=R.z.object({id:R.z.string(),organizationId:R.z.string(),email:R.z.string(),role:st,status:an,inviterId:R.z.string(),expiresAt:R.z.date()});var T=require("better-call"),_r=c("/organization/invite-member",{method:"POST",use:[x,D],body:F.z.object({email:F.z.string(),role:st,organizationId:F.z.string().optional(),resend:F.z.boolean().optional()})},async e=>{if(!e.context.orgOptions.sendInvitationEmail)throw y.warn("Invitation email is not enabled. Pass `sendInvitationEmail` to the plugin options to enable it."),new T.APIError("BAD_REQUEST",{message:"Invitation email is not enabled"});let o=e.context.session,r=e.body.organizationId||o.session.activeOrganizationId;if(!r)throw new T.APIError("BAD_REQUEST",{message:"Organization not found"});let t=C(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)throw new T.APIError("BAD_REQUEST",{message:"Member not found!"});let i=e.context.roles[n.role];if(!i)throw new T.APIError("BAD_REQUEST",{message:"Role not found!"});if(i.authorize({invitation:["create"]}).error)throw new T.APIError("FORBIDDEN",{message:"You are not allowed to invite members"});if(await t.findMemberByEmail({email:e.body.email,organizationId:r}))throw new T.APIError("BAD_REQUEST",{message:"User is already a member of this organization"});if((await t.findPendingInvitation({email:e.body.email,organizationId:r})).length&&!e.body.resend)throw new T.APIError("BAD_REQUEST",{message:"User is already invited to this organization"});let u=await t.createInvitation({invitation:{role:e.body.role,email:e.body.email,organizationId:r},user:o.user}),l=await t.findOrganizationById(r);if(!l)throw new T.APIError("BAD_REQUEST",{message:"Organization not found"});return await e.context.orgOptions.sendInvitationEmail?.({id:u.id,role:u.role,email:u.email,organization:l,inviter:{...n,user:o.user}},e.request),e.json(u)}),Cr=c("/organization/accept-invitation",{method:"POST",body:F.z.object({invitationId:F.z.string()}),use:[x,D]},async e=>{let o=e.context.session,r=C(e.context,e.context.orgOptions),t=await r.findInvitationById(e.body.invitationId);if(!t||t.expiresAt<new Date||t.status!=="pending")throw new T.APIError("BAD_REQUEST",{message:"Invitation not found!"});if(t.email!==o.user.email)throw new T.APIError("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.updateInvitation({invitationId:e.body.invitationId,status:"accepted"}),i=await r.createMember({id:B(),organizationId:t.organizationId,userId:o.user.id,role:t.role,createdAt:new Date});return await r.setActiveOrganization(o.session.id,t.organizationId),n?e.json({invitation:n,member:i}):e.json(null,{status:400,body:{message:"Invitation not found!"}})}),zr=c("/organization/reject-invitation",{method:"POST",body:F.z.object({invitationId:F.z.string()}),use:[x,D]},async e=>{let o=e.context.session,r=C(e.context,e.context.orgOptions),t=await r.findInvitationById(e.body.invitationId);if(!t||t.expiresAt<new Date||t.status!=="pending")throw new T.APIError("BAD_REQUEST",{message:"Invitation not found!"});if(t.email!==o.user.email)throw new T.APIError("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.updateInvitation({invitationId:e.body.invitationId,status:"rejected"});return e.json({invitation:n,member:null})}),Br=c("/organization/cancel-invitation",{method:"POST",body:F.z.object({invitationId:F.z.string()}),use:[x,D]},async e=>{let o=e.context.session,r=C(e.context,e.context.orgOptions),t=await r.findInvitationById(e.body.invitationId);if(!t)throw new T.APIError("BAD_REQUEST",{message:"Invitation not found!"});let n=await r.findMemberByOrgId({userId:o.user.id,organizationId:t.organizationId});if(!n)throw new T.APIError("BAD_REQUEST",{message:"Member not found!"});if(e.context.roles[n.role].authorize({invitation:["cancel"]}).error)throw new T.APIError("FORBIDDEN",{message:"You are not allowed to cancel this invitation"});let s=await r.updateInvitation({invitationId:e.body.invitationId,status:"canceled"});return e.json(s)}),xr=c("/organization/get-invitation",{method:"GET",use:[x],requireHeaders:!0,query:F.z.object({id:F.z.string()})},async e=>{let o=await z(e);if(!o)throw new T.APIError("UNAUTHORIZED",{message:"Not authenticated"});let r=C(e.context,e.context.orgOptions),t=await r.findInvitationById(e.query.id);if(!t||t.status!=="pending"||t.expiresAt<new Date)throw new T.APIError("BAD_REQUEST",{message:"Invitation not found!"});if(t.email!==o.user.email)throw new T.APIError("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.findOrganizationById(t.organizationId);if(!n)throw new T.APIError("BAD_REQUEST",{message:"Organization not found"});let i=await r.findMemberByOrgId({userId:t.inviterId,organizationId:t.organizationId});if(!i)throw new T.APIError("BAD_REQUEST",{message:"Inviter is no longer a member of the organization"});return e.json({...t,organizationName:n.name,organizationSlug:n.slug,inviterEmail:i.user.email})});var de=require("zod");var Se=require("better-call"),Lr=c("/organization/remove-member",{method:"POST",body:de.z.object({memberIdOrEmail:de.z.string(),organizationId:de.z.string().optional()}),use:[x,D]},async e=>{let o=e.context.session,r=e.body.organizationId||o.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"No active organization found!"}});let t=C(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)throw new Se.APIError("BAD_REQUEST",{message:"Member not found!"});let i=e.context.roles[n.role];if(!i)throw new Se.APIError("BAD_REQUEST",{message:"Role not found!"});let s=o.user.email===e.body.memberIdOrEmail||n.id===e.body.memberIdOrEmail;if(s&&n.role===(e.context.orgOptions?.creatorRole||"owner"))throw new Se.APIError("BAD_REQUEST",{message:"You cannot leave the organization as the owner"});if(!(s||i.authorize({member:["delete"]}).success))throw new Se.APIError("UNAUTHORIZED",{message:"You are not allowed to delete this member"});let u=null;if(e.body.memberIdOrEmail.includes("@")?u=await t.findMemberByEmail({email:e.body.memberIdOrEmail,organizationId:r}):u=await t.findMemberById(e.body.memberIdOrEmail),u?.organizationId!==r)throw new Se.APIError("BAD_REQUEST",{message:"Member not found!"});return await t.deleteMember(u.id),o.user.id===u.userId&&o.session.activeOrganizationId===u.organizationId&&await t.setActiveOrganization(o.session.id,null),e.json({member:u})}),Dr=c("/organization/update-member-role",{method:"POST",body:de.z.object({role:de.z.enum(["admin","member","owner"]),memberId:de.z.string(),organizationId:de.z.string().optional()}),use:[x,D]},async e=>{let o=e.context.session,r=e.body.organizationId||o.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"No active organization found!"}});let t=C(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)return e.json(null,{status:400,body:{message:"Member not found!"}});let i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({member:["update"]}).error||e.body.role==="owner"&&n.role!=="owner")return e.json(null,{body:{message:"You are not allowed to update this member"},status:403});let a=await t.updateMember(e.body.memberId,e.body.role);return a?e.json(a):e.json(null,{status:400,body:{message:"Member not found!"}})}),jr=c("/organization/get-active-member",{method:"GET",use:[x,D]},async e=>{let o=e.context.session,r=o.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"No active organization found!"}});let n=await C(e.context,e.context.orgOptions).findMemberByOrgId({userId:o.user.id,organizationId:r});return n?e.json(n):e.json(null,{status:400,body:{message:"Member not found!"}})});var I=require("zod");var ue=require("better-call"),Nr=c("/organization/create",{method:"POST",body:I.z.object({name:I.z.string(),slug:I.z.string(),userId:I.z.string().optional(),logo:I.z.string().optional(),metadata:I.z.record(I.z.string(),I.z.any()).optional()}),use:[x,D]},async e=>{let o=e.context.session.user;if(!o)return e.json(null,{status:401});let r=e.context.orgOptions;if(!(typeof r?.allowUserToCreateOrganization=="function"?await r.allowUserToCreateOrganization(o):r?.allowUserToCreateOrganization===void 0?!0:r.allowUserToCreateOrganization))throw new ue.APIError("FORBIDDEN",{message:"You are not allowed to create an organization"});let n=C(e.context,r),i=await n.listOrganizations(o.id);if(typeof r.organizationLimit=="number"?i.length>=r.organizationLimit:typeof r.organizationLimit=="function"?await r.organizationLimit(o):!1)throw new ue.APIError("FORBIDDEN",{message:"You have reached the organization limit"});if(await n.findOrganizationBySlug(e.body.slug))throw new ue.APIError("BAD_REQUEST",{message:"Organization with this slug already exists"});let d=await n.createOrganization({organization:{id:B(),slug:e.body.slug,name:e.body.name,logo:e.body.logo,createdAt:new Date,metadata:e.body.metadata},user:o});return e.json(d)}),Vr=c("/organization/update",{method:"POST",body:I.z.object({data:I.z.object({name:I.z.string().optional(),slug:I.z.string().optional(),logo:I.z.string().optional()}).partial(),organizationId:I.z.string().optional()}),requireHeaders:!0,use:[x]},async e=>{let o=await e.context.getSession(e);if(!o)throw new ue.APIError("UNAUTHORIZED",{message:"User not found"});let r=e.body.organizationId||o.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"Organization id not found!"}});let t=C(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)return e.json(null,{status:400,body:{message:"User is not a member of this organization!"}});let i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({organization:["update"]}).error)return e.json(null,{body:{message:"You are not allowed to update this organization"},status:403});let a=await t.updateOrganization(r,e.body.data);return e.json(a)}),Fr=c("/organization/delete",{method:"POST",body:I.z.object({organizationId:I.z.string()}),requireHeaders:!0,use:[x]},async e=>{let o=await e.context.getSession(e);if(!o)return e.json(null,{status:401});let r=e.body.organizationId;if(!r)return e.json(null,{status:400,body:{message:"Organization id not found!"}});let t=C(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)return e.json(null,{status:400,body:{message:"User is not a member of this organization!"}});let i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({organization:["delete"]}).error)throw new ue.APIError("FORBIDDEN",{message:"You are not allowed to delete this organization"});return r===o.session.activeOrganizationId&&await t.setActiveOrganization(o.session.id,null),await t.deleteOrganization(r),e.json(r)}),qr=c("/organization/get-full-organization",{method:"GET",query:I.z.optional(I.z.object({organizationId:I.z.string().optional()})),requireHeaders:!0,use:[x,D]},async e=>{let o=e.context.session,r=e.query?.organizationId||o.session.activeOrganizationId;if(!r)return e.json(null,{status:200});let n=await C(e.context,e.context.orgOptions).findFullOrganization(r,e.context.db||void 0);if(!n)throw new ue.APIError("BAD_REQUEST",{message:"Organization not found"});return e.json(n)}),Mr=c("/organization/set-active",{method:"POST",body:I.z.object({organizationId:I.z.string().nullable().optional()}),use:[D,x]},async e=>{let o=C(e.context,e.context.orgOptions),r=e.context.session,t=e.body.organizationId;if(t===null)return r.session.activeOrganizationId&&await o.setActiveOrganization(r.session.id,null),e.json(null);if(!t){let s=r.session.activeOrganizationId;if(!s)return e.json(null);t=s}if(!await o.findMemberByOrgId({userId:r.user.id,organizationId:t}))throw await o.setActiveOrganization(r.session.id,null),new ue.APIError("FORBIDDEN",{message:"You are not a member of this organization"});await o.setActiveOrganization(r.session.id,t);let i=await o.findFullOrganization(t,e.context.db||void 0);return e.json(i)}),$r=c("/organization/list",{method:"GET",use:[x,D]},async e=>{let r=await C(e.context,e.context.orgOptions).listOrganizations(e.context.session.user.id);return e.json(r)});var dn=e=>{let o={createOrganization:Nr,updateOrganization:Vr,deleteOrganization:Fr,setActiveOrganization:Mr,getFullOrganization:qr,listOrganization:$r,createInvitation:_r,cancelInvitation:Br,acceptInvitation:Cr,getInvitation:xr,rejectInvitation:zr,removeMember:Lr,updateMemberRole:Dr,getActiveMember:jr},r={...Pr,...e?.roles};return{id:"organization",endpoints:{...Sr(o,{orgOptions:e||{},roles:r,getSession:async n=>await z(n)}),hasPermission:c("/organization/has-permission",{method:"POST",requireHeaders:!0,body:Pe.z.object({permission:Pe.z.record(Pe.z.string(),Pe.z.array(Pe.z.string()))}),use:[D]},async n=>{if(!n.context.session.session.activeOrganizationId)throw new vt.APIError("BAD_REQUEST",{message:"No active organization"});let s=await C(n.context).findMemberByOrgId({userId:n.context.session.user.id,organizationId:n.context.session.session.activeOrganizationId||""});if(!s)throw new vt.APIError("UNAUTHORIZED",{message:"You are not a member of this organization"});let d=r[s.role].authorize(n.body.permission);return d.error?n.json({error:d.error,success:!1},{status:403}):n.json({error:null,success:!0})})},schema:{session:{fields:{activeOrganizationId:{type:"string",required:!1,fieldName:e?.schema?.session?.fields?.activeOrganizationId}}},organization:{fields:{name:{type:"string",required:!0,fieldName:e?.schema?.organization?.fields?.name},slug:{type:"string",unique:!0,fieldName:e?.schema?.organization?.fields?.slug},logo:{type:"string",required:!1,fieldName:e?.schema?.organization?.fields?.logo},createdAt:{type:"date",required:!0,fieldName:e?.schema?.organization?.fields?.createdAt},metadata:{type:"string",required:!1,fieldName:e?.schema?.organization?.fields?.metadata}}},member:{fields:{organizationId:{type:"string",required:!0,references:{model:"organization",field:"id"},fieldName:e?.schema?.member?.fields?.organizationId},userId:{type:"string",required:!0,fieldName:e?.schema?.member?.fields?.userId},role:{type:"string",required:!0,defaultValue:"member",fieldName:e?.schema?.member?.fields?.role},createdAt:{type:"date",required:!0,fieldName:e?.schema?.member?.fields?.createdAt}}},invitation:{fields:{organizationId:{type:"string",required:!0,references:{model:"organization",field:"id"},fieldName:e?.schema?.invitation?.fields?.organizationId},email:{type:"string",required:!0,fieldName:e?.schema?.invitation?.fields?.email},role:{type:"string",required:!1,fieldName:e?.schema?.invitation?.fields?.role},status:{type:"string",required:!0,defaultValue:"pending",fieldName:e?.schema?.invitation?.fields?.status},expiresAt:{type:"date",required:!0,fieldName:e?.schema?.invitation?.fields?.expiresAt},inviterId:{type:"string",references:{model:"user",field:"id"},fieldName:e?.schema?.invitation?.fields?.inviterId,required:!0}}}},$Infer:{Organization:{},Invitation:{},Member:{},ActiveOrganization:{}}}};var Rt=Nt(require("uncrypto"),1);function un(e){return e.toString(2).padStart(8,"0")}function cn(e){return[...e].map(o=>un(o)).join("")}function Qr(e){return parseInt(cn(e),2)}function ln(e){if(e<0||!Number.isInteger(e))throw new Error("Argument 'max' must be an integer greater than or equal to 0");let o=(e-1).toString(2).length,r=o%8,t=new Uint8Array(Math.ceil(o/8));Rt.default.getRandomValues(t),r!==0&&(t[0]&=(1<<r)-1);let n=Qr(t);for(;n>=e;)Rt.default.getRandomValues(t),r!==0&&(t[0]&=(1<<r)-1),n=Qr(t);return n}function q(e,o){let r="";for(let t=0;t<e;t++)r+=o[ln(o.length)];return r}function M(...e){let o=new Set(e),r="";for(let t of o)t==="a-z"?r+="abcdefghijklmnopqrstuvwxyz":t==="A-Z"?r+="ABCDEFGHIJKLMNOPQRSTUVWXYZ":t==="0-9"?r+="0123456789":r+=t;return r}var $e=require("zod");var Ut=require("@noble/ciphers/chacha"),_e=require("@noble/ciphers/utils"),It=require("@noble/ciphers/webcrypto"),Tt=require("oslo/crypto"),Et=Nt(require("uncrypto"),1);var Hr=require("oslo/encoding");var mn=require("@noble/hashes/scrypt"),pn=require("uncrypto");async function Ve(e,o){let r=new TextEncoder,t={name:"HMAC",hash:"SHA-256"},n=await Et.default.subtle.importKey("raw",r.encode(e),t,!1,["sign","verify"]),i=await Et.default.subtle.sign(t.name,n,r.encode(o));return btoa(String.fromCharCode(...new Uint8Array(i)))}var re=async({key:e,data:o})=>{let r=await(0,Tt.sha256)(new TextEncoder().encode(e)),t=(0,_e.utf8ToBytes)(o),n=(0,It.managedNonce)(Ut.xchacha20poly1305)(new Uint8Array(r));return(0,_e.bytesToHex)(n.encrypt(t))},ce=async({key:e,data:o})=>{let r=await(0,Tt.sha256)(new TextEncoder().encode(e)),t=(0,_e.hexToBytes)(o),n=(0,It.managedNonce)(Ut.xchacha20poly1305)(new Uint8Array(r));return new TextDecoder().decode(n.decrypt(t))};var K=require("zod");var Ce=require("better-call");var at="two_factor";var dt="trust_device";var St=require("zod");var we=S({body:St.z.object({trustDevice:St.z.boolean().optional()})},async e=>{let o=await z(e);if(!o){let r=e.context.createAuthCookie(at),t=await e.getSignedCookie(r.name,e.context.secret);if(!t)throw new Ce.APIError("UNAUTHORIZED",{message:"invalid two factor cookie"});let n=await e.context.internalAdapter.findUserById(t);if(!n)throw new Ce.APIError("UNAUTHORIZED",{message:"invalid two factor cookie"});let i=await e.context.internalAdapter.createSession(t,e.request);if(!i)throw new Ce.APIError("INTERNAL_SERVER_ERROR",{message:"failed to create session"});return{valid:async()=>{if(await w(e,{session:i,user:n}),e.body.trustDevice){let s=e.context.createAuthCookie(dt,{maxAge:2592e3}),a=await Ve(e.context.secret,`${n.id}!${i.id}`);await e.setSignedCookie(s.name,`${a}!${i.id}`,e.context.secret,s.attributes)}return e.json({session:i,user:n})},invalid:async()=>{throw new Ce.APIError("UNAUTHORIZED",{message:"invalid two factor authentication"})},session:{id:i.id,userId:i.userId,expiresAt:i.expiresAt,user:n}}}return{valid:async()=>e.json({session:o,user:o.user}),invalid:async()=>{throw new Ce.APIError("UNAUTHORIZED",{message:"invalid two factor authentication"})},session:o}});var ze=require("better-call");function fn(e){return Array.from({length:e?.amount??10}).fill(null).map(()=>q(e?.length??10,M("a-z","0-9"))).map(o=>`${o.slice(0,5)}-${o.slice(5)}`)}async function Pt(e,o){let r=e,t=o?.customBackupCodesGenerate?o.customBackupCodesGenerate():fn(),n=await re({data:JSON.stringify(t),key:r});return{backupCodes:t,encryptedBackupCodes:n}}async function gn(e,o){let r=await Wr(e.backupCodes,o);return r?{status:r.includes(e.code),updated:r.filter(t=>t!==e.code)}:{status:!1,updated:null}}async function Wr(e,o){let r=Buffer.from(await ce({key:o,data:e})).toString("utf-8"),t=JSON.parse(r),n=K.z.array(K.z.string()).safeParse(t);return n.success?n.data:null}var Gr=(e,o)=>({id:"backup_code",endpoints:{verifyBackupCode:c("/two-factor/verify-backup-code",{method:"POST",body:K.z.object({code:K.z.string(),disableSession:K.z.boolean().optional()}),use:[we]},async r=>{let t=r.context.session.user,n=await r.context.adapter.findOne({model:o,where:[{field:"userId",value:t.id}]});if(!n)throw new ze.APIError("BAD_REQUEST",{message:"Backup codes aren't enabled"});let i=await gn({backupCodes:n.backupCodes,code:r.body.code},r.context.secret);if(!i.status)throw new ze.APIError("UNAUTHORIZED",{message:"Invalid backup code"});let s=await re({key:r.context.secret,data:JSON.stringify(i.updated)});return await r.context.adapter.update({model:o,update:{backupCodes:s},where:[{field:"userId",value:t.id}]}),r.body.disableSession||await w(r,{session:r.context.session,user:t}),r.json({user:t,session:r.context.session})}),generateBackupCodes:c("/two-factor/generate-backup-codes",{method:"POST",body:K.z.object({password:K.z.string()}),use:[b]},async r=>{let t=r.context.session.user;if(!t.twoFactorEnabled)throw new ze.APIError("BAD_REQUEST",{message:"Two factor isn't enabled"});await r.context.password.checkPassword(t.id,r);let n=await Pt(r.context.secret,e);return await r.context.adapter.update({model:o,update:{backupCodes:n.encryptedBackupCodes},where:[{field:"userId",value:r.context.session.user.id}]}),r.json({status:!0,backupCodes:n.backupCodes})}),viewBackupCodes:c("/two-factor/view-backup-codes",{method:"GET",body:K.z.object({userId:K.z.string()}),metadata:{SERVER_ONLY:!0}},async r=>{let t=await r.context.adapter.findOne({model:o,where:[{field:"userId",value:r.body.userId}]});if(!t)throw new ze.APIError("BAD_REQUEST",{message:"Backup codes aren't enabled"});let n=await Wr(t.backupCodes,r.context.secret);if(!n)throw new ze.APIError("BAD_REQUEST",{message:"Backup codes aren't enabled"});return r.json({status:!0,backupCodes:n})})}});var Fe=require("better-call"),Jr=require("oslo/otp"),_t=require("zod");var Kr=require("oslo"),Zr=(e,o)=>{let r={...e,period:new Kr.TimeSpan(e?.period||3,"m")},t=new Jr.TOTPController({digits:6,period:r.period}),n=c("/two-factor/send-otp",{method:"POST",use:[we]},async s=>{if(!e||!e.sendOTP)throw s.context.logger.error("send otp isn't configured. Please configure the send otp function on otp options."),new Fe.APIError("BAD_REQUEST",{message:"otp isn't configured"});let a=s.context.session.user,d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d)throw new Fe.APIError("BAD_REQUEST",{message:"OTP isn't enabled"});let u=await t.generate(Buffer.from(d.secret));return await e.sendOTP({user:a,otp:u},s.request),s.json({status:!0})}),i=c("/two-factor/verify-otp",{method:"POST",body:_t.z.object({code:_t.z.string()}),use:[we]},async s=>{let a=s.context.session.user;if(!a.twoFactorEnabled)throw new Fe.APIError("BAD_REQUEST",{message:"two factor isn't enabled"});let d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d)throw new Fe.APIError("BAD_REQUEST",{message:"OTP isn't enabled"});return await t.generate(Buffer.from(d.secret))===s.body.code?s.context.valid():s.context.invalid()});return{id:"otp",endpoints:{send2FaOTP:n,verifyOTP:i}}};var ye=require("better-call"),Yr=require("oslo"),Me=require("oslo/otp"),qe=require("zod");var Xr=(e,o)=>{let r={...e,digits:6,period:new Yr.TimeSpan(e?.period||30,"s")},t=c("/totp/generate",{method:"POST",use:[b]},async s=>{if(!e)throw s.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp"),new ye.APIError("BAD_REQUEST",{message:"totp isn't configured"});let a=s.context.session.user,d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d)throw new ye.APIError("BAD_REQUEST",{message:"totp isn't enabled"});return{code:await new Me.TOTPController(r).generate(Buffer.from(d.secret))}}),n=c("/two-factor/get-totp-uri",{method:"POST",use:[b],body:qe.z.object({password:qe.z.string()})},async s=>{if(!e)throw s.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp"),new ye.APIError("BAD_REQUEST",{message:"totp isn't configured"});let a=s.context.session.user,d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d||!a.twoFactorEnabled)throw new ye.APIError("BAD_REQUEST",{message:"totp isn't enabled"});return await s.context.password.checkPassword(a.id,s),{totpURI:(0,Me.createTOTPKeyURI)(e.issuer||s.context.appName,a.email,Buffer.from(d.secret),r)}}),i=c("/two-factor/verify-totp",{method:"POST",body:qe.z.object({code:qe.z.string()}),use:[we]},async s=>{if(!e)throw s.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp"),new ye.APIError("BAD_REQUEST",{message:"totp isn't configured"});let a=s.context.session.user,d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d)throw new ye.APIError("BAD_REQUEST",{message:"totp isn't enabled"});let u=new Me.TOTPController(r),l=await ce({key:s.context.secret,data:d.secret}),m=Buffer.from(l);if(!await u.verify(s.body.code,m))return s.context.invalid();if(!a.twoFactorEnabled){let p=await s.context.internalAdapter.updateUser(a.id,{twoFactorEnabled:!0}),h=await s.context.internalAdapter.createSession(a.id,s.request);await w(s,{session:h,user:p})}return s.context.valid()});return{id:"totp",endpoints:{generateTOTP:t,viewTOTPURI:n,verifyTOTP:i}}};var hn=require("better-call");async function Ct(e,o){let t=(await e.context.internalAdapter.findAccounts(o.userId))?.find(s=>s.providerId==="credential"),n=t?.password;return!t||!n?!1:await e.context.password.verify(n,o.password)}var ut=require("better-call"),eo=require("oslo/otp"),to=require("oslo");var wn=(e={redirect:!0,twoFactorPage:"/"})=>({id:"two-factor",$InferServerPlugin:{},atomListeners:[{matcher:o=>o.startsWith("/two-factor/"),signal:"$sessionSignal"}],pathMethods:{"/two-factor/disable":"POST","/two-factor/enable":"POST","/two-factor/send-otp":"POST","/two-factor/generate-backup-codes":"POST"},fetchPlugins:[{id:"two-factor",name:"two-factor",hooks:{async onSuccess(o){o.data?.twoFactorRedirect&&(e.redirect||e.twoFactorPage)&&typeof window<"u"&&(window.location.href=e.twoFactorPage)}}}]});var yn=e=>{let o={twoFactorTable:e?.twoFactorTable||"twoFactor"},r=Xr({issuer:e?.issuer,...e?.totpOptions},o.twoFactorTable),t=Gr({...e?.backupCodeOptions},o.twoFactorTable),n=Zr({...e?.otpOptions},o.twoFactorTable);return{id:"two-factor",endpoints:{...r.endpoints,...n.endpoints,...t.endpoints,enableTwoFactor:c("/two-factor/enable",{method:"POST",body:$e.z.object({password:$e.z.string().min(8)}),use:[b]},async i=>{let s=i.context.session.user,{password:a}=i.body;if(!await Ct(i,{password:a,userId:s.id}))throw new ut.APIError("BAD_REQUEST",{message:"Invalid password"});let u=q(16,M("a-z","0-9","-")),l=await re({key:i.context.secret,data:u}),m=await Pt(i.context.secret,e?.backupCodeOptions);if(e?.skipVerificationOnEnable){let p=await i.context.internalAdapter.updateUser(s.id,{twoFactorEnabled:!0}),h=await i.context.internalAdapter.createSession(p.id,i.request);await w(i,{session:h,user:s})}await i.context.adapter.deleteMany({model:o.twoFactorTable,where:[{field:"userId",value:s.id}]}),await i.context.adapter.create({model:o.twoFactorTable,data:{id:i.context.uuid(),secret:l,backupCodes:m.encryptedBackupCodes,userId:s.id}});let f=(0,eo.createTOTPKeyURI)(e?.issuer||"BetterAuth",s.email,Buffer.from(u),{digits:e?.totpOptions?.digits||6,period:new to.TimeSpan(e?.totpOptions?.period||30,"s")});return i.json({totpURI:f,backupCodes:m.backupCodes})}),disableTwoFactor:c("/two-factor/disable",{method:"POST",body:$e.z.object({password:$e.z.string().min(8)}),use:[b]},async i=>{let s=i.context.session.user,{password:a}=i.body;if(!await Ct(i,{password:a,userId:s.id}))throw new ut.APIError("BAD_REQUEST",{message:"Invalid password"});return await i.context.internalAdapter.updateUser(s.id,{twoFactorEnabled:!1}),await i.context.adapter.delete({model:o.twoFactorTable,where:[{field:"userId",value:s.id}]}),i.json({status:!0})})},options:e,hooks:{after:[{matcher(i){return i.path==="/sign-in/email"||i.path==="/sign-in/username"},handler:S(async i=>{let s=i.context.returned;if(s instanceof Response&&s?.status!==200||s instanceof ut.APIError)return;let a=s instanceof Response?await s.clone().json():s;if(!a.user.twoFactorEnabled)return;let d=i.context.createAuthCookie(dt,{maxAge:30*24*60*60}),u=await i.getSignedCookie(d.name,i.context.secret);if(u){let[f,p]=u.split("!"),h=await Ve(i.context.secret,`${a.user.id}!${p}`);if(f===h){let k=await Ve(i.context.secret,`${a.user.id}!${a.session.id}`);await i.setSignedCookie(d.name,`${k}!${a.session.id}`,i.context.secret,d.attributes);return}}J(i),await i.context.internalAdapter.deleteSession(a.session.id);let l=i.context.createAuthCookie(at,{maxAge:60*10});return await i.setSignedCookie(l.name,a.user.id,i.context.secret,l.attributes),{response:new Response(JSON.stringify({twoFactorRedirect:!0}),{headers:i.responseHeader})}})}]},schema:{user:{fields:{twoFactorEnabled:{type:"boolean",required:!1,defaultValue:!1,input:!1}}},twoFactor:{tableName:o.twoFactorTable,fields:{secret:{type:"string",required:!0,returned:!1},backupCodes:{type:"string",required:!0,returned:!1},userId:{type:"string",required:!0,returned:!1,references:{model:"user",field:"id"}}}}},rateLimit:[{pathMatcher(i){return i.startsWith("/two-factor/")},window:10,max:3}]}};var le=require("@simplewebauthn/server"),H=require("better-call");var Z=require("zod");var Be=require("@simplewebauthn/browser");var An=require("@better-fetch/fetch");var Dc=require("nanostores");var Ec=require("@better-fetch/fetch");var bn=require("nanostores");var Ic=require("@better-fetch/fetch"),ct=require("nanostores"),zt=(e,o,r,t)=>{let n=(0,ct.atom)({data:null,error:null,isPending:!0,isRefetching:!1}),i=()=>{let a=typeof t=="function"?t({data:n.get().data,error:n.get().error,isPending:n.get().isPending}):t;return r(o,{...a,onSuccess:async d=>{n.set({data:d.data,error:null,isPending:!1,isRefetching:!1}),await a?.onSuccess?.(d)},async onError(d){n.set({error:d.error,data:null,isPending:!1,isRefetching:!1}),await a?.onError?.(d)},async onRequest(d){let u=n.get();n.set({isPending:u.data===null,data:u.data,error:null,isRefetching:!0}),await a?.onRequest?.(d)}})};e=Array.isArray(e)?e:[e];let s=!1;for(let a of e)a.subscribe(()=>{s?i():(0,ct.onMount)(n,()=>(i(),s=!0,()=>{n.off(),a.off()}))});return n};var ro=require("nanostores"),oo=(e,{$listPasskeys:o})=>({signIn:{passkey:async(n,i)=>{let s=await e("/passkey/generate-authenticate-options",{method:"POST",body:{email:n?.email}});if(!s.data)return s;try{let a=await(0,Be.startAuthentication)(s.data,n?.autoFill||!1),d=await e("/passkey/verify-authentication",{body:{response:a},...n?.fetchOptions,...i,method:"POST"});if(!d.data)return d}catch{return{data:null,error:{message:"auth cancelled",status:400,statusText:"BAD_REQUEST"}}}}},passkey:{addPasskey:async(n,i)=>{let s=await e("/passkey/generate-register-options",{method:"GET"});if(!s.data)return s;try{let a=await(0,Be.startRegistration)(s.data),d=await e("/passkey/verify-registration",{...n?.fetchOptions,...i,body:{response:a,name:n?.name},method:"POST"});if(!d.data)return d;o.set(Math.random())}catch(a){return a instanceof Be.WebAuthnError?a.code==="ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED"?{data:null,error:{message:"previously registered",status:400,statusText:"BAD_REQUEST"}}:a.code==="ERROR_CEREMONY_ABORTED"?{data:null,error:{message:"registration cancelled",status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:a.message,status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:a instanceof Error?a.message:"unknown error",status:500,statusText:"INTERNAL_SERVER_ERROR"}}}}},$Infer:{}}),kn=()=>{let e=(0,ro.atom)();return{id:"passkey",$InferServerPlugin:{},getActions:o=>oo(o,{$listPasskeys:e}),getAtoms(o){return{listPasskeys:zt(e,"/passkey/list-user-passkeys",o,{method:"GET"}),$listPasskeys:e}},pathMethods:{"/passkey/register":"POST","/passkey/authenticate":"POST"},atomListeners:[{matcher(o){return o==="/passkey/verify-registration"||o==="/passkey/delete-passkey"},signal:"_listPasskeys"}]}};var On=e=>{let o=G.BETTER_AUTH_URL,r=e?.rpID||o?.replace("http://","").replace("https://","").split(":")[0]||"localhost";if(!r)throw new W("passkey rpID not found. Please provide a rpID in the options or set the BETTER_AUTH_URL environment variable.");let t={origin:null,...e,rpID:r,advanced:{webAuthnChallengeCookie:"better-auth-passkey",...e?.advanced}},n=new Date(Date.now()+1e3*60*5),i=new Date,s=Math.floor((n.getTime()-i.getTime())/1e3);return{id:"passkey",endpoints:{generatePasskeyRegistrationOptions:c("/passkey/generate-register-options",{method:"GET",use:[b],metadata:{client:!1}},async a=>{let d=a.context.session,u=await a.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}),l=new Uint8Array(Buffer.from(q(32,M("a-z","0-9")))),m;m=await(0,le.generateRegistrationOptions)({rpName:t.rpName||a.context.appName,rpID:t.rpID,userID:l,userName:d.user.email||d.user.id,attestationType:"none",excludeCredentials:u.map(p=>({id:p.id,transports:p.transports?.split(",")})),authenticatorSelection:{residentKey:"preferred",userVerification:"preferred",authenticatorAttachment:"platform"}});let f=B();return await a.setSignedCookie(t.advanced.webAuthnChallengeCookie,f,a.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:s}),await a.context.internalAdapter.createVerificationValue({identifier:f,value:JSON.stringify({expectedChallenge:m.challenge,userData:{id:d.user.id}}),expiresAt:n}),a.json(m,{status:200})}),generatePasskeyAuthenticationOptions:c("/passkey/generate-authenticate-options",{method:"POST",body:Z.z.object({email:Z.z.string().optional()}).optional()},async a=>{let d=await z(a),u=[];d&&(u=await a.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}));let l=await(0,le.generateAuthenticationOptions)({rpID:t.rpID,userVerification:"preferred",...u.length?{allowCredentials:u.map(p=>({id:p.id,transports:p.transports?.split(",")}))}:{}}),m={expectedChallenge:l.challenge,userData:{id:d?.user.id||""}},f=B();return await a.setSignedCookie(t.advanced.webAuthnChallengeCookie,f,a.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:s}),await a.context.internalAdapter.createVerificationValue({identifier:f,value:JSON.stringify(m),expiresAt:n}),a.json(l,{status:200})}),verifyPasskeyRegistration:c("/passkey/verify-registration",{method:"POST",body:Z.z.object({response:Z.z.any(),name:Z.z.string().optional()}),use:[b]},async a=>{let d=e?.origin||a.headers?.get("origin")||"";if(!d)return a.json(null,{status:400});let u=a.body.response,l=await a.getSignedCookie(t.advanced.webAuthnChallengeCookie,a.context.secret);if(!l)throw new H.APIError("BAD_REQUEST",{message:"Challenge not found"});let m=await a.context.internalAdapter.findVerificationValue(l);if(!m)return a.json(null,{status:400});let{expectedChallenge:f,userData:p}=JSON.parse(m.value);if(p.id!==a.context.session.user.id)throw new H.APIError("UNAUTHORIZED",{message:"You are not authorized to register this passkey"});try{let h=await(0,le.verifyRegistrationResponse)({response:u,expectedChallenge:f,expectedOrigin:d,expectedRPID:e?.rpID}),{verified:k,registrationInfo:E}=h;if(!k||!E)return a.json(null,{status:400});let{credentialID:ee,credentialPublicKey:Ae,counter:N,credentialDeviceType:pt,credentialBackedUp:ke}=E,pe=Buffer.from(Ae).toString("base64"),ft=B(),co={name:a.body.name,userId:p.id,webauthnUserID:ft,id:ee,publicKey:pe,counter:N,deviceType:pt,transports:u.response.transports.join(","),backedUp:ke,createdAt:new Date},lo=await a.context.adapter.create({model:"passkey",data:co});return a.json(lo,{status:200})}catch(h){throw console.log(h),new H.APIError("INTERNAL_SERVER_ERROR",{message:"Failed to verify registration"})}}),verifyPasskeyAuthentication:c("/passkey/verify-authentication",{method:"POST",body:Z.z.object({response:Z.z.any()})},async a=>{let d=e?.origin||a.headers?.get("origin")||"";if(!d)throw new H.APIError("BAD_REQUEST",{message:"origin missing"});let u=a.body.response,l=await a.getSignedCookie(t.advanced.webAuthnChallengeCookie,a.context.secret);if(!l)throw new H.APIError("BAD_REQUEST",{message:"Challenge not found"});let m=await a.context.internalAdapter.findVerificationValue(l);if(!m)throw new H.APIError("BAD_REQUEST",{message:"Challenge not found"});let{expectedChallenge:f}=JSON.parse(m.value),p=await a.context.adapter.findOne({model:"passkey",where:[{field:"id",value:u.id}]});if(!p)throw new H.APIError("UNAUTHORIZED",{message:"Passkey not found"});try{let h=await(0,le.verifyAuthenticationResponse)({response:u,expectedChallenge:f,expectedOrigin:d,expectedRPID:t.rpID,authenticator:{credentialID:p.id,credentialPublicKey:new Uint8Array(Buffer.from(p.publicKey,"base64")),counter:p.counter,transports:p.transports?.split(",")}}),{verified:k}=h;if(!k)throw new H.APIError("UNAUTHORIZED",{message:"Authentication failed"});await a.context.adapter.update({model:"passkey",where:[{field:"id",value:p.id}],update:{counter:h.authenticationInfo.newCounter}});let E=await a.context.internalAdapter.createSession(p.userId,a.request);if(!E)throw new H.APIError("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});let ee=await a.context.internalAdapter.findUserById(p.userId);if(!ee)throw new H.APIError("INTERNAL_SERVER_ERROR",{message:"User not found"});return await w(a,{session:E,user:ee}),a.json({session:E},{status:200})}catch(h){throw a.context.logger.error(h),new H.APIError("BAD_REQUEST",{message:"Failed to verify authentication"})}}),listPasskeys:c("/passkey/list-user-passkeys",{method:"GET",use:[b]},async a=>{let d=await a.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:a.context.session.user.id}]});return a.json(d,{status:200})}),deletePasskey:c("/passkey/delete-passkey",{method:"POST",body:Z.z.object({id:Z.z.string()}),use:[b]},async a=>(await a.context.adapter.delete({model:"passkey",where:[{field:"id",value:a.body.id}]}),a.json(null,{status:200})))},schema:{passkey:{fields:{name:{type:"string",required:!1},publicKey:{type:"string",required:!0},userId:{type:"string",references:{model:"user",field:"id"},required:!0},webauthnUserID:{type:"string",required:!0},counter:{type:"number",required:!0},deviceType:{type:"string",required:!0},backedUp:{type:"boolean",required:!0},transports:{type:"string",required:!1},createdAt:{type:"date",defaultValue:new Date,required:!1}}}}}};var Qe=require("zod");var He=require("better-call"),Bt=()=>({id:"username",endpoints:{signInUsername:c("/sign-in/username",{method:"POST",body:Qe.z.object({username:Qe.z.string(),password:Qe.z.string(),rememberMe:Qe.z.boolean().optional()})},async e=>{let o=await e.context.adapter.findOne({model:e.context.tables.user.tableName,where:[{field:"username",value:e.body.username}]});if(!o)throw await e.context.password.hash(e.body.password),e.context.logger.error("User not found",{username:Bt}),new He.APIError("UNAUTHORIZED",{message:"Invalid username or password"});let r=await e.context.adapter.findOne({model:e.context.tables.account.tableName,where:[{field:e.context.tables.account.fields.userId.fieldName||"userId",value:o.id},{field:e.context.tables.account.fields.providerId.fieldName||"providerId",value:"credential"}]});if(!r)throw new He.APIError("UNAUTHORIZED",{message:"Invalid username or password"});let t=r?.password;if(!t)throw e.context.logger.error("Password not found",{username:Bt}),new He.APIError("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(t,e.body.password))throw e.context.logger.error("Invalid password"),new He.APIError("UNAUTHORIZED",{message:"Invalid username or password"});let i=await e.context.internalAdapter.createSession(o.id,e.request,e.body.rememberMe===!1);return i?(await e.setSignedCookie(e.context.authCookies.sessionToken.name,i.id,e.context.secret,e.body.rememberMe===!1?{...e.context.authCookies.sessionToken.options,maxAge:void 0}:e.context.authCookies.sessionToken.options),e.json({user:o,session:i})):e.json(null,{status:500,body:{message:"Failed to create session",status:500}})})},schema:{user:{fields:{username:{type:"string",required:!1,unique:!0,returned:!0}}}}});var no=require("better-call"),vn=()=>({id:"bearer",hooks:{before:[{matcher(e){return!!(e.request?.headers.get("authorization")||e.headers?.get("authorization"))},handler:async e=>{let o=e.request?.headers.get("authorization")?.replace("Bearer ","")||e.headers?.get("authorization")?.replace("Bearer ","");if(!o)return;let r="";return o.includes(".")?r=o:r=await(0,no.serializeSigned)("",o,e.context.secret),e.request&&e.request.headers.set("cookie",`${e.context.authCookies.sessionToken.name}=${r.replace("=","")}`),e.headers&&e.headers.set("cookie",`${e.context.authCookies.sessionToken.name}=${r.replace("=","")}`),{context:e}}}]}});var be=require("zod");var xt=require("better-call");var Rn=e=>({id:"magic-link",endpoints:{signInMagicLink:c("/sign-in/magic-link",{method:"POST",requireHeaders:!0,body:be.z.object({email:be.z.string().email(),callbackURL:be.z.string().optional()})},async o=>{let{email:r}=o.body;if(e.disableSignUp&&!await o.context.internalAdapter.findUserByEmail(r))throw new xt.APIError("BAD_REQUEST",{message:"User not found"});let t=q(32,M("a-z","A-Z"));await o.context.internalAdapter.createVerificationValue({identifier:t,value:r,expiresAt:new Date(Date.now()+(e.expiresIn||60*5)*1e3)});let n=`${o.context.baseURL}/magic-link/verify?token=${t}&callbackURL=${o.body.callbackURL||"/"}`;try{await e.sendMagicLink({email:r,url:n,token:t},o.request)}catch(i){throw o.context.logger.error("Failed to send magic link",i),new xt.APIError("INTERNAL_SERVER_ERROR",{message:"Failed to send magic link"})}return o.json({status:!0})}),magicLinkVerify:c("/magic-link/verify",{method:"GET",query:be.z.object({token:be.z.string(),callbackURL:be.z.string().optional()}),requireHeaders:!0},async o=>{let{token:r,callbackURL:t}=o.query,n=t?.startsWith("http")?t:t?`${o.context.options.baseURL}${t}`:o.context.options.baseURL,i=await o.context.internalAdapter.findVerificationValue(r);if(!i)throw o.redirect(`${n}?error=INVALID_TOKEN`);if(i.expiresAt<new Date)throw await o.context.internalAdapter.deleteVerificationValue(i.id),o.redirect(`${n}?error=EXPIRED_TOKEN`);await o.context.internalAdapter.deleteVerificationValue(i.id);let s=i.value,a=await o.context.internalAdapter.findUserByEmail(s),d=a?.user.id||"";if(!a){if(e.disableSignUp)throw o.redirect(`${n}?error=USER_NOT_FOUND`);if(d=(await o.context.internalAdapter.createUser({email:s,emailVerified:!0,name:s})).id,!d)throw o.redirect(`${n}?error=USER_NOT_CREATED`)}let u=await o.context.internalAdapter.createSession(d,o.headers);if(!u)throw o.redirect(`${n}?error=SESSION_NOT_CREATED`);if(await w(o,{session:u,user:a?.user}),!t)return o.json({status:!0});throw o.redirect(t)})},rateLimit:[{pathMatcher(o){return o.startsWith("/sign-in/magic-link")||o.startsWith("/magic-link/verify")},window:e.rateLimit?.window||60,max:e.rateLimit?.max||5}]});var me=require("zod");var oe=require("better-call");function En(e){return q(e,M("0-9"))}var Un=e=>{let o={phoneNumber:"phoneNumber",phoneNumberVerified:"phoneNumberVerified",code:"code",createdAt:"createdAt",expiresIn:e?.expiresIn||300,otpLength:e?.otpLength||6};return{id:"phone-number",endpoints:{sendPhoneNumberOTP:c("/phone-number/send-otp",{method:"POST",body:me.z.object({phoneNumber:me.z.string()})},async r=>{if(!e?.sendOTP)throw y.warn("sendOTP not implemented"),new oe.APIError("NOT_IMPLEMENTED",{message:"sendOTP not implemented"});let t=En(o.otpLength);return await r.context.internalAdapter.createVerificationValue({value:t,identifier:r.body.phoneNumber,expiresAt:P(o.expiresIn,"sec")}),await e.sendOTP({phoneNumber:r.body.phoneNumber,code:t},r.request),r.json({code:t},{body:{message:"Code sent"}})}),verifyPhoneNumber:c("/phone-number/verify",{method:"POST",body:me.z.object({phoneNumber:me.z.string(),code:me.z.string(),disableSession:me.z.boolean().optional(),updatePhoneNumber:me.z.boolean().optional()})},async r=>{let t=await r.context.internalAdapter.findVerificationValue(r.body.phoneNumber);if(!t||t.expiresAt<new Date)throw t&&t.expiresAt<new Date?(await r.context.internalAdapter.deleteVerificationValue(t.id),new oe.APIError("BAD_REQUEST",{message:"OTP expired"})):new oe.APIError("BAD_REQUEST",{message:"OTP not found"});if(t.value!==r.body.code)throw new oe.APIError("BAD_REQUEST",{message:"Invalid OTP"});if(await r.context.internalAdapter.deleteVerificationValue(t.id),r.body.updatePhoneNumber){let i=await z(r);if(!i)throw new oe.APIError("UNAUTHORIZED",{message:"Session not found"});let s=await r.context.internalAdapter.updateUser(i.user.id,{[o.phoneNumber]:r.body.phoneNumber,[o.phoneNumberVerified]:!0});return r.json({user:s,session:i.session})}let n=await r.context.adapter.findOne({model:r.context.tables.user.tableName,where:[{value:r.body.phoneNumber,field:o.phoneNumber}]});if(await e?.callbackOnVerification?.({phoneNumber:r.body.phoneNumber,user:n},r.request),n)n=await r.context.internalAdapter.updateUser(n.id,{[o.phoneNumberVerified]:!0});else if(e?.signUpOnVerification){if(n=await r.context.internalAdapter.createUser({email:e.signUpOnVerification.getTempEmail(r.body.phoneNumber),name:e.signUpOnVerification.getTempName?e.signUpOnVerification.getTempName(r.body.phoneNumber):r.body.phoneNumber,[o.phoneNumber]:r.body.phoneNumber,[o.phoneNumberVerified]:!0}),!n)throw new oe.APIError("INTERNAL_SERVER_ERROR",{message:"Failed to create user"})}else return r.json(null);if(!n)throw new oe.APIError("INTERNAL_SERVER_ERROR",{message:"Failed to update user"});if(!r.body.disableSession){let i=await r.context.internalAdapter.createSession(n.id,r.request);if(!i)throw new oe.APIError("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await w(r,{session:i,user:n}),r.json({user:n,session:i})}return r.json({user:n,session:null})})},schema:{user:{fields:{phoneNumber:{type:"string",required:!1,unique:!0,returned:!0},phoneNumberVerified:{type:"boolean",required:!1,returned:!0,input:!1}}}}}};var Tl=require("zod");var In=e=>({id:"anonymous",endpoints:{signInAnonymous:c("/sign-in/anonymous",{method:"POST"},async o=>{let{emailDomainName:r=Oe(o.context.baseURL)}=e||{},t=B(),n=`temp-${t}@${r}`,i=await o.context.internalAdapter.createUser({id:t,email:n,emailVerified:!1,isAnonymous:!0,name:"Anonymous",createdAt:new Date,updatedAt:new Date});if(!i)return o.json(null,{status:500,body:{message:"Failed to create user",status:500}});let s=await o.context.internalAdapter.createSession(i.id,o.request);return s?(await w(o,{session:s,user:i}),o.json({user:i,session:s})):o.json(null,{status:400,body:{message:"Could not create session"}})})},hooks:{after:[{matcher(o){return o.path?.startsWith("/sign-in")||o.path?.startsWith("/sign-up")},async handler(o){let r=o.context.returned;if(!(r instanceof Response))return;let t=r.headers.get("set-cookie"),n=o.context.authCookies.sessionToken.name,i=Ye(t||"").get(n)?.value.split(".")[0];if(!i)return;let s=await z(o);if(!(!s||!s.user.isAnonymous)){if(o.path==="/sign-in/anonymous")throw new v.APIError("BAD_REQUEST",{message:"Anonymous users cannot sign in again anonymously"});if(e?.onLinkAccount){let a=await o.context.internalAdapter.findSession(i);if(!a)return;await e?.onLinkAccount?.({anonymousUser:s,newUser:a})}e?.disableDeleteAnonymousUser||await o.context.internalAdapter.deleteUser(s.user.id)}}}]},schema:{user:{fields:{isAnonymous:{type:"boolean",required:!1}}}}});var g=require("zod");var Tn=e=>{let o={defaultRole:"user",adminRole:"admin",...e},r=S(async t=>{let n=await z(t);if(!n?.session)throw new v.APIError("UNAUTHORIZED");let i=n.user;if(!i.role||(Array.isArray(o.adminRole)?!o.adminRole.includes(i.role):i.role!==o.adminRole))throw new v.APIError("FORBIDDEN",{message:"Only admins can access this endpoint"});return{session:{user:i,session:n.session}}});return{id:"admin",init(t){return{options:{databaseHooks:{user:{create:{async before(n){if(e?.defaultRole!==!1)return{data:{role:e?.defaultRole??"user",...n}}}}},session:{create:{async before(n){let i=await t.internalAdapter.findUserById(n.userId);if(i.banned){if(i.banExpires&&i.banExpires<Date.now()){await t.internalAdapter.updateUser(n.userId,{banned:!1,banReason:null,banExpires:null});return}return!1}}}}}}}},hooks:{after:[{matcher(t){return t.path==="/list-sessions"},handler:S(async t=>{let n=t.context.returned;if(n instanceof Response){let s=(await n.clone().json()).filter(d=>!d.impersonatedBy),a=new Response(JSON.stringify(s),{status:200,statusText:"OK",headers:n.headers});return t.json({response:a})}})}]},endpoints:{setRole:c("/admin/set-role",{method:"POST",body:g.z.object({userId:g.z.string(),role:g.z.string()}),use:[r]},async t=>{let n=await t.context.internalAdapter.updateUser(t.body.userId,{role:t.body.role});return t.json({user:n})}),createUser:c("/admin/create-user",{method:"POST",body:g.z.object({email:g.z.string(),password:g.z.string(),name:g.z.string(),role:g.z.string(),data:g.z.optional(g.z.record(g.z.any()))}),use:[r]},async t=>{if(await t.context.internalAdapter.findUserByEmail(t.body.email))throw new v.APIError("BAD_REQUEST",{message:"User already exists"});let i=await t.context.internalAdapter.createUser({email:t.body.email,name:t.body.name,role:t.body.role,...t.body.data});if(!i)throw new v.APIError("INTERNAL_SERVER_ERROR",{message:"Failed to create user"});let s=await t.context.password.hash(t.body.password);return await t.context.internalAdapter.linkAccount({accountId:i.id,providerId:"credential",password:s,userId:i.id}),t.json({user:i})}),listUsers:c("/admin/list-users",{method:"GET",use:[r],query:g.z.object({searchValue:g.z.string().optional(),searchField:g.z.enum(["email","name"]).optional(),searchOperator:g.z.enum(["contains","starts_with","ends_with"]).optional(),limit:g.z.string().or(g.z.number()).optional(),offset:g.z.string().or(g.z.number()).optional(),sortBy:g.z.string().optional(),sortDirection:g.z.enum(["asc","desc"]).optional(),filterField:g.z.string().optional(),filterValue:g.z.string().or(g.z.number()).or(g.z.boolean()).optional(),filterOperator:g.z.enum(["eq","ne","lt","lte","gt","gte"]).optional()})},async t=>{let n=[];t.query?.searchValue&&n.push({field:t.query.searchField||"email",operator:t.query.searchOperator||"contains",value:t.query.searchValue}),t.query?.filterValue&&n.push({field:t.query.filterField||"email",operator:t.query.filterOperator||"eq",value:t.query.filterValue});try{let i=await t.context.internalAdapter.listUsers(Number(t.query?.limit)||void 0,Number(t.query?.offset)||void 0,t.query?.sortBy?{field:t.query.sortBy,direction:t.query.sortDirection||"asc"}:void 0,n.length?n:void 0);return t.json({users:i})}catch(i){return console.log(i),t.json({users:[]})}}),listUserSessions:c("/admin/list-user-sessions",{method:"POST",use:[r],body:g.z.object({userId:g.z.string()})},async t=>({sessions:await t.context.internalAdapter.listSessions(t.body.userId)})),unbanUser:c("/admin/unban-user",{method:"POST",body:g.z.object({userId:g.z.string()}),use:[r]},async t=>{let n=await t.context.internalAdapter.updateUser(t.body.userId,{banned:!1});return t.json({user:n})}),banUser:c("/admin/ban-user",{method:"POST",body:g.z.object({userId:g.z.string(),banReason:g.z.string().optional(),banExpiresIn:g.z.number().optional()}),use:[r]},async t=>{if(t.body.userId===t.context.session.user.id)throw new v.APIError("BAD_REQUEST",{message:"You cannot ban yourself"});let n=await t.context.internalAdapter.updateUser(t.body.userId,{banned:!0,banReason:t.body.banReason||e?.defaultBanReason||"No reason",banExpires:t.body.banExpiresIn?P(t.body.banExpiresIn,"sec"):e?.defaultBanExpiresIn?P(e.defaultBanExpiresIn,"sec"):void 0});return await t.context.internalAdapter.deleteSessions(t.body.userId),t.json({user:n})}),impersonateUser:c("/admin/impersonate-user",{method:"POST",body:g.z.object({userId:g.z.string()}),use:[r]},async t=>{let n=await t.context.internalAdapter.findUserById(t.body.userId);if(!n)throw new v.APIError("NOT_FOUND",{message:"User not found"});let i=await t.context.internalAdapter.createSession(n.id,void 0,!0,{impersonatedBy:t.context.session.user.id,expiresAt:e?.impersonationSessionDuration?P(e.impersonationSessionDuration,"sec"):P(60*60,"sec")});if(!i)throw new v.APIError("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await w(t,{session:i,user:n},!0),t.json({session:i,user:n})}),revokeUserSession:c("/admin/revoke-user-session",{method:"POST",body:g.z.object({sessionId:g.z.string()}),use:[r]},async t=>(await t.context.internalAdapter.deleteSession(t.body.sessionId),t.json({success:!0}))),revokeUserSessions:c("/admin/revoke-user-sessions",{method:"POST",body:g.z.object({userId:g.z.string()}),use:[r]},async t=>(await t.context.internalAdapter.deleteSessions(t.body.userId),t.json({success:!0}))),removeUser:c("/admin/remove-user",{method:"POST",body:g.z.object({userId:g.z.string()}),use:[r]},async t=>(await t.context.internalAdapter.deleteUser(t.body.userId),t.json({success:!0})))},schema:{user:{fields:{role:{type:"string",required:!1,input:!1},banned:{type:"boolean",defaultValue:!1,required:!1,input:!1},banReason:{type:"string",required:!1,input:!1},banExpires:{type:"date",required:!1,input:!1}}},session:{fields:{impersonatedBy:{type:"string",required:!1}}}}}};var Y=require("zod"),xe=require("better-call");var lt=require("@better-fetch/fetch");var io=require("oslo/jwt");async function Sn(e,o,r){if(o==="oidc"&&e.idToken){let n=(0,io.parseJWT)(e.idToken);if(n?.payload)return n.payload}return r?(await(0,lt.betterFetch)(r,{method:"GET",headers:{Authorization:`Bearer ${e.accessToken}`}})).data:null}var Pn=e=>({id:"generic-oauth",endpoints:{signInWithOAuth2:c("/sign-in/oauth2",{method:"POST",query:Y.z.object({currentURL:Y.z.string().optional()}).optional(),body:Y.z.object({providerId:Y.z.string(),callbackURL:Y.z.string().optional()})},async o=>{let{providerId:r}=o.body,t=e.config.find(pe=>pe.providerId===r);if(!t)throw new xe.APIError("BAD_REQUEST",{message:`No config found for provider ${r}`});let{discoveryUrl:n,authorizationUrl:i,tokenUrl:s,clientId:a,clientSecret:d,scopes:u,redirectURI:l,responseType:m,pkce:f,prompt:p,accessType:h}=t,k=i,E=s;if(n){let pe=await(0,lt.betterFetch)(n,{onError(ft){y.error(ft.error,{discoveryUrl:n})}});pe.data&&(k=pe.data.authorization_endpoint,E=pe.data.token_endpoint)}if(!k||!E)throw new xe.APIError("BAD_REQUEST",{message:"Invalid OAuth configuration."});let ee=o.query?.currentURL?new URL(o.query?.currentURL):null,Ae=o.body.callbackURL?.startsWith("http")?o.body.callbackURL:`${ee?.origin}${o.body.callbackURL||""}`,{state:N,codeVerifier:pt}=await ve(o),ke=await U({id:r,options:{clientId:a,clientSecret:d,redirectURI:l},authorizationEndpoint:k,state:N,codeVerifier:f?pt:void 0,scopes:u||[],redirectURI:`${o.context.baseURL}/oauth2/callback/${r}`});return m&&m!=="code"&&ke.searchParams.set("response_type",m),p&&ke.searchParams.set("prompt",p),h&&ke.searchParams.set("access_type",h),o.json({url:ke.toString(),redirect:!0})}),oAuth2Callback:c("/oauth2/callback/:providerId",{method:"GET",query:Y.z.object({code:Y.z.string().optional(),error:Y.z.string().optional(),state:Y.z.string()})},async o=>{if(o.query.error||!o.query.code)throw o.redirect(`${o.context.baseURL}?error=${o.query.error||"oAuth_code_missing"}`);let r=e.config.find(N=>N.providerId===o.params.providerId);if(!r)throw new xe.APIError("BAD_REQUEST",{message:`No config found for provider ${o.params.providerId}`});let t,n=await tt(o),{callbackURL:i,codeVerifier:s,errorURL:a}=n,d=o.query.code,u=r.tokenUrl,l=r.userInfoUrl;if(r.discoveryUrl){let N=await(0,lt.betterFetch)(r.discoveryUrl,{method:"GET"});N.data&&(u=N.data.token_endpoint,l=N.data.userinfo_endpoint)}try{if(!u)throw new xe.APIError("BAD_REQUEST",{message:"Invalid OAuth configuration."});t=await O({code:d,codeVerifier:s,redirectURI:`${o.context.baseURL}/oauth2/callback/${r.providerId}`,options:{clientId:r.clientId,clientSecret:r.clientSecret},tokenEndpoint:u})}catch(N){throw o.context.logger.error(N),o.redirect(`${a}?error=oauth_code_verification_failed`)}if(!t)throw new xe.APIError("BAD_REQUEST",{message:"Invalid OAuth configuration."});let m=r.getUserInfo?await r.getUserInfo(t):await Sn(t,r.type||"oauth2",l),f=B(),p=Ur.safeParse({...m,id:f});if(!m||p.success===!1)throw y.error("Unable to get user info",p.error),o.redirect(`${o.context.baseURL}/error?error=please_restart_the_process`);let h=await Ue(o,{userInfo:p.data,account:{providerId:r.providerId,accountId:m.id,accessToken:t.accessToken}});function k(N){throw o.redirect(`${a||i||`${o.context.baseURL}/error`}?error=${N}`)}if(h.error)return k(h.error.split(" ").join("_"));let{session:E,user:ee}=h.data;await w(o,{session:E,user:ee});let Ae;try{Ae=new URL(i).toString()}catch{Ae=i}throw o.redirect(Ae)})}});var Le=require("zod"),so={jwks:{fields:{publicKey:{type:"string",required:!0},privateKey:{type:"string",required:!0},createdAt:{type:"date",required:!0}}}},Hl=Le.z.object({id:Le.z.string(),publicKey:Le.z.string(),privateKey:Le.z.string(),createdAt:Le.z.date()});var Lt=e=>({getAllKeys:async()=>await e.findMany({model:"jwks"}),getLatestKey:async()=>(await e.findMany({model:"jwks",sortBy:{field:"createdAt",direction:"desc"},limit:1}))[0],createJwk:async o=>await e.create({model:"jwks",data:{...o,createdAt:new Date}})});var ne=require("jose");var _n=e=>({id:"jwt",endpoints:{getJwks:c("/jwks",{method:"GET"},async o=>{let t=await Lt(o.context.adapter).getAllKeys();return o.json({keys:t.map(n=>({...JSON.parse(n.publicKey),kid:n.id}))})}),getToken:c("/token",{method:"GET",requireHeaders:!0,use:[b]},async o=>{let r=Lt(o.context.adapter),t=await r.getLatestKey(),n=!e?.jwks?.disablePrivateKeyEncryption;if(t===void 0){let{publicKey:u,privateKey:l}=await(0,ne.generateKeyPair)(e?.jwks?.keyPairConfig?.alg??"EdDSA",e?.jwks?.keyPairConfig??{crv:"Ed25519"}),m=await(0,ne.exportJWK)(u),f=await(0,ne.exportJWK)(l),p=JSON.stringify(f),h={id:crypto.randomUUID(),publicKey:JSON.stringify(m),privateKey:n?JSON.stringify(await re({key:o.context.options.secret,data:p})):p,createdAt:new Date};t=await r.createJwk(h)}let i=n?await ce({key:o.context.options.secret,data:JSON.parse(t.privateKey)}):t.privateKey,s=await(0,ne.importJWK)(JSON.parse(i)),a=e?.jwt?.definePayload?await e?.jwt.definePayload(o.context.session.user):o.context.session.user,d=await new ne.SignJWT({...a,...o.context.session.session.impersonatedBy?{impersonatedBy:o.context.session.session.impersonatedBy}:{}}).setProtectedHeader({alg:e?.jwks?.keyPairConfig?.alg??"EdDSA",kid:t.id}).setIssuedAt().setIssuer(e?.jwt?.issuer??o.context.options.baseURL).setAudience(e?.jwt?.audience??o.context.options.baseURL).setExpirationTime(e?.jwt?.expirationTime??"15m").setSubject(o.context.session.user.id).sign(s);return o.json({token:d})})},schema:so});var We=require("zod");var Cn=e=>{let o={maximumSessions:5,...e},r=t=>t.includes("_multi-");return{id:"multi-session",endpoints:{listDeviceSessions:c("/multi-session/list-device-sessions",{method:"GET",requireHeaders:!0},async t=>{let n=t.headers?.get("cookie");if(!n)return t.json([]);let i=Object.fromEntries(Xe(n)),s=(await Promise.all(Object.entries(i).filter(([u])=>r(u)).map(async([u])=>await t.getSignedCookie(u,t.context.secret)))).filter(u=>u!==void 0);if(!s.length)return t.json([]);let d=(await t.context.internalAdapter.findSessions(s)).filter(u=>u&&u.session.expiresAt>new Date).filter((u,l,m)=>l===m.findIndex(f=>f.user.id===u.user.id));return Object.entries(i).filter(([u])=>r(u)).forEach(([u,l])=>{d.some(m=>m.session.id===l)||t.setCookie(u,"",{...t.context.authCookies.sessionToken.options,maxAge:0})}),t.json(d)}),setActiveSession:c("/multi-session/set-active",{method:"POST",body:We.z.object({sessionId:We.z.string()}),requireHeaders:!0,use:[b]},async t=>{let n=t.body.sessionId,i=`${t.context.authCookies.sessionToken.name}_multi-${n}`;if(!await t.getSignedCookie(i,t.context.secret))throw new v.APIError("UNAUTHORIZED",{message:"Invalid session id"});let a=await t.context.internalAdapter.findSession(n);if(!a||a.session.expiresAt<new Date)throw t.setCookie(i,"",{...t.context.authCookies.sessionToken.options,maxAge:0}),new v.APIError("UNAUTHORIZED",{message:"Invalid session id"});return await t.setSignedCookie(t.context.authCookies.sessionToken.name,n,t.context.secret,t.context.authCookies.sessionToken.options),t.json(a)}),revokeDeviceSession:c("/multi-session/revoke",{method:"POST",body:We.z.object({sessionId:We.z.string()}),requireHeaders:!0,use:[b]},async t=>{let n=t.body.sessionId,i=`${t.context.authCookies.sessionToken.name}_multi-${n}`;if(!await t.getSignedCookie(i,t.context.secret))throw new v.APIError("UNAUTHORIZED",{message:"Invalid session id"});let a=await t.context.internalAdapter.findSession(n);return t.setCookie(i,"",{...t.context.authCookies.sessionToken.options,maxAge:0}),a?(await t.context.internalAdapter.deleteSession(n),t.json({success:!0})):t.json({success:!0})})},hooks:{after:[{matcher:()=>!0,handler:S(async t=>{if(!t.context.returned||!(t.context.returned instanceof Response))return;let n=t.context.returned.headers.get("set-cookie");if(!n)return;let i=Ye(n),s=t.context.authCookies.sessionToken,a=i.get(s.name)?.value;if(!a)return;let d=Xe(t.headers?.get("cookie")||""),u=a.split(".")[0],l=`${s.name}_multi-${u}`;if(i.get(l)||d.get(l)||Object.keys(Object.fromEntries(d)).filter(r).length+(n.includes("session_token")?1:0)>o.maximumSessions)return;await t.setSignedCookie(l,u,t.context.secret,s.options);let f=t.context.returned;return f.headers.append("Set-Cookie",t.responseHeader.get("set-cookie")),{response:f}})},{matcher:t=>t.path==="/sign-out",handler:S(async t=>{if(!(t.context.returned instanceof Response))return;let n=t.headers?.get("cookie");if(!n)return;let i=Object.fromEntries(Xe(n));await Promise.all(Object.entries(i).map(async([a,d])=>{if(r(a)){t.setCookie(a,"",{maxAge:0});let u=a.split("_multi-")[1];await t.context.internalAdapter.deleteSession(u)}}));let s=t.context.returned;return s.headers.append("Set-Cookie",t.responseHeader.get("set-cookie")),{response:s}})}]}}};var X=require("zod");var zn=e=>{let o={expireIn:300,otpLength:6,...e};return{id:"email-otp",endpoints:{sendVerificationOTP:c("/email-otp/send-verification-otp",{method:"POST",body:X.z.object({email:X.z.string(),type:X.z.enum(["email-verification","sign-in"])})},async r=>{if(!e?.sendVerificationOTP)throw y.error("send email verification is not implemented"),new v.APIError("BAD_REQUEST",{message:"send email verification is not implemented"});let t=r.body.email,n=q(o.otpLength,M("0-9"));return await r.context.internalAdapter.createVerificationValue({value:n,identifier:`${r.body.type}-otp-${t}`,expiresAt:P(o.expireIn,"sec")}),await e.sendVerificationOTP({email:t,otp:n,type:r.body.type},r.request),r.json({success:!0})}),verifyEmailOTP:c("/email-otp/verify-email",{method:"POST",body:X.z.object({email:X.z.string(),otp:X.z.string()})},async r=>{let t=r.body.email,n=await r.context.internalAdapter.findVerificationValue(`email-verification-otp-${t}`);if(!n||n.expiresAt<new Date)throw n&&await r.context.internalAdapter.deleteVerificationValue(n.id),new v.APIError("BAD_REQUEST",{message:"Invalid OTP"});let i=r.body.otp;if(n.value!==i)throw new v.APIError("BAD_REQUEST",{message:"Invalid OTP"});await r.context.internalAdapter.deleteVerificationValue(n.id);let s=await r.context.internalAdapter.findUserByEmail(t);if(!s)throw new v.APIError("BAD_REQUEST",{message:"User not found"});let a=await r.context.internalAdapter.updateUser(s.user.id,{email:t,emailVerified:!0});return r.json({user:a})}),signInEmailOTP:c("/sign-in/email-otp",{method:"POST",body:X.z.object({email:X.z.string(),otp:X.z.string()})},async r=>{let t=r.body.email,n=await r.context.internalAdapter.findVerificationValue(`sign-in-otp-${t}`);if(!n||n.expiresAt<new Date)throw n&&await r.context.internalAdapter.deleteVerificationValue(n.id),new v.APIError("BAD_REQUEST",{message:"Invalid OTP"});let i=r.body.otp;if(n.value!==i)throw new v.APIError("BAD_REQUEST",{message:"Invalid OTP"});await r.context.internalAdapter.deleteVerificationValue(n.id);let s=await r.context.internalAdapter.findUserByEmail(t);if(!s){if(o.disableSignUp)throw new v.APIError("BAD_REQUEST",{message:"User not found"});let d=await r.context.internalAdapter.createUser({email:t,emailVerified:!0,name:t}),u=await r.context.internalAdapter.createSession(d.id,r.request);return await w(r,{session:u,user:d}),r.json({user:d,session:u})}let a=await r.context.internalAdapter.createSession(s.user.id,r.request);return await w(r,{session:a,user:s.user}),r.json({session:a,user:s})})},hooks:{after:[{matcher(r){return!!(r.path?.startsWith("/sign-up")&&o.sendVerificationOnSignUp)},async handler(r){let t=r.context.returned;if(t?.status!==200)return;let n=await t.clone().json();if(n.user.email&&n.user.emailVerified===!1){let i=q(o.otpLength,M("0-9"));await r.context.internalAdapter.createVerificationValue({value:i,identifier:`email-verification-otp-${n.user.email}`,expiresAt:P(o.expireIn,"sec")}),await e.sendVerificationOTP({email:n.user.email,otp:i,type:"email-verification"},r.request)}}}]}}};var Dt=require("zod");var uo=require("@better-fetch/fetch");function ao(e){return e==="true"||e===!0}var Bn=e=>({id:"one-tap",endpoints:{oneTapCallback:c("/one-tap/callback",{method:"POST",body:Dt.z.object({idToken:Dt.z.string()})},async o=>{let{idToken:r}=o.body,{data:t,error:n}=await(0,uo.betterFetch)("https://oauth2.googleapis.com/tokeninfo?id_token="+r);if(n)return o.json({error:"Invalid token"});let i=await o.context.internalAdapter.findUserByEmail(t.email);if(!i){if(e?.disableSignup)throw new v.APIError("BAD_GATEWAY",{message:"User not found"});let a=await o.context.internalAdapter.createOAuthUser({email:t.email,emailVerified:ao(t.email_verified),name:t.name,image:t.picture},{providerId:"google",accountId:t.sub});if(!a)throw new v.APIError("INTERNAL_SERVER_ERROR",{message:"Could not create user"});let d=await o.context.internalAdapter.createSession(a?.user.id,o.request);return await w(o,{user:a.user,session:d}),o.json({session:d,user:a})}let s=await o.context.internalAdapter.createSession(i.user.id,o.request);return await w(o,{user:i.user,session:s}),o.json({session:s,user:i})})}});var mt=require("zod");function xn(){let e=G.VERCEL_URL,o=G.NETLIFY_URL,r=G.RENDER_URL,t=G.AWS_LAMBDA_FUNCTION_NAME,n=G.GOOGLE_CLOUD_FUNCTION_NAME,i=G.AZURE_FUNCTION_NAME;return e||o||r||t||n||i}var Ln=e=>({id:"oauth-proxy",endpoints:{oAuthProxy:c("/oauth-proxy-callback",{method:"GET",query:mt.z.object({callbackURL:mt.z.string(),cookies:mt.z.string()})},async o=>{let r=o.query.cookies,t=await ce({key:o.context.secret,data:r});throw o.setHeader("set-cookie",t),o.redirect(o.query.callbackURL)})},hooks:{after:[{matcher(o){return o.path?.startsWith("/callback")},handler:S(async o=>{let r=o.context.returned;if(!r||!(r instanceof Response))return;let t=r.headers.get("location");if(t?.includes("/oauth-proxy-callback?callbackURL")){if(!t.startsWith("http"))return;let n=new URL(t);if(n.origin===Oe(o.context.baseURL)){let u=n.searchParams.get("callbackURL");return u?(r.headers.set("location",u),{response:r}):void 0}let s=r.headers.get("set-cookie");if(!s)return;let a=await re({key:o.context.secret,data:s}),d=`${t}&cookies=${encodeURIComponent(a)}`;return r.headers.set("location",d),{response:r}}})}],before:[{matcher(o){return o.path?.startsWith("/sign-in/social")},async handler(o){let r=new URL(e?.currentURL||o.request?.url||xn()||o.context.baseURL);return o.body.callbackURL=`${r.origin}${o.context.options.basePath||"/api/auth"}/oauth-proxy-callback?callbackURL=${encodeURIComponent(o.body.callbackURL||o.context.baseURL)}`,{context:o}}}]}});0&&(module.exports={HIDE_METADATA,admin,anonymous,bearer,createAuthEndpoint,createAuthMiddleware,emailOTP,genericOAuth,getPasskeyActions,jwt,magicLink,multiSession,oAuthProxy,oneTap,optionsMiddleware,organization,passkey,passkeyClient,phoneNumber,twoFactor,twoFactorClient,username});
package/dist/plugins.js CHANGED
@@ -81,4 +81,4 @@ import{APIError as Zt}from"better-call";import{z as Ie}from"zod";import{createEn
81
81
  </div>
82
82
  </body>
83
83
  </html>`,ho=c("/error",{method:"GET",metadata:he},async e=>{let o=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(go(o),{headers:{"Content-Type":"text/html"}})});import{APIError as v}from"better-call";async function be(e,{userInfo:o,account:r,callbackURL:t}){let n=await e.context.internalAdapter.findUserByEmail(o.email.toLowerCase(),{includeAccounts:!0}).catch(a=>{throw y.error(`Better auth was unable to query your database.
84
- Error: `,a),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)}),i=n?.user;if(n){let a=n.accounts.find(d=>d.providerId===r.providerId);if(a)await e.context.internalAdapter.updateAccount(a.id,{accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,expiresAt:r.expiresAt});else{if(!e.context.options.account?.accountLinking?.trustedProviders?.includes(r.providerId)&&!o.emailVerified||e.context.options.account?.accountLinking?.enabled===!1)return mt&&y.warn(`User already exist but account isn't linked to ${r.providerId}. To read more about how account linking works in Better Auth see https://www.better-auth.com/docs/concepts/users-accounts#account-linking.`),{error:"account not linked",data:null};try{await e.context.internalAdapter.linkAccount({providerId:r.providerId,accountId:o.id.toString(),id:e.context.uuid(),userId:n.user.id,accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,expiresAt:r.expiresAt})}catch(l){return y.error("Unable to link account",l),{error:"unable to link account",data:null}}}}else try{let a=o.emailVerified||!1;if(i=await e.context.internalAdapter.createOAuthUser({...o,id:e.context.uuid(),emailVerified:a,email:o.email.toLowerCase()},{accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,expiresAt:r.expiresAt,providerId:r.providerId,accountId:o.id.toString()}).then(d=>d?.user),!a&&i&&e.context.options.emailVerification?.sendOnSignUp){let d=await oe(e.context.secret,i.email),u=`${e.context.baseURL}/verify-email?token=${d}&callbackURL=${t}`;await e.context.options.emailVerification?.sendVerificationEmail?.({user:i,url:u,token:d},e.request)}}catch(a){return y.error("Unable to create user",a),{error:"unable to create user",data:null}}if(!i)return{error:"unable to create user",data:null};let s=await e.context.internalAdapter.createSession(i.id,e.request);return s?{data:{session:s,user:i},error:null}:{error:"unable to create session",data:null}}var wo=c("/sign-in/social",{method:"POST",query:z.object({currentURL:z.string().optional()}).optional(),body:z.object({callbackURL:z.string().optional(),provider:z.enum(je),idToken:z.optional(z.object({token:z.string(),nonce:z.string().optional(),accessToken:z.string().optional(),refreshToken:z.string().optional(),expiresAt:z.number().optional()}))})},async e=>{let o=e.context.socialProviders.find(i=>i.id===e.body.provider);if(!o)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new D("NOT_FOUND",{message:"Provider not found"});if(e.body.idToken){if(!o.verifyIdToken)throw e.context.logger.error("Provider does not support id token verification",{provider:e.body.provider}),new D("NOT_FOUND",{message:"Provider does not support id token verification"});let{token:i,nonce:s}=e.body.idToken;if(!await o.verifyIdToken(i,s))throw e.context.logger.error("Invalid id token",{provider:e.body.provider}),new D("UNAUTHORIZED",{message:"Invalid id token"});let d=await o.getUserInfo({idToken:i,accessToken:e.body.idToken.accessToken,refreshToken:e.body.idToken.refreshToken});if(!d||!d?.user)throw e.context.logger.error("Failed to get user info",{provider:e.body.provider}),new D("UNAUTHORIZED",{message:"Failed to get user info"});if(!d.user.email)throw e.context.logger.error("User email not found",{provider:e.body.provider}),new D("UNAUTHORIZED",{message:"User email not found"});let u=await be(e,{userInfo:{email:d.user.email,id:d.user.id,name:d.user.name||"",image:d.user.image,emailVerified:d.user.emailVerified||!1},account:{providerId:o.id,accountId:d.user.id,accessToken:e.body.idToken.accessToken}});if(u.error)throw new D("UNAUTHORIZED",{message:u.error});return await w(e,u.data),e.json({session:u.data.session,user:u.data.user,url:`${e.body.callbackURL||e.query?.currentURL||e.context.options.baseURL}`,redirect:!0})}let{codeVerifier:r,state:t}=await ye(e),n=await o.createAuthorizationURL({state:t,codeVerifier:r,redirectURI:`${e.context.baseURL}/callback/${o.id}`});return e.json({url:n.toString(),redirect:!0})}),yo=c("/sign-in/email",{method:"POST",body:z.object({email:z.string(),password:z.string(),callbackURL:z.string().optional(),rememberMe:z.boolean().default(!1).optional()})},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 D("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:o,password:r}=e.body;if(!z.string().email().safeParse(o).success)throw new D("BAD_REQUEST",{message:"Invalid email"});let n=await e.context.internalAdapter.findUserByEmail(o,{includeAccounts:!0});if(!n)throw await e.context.password.hash(r),e.context.logger.error("User not found",{email:o}),new D("UNAUTHORIZED",{message:"Invalid email or password"});let i=n.accounts.find(u=>u.providerId==="credential");if(!i)throw e.context.logger.error("Credential account not found",{email:o}),new D("UNAUTHORIZED",{message:"Invalid email or password"});let s=i?.password;if(!s)throw e.context.logger.error("Password not found",{email:o}),new D("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(s,r))throw e.context.logger.error("Invalid password"),new D("UNAUTHORIZED",{message:"Invalid email or password"});if(e.context.options?.emailAndPassword?.requireEmailVerification&&!n.user.emailVerified){if(!e.context.options?.emailVerification?.sendVerificationEmail)throw y.error("Email verification is required but no email verification handler is provided"),new D("INTERNAL_SERVER_ERROR",{message:"Email is not verified."});let u=await oe(e.context.secret,n.user.email),l=`${e.context.baseURL}/verify-email?token=${u}`;throw await e.context.options.emailVerification.sendVerificationEmail({user:n.user,url:l,token:u},e.request),e.context.logger.error("Email not verified",{email:o}),new D("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.rememberMe===!1);if(!d)throw e.context.logger.error("Failed to create session"),new D("UNAUTHORIZED",{message:"Failed to create session"});return await w(e,{session:d,user:n.user},e.body.rememberMe===!1),e.json({user:n.user,session:d,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});import{z as Ne}from"zod";var bo=c("/callback/:id",{method:["GET","POST"],query:Ne.object({state:Ne.string(),code:Ne.string().optional(),error:Ne.string().optional()}),metadata:he},async e=>{if(!e.query.code)throw e.redirect(`${e.context.baseURL}/error?error=${e.query.error||"no_code"}`);let o=e.context.socialProviders.find(k=>k.id===e.params.id);if(!o)throw e.context.logger.error("Oauth provider with id",e.params.id,"not found"),e.redirect(`${e.context.baseURL}/error?error=oauth_provider_not_found`);let{codeVerifier:r,callbackURL:t,link:n,errorURL:i}=await De(e),s;try{s=await o.validateAuthorizationCode({code:e.query.code,codeVerifier:r,redirectURI:`${e.context.baseURL}/callback/${o.id}`})}catch(k){throw e.context.logger.error(k),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let a=await o.getUserInfo(s).then(k=>k?.user),u={id:B(),...a};function l(k){let R=i||t||`${e.context.baseURL}/error`;throw R.includes("?")?R=`${R}&error=${k}`:R=`${R}?error=${k}`,e.redirect(R)}if(!a)return y.error("Unable to get user info"),l("unable_to_get_user_info");if(!u.email)return e.context.logger.error("Provider did not return email. This could be due to misconfiguration in the provider settings."),l("email_not_found");if(!t)throw y.error("No callback URL found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(n){if(n.email!==u.email.toLowerCase())return l("email_doesn't_match");if(!await e.context.internalAdapter.createAccount({userId:n.userId,providerId:o.id,accountId:a.id}))return l("unable_to_link_account");let R;try{R=new URL(t).toString()}catch{R=t}throw e.redirect(R)}let m=await be(e,{userInfo:{email:u.email,id:u.id,name:u.name||"",image:u.image,emailVerified:u.emailVerified||!1},account:{providerId:o.id,accountId:a.id,accessToken:s.accessToken,refreshToken:s.refreshToken,expiresAt:s.accessTokenExpiresAt},callbackURL:t});if(m.error)return l(m.error.split(" ").join("_"));let{session:f,user:p}=m.data;await w(e,{session:f,user:p});let h;try{h=new URL(t).toString()}catch{h=t}throw e.redirect(h)});import"zod";import{APIError as Po}from"better-call";var Ao=c("/sign-out",{method:"POST",requireHeaders:!0},async e=>{let o=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!o)throw new Po("BAD_REQUEST",{message:"Session not found"});return await e.context.internalAdapter.deleteSession(o),J(e),e.json({success:!0})});import{z as W}from"zod";import{APIError as Ve}from"better-call";function zt(e,o,r){let t=o?new URL(o,e.baseURL):new URL(`${e.baseURL}/error`);return r&&Object.entries(r).forEach(([n,i])=>t.searchParams.set(n,i)),t.href}function _o(e,o,r){let t=new URL(o,e.baseURL);return r&&Object.entries(r).forEach(([n,i])=>t.searchParams.set(n,i)),t.href}var ko=c("/forget-password",{method:"POST",body:W.object({email:W.string().email(),redirectTo:W.string()})},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 Ve("BAD_REQUEST",{message:"Reset password isn't enabled"});let{email:o,redirectTo:r}=e.body,t=await e.context.internalAdapter.findUserByEmail(o,{includeAccounts:!0});if(!t)return e.context.logger.error("Reset Password: User not found",{email:o}),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:t.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({user:t.user,url:a},e.request),e.json({status:!0})}),Oo=c("/reset-password/:token",{method:"GET",query:W.object({callbackURL:W.string()})},async e=>{let{token:o}=e.params,{callbackURL:r}=e.query;if(!o||!r)throw e.redirect(zt(e.context,r,{error:"INVALID_TOKEN"}));let t=await e.context.internalAdapter.findVerificationValue(`reset-password:${o}`);throw!t||t.expiresAt<new Date?e.redirect(zt(e.context,r,{error:"INVALID_TOKEN"})):e.redirect(_o(e.context,r,{token:o}))}),vo=c("/reset-password",{query:W.optional(W.object({token:W.string().optional(),currentURL:W.string().optional()})),method:"POST",body:W.object({newPassword:W.string()})},async e=>{let o=e.query?.token||(e.query?.currentURL?new URL(e.query.currentURL).searchParams.get("token"):"");if(!o)throw new Ve("BAD_REQUEST",{message:"Token not found"});let{newPassword:r}=e.body,t=`reset-password:${o}`,n=await e.context.internalAdapter.findVerificationValue(t);if(!n||n.expiresAt<new Date)throw new Ve("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 Ve("BAD_REQUEST",{message:"Failed to update password"});return e.json({status:!0})});import{z as V}from"zod";import{APIError as N}from"better-call";var Ro=c("/change-password",{method:"POST",body:V.object({newPassword:V.string(),currentPassword:V.string(),revokeOtherSessions:V.boolean().optional()}),use:[b]},async e=>{let{newPassword:o,currentPassword:r,revokeOtherSessions:t}=e.body,n=e.context.session,i=e.context.password.config.minPasswordLength;if(o.length<i)throw e.context.logger.error("Password is too short"),new N("BAD_REQUEST",{message:"Password is too short"});let s=e.context.password.config.maxPasswordLength;if(o.length>s)throw e.context.logger.error("Password is too long"),new N("BAD_REQUEST",{message:"Password too long"});let d=(await e.context.internalAdapter.findAccounts(n.user.id)).find(m=>m.providerId==="credential"&&m.password);if(!d||!d.password)throw new N("BAD_REQUEST",{message:"User does not have a password"});let u=await e.context.password.hash(o);if(!await e.context.password.verify(d.password,r))throw new N("BAD_REQUEST",{message:"Incorrect password"});if(await e.context.internalAdapter.updateAccount(d.id,{password:u}),t){await e.context.internalAdapter.deleteSessions(n.user.id);let m=await e.context.internalAdapter.createSession(n.user.id,e.headers);if(!m)throw new N("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});await w(e,{session:m,user:n.user})}return e.json(n.user)}),Eo=c("/set-password",{method:"POST",body:V.object({newPassword:V.string()}),metadata:{SERVER_ONLY:!0},use:[b]},async e=>{let{newPassword:o}=e.body,r=e.context.session,t=e.context.password.config.minPasswordLength;if(o.length<t)throw e.context.logger.error("Password is too short"),new N("BAD_REQUEST",{message:"Password is too short"});let n=e.context.password.config.maxPasswordLength;if(o.length>n)throw e.context.logger.error("Password is too long"),new N("BAD_REQUEST",{message:"Password too long"});let s=(await e.context.internalAdapter.findAccounts(r.user.id)).find(d=>d.providerId==="credential"&&d.password),a=await e.context.password.hash(o);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 N("BAD_REQUEST",{message:"user already has a password"})}),Uo=c("/delete-user",{method:"POST",body:V.object({password:V.string()}),use:[b]},async e=>{let{password:o}=e.body,r=e.context.session,n=(await e.context.internalAdapter.findAccounts(r.user.id)).find(s=>s.providerId==="credential"&&s.password);if(!n||!n.password)throw new N("BAD_REQUEST",{message:"User does not have a password"});if(!await e.context.password.verify(n.password,o))throw new N("BAD_REQUEST",{message:"Incorrect password"});return await e.context.internalAdapter.deleteUser(r.user.id),await e.context.internalAdapter.deleteSessions(r.user.id),J(e),e.json(null)}),Io=c("/change-email",{method:"POST",query:V.object({currentURL:V.string().optional()}).optional(),body:V.object({newEmail:V.string().email(),callbackURL:V.string().optional()}),use:[b]},async e=>{if(!e.context.options.user?.changeEmail?.enabled)throw e.context.logger.error("Change email is disabled."),new N("BAD_REQUEST",{message:"Change email is disabled"});if(e.body.newEmail===e.context.session.user.email)throw e.context.logger.error("Email is the same"),new N("BAD_REQUEST",{message:"Email is the same"});if(await e.context.internalAdapter.findUserByEmail(e.body.newEmail))throw e.context.logger.error("Email already exists"),new N("BAD_REQUEST",{message:"Couldn't update your email"});if(e.context.session.user.emailVerified!==!0){let n=await e.context.internalAdapter.updateUserByEmail(e.context.session.user.email,{email:e.body.newEmail});return e.json({user:n,status:!0})}if(!e.context.options.user.changeEmail.sendChangeEmailVerification)throw e.context.logger.error("Verification email isn't enabled."),new N("BAD_REQUEST",{message:"Verification email isn't enabled"});let r=await oe(e.context.secret,e.context.session.user.email,e.body.newEmail),t=`${e.context.baseURL}/verify-email?token=${r}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.user.changeEmail.sendChangeEmailVerification({user:e.context.session.user,newEmail:e.body.newEmail,url:t,token:r},e.request),e.json({user:null,status:!0})});import{z as Ee}from"zod";import{APIError as Bt}from"better-call";var To=c("/list-accounts",{method:"GET",use:[b]},async e=>{let o=e.context.session,r=await e.context.internalAdapter.findAccounts(o.user.id);return e.json(r.map(t=>({id:t.id,provider:t.providerId})))}),So=c("/link-social",{method:"POST",requireHeaders:!0,query:Ee.object({currentURL:Ee.string().optional()}).optional(),body:Ee.object({callbackURL:Ee.string().optional(),provider:Ee.enum(je)}),use:[b]},async e=>{let o=e.context.session;if((await e.context.internalAdapter.findAccounts(o.user.id)).find(a=>a.providerId===e.body.provider))throw new Bt("BAD_REQUEST",{message:"Social Account is already linked."});let n=e.context.socialProviders.find(a=>a.id===e.body.provider);if(!n)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new Bt("NOT_FOUND",{message:"Provider not found"});let i=await ye(e,{userId:o.user.id,email:o.user.email}),s=await n.createAuthorizationURL({state:i.state,codeVerifier:i.codeVerifier,redirectURI:`${e.context.baseURL}/callback/${n.id}`});return e.json({url:s.toString(),redirect:!0})});var xt=(e,o)=>{let r={};for(let[t,n]of Object.entries(e))r[t]=i=>n({...i,context:{...o,...i.context}}),r[t].path=n.path,r[t].method=n.method,r[t].options=n.options,r[t].headers=n.headers;return r};var Ae=class extends Error{path;constructor(o,r){super(o),this.path=r}},Fe=class{constructor(o){this.s=o;this.statements=o}statements;newRole(o){return new qe(o)}},qe=class e{statements;constructor(o){this.statements=o}authorize(o,r){for(let[t,n]of Object.entries(o)){let i=this.statements[t];if(!i)return{success:!1,error:`You are not allowed to access resource: ${t}`};let s=r==="OR"?n.some(a=>i.includes(a)):n.every(a=>i.includes(a));return s?{success:s}:{success:!1,error:`unauthorized to access resource "${t}"`}}return{success:!1,error:"Not authorized"}}static fromString(o){let r=JSON.parse(o);if(typeof r!="object")throw new Ae("statements is not an object",".");for(let[t,n]of Object.entries(r)){if(typeof t!="string")throw new Ae("invalid resource identifier",t);if(!Array.isArray(n))throw new Ae("actions is not an array",t);for(let i=0;i<n.length;i++)if(typeof n[i]!="string")throw new Ae("action is not a string",`${t}[${i}]`)}return new e(r)}toString(){return JSON.stringify(this.statements)}};var Co=e=>new Fe(e),zo={organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]},rt=Co(zo),Bo=rt.newRole({organization:["update"],invitation:["create","cancel"],member:["create","update","delete"]}),xo=rt.newRole({organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]}),Lo=rt.newRole({organization:[],member:[],invitation:[]}),Lt={admin:Bo,owner:xo,member:Lo};var _=(e,o)=>{let r=e.adapter;return{findOrganizationBySlug:async t=>await r.findOne({model:"organization",where:[{field:"slug",value:t}]}),createOrganization:async t=>{let n=await r.create({model:"organization",data:{...t.organization,metadata:t.organization.metadata?JSON.stringify(t.organization.metadata):void 0}}),i=await r.create({model:"member",data:{id:B(),organizationId:n.id,userId:t.user.id,createdAt:new Date,role:o?.creatorRole||"owner"}});return{...n,metadata:n.metadata?JSON.parse(n.metadata):void 0,members:[{...i,user:{id:t.user.id,name:t.user.name,email:t.user.email,image:t.user.image}}]}},findMemberByEmail:async t=>{let n=await r.findOne({model:e.tables.user.tableName,where:[{field:"email",value:t.email}]});if(!n)return null;let i=await r.findOne({model:"member",where:[{field:"organizationId",value:t.organizationId},{field:"userId",value:n.id}]});return i?{...i,user:{id:n.id,name:n.name,email:n.email,image:n.image}}:null},findMemberByOrgId:async t=>{let[n,i]=await Promise.all([await r.findOne({model:"member",where:[{field:"userId",value:t.userId},{field:"organizationId",value:t.organizationId}]}),await r.findOne({model:e.tables.user.tableName,where:[{field:"id",value:t.userId}]})]);return!i||!n?null:{...n,user:{id:i.id,name:i.name,email:i.email,image:i.image}}},findMemberById:async t=>{let n=await r.findOne({model:"member",where:[{field:"id",value:t}]});if(!n)return null;let i=await r.findOne({model:e.tables.user.tableName,where:[{field:"id",value:n.userId}]});return i?{...n,user:{id:i.id,name:i.name,email:i.email,image:i.image}}:null},createMember:async t=>await r.create({model:"member",data:t}),updateMember:async(t,n)=>await r.update({model:"member",where:[{field:"id",value:t}],update:{role:n}}),deleteMember:async t=>await r.delete({model:"member",where:[{field:"id",value:t}]}),updateOrganization:async(t,n)=>await r.update({model:"organization",where:[{field:"id",value:t}],update:n}),deleteOrganization:async t=>(await r.delete({model:"member",where:[{field:"organizationId",value:t}]}),await r.delete({model:"invitation",where:[{field:"organizationId",value:t}]}),await r.delete({model:"organization",where:[{field:"id",value:t}]}),t),setActiveOrganization:async(t,n)=>await r.update({model:e.tables.session.tableName,where:[{field:"id",value:t}],update:{activeOrganizationId:n}}),findOrganizationById:async t=>await r.findOne({model:"organization",where:[{field:"id",value:t}]}),findFullOrganization:async(t,n)=>{let[i,s,a]=await Promise.all([r.findOne({model:"organization",where:[{field:"id",value:t}]}),r.findMany({model:"invitation",where:[{field:"organizationId",value:t}]}),r.findMany({model:"member",where:[{field:"organizationId",value:t}]})]);if(!i)return null;let d=a.map(f=>f.userId),u=await r.findMany({model:e.tables.user.tableName,where:[{field:"id",value:d,operator:"in"}]}),l=new Map(u.map(f=>[f.id,f])),m=a.map(f=>{let p=l.get(f.userId);if(!p)throw new $("Unexpected error: User not found for member");return{...f,user:{id:p.id,name:p.name,email:p.email,image:p.image}}});return{...i,invitations:s,members:m}},listOrganizations:async t=>{let n=await r.findMany({model:"member",where:[{field:"userId",value:t}]});if(!n||n.length===0)return[];let i=n.map(a=>a.organizationId);return await r.findMany({model:"organization",where:[{field:"id",value:i,operator:"in"}]})},createInvitation:async({invitation:t,user:n})=>{let s=P(o?.invitationExpiresIn||1728e5);return await r.create({model:"invitation",data:{id:B(),email:t.email,role:t.role,organizationId:t.organizationId,status:"pending",expiresAt:s,inviterId:n.id}})},findInvitationById:async t=>await r.findOne({model:"invitation",where:[{field:"id",value:t}]}),findPendingInvitation:async t=>(await r.findMany({model:"invitation",where:[{field:"email",value:t.email},{field:"organizationId",value:t.organizationId},{field:"status",value:"pending"}]})).filter(i=>new Date(i.expiresAt)>new Date),updateInvitation:async t=>await r.update({model:"invitation",where:[{field:"id",value:t.invitationId}],update:{status:t.status}})}};import"better-call";var x=S(async e=>({})),L=S({use:[b]},async e=>({session:e.context.session}));import{z as M}from"zod";import{z as U}from"zod";var Me=U.enum(["admin","member","owner"]),Do=U.enum(["pending","accepted","rejected","canceled"]).default("pending"),Vu=U.object({id:U.string(),name:U.string(),slug:U.string(),logo:U.string().nullish(),metadata:U.record(U.string()).or(U.string().transform(e=>JSON.parse(e))).nullish(),createdAt:U.date()}),Fu=U.object({id:U.string(),organizationId:U.string(),userId:U.string(),role:Me,createdAt:U.date()}),qu=U.object({id:U.string(),organizationId:U.string(),email:U.string(),role:Me,status:Do,inviterId:U.string(),expiresAt:U.date()});import{APIError as T}from"better-call";var Dt=c("/organization/invite-member",{method:"POST",use:[x,L],body:M.object({email:M.string(),role:Me,organizationId:M.string().optional(),resend:M.boolean().optional()})},async e=>{if(!e.context.orgOptions.sendInvitationEmail)throw y.warn("Invitation email is not enabled. Pass `sendInvitationEmail` to the plugin options to enable it."),new T("BAD_REQUEST",{message:"Invitation email is not enabled"});let o=e.context.session,r=e.body.organizationId||o.session.activeOrganizationId;if(!r)throw new T("BAD_REQUEST",{message:"Organization not found"});let t=_(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)throw new T("BAD_REQUEST",{message:"Member not found!"});let i=e.context.roles[n.role];if(!i)throw new T("BAD_REQUEST",{message:"Role not found!"});if(i.authorize({invitation:["create"]}).error)throw new T("FORBIDDEN",{message:"You are not allowed to invite members"});if(await t.findMemberByEmail({email:e.body.email,organizationId:r}))throw new T("BAD_REQUEST",{message:"User is already a member of this organization"});if((await t.findPendingInvitation({email:e.body.email,organizationId:r})).length&&!e.body.resend)throw new T("BAD_REQUEST",{message:"User is already invited to this organization"});let u=await t.createInvitation({invitation:{role:e.body.role,email:e.body.email,organizationId:r},user:o.user}),l=await t.findOrganizationById(r);if(!l)throw new T("BAD_REQUEST",{message:"Organization not found"});return await e.context.orgOptions.sendInvitationEmail?.({id:u.id,role:u.role,email:u.email,organization:l,inviter:{...n,user:o.user}},e.request),e.json(u)}),jt=c("/organization/accept-invitation",{method:"POST",body:M.object({invitationId:M.string()}),use:[x,L]},async e=>{let o=e.context.session,r=_(e.context,e.context.orgOptions),t=await r.findInvitationById(e.body.invitationId);if(!t||t.expiresAt<new Date||t.status!=="pending")throw new T("BAD_REQUEST",{message:"Invitation not found!"});if(t.email!==o.user.email)throw new T("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.updateInvitation({invitationId:e.body.invitationId,status:"accepted"}),i=await r.createMember({id:B(),organizationId:t.organizationId,userId:o.user.id,role:t.role,createdAt:new Date});return await r.setActiveOrganization(o.session.id,t.organizationId),n?e.json({invitation:n,member:i}):e.json(null,{status:400,body:{message:"Invitation not found!"}})}),Nt=c("/organization/reject-invitation",{method:"POST",body:M.object({invitationId:M.string()}),use:[x,L]},async e=>{let o=e.context.session,r=_(e.context,e.context.orgOptions),t=await r.findInvitationById(e.body.invitationId);if(!t||t.expiresAt<new Date||t.status!=="pending")throw new T("BAD_REQUEST",{message:"Invitation not found!"});if(t.email!==o.user.email)throw new T("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.updateInvitation({invitationId:e.body.invitationId,status:"rejected"});return e.json({invitation:n,member:null})}),Vt=c("/organization/cancel-invitation",{method:"POST",body:M.object({invitationId:M.string()}),use:[x,L]},async e=>{let o=e.context.session,r=_(e.context,e.context.orgOptions),t=await r.findInvitationById(e.body.invitationId);if(!t)throw new T("BAD_REQUEST",{message:"Invitation not found!"});let n=await r.findMemberByOrgId({userId:o.user.id,organizationId:t.organizationId});if(!n)throw new T("BAD_REQUEST",{message:"Member not found!"});if(e.context.roles[n.role].authorize({invitation:["cancel"]}).error)throw new T("FORBIDDEN",{message:"You are not allowed to cancel this invitation"});let s=await r.updateInvitation({invitationId:e.body.invitationId,status:"canceled"});return e.json(s)}),Ft=c("/organization/get-invitation",{method:"GET",use:[x],requireHeaders:!0,query:M.object({id:M.string()})},async e=>{let o=await C(e);if(!o)throw new T("UNAUTHORIZED",{message:"Not authenticated"});let r=_(e.context,e.context.orgOptions),t=await r.findInvitationById(e.query.id);if(!t||t.status!=="pending"||t.expiresAt<new Date)throw new T("BAD_REQUEST",{message:"Invitation not found!"});if(t.email!==o.user.email)throw new T("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.findOrganizationById(t.organizationId);if(!n)throw new T("BAD_REQUEST",{message:"Organization not found"});let i=await r.findMemberByOrgId({userId:t.inviterId,organizationId:t.organizationId});if(!i)throw new T("BAD_REQUEST",{message:"Inviter is no longer a member of the organization"});return e.json({...t,organizationName:n.name,organizationSlug:n.slug,inviterEmail:i.user.email})});import{z as ce}from"zod";import{APIError as Ue}from"better-call";var qt=c("/organization/remove-member",{method:"POST",body:ce.object({memberIdOrEmail:ce.string(),organizationId:ce.string().optional()}),use:[x,L]},async e=>{let o=e.context.session,r=e.body.organizationId||o.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"No active organization found!"}});let t=_(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)throw new Ue("BAD_REQUEST",{message:"Member not found!"});let i=e.context.roles[n.role];if(!i)throw new Ue("BAD_REQUEST",{message:"Role not found!"});let s=o.user.email===e.body.memberIdOrEmail||n.id===e.body.memberIdOrEmail;if(s&&n.role===(e.context.orgOptions?.creatorRole||"owner"))throw new Ue("BAD_REQUEST",{message:"You cannot leave the organization as the owner"});if(!(s||i.authorize({member:["delete"]}).success))throw new Ue("UNAUTHORIZED",{message:"You are not allowed to delete this member"});let u=null;if(e.body.memberIdOrEmail.includes("@")?u=await t.findMemberByEmail({email:e.body.memberIdOrEmail,organizationId:r}):u=await t.findMemberById(e.body.memberIdOrEmail),u?.organizationId!==r)throw new Ue("BAD_REQUEST",{message:"Member not found!"});return await t.deleteMember(u.id),o.user.id===u.userId&&o.session.activeOrganizationId===u.organizationId&&await t.setActiveOrganization(o.session.id,null),e.json({member:u})}),Mt=c("/organization/update-member-role",{method:"POST",body:ce.object({role:ce.enum(["admin","member","owner"]),memberId:ce.string(),organizationId:ce.string().optional()}),use:[x,L]},async e=>{let o=e.context.session,r=e.body.organizationId||o.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"No active organization found!"}});let t=_(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)return e.json(null,{status:400,body:{message:"Member not found!"}});let i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({member:["update"]}).error||e.body.role==="owner"&&n.role!=="owner")return e.json(null,{body:{message:"You are not allowed to update this member"},status:403});let a=await t.updateMember(e.body.memberId,e.body.role);return a?e.json(a):e.json(null,{status:400,body:{message:"Member not found!"}})}),$t=c("/organization/get-active-member",{method:"GET",use:[x,L]},async e=>{let o=e.context.session,r=o.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"No active organization found!"}});let n=await _(e.context,e.context.orgOptions).findMemberByOrgId({userId:o.user.id,organizationId:r});return n?e.json(n):e.json(null,{status:400,body:{message:"Member not found!"}})});import{z as I}from"zod";import{APIError as le}from"better-call";var Qt=c("/organization/create",{method:"POST",body:I.object({name:I.string(),slug:I.string(),userId:I.string().optional(),logo:I.string().optional(),metadata:I.record(I.string(),I.any()).optional()}),use:[x,L]},async e=>{let o=e.context.session.user;if(!o)return e.json(null,{status:401});let r=e.context.orgOptions;if(!(typeof r?.allowUserToCreateOrganization=="function"?await r.allowUserToCreateOrganization(o):r?.allowUserToCreateOrganization===void 0?!0:r.allowUserToCreateOrganization))throw new le("FORBIDDEN",{message:"You are not allowed to create an organization"});let n=_(e.context,r),i=await n.listOrganizations(o.id);if(typeof r.organizationLimit=="number"?i.length>=r.organizationLimit:typeof r.organizationLimit=="function"?await r.organizationLimit(o):!1)throw new le("FORBIDDEN",{message:"You have reached the organization limit"});if(await n.findOrganizationBySlug(e.body.slug))throw new le("BAD_REQUEST",{message:"Organization with this slug already exists"});let d=await n.createOrganization({organization:{id:B(),slug:e.body.slug,name:e.body.name,logo:e.body.logo,createdAt:new Date,metadata:e.body.metadata},user:o});return e.json(d)}),Ht=c("/organization/update",{method:"POST",body:I.object({data:I.object({name:I.string().optional(),slug:I.string().optional(),logo:I.string().optional()}).partial(),organizationId:I.string().optional()}),requireHeaders:!0,use:[x]},async e=>{let o=await e.context.getSession(e);if(!o)throw new le("UNAUTHORIZED",{message:"User not found"});let r=e.body.organizationId||o.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"Organization id not found!"}});let t=_(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)return e.json(null,{status:400,body:{message:"User is not a member of this organization!"}});let i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({organization:["update"]}).error)return e.json(null,{body:{message:"You are not allowed to update this organization"},status:403});let a=await t.updateOrganization(r,e.body.data);return e.json(a)}),Wt=c("/organization/delete",{method:"POST",body:I.object({organizationId:I.string()}),requireHeaders:!0,use:[x]},async e=>{let o=await e.context.getSession(e);if(!o)return e.json(null,{status:401});let r=e.body.organizationId;if(!r)return e.json(null,{status:400,body:{message:"Organization id not found!"}});let t=_(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)return e.json(null,{status:400,body:{message:"User is not a member of this organization!"}});let i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({organization:["delete"]}).error)throw new le("FORBIDDEN",{message:"You are not allowed to delete this organization"});return r===o.session.activeOrganizationId&&await t.setActiveOrganization(o.session.id,null),await t.deleteOrganization(r),e.json(r)}),Gt=c("/organization/get-full-organization",{method:"GET",query:I.optional(I.object({organizationId:I.string().optional()})),requireHeaders:!0,use:[x,L]},async e=>{let o=e.context.session,r=e.query?.organizationId||o.session.activeOrganizationId;if(!r)return e.json(null,{status:200});let n=await _(e.context,e.context.orgOptions).findFullOrganization(r,e.context.db||void 0);if(!n)throw new le("BAD_REQUEST",{message:"Organization not found"});return e.json(n)}),Jt=c("/organization/set-active",{method:"POST",body:I.object({organizationId:I.string().nullable().optional()}),use:[L,x]},async e=>{let o=_(e.context,e.context.orgOptions),r=e.context.session,t=e.body.organizationId;if(t===null)return r.session.activeOrganizationId&&await o.setActiveOrganization(r.session.id,null),e.json(null);if(!t){let s=r.session.activeOrganizationId;if(!s)return e.json(null);t=s}if(!await o.findMemberByOrgId({userId:r.user.id,organizationId:t}))throw await o.setActiveOrganization(r.session.id,null),new le("FORBIDDEN",{message:"You are not a member of this organization"});await o.setActiveOrganization(r.session.id,t);let i=await o.findFullOrganization(t,e.context.db||void 0);return e.json(i)}),Kt=c("/organization/list",{method:"GET",use:[x,L]},async e=>{let r=await _(e.context,e.context.orgOptions).listOrganizations(e.context.session.user.id);return e.json(r)});var Rc=e=>{let o={createOrganization:Qt,updateOrganization:Ht,deleteOrganization:Wt,setActiveOrganization:Jt,getFullOrganization:Gt,listOrganization:Kt,createInvitation:Dt,cancelInvitation:Vt,acceptInvitation:jt,getInvitation:Ft,rejectInvitation:Nt,removeMember:qt,updateMemberRole:Mt,getActiveMember:$t},r={...Lt,...e?.roles};return{id:"organization",endpoints:{...xt(o,{orgOptions:e||{},roles:r,getSession:async n=>await C(n)}),hasPermission:c("/organization/has-permission",{method:"POST",requireHeaders:!0,body:Ie.object({permission:Ie.record(Ie.string(),Ie.array(Ie.string()))}),use:[L]},async n=>{if(!n.context.session.session.activeOrganizationId)throw new Zt("BAD_REQUEST",{message:"No active organization"});let s=await _(n.context).findMemberByOrgId({userId:n.context.session.user.id,organizationId:n.context.session.session.activeOrganizationId||""});if(!s)throw new Zt("UNAUTHORIZED",{message:"You are not a member of this organization"});let d=r[s.role].authorize(n.body.permission);return d.error?n.json({error:d.error,success:!1},{status:403}):n.json({error:null,success:!0})})},schema:{session:{fields:{activeOrganizationId:{type:"string",required:!1,fieldName:e?.schema?.session?.fields?.activeOrganizationId}}},organization:{fields:{name:{type:"string",required:!0,fieldName:e?.schema?.organization?.fields?.name},slug:{type:"string",unique:!0,fieldName:e?.schema?.organization?.fields?.slug},logo:{type:"string",required:!1,fieldName:e?.schema?.organization?.fields?.logo},createdAt:{type:"date",required:!0,fieldName:e?.schema?.organization?.fields?.createdAt},metadata:{type:"string",required:!1,fieldName:e?.schema?.organization?.fields?.metadata}}},member:{fields:{organizationId:{type:"string",required:!0,references:{model:"organization",field:"id"},fieldName:e?.schema?.member?.fields?.organizationId},userId:{type:"string",required:!0,fieldName:e?.schema?.member?.fields?.userId},role:{type:"string",required:!0,defaultValue:"member",fieldName:e?.schema?.member?.fields?.role},createdAt:{type:"date",required:!0,fieldName:e?.schema?.member?.fields?.createdAt}}},invitation:{fields:{organizationId:{type:"string",required:!0,references:{model:"organization",field:"id"},fieldName:e?.schema?.invitation?.fields?.organizationId},email:{type:"string",required:!0,fieldName:e?.schema?.invitation?.fields?.email},role:{type:"string",required:!1,fieldName:e?.schema?.invitation?.fields?.role},status:{type:"string",required:!0,defaultValue:"pending",fieldName:e?.schema?.invitation?.fields?.status},expiresAt:{type:"date",required:!0,fieldName:e?.schema?.invitation?.fields?.expiresAt},inviterId:{type:"string",references:{model:"user",field:"id"},fieldName:e?.schema?.invitation?.fields?.inviterId,required:!0}}}},$Infer:{Organization:{},Invitation:{},Member:{},ActiveOrganization:{}}}};import Yt from"uncrypto";function jo(e){return e.toString(2).padStart(8,"0")}function No(e){return[...e].map(o=>jo(o)).join("")}function Xt(e){return parseInt(No(e),2)}function Vo(e){if(e<0||!Number.isInteger(e))throw new Error("Argument 'max' must be an integer greater than or equal to 0");let o=(e-1).toString(2).length,r=o%8,t=new Uint8Array(Math.ceil(o/8));Yt.getRandomValues(t),r!==0&&(t[0]&=(1<<r)-1);let n=Xt(t);for(;n>=e;)Yt.getRandomValues(t),r!==0&&(t[0]&=(1<<r)-1),n=Xt(t);return n}function F(e,o){let r="";for(let t=0;t<e;t++)r+=o[Vo(o.length)];return r}function q(...e){let o=new Set(e),r="";for(let t of o)t==="a-z"?r+="abcdefghijklmnopqrstuvwxyz":t==="A-Z"?r+="ABCDEFGHIJKLMNOPQRSTUVWXYZ":t==="0-9"?r+="0123456789":r+=t;return r}import{z as Ge}from"zod";import{xchacha20poly1305 as tr}from"@noble/ciphers/chacha";import{bytesToHex as Fo,hexToBytes as qo,utf8ToBytes as Mo}from"@noble/ciphers/utils";import{managedNonce as rr}from"@noble/ciphers/webcrypto";import{sha256 as or}from"oslo/crypto";import er from"uncrypto";import{decodeHex as _c,encodeHex as Cc}from"oslo/encoding";import{scryptAsync as xc}from"@noble/hashes/scrypt";import{getRandomValues as Dc}from"uncrypto";async function Te(e,o){let r=new TextEncoder,t={name:"HMAC",hash:"SHA-256"},n=await er.subtle.importKey("raw",r.encode(e),t,!1,["sign","verify"]),i=await er.subtle.sign(t.name,n,r.encode(o));return btoa(String.fromCharCode(...new Uint8Array(i)))}var Z=async({key:e,data:o})=>{let r=await or(new TextEncoder().encode(e)),t=Mo(o),n=rr(tr)(new Uint8Array(r));return Fo(n.encrypt(t))},ne=async({key:e,data:o})=>{let r=await or(new TextEncoder().encode(e)),t=qo(o),n=rr(tr)(new Uint8Array(r));return new TextDecoder().decode(n.decrypt(t))};import{z as Y}from"zod";import{APIError as Se}from"better-call";var $e="two_factor";var Qe="trust_device";import{z as nr}from"zod";var me=S({body:nr.object({trustDevice:nr.boolean().optional()})},async e=>{let o=await C(e);if(!o){let r=e.context.createAuthCookie($e),t=await e.getSignedCookie(r.name,e.context.secret);if(!t)throw new Se("UNAUTHORIZED",{message:"invalid two factor cookie"});let n=await e.context.internalAdapter.findUserById(t);if(!n)throw new Se("UNAUTHORIZED",{message:"invalid two factor cookie"});let i=await e.context.internalAdapter.createSession(t,e.request);if(!i)throw new Se("INTERNAL_SERVER_ERROR",{message:"failed to create session"});return{valid:async()=>{if(await w(e,{session:i,user:n}),e.body.trustDevice){let s=e.context.createAuthCookie(Qe,{maxAge:2592e3}),a=await Te(e.context.secret,`${n.id}!${i.id}`);await e.setSignedCookie(s.name,`${a}!${i.id}`,e.context.secret,s.attributes)}return e.json({session:i,user:n})},invalid:async()=>{throw new Se("UNAUTHORIZED",{message:"invalid two factor authentication"})},session:{id:i.id,userId:i.userId,expiresAt:i.expiresAt,user:n}}}return{valid:async()=>e.json({session:o,user:o.user}),invalid:async()=>{throw new Se("UNAUTHORIZED",{message:"invalid two factor authentication"})},session:o}});import{APIError as Pe}from"better-call";function $o(e){return Array.from({length:e?.amount??10}).fill(null).map(()=>F(e?.length??10,q("a-z","0-9"))).map(o=>`${o.slice(0,5)}-${o.slice(5)}`)}async function ot(e,o){let r=e,t=o?.customBackupCodesGenerate?o.customBackupCodesGenerate():$o(),n=await Z({data:JSON.stringify(t),key:r});return{backupCodes:t,encryptedBackupCodes:n}}async function Qo(e,o){let r=await ir(e.backupCodes,o);return r?{status:r.includes(e.code),updated:r.filter(t=>t!==e.code)}:{status:!1,updated:null}}async function ir(e,o){let r=Buffer.from(await ne({key:o,data:e})).toString("utf-8"),t=JSON.parse(r),n=Y.array(Y.string()).safeParse(t);return n.success?n.data:null}var sr=(e,o)=>({id:"backup_code",endpoints:{verifyBackupCode:c("/two-factor/verify-backup-code",{method:"POST",body:Y.object({code:Y.string(),disableSession:Y.boolean().optional()}),use:[me]},async r=>{let t=r.context.session.user,n=await r.context.adapter.findOne({model:o,where:[{field:"userId",value:t.id}]});if(!n)throw new Pe("BAD_REQUEST",{message:"Backup codes aren't enabled"});let i=await Qo({backupCodes:n.backupCodes,code:r.body.code},r.context.secret);if(!i.status)throw new Pe("UNAUTHORIZED",{message:"Invalid backup code"});let s=await Z({key:r.context.secret,data:JSON.stringify(i.updated)});return await r.context.adapter.update({model:o,update:{backupCodes:s},where:[{field:"userId",value:t.id}]}),r.body.disableSession||await w(r,{session:r.context.session,user:t}),r.json({user:t,session:r.context.session})}),generateBackupCodes:c("/two-factor/generate-backup-codes",{method:"POST",body:Y.object({password:Y.string()}),use:[b]},async r=>{let t=r.context.session.user;if(!t.twoFactorEnabled)throw new Pe("BAD_REQUEST",{message:"Two factor isn't enabled"});await r.context.password.checkPassword(t.id,r);let n=await ot(r.context.secret,e);return await r.context.adapter.update({model:o,update:{backupCodes:n.encryptedBackupCodes},where:[{field:"userId",value:r.context.session.user.id}]}),r.json({status:!0,backupCodes:n.backupCodes})}),viewBackupCodes:c("/two-factor/view-backup-codes",{method:"GET",body:Y.object({userId:Y.string()}),metadata:{SERVER_ONLY:!0}},async r=>{let t=await r.context.adapter.findOne({model:o,where:[{field:"userId",value:r.body.userId}]});if(!t)throw new Pe("BAD_REQUEST",{message:"Backup codes aren't enabled"});let n=await ir(t.backupCodes,r.context.secret);if(!n)throw new Pe("BAD_REQUEST",{message:"Backup codes aren't enabled"});return r.json({status:!0,backupCodes:n})})}});import{APIError as He}from"better-call";import{TOTPController as Ho}from"oslo/otp";import{z as ar}from"zod";import{TimeSpan as Wo}from"oslo";var dr=(e,o)=>{let r={...e,period:new Wo(e?.period||3,"m")},t=new Ho({digits:6,period:r.period}),n=c("/two-factor/send-otp",{method:"POST",use:[me]},async s=>{if(!e||!e.sendOTP)throw s.context.logger.error("send otp isn't configured. Please configure the send otp function on otp options."),new He("BAD_REQUEST",{message:"otp isn't configured"});let a=s.context.session.user,d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d)throw new He("BAD_REQUEST",{message:"OTP isn't enabled"});let u=await t.generate(Buffer.from(d.secret));return await e.sendOTP({user:a,otp:u},s.request),s.json({status:!0})}),i=c("/two-factor/verify-otp",{method:"POST",body:ar.object({code:ar.string()}),use:[me]},async s=>{let a=s.context.session.user;if(!a.twoFactorEnabled)throw new He("BAD_REQUEST",{message:"two factor isn't enabled"});let d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d)throw new He("BAD_REQUEST",{message:"OTP isn't enabled"});return await t.generate(Buffer.from(d.secret))===s.body.code?s.context.valid():s.context.invalid()});return{id:"otp",endpoints:{send2FaOTP:n,verifyOTP:i}}};import{APIError as ke}from"better-call";import{TimeSpan as Go}from"oslo";import{TOTPController as ur,createTOTPKeyURI as Jo}from"oslo/otp";import{z as We}from"zod";var cr=(e,o)=>{let r={...e,digits:6,period:new Go(e?.period||30,"s")},t=c("/totp/generate",{method:"POST",use:[b]},async s=>{if(!e)throw s.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp"),new ke("BAD_REQUEST",{message:"totp isn't configured"});let a=s.context.session.user,d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d)throw new ke("BAD_REQUEST",{message:"totp isn't enabled"});return{code:await new ur(r).generate(Buffer.from(d.secret))}}),n=c("/two-factor/get-totp-uri",{method:"POST",use:[b],body:We.object({password:We.string()})},async s=>{if(!e)throw s.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp"),new ke("BAD_REQUEST",{message:"totp isn't configured"});let a=s.context.session.user,d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d||!a.twoFactorEnabled)throw new ke("BAD_REQUEST",{message:"totp isn't enabled"});return await s.context.password.checkPassword(a.id,s),{totpURI:Jo(e.issuer||s.context.appName,a.email,Buffer.from(d.secret),r)}}),i=c("/two-factor/verify-totp",{method:"POST",body:We.object({code:We.string()}),use:[me]},async s=>{if(!e)throw s.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp"),new ke("BAD_REQUEST",{message:"totp isn't configured"});let a=s.context.session.user,d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d)throw new ke("BAD_REQUEST",{message:"totp isn't enabled"});let u=new ur(r),l=await ne({key:s.context.secret,data:d.secret}),m=Buffer.from(l);if(!await u.verify(s.body.code,m))return s.context.invalid();if(!a.twoFactorEnabled){let p=await s.context.internalAdapter.updateUser(a.id,{twoFactorEnabled:!0}),h=await s.context.internalAdapter.createSession(a.id,s.request);await w(s,{session:h,user:p})}return s.context.valid()});return{id:"totp",endpoints:{generateTOTP:t,viewTOTPURI:n,verifyTOTP:i}}};import{APIError as _l}from"better-call";async function nt(e,o){let t=(await e.context.internalAdapter.findAccounts(o.userId))?.find(s=>s.providerId==="credential"),n=t?.password;return!t||!n?!1:await e.context.password.verify(n,o.password)}import{APIError as it}from"better-call";import{createTOTPKeyURI as Ko}from"oslo/otp";import{TimeSpan as Zo}from"oslo";var zl=(e={redirect:!0,twoFactorPage:"/"})=>({id:"two-factor",$InferServerPlugin:{},atomListeners:[{matcher:o=>o.startsWith("/two-factor/"),signal:"$sessionSignal"}],pathMethods:{"/two-factor/disable":"POST","/two-factor/enable":"POST","/two-factor/send-otp":"POST","/two-factor/generate-backup-codes":"POST"},fetchPlugins:[{id:"two-factor",name:"two-factor",hooks:{async onSuccess(o){o.data?.twoFactorRedirect&&(e.redirect||e.twoFactorPage)&&typeof window<"u"&&(window.location.href=e.twoFactorPage)}}}]});var Jl=e=>{let o={twoFactorTable:e?.twoFactorTable||"twoFactor"},r=cr({issuer:e?.issuer,...e?.totpOptions},o.twoFactorTable),t=sr({...e?.backupCodeOptions},o.twoFactorTable),n=dr({...e?.otpOptions},o.twoFactorTable);return{id:"two-factor",endpoints:{...r.endpoints,...n.endpoints,...t.endpoints,enableTwoFactor:c("/two-factor/enable",{method:"POST",body:Ge.object({password:Ge.string().min(8)}),use:[b]},async i=>{let s=i.context.session.user,{password:a}=i.body;if(!await nt(i,{password:a,userId:s.id}))throw new it("BAD_REQUEST",{message:"Invalid password"});let u=F(16,q("a-z","0-9","-")),l=await Z({key:i.context.secret,data:u}),m=await ot(i.context.secret,e?.backupCodeOptions);if(e?.skipVerificationOnEnable){let p=await i.context.internalAdapter.updateUser(s.id,{twoFactorEnabled:!0}),h=await i.context.internalAdapter.createSession(p.id,i.request);await w(i,{session:h,user:s})}await i.context.adapter.deleteMany({model:o.twoFactorTable,where:[{field:"userId",value:s.id}]}),await i.context.adapter.create({model:o.twoFactorTable,data:{id:i.context.uuid(),secret:l,backupCodes:m.encryptedBackupCodes,userId:s.id}});let f=Ko(e?.issuer||"BetterAuth",s.email,Buffer.from(u),{digits:e?.totpOptions?.digits||6,period:new Zo(e?.totpOptions?.period||30,"s")});return i.json({totpURI:f,backupCodes:m.backupCodes})}),disableTwoFactor:c("/two-factor/disable",{method:"POST",body:Ge.object({password:Ge.string().min(8)}),use:[b]},async i=>{let s=i.context.session.user,{password:a}=i.body;if(!await nt(i,{password:a,userId:s.id}))throw new it("BAD_REQUEST",{message:"Invalid password"});return await i.context.internalAdapter.updateUser(s.id,{twoFactorEnabled:!1}),await i.context.adapter.delete({model:o.twoFactorTable,where:[{field:"userId",value:s.id}]}),i.json({status:!0})})},options:e,hooks:{after:[{matcher(i){return i.path==="/sign-in/email"||i.path==="/sign-in/username"},handler:S(async i=>{let s=i.context.returned;if(s instanceof Response&&s?.status!==200||s instanceof it)return;let a=s instanceof Response?await s.clone().json():s;if(!a.user.twoFactorEnabled)return;let d=i.context.createAuthCookie(Qe,{maxAge:30*24*60*60}),u=await i.getSignedCookie(d.name,i.context.secret);if(u){let[f,p]=u.split("!"),h=await Te(i.context.secret,`${a.user.id}!${p}`);if(f===h){let k=await Te(i.context.secret,`${a.user.id}!${a.session.id}`);await i.setSignedCookie(d.name,`${k}!${a.session.id}`,i.context.secret,d.attributes);return}}J(i),await i.context.internalAdapter.deleteSession(a.session.id);let l=i.context.createAuthCookie($e,{maxAge:60*10});return await i.setSignedCookie(l.name,a.user.id,i.context.secret,l.attributes),{response:new Response(JSON.stringify({twoFactorRedirect:!0}),{headers:i.responseHeader})}})}]},schema:{user:{fields:{twoFactorEnabled:{type:"boolean",required:!1,defaultValue:!1,input:!1}}},twoFactor:{tableName:o.twoFactorTable,fields:{secret:{type:"string",required:!0,returned:!1},backupCodes:{type:"string",required:!0,returned:!1},userId:{type:"string",required:!0,returned:!1,references:{model:"user",field:"id"}}}}},rateLimit:[{pathMatcher(i){return i.startsWith("/two-factor/")},window:10,max:3}]}};import{generateAuthenticationOptions as sn,generateRegistrationOptions as an,verifyAuthenticationResponse as dn,verifyRegistrationResponse as un}from"@simplewebauthn/server";import{APIError as G}from"better-call";import{z as X}from"zod";import{WebAuthnError as en,startAuthentication as tn,startRegistration as rn}from"@simplewebauthn/browser";import{createFetch as pm}from"@better-fetch/fetch";import"nanostores";import"@better-fetch/fetch";import{atom as im}from"nanostores";import"@better-fetch/fetch";import{atom as Yo,onMount as Xo}from"nanostores";var st=(e,o,r,t)=>{let n=Yo({data:null,error:null,isPending:!0,isRefetching:!1}),i=()=>{let a=typeof t=="function"?t({data:n.get().data,error:n.get().error,isPending:n.get().isPending}):t;return r(o,{...a,onSuccess:async d=>{n.set({data:d.data,error:null,isPending:!1,isRefetching:!1}),await a?.onSuccess?.(d)},async onError(d){n.set({error:d.error,data:null,isPending:!1,isRefetching:!1}),await a?.onError?.(d)},async onRequest(d){let u=n.get();n.set({isPending:u.data===null,data:u.data,error:null,isRefetching:!0}),await a?.onRequest?.(d)}})};e=Array.isArray(e)?e:[e];let s=!1;for(let a of e)a.subscribe(()=>{s?i():Xo(n,()=>(i(),s=!0,()=>{n.off(),a.off()}))});return n};import{atom as on}from"nanostores";var nn=(e,{$listPasskeys:o})=>({signIn:{passkey:async(n,i)=>{let s=await e("/passkey/generate-authenticate-options",{method:"POST",body:{email:n?.email}});if(!s.data)return s;try{let a=await tn(s.data,n?.autoFill||!1),d=await e("/passkey/verify-authentication",{body:{response:a},...n?.fetchOptions,...i,method:"POST"});if(!d.data)return d}catch{return{data:null,error:{message:"auth cancelled",status:400,statusText:"BAD_REQUEST"}}}}},passkey:{addPasskey:async(n,i)=>{let s=await e("/passkey/generate-register-options",{method:"GET"});if(!s.data)return s;try{let a=await rn(s.data),d=await e("/passkey/verify-registration",{...n?.fetchOptions,...i,body:{response:a,name:n?.name},method:"POST"});if(!d.data)return d;o.set(Math.random())}catch(a){return a instanceof en?a.code==="ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED"?{data:null,error:{message:"previously registered",status:400,statusText:"BAD_REQUEST"}}:a.code==="ERROR_CEREMONY_ABORTED"?{data:null,error:{message:"registration cancelled",status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:a.message,status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:a instanceof Error?a.message:"unknown error",status:500,statusText:"INTERNAL_SERVER_ERROR"}}}}},$Infer:{}}),Bm=()=>{let e=on();return{id:"passkey",$InferServerPlugin:{},getActions:o=>nn(o,{$listPasskeys:e}),getAtoms(o){return{listPasskeys:st(e,"/passkey/list-user-passkeys",o,{method:"GET"}),$listPasskeys:e}},pathMethods:{"/passkey/register":"POST","/passkey/authenticate":"POST"},atomListeners:[{matcher(o){return o==="/passkey/verify-registration"||o==="/passkey/delete-passkey"},signal:"_listPasskeys"}]}};var Wm=e=>{let o=Q.BETTER_AUTH_URL,r=e?.rpID||o?.replace("http://","").replace("https://","").split(":")[0]||"localhost";if(!r)throw new $("passkey rpID not found. Please provide a rpID in the options or set the BETTER_AUTH_URL environment variable.");let t={origin:null,...e,rpID:r,advanced:{webAuthnChallengeCookie:"better-auth-passkey",...e?.advanced}},n=new Date(Date.now()+1e3*60*5),i=new Date,s=Math.floor((n.getTime()-i.getTime())/1e3);return{id:"passkey",endpoints:{generatePasskeyRegistrationOptions:c("/passkey/generate-register-options",{method:"GET",use:[b],metadata:{client:!1}},async a=>{let d=a.context.session,u=await a.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}),l=new Uint8Array(Buffer.from(F(32,q("a-z","0-9")))),m;m=await an({rpName:t.rpName||a.context.appName,rpID:t.rpID,userID:l,userName:d.user.email||d.user.id,attestationType:"none",excludeCredentials:u.map(p=>({id:p.id,transports:p.transports?.split(",")})),authenticatorSelection:{residentKey:"preferred",userVerification:"preferred",authenticatorAttachment:"platform"}});let f=B();return await a.setSignedCookie(t.advanced.webAuthnChallengeCookie,f,a.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:s}),await a.context.internalAdapter.createVerificationValue({identifier:f,value:JSON.stringify({expectedChallenge:m.challenge,userData:{id:d.user.id}}),expiresAt:n}),a.json(m,{status:200})}),generatePasskeyAuthenticationOptions:c("/passkey/generate-authenticate-options",{method:"POST",body:X.object({email:X.string().optional()}).optional()},async a=>{let d=await C(a),u=[];d&&(u=await a.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}));let l=await sn({rpID:t.rpID,userVerification:"preferred",...u.length?{allowCredentials:u.map(p=>({id:p.id,transports:p.transports?.split(",")}))}:{}}),m={expectedChallenge:l.challenge,userData:{id:d?.user.id||""}},f=B();return await a.setSignedCookie(t.advanced.webAuthnChallengeCookie,f,a.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:s}),await a.context.internalAdapter.createVerificationValue({identifier:f,value:JSON.stringify(m),expiresAt:n}),a.json(l,{status:200})}),verifyPasskeyRegistration:c("/passkey/verify-registration",{method:"POST",body:X.object({response:X.any(),name:X.string().optional()}),use:[b]},async a=>{let d=e?.origin||a.headers?.get("origin")||"";if(!d)return a.json(null,{status:400});let u=a.body.response,l=await a.getSignedCookie(t.advanced.webAuthnChallengeCookie,a.context.secret);if(!l)throw new G("BAD_REQUEST",{message:"Challenge not found"});let m=await a.context.internalAdapter.findVerificationValue(l);if(!m)return a.json(null,{status:400});let{expectedChallenge:f,userData:p}=JSON.parse(m.value);if(p.id!==a.context.session.user.id)throw new G("UNAUTHORIZED",{message:"You are not authorized to register this passkey"});try{let h=await un({response:u,expectedChallenge:f,expectedOrigin:d,expectedRPID:e?.rpID}),{verified:k,registrationInfo:R}=h;if(!k||!R)return a.json(null,{status:400});let{credentialID:K,credentialPublicKey:fe,counter:j,credentialDeviceType:Ye,credentialBackedUp:ge}=R,se=Buffer.from(fe).toString("base64"),Xe=B(),wr={name:a.body.name,userId:p.id,webauthnUserID:Xe,id:K,publicKey:se,counter:j,deviceType:Ye,transports:u.response.transports.join(","),backedUp:ge,createdAt:new Date},yr=await a.context.adapter.create({model:"passkey",data:wr});return a.json(yr,{status:200})}catch(h){throw console.log(h),new G("INTERNAL_SERVER_ERROR",{message:"Failed to verify registration"})}}),verifyPasskeyAuthentication:c("/passkey/verify-authentication",{method:"POST",body:X.object({response:X.any()})},async a=>{let d=e?.origin||a.headers?.get("origin")||"";if(!d)throw new G("BAD_REQUEST",{message:"origin missing"});let u=a.body.response,l=await a.getSignedCookie(t.advanced.webAuthnChallengeCookie,a.context.secret);if(!l)throw new G("BAD_REQUEST",{message:"Challenge not found"});let m=await a.context.internalAdapter.findVerificationValue(l);if(!m)throw new G("BAD_REQUEST",{message:"Challenge not found"});let{expectedChallenge:f}=JSON.parse(m.value),p=await a.context.adapter.findOne({model:"passkey",where:[{field:"id",value:u.id}]});if(!p)throw new G("UNAUTHORIZED",{message:"Passkey not found"});try{let h=await dn({response:u,expectedChallenge:f,expectedOrigin:d,expectedRPID:t.rpID,authenticator:{credentialID:p.id,credentialPublicKey:new Uint8Array(Buffer.from(p.publicKey,"base64")),counter:p.counter,transports:p.transports?.split(",")}}),{verified:k}=h;if(!k)throw new G("UNAUTHORIZED",{message:"Authentication failed"});await a.context.adapter.update({model:"passkey",where:[{field:"id",value:p.id}],update:{counter:h.authenticationInfo.newCounter}});let R=await a.context.internalAdapter.createSession(p.userId,a.request);if(!R)throw new G("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});let K=await a.context.internalAdapter.findUserById(p.userId);if(!K)throw new G("INTERNAL_SERVER_ERROR",{message:"User not found"});return await w(a,{session:R,user:K}),a.json({session:R},{status:200})}catch(h){throw a.context.logger.error(h),new G("BAD_REQUEST",{message:"Failed to verify authentication"})}}),listPasskeys:c("/passkey/list-user-passkeys",{method:"GET",use:[b]},async a=>{let d=await a.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:a.context.session.user.id}]});return a.json(d,{status:200})}),deletePasskey:c("/passkey/delete-passkey",{method:"POST",body:X.object({id:X.string()}),use:[b]},async a=>(await a.context.adapter.delete({model:"passkey",where:[{field:"id",value:a.body.id}]}),a.json(null,{status:200})))},schema:{passkey:{fields:{name:{type:"string",required:!1},publicKey:{type:"string",required:!0},userId:{type:"string",references:{model:"user",field:"id"},required:!0},webauthnUserID:{type:"string",required:!0},counter:{type:"number",required:!0},deviceType:{type:"string",required:!0},backedUp:{type:"boolean",required:!0},transports:{type:"string",required:!1},createdAt:{type:"date",defaultValue:new Date,required:!1}}}}}};import{z as Je}from"zod";import{APIError as Ke}from"better-call";var lr=()=>({id:"username",endpoints:{signInUsername:c("/sign-in/username",{method:"POST",body:Je.object({username:Je.string(),password:Je.string(),rememberMe:Je.boolean().optional()})},async e=>{let o=await e.context.adapter.findOne({model:e.context.tables.user.tableName,where:[{field:"username",value:e.body.username}]});if(!o)throw await e.context.password.hash(e.body.password),e.context.logger.error("User not found",{username:lr}),new Ke("UNAUTHORIZED",{message:"Invalid username or password"});let r=await e.context.adapter.findOne({model:e.context.tables.account.tableName,where:[{field:e.context.tables.account.fields.userId.fieldName||"userId",value:o.id},{field:e.context.tables.account.fields.providerId.fieldName||"providerId",value:"credential"}]});if(!r)throw new Ke("UNAUTHORIZED",{message:"Invalid username or password"});let t=r?.password;if(!t)throw e.context.logger.error("Password not found",{username:lr}),new Ke("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(t,e.body.password))throw e.context.logger.error("Invalid password"),new Ke("UNAUTHORIZED",{message:"Invalid username or password"});let i=await e.context.internalAdapter.createSession(o.id,e.request,e.body.rememberMe===!1);return i?(await e.setSignedCookie(e.context.authCookies.sessionToken.name,i.id,e.context.secret,e.body.rememberMe===!1?{...e.context.authCookies.sessionToken.options,maxAge:void 0}:e.context.authCookies.sessionToken.options),e.json({user:o,session:i})):e.json(null,{status:500,body:{message:"Failed to create session",status:500}})})},schema:{user:{fields:{username:{type:"string",required:!1,unique:!0,returned:!0}}}}});import{serializeSigned as cn}from"better-call";var tp=()=>({id:"bearer",hooks:{before:[{matcher(e){return!!(e.request?.headers.get("authorization")||e.headers?.get("authorization"))},handler:async e=>{let o=e.request?.headers.get("authorization")?.replace("Bearer ","")||e.headers?.get("authorization")?.replace("Bearer ","");if(!o)return;let r="";return o.includes(".")?r=o:r=await cn("",o,e.context.secret),e.request&&e.request.headers.set("cookie",`${e.context.authCookies.sessionToken.name}=${r.replace("=","")}`),e.headers&&e.headers.set("cookie",`${e.context.authCookies.sessionToken.name}=${r.replace("=","")}`),{context:e}}}]}});import{z as Oe}from"zod";import{APIError as mr}from"better-call";var dp=e=>({id:"magic-link",endpoints:{signInMagicLink:c("/sign-in/magic-link",{method:"POST",requireHeaders:!0,body:Oe.object({email:Oe.string().email(),callbackURL:Oe.string().optional()})},async o=>{let{email:r}=o.body;if(e.disableSignUp&&!await o.context.internalAdapter.findUserByEmail(r))throw new mr("BAD_REQUEST",{message:"User not found"});let t=F(32,q("a-z","A-Z"));await o.context.internalAdapter.createVerificationValue({identifier:t,value:r,expiresAt:new Date(Date.now()+(e.expiresIn||60*5)*1e3)});let n=`${o.context.baseURL}/magic-link/verify?token=${t}&callbackURL=${o.body.callbackURL||"/"}`;try{await e.sendMagicLink({email:r,url:n,token:t},o.request)}catch(i){throw o.context.logger.error("Failed to send magic link",i),new mr("INTERNAL_SERVER_ERROR",{message:"Failed to send magic link"})}return o.json({status:!0})}),magicLinkVerify:c("/magic-link/verify",{method:"GET",query:Oe.object({token:Oe.string(),callbackURL:Oe.string().optional()}),requireHeaders:!0},async o=>{let{token:r,callbackURL:t}=o.query,n=t?.startsWith("http")?t:t?`${o.context.options.baseURL}${t}`:o.context.options.baseURL,i=await o.context.internalAdapter.findVerificationValue(r);if(!i)throw o.redirect(`${n}?error=INVALID_TOKEN`);if(i.expiresAt<new Date)throw await o.context.internalAdapter.deleteVerificationValue(i.id),o.redirect(`${n}?error=EXPIRED_TOKEN`);await o.context.internalAdapter.deleteVerificationValue(i.id);let s=i.value,a=await o.context.internalAdapter.findUserByEmail(s),d=a?.user.id||"";if(!a){if(e.disableSignUp)throw o.redirect(`${n}?error=USER_NOT_FOUND`);if(d=(await o.context.internalAdapter.createUser({email:s,emailVerified:!0,name:s})).id,!d)throw o.redirect(`${n}?error=USER_NOT_CREATED`)}let u=await o.context.internalAdapter.createSession(d,o.headers);if(!u)throw o.redirect(`${n}?error=SESSION_NOT_CREATED`);if(await w(o,{session:u,user:a?.user}),!t)return o.json({status:!0});throw o.redirect(t)})},rateLimit:[{pathMatcher(o){return o.startsWith("/sign-in/magic-link")||o.startsWith("/magic-link/verify")},window:e.rateLimit?.window||60,max:e.rateLimit?.max||5}]});import{z as pe}from"zod";import{APIError as ie}from"better-call";function ln(e){return F(e,q("0-9"))}var yp=e=>{let o={phoneNumber:"phoneNumber",phoneNumberVerified:"phoneNumberVerified",code:"code",createdAt:"createdAt",expiresIn:e?.expiresIn||300,otpLength:e?.otpLength||6};return{id:"phone-number",endpoints:{sendPhoneNumberOTP:c("/phone-number/send-otp",{method:"POST",body:pe.object({phoneNumber:pe.string()})},async r=>{if(!e?.sendOTP)throw y.warn("sendOTP not implemented"),new ie("NOT_IMPLEMENTED",{message:"sendOTP not implemented"});let t=ln(o.otpLength);return await r.context.internalAdapter.createVerificationValue({value:t,identifier:r.body.phoneNumber,expiresAt:P(o.expiresIn,"sec")}),await e.sendOTP({phoneNumber:r.body.phoneNumber,code:t},r.request),r.json({code:t},{body:{message:"Code sent"}})}),verifyPhoneNumber:c("/phone-number/verify",{method:"POST",body:pe.object({phoneNumber:pe.string(),code:pe.string(),disableSession:pe.boolean().optional(),updatePhoneNumber:pe.boolean().optional()})},async r=>{let t=await r.context.internalAdapter.findVerificationValue(r.body.phoneNumber);if(!t||t.expiresAt<new Date)throw t&&t.expiresAt<new Date?(await r.context.internalAdapter.deleteVerificationValue(t.id),new ie("BAD_REQUEST",{message:"OTP expired"})):new ie("BAD_REQUEST",{message:"OTP not found"});if(t.value!==r.body.code)throw new ie("BAD_REQUEST",{message:"Invalid OTP"});if(await r.context.internalAdapter.deleteVerificationValue(t.id),r.body.updatePhoneNumber){let i=await C(r);if(!i)throw new ie("UNAUTHORIZED",{message:"Session not found"});let s=await r.context.internalAdapter.updateUser(i.user.id,{[o.phoneNumber]:r.body.phoneNumber,[o.phoneNumberVerified]:!0});return r.json({user:s,session:i.session})}let n=await r.context.adapter.findOne({model:r.context.tables.user.tableName,where:[{value:r.body.phoneNumber,field:o.phoneNumber}]});if(await e?.callbackOnVerification?.({phoneNumber:r.body.phoneNumber,user:n},r.request),n)n=await r.context.internalAdapter.updateUser(n.id,{[o.phoneNumberVerified]:!0});else if(e?.signUpOnVerification){if(n=await r.context.internalAdapter.createUser({email:e.signUpOnVerification.getTempEmail(r.body.phoneNumber),name:e.signUpOnVerification.getTempName?e.signUpOnVerification.getTempName(r.body.phoneNumber):r.body.phoneNumber,[o.phoneNumber]:r.body.phoneNumber,[o.phoneNumberVerified]:!0}),!n)throw new ie("INTERNAL_SERVER_ERROR",{message:"Failed to create user"})}else return r.json(null);if(!n)throw new ie("INTERNAL_SERVER_ERROR",{message:"Failed to update user"});if(!r.body.disableSession){let i=await r.context.internalAdapter.createSession(n.id,r.request);if(!i)throw new ie("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await w(r,{session:i,user:n}),r.json({user:n,session:i})}return r.json({user:n,session:null})})},schema:{user:{fields:{phoneNumber:{type:"string",required:!1,unique:!0,returned:!0},phoneNumberVerified:{type:"boolean",required:!1,returned:!0,input:!1}}}}}};import"zod";var Ip=e=>({id:"anonymous",endpoints:{signInAnonymous:c("/sign-in/anonymous",{method:"POST"},async o=>{let{emailDomainName:r=we(o.context.baseURL)}=e||{},t=B(),n=`temp-${t}@${r}`,i=await o.context.internalAdapter.createUser({id:t,email:n,emailVerified:!1,isAnonymous:!0,name:"Anonymous",createdAt:new Date,updatedAt:new Date});if(!i)return o.json(null,{status:500,body:{message:"Failed to create user",status:500}});let s=await o.context.internalAdapter.createSession(i.id,o.request);return s?(await w(o,{session:s,user:i}),o.json({user:i,session:s})):o.json(null,{status:400,body:{message:"Could not create session"}})})},hooks:{after:[{matcher(o){return o.path?.startsWith("/sign-in")||o.path?.startsWith("/sign-up")},async handler(o){let r=o.context.returned;if(!(r instanceof Response))return;let t=r.headers.get("set-cookie"),n=o.context.authCookies.sessionToken.name,i=xe(t||"").get(n)?.value.split(".")[0];if(!i)return;let s=await C(o);if(!(!s||!s.user.isAnonymous)){if(o.path==="/sign-in/anonymous")throw new v("BAD_REQUEST",{message:"Anonymous users cannot sign in again anonymously"});if(e?.onLinkAccount){let a=await o.context.internalAdapter.findSession(i);if(!a)return;await e?.onLinkAccount?.({anonymousUser:s,newUser:a})}e?.disableDeleteAnonymousUser||await o.context.internalAdapter.deleteUser(s.user.id)}}}]},schema:{user:{fields:{isAnonymous:{type:"boolean",required:!1}}}}});import{z as g}from"zod";var zp=e=>{let o={defaultRole:"user",adminRole:"admin",...e},r=S(async t=>{let n=await C(t);if(!n?.session)throw new v("UNAUTHORIZED");let i=n.user;if(!i.role||(Array.isArray(o.adminRole)?!o.adminRole.includes(i.role):i.role!==o.adminRole))throw new v("FORBIDDEN",{message:"Only admins can access this endpoint"});return{session:{user:i,session:n.session}}});return{id:"admin",init(t){return{options:{databaseHooks:{user:{create:{async before(n){if(e?.defaultRole!==!1)return{data:{role:e?.defaultRole??"user",...n}}}}},session:{create:{async before(n){let i=await t.internalAdapter.findUserById(n.userId);if(i.banned){if(i.banExpires&&i.banExpires<Date.now()){await t.internalAdapter.updateUser(n.userId,{banned:!1,banReason:null,banExpires:null});return}return!1}}}}}}}},hooks:{after:[{matcher(t){return t.path==="/list-sessions"},handler:S(async t=>{let n=t.context.returned;if(n instanceof Response){let s=(await n.clone().json()).filter(d=>!d.impersonatedBy),a=new Response(JSON.stringify(s),{status:200,statusText:"OK",headers:n.headers});return t.json({response:a})}})}]},endpoints:{setRole:c("/admin/set-role",{method:"POST",body:g.object({userId:g.string(),role:g.string()}),use:[r]},async t=>{let n=await t.context.internalAdapter.updateUser(t.body.userId,{role:t.body.role});return t.json({user:n})}),createUser:c("/admin/create-user",{method:"POST",body:g.object({email:g.string(),password:g.string(),name:g.string(),role:g.string(),data:g.optional(g.record(g.any()))}),use:[r]},async t=>{if(await t.context.internalAdapter.findUserByEmail(t.body.email))throw new v("BAD_REQUEST",{message:"User already exists"});let i=await t.context.internalAdapter.createUser({email:t.body.email,name:t.body.name,role:t.body.role,...t.body.data});if(!i)throw new v("INTERNAL_SERVER_ERROR",{message:"Failed to create user"});let s=await t.context.password.hash(t.body.password);return await t.context.internalAdapter.linkAccount({accountId:i.id,providerId:"credential",password:s,userId:i.id}),t.json({user:i})}),listUsers:c("/admin/list-users",{method:"GET",use:[r],query:g.object({searchValue:g.string().optional(),searchField:g.enum(["email","name"]).optional(),searchOperator:g.enum(["contains","starts_with","ends_with"]).optional(),limit:g.string().or(g.number()).optional(),offset:g.string().or(g.number()).optional(),sortBy:g.string().optional(),sortDirection:g.enum(["asc","desc"]).optional(),filterField:g.string().optional(),filterValue:g.string().or(g.number()).or(g.boolean()).optional(),filterOperator:g.enum(["eq","ne","lt","lte","gt","gte"]).optional()})},async t=>{let n=[];t.query?.searchValue&&n.push({field:t.query.searchField||"email",operator:t.query.searchOperator||"contains",value:t.query.searchValue}),t.query?.filterValue&&n.push({field:t.query.filterField||"email",operator:t.query.filterOperator||"eq",value:t.query.filterValue});try{let i=await t.context.internalAdapter.listUsers(Number(t.query?.limit)||void 0,Number(t.query?.offset)||void 0,t.query?.sortBy?{field:t.query.sortBy,direction:t.query.sortDirection||"asc"}:void 0,n.length?n:void 0);return t.json({users:i})}catch(i){return console.log(i),t.json({users:[]})}}),listUserSessions:c("/admin/list-user-sessions",{method:"POST",use:[r],body:g.object({userId:g.string()})},async t=>({sessions:await t.context.internalAdapter.listSessions(t.body.userId)})),unbanUser:c("/admin/unban-user",{method:"POST",body:g.object({userId:g.string()}),use:[r]},async t=>{let n=await t.context.internalAdapter.updateUser(t.body.userId,{banned:!1});return t.json({user:n})}),banUser:c("/admin/ban-user",{method:"POST",body:g.object({userId:g.string(),banReason:g.string().optional(),banExpiresIn:g.number().optional()}),use:[r]},async t=>{if(t.body.userId===t.context.session.user.id)throw new v("BAD_REQUEST",{message:"You cannot ban yourself"});let n=await t.context.internalAdapter.updateUser(t.body.userId,{banned:!0,banReason:t.body.banReason||e?.defaultBanReason||"No reason",banExpires:t.body.banExpiresIn?P(t.body.banExpiresIn,"sec"):e?.defaultBanExpiresIn?P(e.defaultBanExpiresIn,"sec"):void 0});return await t.context.internalAdapter.deleteSessions(t.body.userId),t.json({user:n})}),impersonateUser:c("/admin/impersonate-user",{method:"POST",body:g.object({userId:g.string()}),use:[r]},async t=>{let n=await t.context.internalAdapter.findUserById(t.body.userId);if(!n)throw new v("NOT_FOUND",{message:"User not found"});let i=await t.context.internalAdapter.createSession(n.id,void 0,!0,{impersonatedBy:t.context.session.user.id,expiresAt:e?.impersonationSessionDuration?P(e.impersonationSessionDuration,"sec"):P(60*60,"sec")});if(!i)throw new v("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await w(t,{session:i,user:n},!0),t.json({session:i,user:n})}),revokeUserSession:c("/admin/revoke-user-session",{method:"POST",body:g.object({sessionId:g.string()}),use:[r]},async t=>(await t.context.internalAdapter.deleteSession(t.body.sessionId),t.json({success:!0}))),revokeUserSessions:c("/admin/revoke-user-sessions",{method:"POST",body:g.object({userId:g.string()}),use:[r]},async t=>(await t.context.internalAdapter.deleteSessions(t.body.userId),t.json({success:!0}))),removeUser:c("/admin/remove-user",{method:"POST",body:g.object({userId:g.string()}),use:[r]},async t=>(await t.context.internalAdapter.deleteUser(t.body.userId),t.json({success:!0})))},schema:{user:{fields:{role:{type:"string",required:!1,input:!1},banned:{type:"boolean",defaultValue:!1,required:!1,input:!1},banReason:{type:"string",required:!1,input:!1},banExpires:{type:"date",required:!1,input:!1}}},session:{fields:{impersonatedBy:{type:"string",required:!1}}}}}};import{z as ee}from"zod";import{APIError as _e}from"better-call";import{betterFetch as at}from"@better-fetch/fetch";import{parseJWT as mn}from"oslo/jwt";async function pn(e,o,r){if(o==="oidc"&&e.idToken){let n=mn(e.idToken);if(n?.payload)return n.payload}return r?(await at(r,{method:"GET",headers:{Authorization:`Bearer ${e.accessToken}`}})).data:null}var Wp=e=>({id:"generic-oauth",endpoints:{signInWithOAuth2:c("/sign-in/oauth2",{method:"POST",query:ee.object({currentURL:ee.string().optional()}).optional(),body:ee.object({providerId:ee.string(),callbackURL:ee.string().optional()})},async o=>{let{providerId:r}=o.body,t=e.config.find(se=>se.providerId===r);if(!t)throw new _e("BAD_REQUEST",{message:`No config found for provider ${r}`});let{discoveryUrl:n,authorizationUrl:i,tokenUrl:s,clientId:a,clientSecret:d,scopes:u,redirectURI:l,responseType:m,pkce:f,prompt:p,accessType:h}=t,k=i,R=s;if(n){let se=await at(n,{onError(Xe){y.error(Xe.error,{discoveryUrl:n})}});se.data&&(k=se.data.authorization_endpoint,R=se.data.token_endpoint)}if(!k||!R)throw new _e("BAD_REQUEST",{message:"Invalid OAuth configuration."});let K=o.query?.currentURL?new URL(o.query?.currentURL):null,fe=o.body.callbackURL?.startsWith("http")?o.body.callbackURL:`${K?.origin}${o.body.callbackURL||""}`,{state:j,codeVerifier:Ye}=await ye(o),ge=await E({id:r,options:{clientId:a,clientSecret:d,redirectURI:l},authorizationEndpoint:k,state:j,codeVerifier:f?Ye:void 0,scopes:u||[],redirectURI:`${o.context.baseURL}/oauth2/callback/${r}`});return m&&m!=="code"&&ge.searchParams.set("response_type",m),p&&ge.searchParams.set("prompt",p),h&&ge.searchParams.set("access_type",h),o.json({url:ge.toString(),redirect:!0})}),oAuth2Callback:c("/oauth2/callback/:providerId",{method:"GET",query:ee.object({code:ee.string().optional(),error:ee.string().optional(),state:ee.string()})},async o=>{if(o.query.error||!o.query.code)throw o.redirect(`${o.context.baseURL}?error=${o.query.error||"oAuth_code_missing"}`);let r=e.config.find(j=>j.providerId===o.params.providerId);if(!r)throw new _e("BAD_REQUEST",{message:`No config found for provider ${o.params.providerId}`});let t,n=await De(o),{callbackURL:i,codeVerifier:s,errorURL:a}=n,d=o.query.code,u=r.tokenUrl,l=r.userInfoUrl;if(r.discoveryUrl){let j=await at(r.discoveryUrl,{method:"GET"});j.data&&(u=j.data.token_endpoint,l=j.data.userinfo_endpoint)}try{if(!u)throw new _e("BAD_REQUEST",{message:"Invalid OAuth configuration."});t=await O({code:d,codeVerifier:s,redirectURI:`${o.context.baseURL}/oauth2/callback/${r.providerId}`,options:{clientId:r.clientId,clientSecret:r.clientSecret},tokenEndpoint:u})}catch(j){throw o.context.logger.error(j),o.redirect(`${a}?error=oauth_code_verification_failed`)}if(!t)throw new _e("BAD_REQUEST",{message:"Invalid OAuth configuration."});let m=r.getUserInfo?await r.getUserInfo(t):await pn(t,r.type||"oauth2",l),f=B(),p=Ct.safeParse({...m,id:f});if(!m||p.success===!1)throw y.error("Unable to get user info",p.error),o.redirect(`${o.context.baseURL}/error?error=please_restart_the_process`);let h=await be(o,{userInfo:p.data,account:{providerId:r.providerId,accountId:m.id,accessToken:t.accessToken}});function k(j){throw o.redirect(`${a||i||`${o.context.baseURL}/error`}?error=${j}`)}if(h.error)return k(h.error.split(" ").join("_"));let{session:R,user:K}=h.data;await w(o,{session:R,user:K});let fe;try{fe=new URL(i).toString()}catch{fe=i}throw o.redirect(fe)})}});import{z as Ce}from"zod";var pr={jwks:{fields:{publicKey:{type:"string",required:!0},privateKey:{type:"string",required:!0},createdAt:{type:"date",required:!0}}}},Kp=Ce.object({id:Ce.string(),publicKey:Ce.string(),privateKey:Ce.string(),createdAt:Ce.date()});var dt=e=>({getAllKeys:async()=>await e.findMany({model:"jwks"}),getLatestKey:async()=>(await e.findMany({model:"jwks",sortBy:{field:"createdAt",direction:"desc"},limit:1}))[0],createJwk:async o=>await e.create({model:"jwks",data:{...o,createdAt:new Date}})});import{exportJWK as fr,generateKeyPair as fn,importJWK as gn,SignJWT as hn}from"jose";var nf=e=>({id:"jwt",endpoints:{getJwks:c("/jwks",{method:"GET"},async o=>{let t=await dt(o.context.adapter).getAllKeys();return o.json({keys:t.map(n=>({...JSON.parse(n.publicKey),kid:n.id}))})}),getToken:c("/token",{method:"GET",requireHeaders:!0,use:[b]},async o=>{let r=dt(o.context.adapter),t=await r.getLatestKey(),n=!e?.jwks?.disablePrivateKeyEncryption;if(t===void 0){let{publicKey:u,privateKey:l}=await fn(e?.jwks?.keyPairConfig?.alg??"EdDSA",e?.jwks?.keyPairConfig??{crv:"Ed25519"}),m=await fr(u),f=await fr(l),p=JSON.stringify(f),h={id:crypto.randomUUID(),publicKey:JSON.stringify(m),privateKey:n?JSON.stringify(await Z({key:o.context.options.secret,data:p})):p,createdAt:new Date};t=await r.createJwk(h)}let i=n?await ne({key:o.context.options.secret,data:JSON.parse(t.privateKey)}):t.privateKey,s=await gn(JSON.parse(i)),a=e?.jwt?.definePayload?await e?.jwt.definePayload(o.context.session.user):o.context.session.user,d=await new hn({...a,...o.context.session.session.impersonatedBy?{impersonatedBy:o.context.session.session.impersonatedBy}:{}}).setProtectedHeader({alg:e?.jwks?.keyPairConfig?.alg??"EdDSA",kid:t.id}).setIssuedAt().setIssuer(e?.jwt?.issuer??o.context.options.baseURL).setAudience(e?.jwt?.audience??o.context.options.baseURL).setExpirationTime(e?.jwt?.expirationTime??"15m").setSubject(o.context.session.user.id).sign(s);return o.json({token:d})})},schema:pr});import{z as Ze}from"zod";var cf=e=>{let o={maximumSessions:5,...e},r=t=>t.includes("_multi-");return{id:"multi-session",endpoints:{listDeviceSessions:c("/multi-session/list-device-sessions",{method:"GET",requireHeaders:!0},async t=>{let n=t.headers?.get("cookie");if(!n)return t.json([]);let i=Object.fromEntries(Le(n)),s=(await Promise.all(Object.entries(i).filter(([u])=>r(u)).map(async([u])=>await t.getSignedCookie(u,t.context.secret)))).filter(u=>u!==void 0);if(!s.length)return t.json([]);let d=(await t.context.internalAdapter.findSessions(s)).filter(u=>u&&u.session.expiresAt>new Date).filter((u,l,m)=>l===m.findIndex(f=>f.user.id===u.user.id));return t.json(d)}),setActiveSession:c("/multi-session/set-active",{method:"POST",body:Ze.object({sessionId:Ze.string()}),requireHeaders:!0,use:[b]},async t=>{let n=t.body.sessionId,i=`${t.context.authCookies.sessionToken.name}_multi-${n}`;if(!await t.getSignedCookie(i,t.context.secret))throw new v("UNAUTHORIZED",{message:"Invalid session id"});let a=await t.context.internalAdapter.findSession(n);if(!a||a.session.expiresAt<new Date)throw t.setCookie(i,"",{...t.context.authCookies.sessionToken.options,maxAge:0}),new v("UNAUTHORIZED",{message:"Invalid session id"});return await t.setSignedCookie(t.context.authCookies.sessionToken.name,n,t.context.secret,t.context.authCookies.sessionToken.options),t.json(a)}),revokeDeviceSession:c("/multi-session/revoke",{method:"POST",body:Ze.object({sessionId:Ze.string()}),requireHeaders:!0,use:[b]},async t=>{let n=t.body.sessionId,i=`${t.context.authCookies.sessionToken.name}_multi-${n}`;if(!await t.getSignedCookie(i,t.context.secret))throw new v("UNAUTHORIZED",{message:"Invalid session id"});let a=await t.context.internalAdapter.findSession(n);return t.setCookie(i,"",{...t.context.authCookies.sessionToken.options,maxAge:0}),a?(await t.context.internalAdapter.deleteSession(n),t.json({success:!0})):t.json({success:!0})})},hooks:{after:[{matcher:()=>!0,handler:S(async t=>{if(!t.context.returned||!(t.context.returned instanceof Response))return;let n=t.context.returned.headers.get("set-cookie");if(!n)return;let i=xe(n),s=t.context.authCookies.sessionToken,a=i.get(s.name)?.value;if(!a)return;let d=Le(t.headers?.get("cookie")||""),u=a.split(".")[0],l=`${s.name}_multi-${u}`;if(i.get(l)||d.get(l)||Object.keys(Object.fromEntries(d)).filter(r).length+(n.includes("session_token")?1:0)>o.maximumSessions)return;await t.setSignedCookie(l,u,t.context.secret,s.options);let f=t.context.returned;return f.headers.append("Set-Cookie",t.responseHeader.get("set-cookie")),{response:f}})},{matcher:t=>t.path==="/sign-out",handler:S(async t=>{if(!(t.context.returned instanceof Response))return;let n=t.headers?.get("cookie");if(!n)return;let i=Object.fromEntries(Le(n));await Promise.all(Object.entries(i).map(async([a,d])=>{if(r(a)){t.setCookie(a,"",{maxAge:0});let u=a.split("_multi-")[1];await t.context.internalAdapter.deleteSession(u)}}));let s=t.context.returned;return s.headers.append("Set-Cookie",t.responseHeader.get("set-cookie")),{response:s}})}]}}};import{z as te}from"zod";var bf=e=>{let o={expireIn:300,otpLength:6,...e};return{id:"email-otp",endpoints:{sendVerificationOTP:c("/email-otp/send-verification-otp",{method:"POST",body:te.object({email:te.string(),type:te.enum(["email-verification","sign-in"])})},async r=>{if(!e?.sendVerificationOTP)throw y.error("send email verification is not implemented"),new v("BAD_REQUEST",{message:"send email verification is not implemented"});let t=r.body.email,n=F(o.otpLength,q("0-9"));return await r.context.internalAdapter.createVerificationValue({value:n,identifier:`${r.body.type}-otp-${t}`,expiresAt:P(o.expireIn,"sec")}),await e.sendVerificationOTP({email:t,otp:n,type:r.body.type},r.request),r.json({success:!0})}),verifyEmailOTP:c("/email-otp/verify-email",{method:"POST",body:te.object({email:te.string(),otp:te.string()})},async r=>{let t=r.body.email,n=await r.context.internalAdapter.findVerificationValue(`email-verification-otp-${t}`);if(!n||n.expiresAt<new Date)throw n&&await r.context.internalAdapter.deleteVerificationValue(n.id),new v("BAD_REQUEST",{message:"Invalid OTP"});let i=r.body.otp;if(n.value!==i)throw new v("BAD_REQUEST",{message:"Invalid OTP"});await r.context.internalAdapter.deleteVerificationValue(n.id);let s=await r.context.internalAdapter.findUserByEmail(t);if(!s)throw new v("BAD_REQUEST",{message:"User not found"});let a=await r.context.internalAdapter.updateUser(s.user.id,{email:t,emailVerified:!0});return r.json({user:a})}),signInEmailOTP:c("/sign-in/email-otp",{method:"POST",body:te.object({email:te.string(),otp:te.string()})},async r=>{let t=r.body.email,n=await r.context.internalAdapter.findVerificationValue(`sign-in-otp-${t}`);if(!n||n.expiresAt<new Date)throw n&&await r.context.internalAdapter.deleteVerificationValue(n.id),new v("BAD_REQUEST",{message:"Invalid OTP"});let i=r.body.otp;if(n.value!==i)throw new v("BAD_REQUEST",{message:"Invalid OTP"});await r.context.internalAdapter.deleteVerificationValue(n.id);let s=await r.context.internalAdapter.findUserByEmail(t);if(!s){if(o.disableSignUp)throw new v("BAD_REQUEST",{message:"User not found"});let d=await r.context.internalAdapter.createUser({email:t,emailVerified:!0,name:t}),u=await r.context.internalAdapter.createSession(d.id,r.request);return await w(r,{session:u,user:d}),r.json({user:d,session:u})}let a=await r.context.internalAdapter.createSession(s.user.id,r.request);return await w(r,{session:a,user:s.user}),r.json({session:a,user:s})})},hooks:{after:[{matcher(r){return!!(r.path?.startsWith("/sign-up")&&o.sendVerificationOnSignUp)},async handler(r){let t=r.context.returned;if(t?.status!==200)return;let n=await t.clone().json();if(n.user.email&&n.user.emailVerified===!1){let i=F(o.otpLength,q("0-9"));await r.context.internalAdapter.createVerificationValue({value:i,identifier:`email-verification-otp-${n.user.email}`,expiresAt:P(o.expireIn,"sec")}),await e.sendVerificationOTP({email:n.user.email,otp:i,type:"email-verification"},r.request)}}}]}}};import{z as hr}from"zod";import{betterFetch as wn}from"@better-fetch/fetch";function gr(e){return e==="true"||e===!0}var If=e=>({id:"one-tap",endpoints:{oneTapCallback:c("/one-tap/callback",{method:"POST",body:hr.object({idToken:hr.string()})},async o=>{let{idToken:r}=o.body,{data:t,error:n}=await wn("https://oauth2.googleapis.com/tokeninfo?id_token="+r);if(n)return o.json({error:"Invalid token"});let i=await o.context.internalAdapter.findUserByEmail(t.email);if(!i){if(e?.disableSignup)throw new v("BAD_GATEWAY",{message:"User not found"});let a=await o.context.internalAdapter.createOAuthUser({email:t.email,emailVerified:gr(t.email_verified),name:t.name,image:t.picture},{providerId:"google",accountId:t.sub});if(!a)throw new v("INTERNAL_SERVER_ERROR",{message:"Could not create user"});let d=await o.context.internalAdapter.createSession(a?.user.id,o.request);return await w(o,{user:a.user,session:d}),o.json({session:d,user:a})}let s=await o.context.internalAdapter.createSession(i.user.id,o.request);return await w(o,{user:i.user,session:s}),o.json({session:s,user:i})})}});import{z as ut}from"zod";function yn(){let e=Q.VERCEL_URL,o=Q.NETLIFY_URL,r=Q.RENDER_URL,t=Q.AWS_LAMBDA_FUNCTION_NAME,n=Q.GOOGLE_CLOUD_FUNCTION_NAME,i=Q.AZURE_FUNCTION_NAME;return e||o||r||t||n||i}var Bf=e=>({id:"oauth-proxy",endpoints:{oAuthProxy:c("/oauth-proxy-callback",{method:"GET",query:ut.object({callbackURL:ut.string(),cookies:ut.string()})},async o=>{let r=o.query.cookies,t=await ne({key:o.context.secret,data:r});throw o.setHeader("set-cookie",t),o.redirect(o.query.callbackURL)})},hooks:{after:[{matcher(o){return o.path?.startsWith("/callback")},handler:S(async o=>{let r=o.context.returned;if(!r||!(r instanceof Response))return;let t=r.headers.get("location");if(t?.includes("/oauth-proxy-callback?callbackURL")){if(!t.startsWith("http"))return;let n=new URL(t);if(n.origin===we(o.context.baseURL)){let u=n.searchParams.get("callbackURL");return u?(r.headers.set("location",u),{response:r}):void 0}let s=r.headers.get("set-cookie");if(!s)return;let a=await Z({key:o.context.secret,data:s}),d=`${t}&cookies=${encodeURIComponent(a)}`;return r.headers.set("location",d),{response:r}}})}],before:[{matcher(o){return o.path?.startsWith("/sign-in/social")},async handler(o){let r=new URL(e?.currentURL||o.request?.url||yn()||o.context.baseURL);return o.body.callbackURL=`${r.origin}${o.context.options.basePath||"/api/auth"}/oauth-proxy-callback?callbackURL=${encodeURIComponent(o.body.callbackURL||o.context.baseURL)}`,{context:o}}}]}});export{he as HIDE_METADATA,zp as admin,Ip as anonymous,tp as bearer,c as createAuthEndpoint,S as createAuthMiddleware,bf as emailOTP,Wp as genericOAuth,nn as getPasskeyActions,nf as jwt,dp as magicLink,cf as multiSession,Bf as oAuthProxy,If as oneTap,lt as optionsMiddleware,Rc as organization,Wm as passkey,Bm as passkeyClient,yp as phoneNumber,Jl as twoFactor,zl as twoFactorClient,lr as username};
84
+ Error: `,a),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)}),i=n?.user;if(n){let a=n.accounts.find(d=>d.providerId===r.providerId);if(a)await e.context.internalAdapter.updateAccount(a.id,{accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,expiresAt:r.expiresAt});else{if(!e.context.options.account?.accountLinking?.trustedProviders?.includes(r.providerId)&&!o.emailVerified||e.context.options.account?.accountLinking?.enabled===!1)return mt&&y.warn(`User already exist but account isn't linked to ${r.providerId}. To read more about how account linking works in Better Auth see https://www.better-auth.com/docs/concepts/users-accounts#account-linking.`),{error:"account not linked",data:null};try{await e.context.internalAdapter.linkAccount({providerId:r.providerId,accountId:o.id.toString(),id:e.context.uuid(),userId:n.user.id,accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,expiresAt:r.expiresAt})}catch(l){return y.error("Unable to link account",l),{error:"unable to link account",data:null}}}}else try{let a=o.emailVerified||!1;if(i=await e.context.internalAdapter.createOAuthUser({...o,id:e.context.uuid(),emailVerified:a,email:o.email.toLowerCase()},{accessToken:r.accessToken,idToken:r.idToken,refreshToken:r.refreshToken,expiresAt:r.expiresAt,providerId:r.providerId,accountId:o.id.toString()}).then(d=>d?.user),!a&&i&&e.context.options.emailVerification?.sendOnSignUp){let d=await oe(e.context.secret,i.email),u=`${e.context.baseURL}/verify-email?token=${d}&callbackURL=${t}`;await e.context.options.emailVerification?.sendVerificationEmail?.({user:i,url:u,token:d},e.request)}}catch(a){return y.error("Unable to create user",a),{error:"unable to create user",data:null}}if(!i)return{error:"unable to create user",data:null};let s=await e.context.internalAdapter.createSession(i.id,e.request);return s?{data:{session:s,user:i},error:null}:{error:"unable to create session",data:null}}var wo=c("/sign-in/social",{method:"POST",query:z.object({currentURL:z.string().optional()}).optional(),body:z.object({callbackURL:z.string().optional(),provider:z.enum(je),idToken:z.optional(z.object({token:z.string(),nonce:z.string().optional(),accessToken:z.string().optional(),refreshToken:z.string().optional(),expiresAt:z.number().optional()}))})},async e=>{let o=e.context.socialProviders.find(i=>i.id===e.body.provider);if(!o)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new D("NOT_FOUND",{message:"Provider not found"});if(e.body.idToken){if(!o.verifyIdToken)throw e.context.logger.error("Provider does not support id token verification",{provider:e.body.provider}),new D("NOT_FOUND",{message:"Provider does not support id token verification"});let{token:i,nonce:s}=e.body.idToken;if(!await o.verifyIdToken(i,s))throw e.context.logger.error("Invalid id token",{provider:e.body.provider}),new D("UNAUTHORIZED",{message:"Invalid id token"});let d=await o.getUserInfo({idToken:i,accessToken:e.body.idToken.accessToken,refreshToken:e.body.idToken.refreshToken});if(!d||!d?.user)throw e.context.logger.error("Failed to get user info",{provider:e.body.provider}),new D("UNAUTHORIZED",{message:"Failed to get user info"});if(!d.user.email)throw e.context.logger.error("User email not found",{provider:e.body.provider}),new D("UNAUTHORIZED",{message:"User email not found"});let u=await be(e,{userInfo:{email:d.user.email,id:d.user.id,name:d.user.name||"",image:d.user.image,emailVerified:d.user.emailVerified||!1},account:{providerId:o.id,accountId:d.user.id,accessToken:e.body.idToken.accessToken}});if(u.error)throw new D("UNAUTHORIZED",{message:u.error});return await w(e,u.data),e.json({session:u.data.session,user:u.data.user,url:`${e.body.callbackURL||e.query?.currentURL||e.context.options.baseURL}`,redirect:!0})}let{codeVerifier:r,state:t}=await ye(e),n=await o.createAuthorizationURL({state:t,codeVerifier:r,redirectURI:`${e.context.baseURL}/callback/${o.id}`});return e.json({url:n.toString(),redirect:!0})}),yo=c("/sign-in/email",{method:"POST",body:z.object({email:z.string(),password:z.string(),callbackURL:z.string().optional(),rememberMe:z.boolean().default(!1).optional()})},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 D("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:o,password:r}=e.body;if(!z.string().email().safeParse(o).success)throw new D("BAD_REQUEST",{message:"Invalid email"});let n=await e.context.internalAdapter.findUserByEmail(o,{includeAccounts:!0});if(!n)throw await e.context.password.hash(r),e.context.logger.error("User not found",{email:o}),new D("UNAUTHORIZED",{message:"Invalid email or password"});let i=n.accounts.find(u=>u.providerId==="credential");if(!i)throw e.context.logger.error("Credential account not found",{email:o}),new D("UNAUTHORIZED",{message:"Invalid email or password"});let s=i?.password;if(!s)throw e.context.logger.error("Password not found",{email:o}),new D("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(s,r))throw e.context.logger.error("Invalid password"),new D("UNAUTHORIZED",{message:"Invalid email or password"});if(e.context.options?.emailAndPassword?.requireEmailVerification&&!n.user.emailVerified){if(!e.context.options?.emailVerification?.sendVerificationEmail)throw y.error("Email verification is required but no email verification handler is provided"),new D("INTERNAL_SERVER_ERROR",{message:"Email is not verified."});let u=await oe(e.context.secret,n.user.email),l=`${e.context.baseURL}/verify-email?token=${u}`;throw await e.context.options.emailVerification.sendVerificationEmail({user:n.user,url:l,token:u},e.request),e.context.logger.error("Email not verified",{email:o}),new D("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.rememberMe===!1);if(!d)throw e.context.logger.error("Failed to create session"),new D("UNAUTHORIZED",{message:"Failed to create session"});return await w(e,{session:d,user:n.user},e.body.rememberMe===!1),e.json({user:n.user,session:d,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});import{z as Ne}from"zod";var bo=c("/callback/:id",{method:["GET","POST"],query:Ne.object({state:Ne.string(),code:Ne.string().optional(),error:Ne.string().optional()}),metadata:he},async e=>{if(!e.query.code)throw e.redirect(`${e.context.baseURL}/error?error=${e.query.error||"no_code"}`);let o=e.context.socialProviders.find(k=>k.id===e.params.id);if(!o)throw e.context.logger.error("Oauth provider with id",e.params.id,"not found"),e.redirect(`${e.context.baseURL}/error?error=oauth_provider_not_found`);let{codeVerifier:r,callbackURL:t,link:n,errorURL:i}=await De(e),s;try{s=await o.validateAuthorizationCode({code:e.query.code,codeVerifier:r,redirectURI:`${e.context.baseURL}/callback/${o.id}`})}catch(k){throw e.context.logger.error(k),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let a=await o.getUserInfo(s).then(k=>k?.user),u={id:B(),...a};function l(k){let R=i||t||`${e.context.baseURL}/error`;throw R.includes("?")?R=`${R}&error=${k}`:R=`${R}?error=${k}`,e.redirect(R)}if(!a)return y.error("Unable to get user info"),l("unable_to_get_user_info");if(!u.email)return e.context.logger.error("Provider did not return email. This could be due to misconfiguration in the provider settings."),l("email_not_found");if(!t)throw y.error("No callback URL found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(n){if(n.email!==u.email.toLowerCase())return l("email_doesn't_match");if(!await e.context.internalAdapter.createAccount({userId:n.userId,providerId:o.id,accountId:a.id}))return l("unable_to_link_account");let R;try{R=new URL(t).toString()}catch{R=t}throw e.redirect(R)}let m=await be(e,{userInfo:{email:u.email,id:u.id,name:u.name||"",image:u.image,emailVerified:u.emailVerified||!1},account:{providerId:o.id,accountId:a.id,accessToken:s.accessToken,refreshToken:s.refreshToken,expiresAt:s.accessTokenExpiresAt},callbackURL:t});if(m.error)return l(m.error.split(" ").join("_"));let{session:f,user:p}=m.data;await w(e,{session:f,user:p});let h;try{h=new URL(t).toString()}catch{h=t}throw e.redirect(h)});import"zod";import{APIError as Po}from"better-call";var Ao=c("/sign-out",{method:"POST",requireHeaders:!0},async e=>{let o=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!o)throw new Po("BAD_REQUEST",{message:"Session not found"});return await e.context.internalAdapter.deleteSession(o),J(e),e.json({success:!0})});import{z as W}from"zod";import{APIError as Ve}from"better-call";function zt(e,o,r){let t=o?new URL(o,e.baseURL):new URL(`${e.baseURL}/error`);return r&&Object.entries(r).forEach(([n,i])=>t.searchParams.set(n,i)),t.href}function _o(e,o,r){let t=new URL(o,e.baseURL);return r&&Object.entries(r).forEach(([n,i])=>t.searchParams.set(n,i)),t.href}var ko=c("/forget-password",{method:"POST",body:W.object({email:W.string().email(),redirectTo:W.string()})},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 Ve("BAD_REQUEST",{message:"Reset password isn't enabled"});let{email:o,redirectTo:r}=e.body,t=await e.context.internalAdapter.findUserByEmail(o,{includeAccounts:!0});if(!t)return e.context.logger.error("Reset Password: User not found",{email:o}),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:t.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({user:t.user,url:a},e.request),e.json({status:!0})}),Oo=c("/reset-password/:token",{method:"GET",query:W.object({callbackURL:W.string()})},async e=>{let{token:o}=e.params,{callbackURL:r}=e.query;if(!o||!r)throw e.redirect(zt(e.context,r,{error:"INVALID_TOKEN"}));let t=await e.context.internalAdapter.findVerificationValue(`reset-password:${o}`);throw!t||t.expiresAt<new Date?e.redirect(zt(e.context,r,{error:"INVALID_TOKEN"})):e.redirect(_o(e.context,r,{token:o}))}),vo=c("/reset-password",{query:W.optional(W.object({token:W.string().optional(),currentURL:W.string().optional()})),method:"POST",body:W.object({newPassword:W.string()})},async e=>{let o=e.query?.token||(e.query?.currentURL?new URL(e.query.currentURL).searchParams.get("token"):"");if(!o)throw new Ve("BAD_REQUEST",{message:"Token not found"});let{newPassword:r}=e.body,t=`reset-password:${o}`,n=await e.context.internalAdapter.findVerificationValue(t);if(!n||n.expiresAt<new Date)throw new Ve("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 Ve("BAD_REQUEST",{message:"Failed to update password"});return e.json({status:!0})});import{z as V}from"zod";import{APIError as N}from"better-call";var Ro=c("/change-password",{method:"POST",body:V.object({newPassword:V.string(),currentPassword:V.string(),revokeOtherSessions:V.boolean().optional()}),use:[b]},async e=>{let{newPassword:o,currentPassword:r,revokeOtherSessions:t}=e.body,n=e.context.session,i=e.context.password.config.minPasswordLength;if(o.length<i)throw e.context.logger.error("Password is too short"),new N("BAD_REQUEST",{message:"Password is too short"});let s=e.context.password.config.maxPasswordLength;if(o.length>s)throw e.context.logger.error("Password is too long"),new N("BAD_REQUEST",{message:"Password too long"});let d=(await e.context.internalAdapter.findAccounts(n.user.id)).find(m=>m.providerId==="credential"&&m.password);if(!d||!d.password)throw new N("BAD_REQUEST",{message:"User does not have a password"});let u=await e.context.password.hash(o);if(!await e.context.password.verify(d.password,r))throw new N("BAD_REQUEST",{message:"Incorrect password"});if(await e.context.internalAdapter.updateAccount(d.id,{password:u}),t){await e.context.internalAdapter.deleteSessions(n.user.id);let m=await e.context.internalAdapter.createSession(n.user.id,e.headers);if(!m)throw new N("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});await w(e,{session:m,user:n.user})}return e.json(n.user)}),Eo=c("/set-password",{method:"POST",body:V.object({newPassword:V.string()}),metadata:{SERVER_ONLY:!0},use:[b]},async e=>{let{newPassword:o}=e.body,r=e.context.session,t=e.context.password.config.minPasswordLength;if(o.length<t)throw e.context.logger.error("Password is too short"),new N("BAD_REQUEST",{message:"Password is too short"});let n=e.context.password.config.maxPasswordLength;if(o.length>n)throw e.context.logger.error("Password is too long"),new N("BAD_REQUEST",{message:"Password too long"});let s=(await e.context.internalAdapter.findAccounts(r.user.id)).find(d=>d.providerId==="credential"&&d.password),a=await e.context.password.hash(o);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 N("BAD_REQUEST",{message:"user already has a password"})}),Uo=c("/delete-user",{method:"POST",body:V.object({password:V.string()}),use:[b]},async e=>{let{password:o}=e.body,r=e.context.session,n=(await e.context.internalAdapter.findAccounts(r.user.id)).find(s=>s.providerId==="credential"&&s.password);if(!n||!n.password)throw new N("BAD_REQUEST",{message:"User does not have a password"});if(!await e.context.password.verify(n.password,o))throw new N("BAD_REQUEST",{message:"Incorrect password"});return await e.context.internalAdapter.deleteUser(r.user.id),await e.context.internalAdapter.deleteSessions(r.user.id),J(e),e.json(null)}),Io=c("/change-email",{method:"POST",query:V.object({currentURL:V.string().optional()}).optional(),body:V.object({newEmail:V.string().email(),callbackURL:V.string().optional()}),use:[b]},async e=>{if(!e.context.options.user?.changeEmail?.enabled)throw e.context.logger.error("Change email is disabled."),new N("BAD_REQUEST",{message:"Change email is disabled"});if(e.body.newEmail===e.context.session.user.email)throw e.context.logger.error("Email is the same"),new N("BAD_REQUEST",{message:"Email is the same"});if(await e.context.internalAdapter.findUserByEmail(e.body.newEmail))throw e.context.logger.error("Email already exists"),new N("BAD_REQUEST",{message:"Couldn't update your email"});if(e.context.session.user.emailVerified!==!0){let n=await e.context.internalAdapter.updateUserByEmail(e.context.session.user.email,{email:e.body.newEmail});return e.json({user:n,status:!0})}if(!e.context.options.user.changeEmail.sendChangeEmailVerification)throw e.context.logger.error("Verification email isn't enabled."),new N("BAD_REQUEST",{message:"Verification email isn't enabled"});let r=await oe(e.context.secret,e.context.session.user.email,e.body.newEmail),t=`${e.context.baseURL}/verify-email?token=${r}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.user.changeEmail.sendChangeEmailVerification({user:e.context.session.user,newEmail:e.body.newEmail,url:t,token:r},e.request),e.json({user:null,status:!0})});import{z as Ee}from"zod";import{APIError as Bt}from"better-call";var To=c("/list-accounts",{method:"GET",use:[b]},async e=>{let o=e.context.session,r=await e.context.internalAdapter.findAccounts(o.user.id);return e.json(r.map(t=>({id:t.id,provider:t.providerId})))}),So=c("/link-social",{method:"POST",requireHeaders:!0,query:Ee.object({currentURL:Ee.string().optional()}).optional(),body:Ee.object({callbackURL:Ee.string().optional(),provider:Ee.enum(je)}),use:[b]},async e=>{let o=e.context.session;if((await e.context.internalAdapter.findAccounts(o.user.id)).find(a=>a.providerId===e.body.provider))throw new Bt("BAD_REQUEST",{message:"Social Account is already linked."});let n=e.context.socialProviders.find(a=>a.id===e.body.provider);if(!n)throw e.context.logger.error("Provider not found. Make sure to add the provider in your auth config",{provider:e.body.provider}),new Bt("NOT_FOUND",{message:"Provider not found"});let i=await ye(e,{userId:o.user.id,email:o.user.email}),s=await n.createAuthorizationURL({state:i.state,codeVerifier:i.codeVerifier,redirectURI:`${e.context.baseURL}/callback/${n.id}`});return e.json({url:s.toString(),redirect:!0})});var xt=(e,o)=>{let r={};for(let[t,n]of Object.entries(e))r[t]=i=>n({...i,context:{...o,...i.context}}),r[t].path=n.path,r[t].method=n.method,r[t].options=n.options,r[t].headers=n.headers;return r};var Ae=class extends Error{path;constructor(o,r){super(o),this.path=r}},Fe=class{constructor(o){this.s=o;this.statements=o}statements;newRole(o){return new qe(o)}},qe=class e{statements;constructor(o){this.statements=o}authorize(o,r){for(let[t,n]of Object.entries(o)){let i=this.statements[t];if(!i)return{success:!1,error:`You are not allowed to access resource: ${t}`};let s=r==="OR"?n.some(a=>i.includes(a)):n.every(a=>i.includes(a));return s?{success:s}:{success:!1,error:`unauthorized to access resource "${t}"`}}return{success:!1,error:"Not authorized"}}static fromString(o){let r=JSON.parse(o);if(typeof r!="object")throw new Ae("statements is not an object",".");for(let[t,n]of Object.entries(r)){if(typeof t!="string")throw new Ae("invalid resource identifier",t);if(!Array.isArray(n))throw new Ae("actions is not an array",t);for(let i=0;i<n.length;i++)if(typeof n[i]!="string")throw new Ae("action is not a string",`${t}[${i}]`)}return new e(r)}toString(){return JSON.stringify(this.statements)}};var Co=e=>new Fe(e),zo={organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]},rt=Co(zo),Bo=rt.newRole({organization:["update"],invitation:["create","cancel"],member:["create","update","delete"]}),xo=rt.newRole({organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]}),Lo=rt.newRole({organization:[],member:[],invitation:[]}),Lt={admin:Bo,owner:xo,member:Lo};var _=(e,o)=>{let r=e.adapter;return{findOrganizationBySlug:async t=>await r.findOne({model:"organization",where:[{field:"slug",value:t}]}),createOrganization:async t=>{let n=await r.create({model:"organization",data:{...t.organization,metadata:t.organization.metadata?JSON.stringify(t.organization.metadata):void 0}}),i=await r.create({model:"member",data:{id:B(),organizationId:n.id,userId:t.user.id,createdAt:new Date,role:o?.creatorRole||"owner"}});return{...n,metadata:n.metadata?JSON.parse(n.metadata):void 0,members:[{...i,user:{id:t.user.id,name:t.user.name,email:t.user.email,image:t.user.image}}]}},findMemberByEmail:async t=>{let n=await r.findOne({model:e.tables.user.tableName,where:[{field:"email",value:t.email}]});if(!n)return null;let i=await r.findOne({model:"member",where:[{field:"organizationId",value:t.organizationId},{field:"userId",value:n.id}]});return i?{...i,user:{id:n.id,name:n.name,email:n.email,image:n.image}}:null},findMemberByOrgId:async t=>{let[n,i]=await Promise.all([await r.findOne({model:"member",where:[{field:"userId",value:t.userId},{field:"organizationId",value:t.organizationId}]}),await r.findOne({model:e.tables.user.tableName,where:[{field:"id",value:t.userId}]})]);return!i||!n?null:{...n,user:{id:i.id,name:i.name,email:i.email,image:i.image}}},findMemberById:async t=>{let n=await r.findOne({model:"member",where:[{field:"id",value:t}]});if(!n)return null;let i=await r.findOne({model:e.tables.user.tableName,where:[{field:"id",value:n.userId}]});return i?{...n,user:{id:i.id,name:i.name,email:i.email,image:i.image}}:null},createMember:async t=>await r.create({model:"member",data:t}),updateMember:async(t,n)=>await r.update({model:"member",where:[{field:"id",value:t}],update:{role:n}}),deleteMember:async t=>await r.delete({model:"member",where:[{field:"id",value:t}]}),updateOrganization:async(t,n)=>await r.update({model:"organization",where:[{field:"id",value:t}],update:n}),deleteOrganization:async t=>(await r.delete({model:"member",where:[{field:"organizationId",value:t}]}),await r.delete({model:"invitation",where:[{field:"organizationId",value:t}]}),await r.delete({model:"organization",where:[{field:"id",value:t}]}),t),setActiveOrganization:async(t,n)=>await r.update({model:e.tables.session.tableName,where:[{field:"id",value:t}],update:{activeOrganizationId:n}}),findOrganizationById:async t=>await r.findOne({model:"organization",where:[{field:"id",value:t}]}),findFullOrganization:async(t,n)=>{let[i,s,a]=await Promise.all([r.findOne({model:"organization",where:[{field:"id",value:t}]}),r.findMany({model:"invitation",where:[{field:"organizationId",value:t}]}),r.findMany({model:"member",where:[{field:"organizationId",value:t}]})]);if(!i)return null;let d=a.map(f=>f.userId),u=await r.findMany({model:e.tables.user.tableName,where:[{field:"id",value:d,operator:"in"}]}),l=new Map(u.map(f=>[f.id,f])),m=a.map(f=>{let p=l.get(f.userId);if(!p)throw new $("Unexpected error: User not found for member");return{...f,user:{id:p.id,name:p.name,email:p.email,image:p.image}}});return{...i,invitations:s,members:m}},listOrganizations:async t=>{let n=await r.findMany({model:"member",where:[{field:"userId",value:t}]});if(!n||n.length===0)return[];let i=n.map(a=>a.organizationId);return await r.findMany({model:"organization",where:[{field:"id",value:i,operator:"in"}]})},createInvitation:async({invitation:t,user:n})=>{let s=P(o?.invitationExpiresIn||1728e5);return await r.create({model:"invitation",data:{id:B(),email:t.email,role:t.role,organizationId:t.organizationId,status:"pending",expiresAt:s,inviterId:n.id}})},findInvitationById:async t=>await r.findOne({model:"invitation",where:[{field:"id",value:t}]}),findPendingInvitation:async t=>(await r.findMany({model:"invitation",where:[{field:"email",value:t.email},{field:"organizationId",value:t.organizationId},{field:"status",value:"pending"}]})).filter(i=>new Date(i.expiresAt)>new Date),updateInvitation:async t=>await r.update({model:"invitation",where:[{field:"id",value:t.invitationId}],update:{status:t.status}})}};import"better-call";var x=S(async e=>({})),L=S({use:[b]},async e=>({session:e.context.session}));import{z as M}from"zod";import{z as U}from"zod";var Me=U.enum(["admin","member","owner"]),Do=U.enum(["pending","accepted","rejected","canceled"]).default("pending"),Vu=U.object({id:U.string(),name:U.string(),slug:U.string(),logo:U.string().nullish(),metadata:U.record(U.string()).or(U.string().transform(e=>JSON.parse(e))).nullish(),createdAt:U.date()}),Fu=U.object({id:U.string(),organizationId:U.string(),userId:U.string(),role:Me,createdAt:U.date()}),qu=U.object({id:U.string(),organizationId:U.string(),email:U.string(),role:Me,status:Do,inviterId:U.string(),expiresAt:U.date()});import{APIError as T}from"better-call";var Dt=c("/organization/invite-member",{method:"POST",use:[x,L],body:M.object({email:M.string(),role:Me,organizationId:M.string().optional(),resend:M.boolean().optional()})},async e=>{if(!e.context.orgOptions.sendInvitationEmail)throw y.warn("Invitation email is not enabled. Pass `sendInvitationEmail` to the plugin options to enable it."),new T("BAD_REQUEST",{message:"Invitation email is not enabled"});let o=e.context.session,r=e.body.organizationId||o.session.activeOrganizationId;if(!r)throw new T("BAD_REQUEST",{message:"Organization not found"});let t=_(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)throw new T("BAD_REQUEST",{message:"Member not found!"});let i=e.context.roles[n.role];if(!i)throw new T("BAD_REQUEST",{message:"Role not found!"});if(i.authorize({invitation:["create"]}).error)throw new T("FORBIDDEN",{message:"You are not allowed to invite members"});if(await t.findMemberByEmail({email:e.body.email,organizationId:r}))throw new T("BAD_REQUEST",{message:"User is already a member of this organization"});if((await t.findPendingInvitation({email:e.body.email,organizationId:r})).length&&!e.body.resend)throw new T("BAD_REQUEST",{message:"User is already invited to this organization"});let u=await t.createInvitation({invitation:{role:e.body.role,email:e.body.email,organizationId:r},user:o.user}),l=await t.findOrganizationById(r);if(!l)throw new T("BAD_REQUEST",{message:"Organization not found"});return await e.context.orgOptions.sendInvitationEmail?.({id:u.id,role:u.role,email:u.email,organization:l,inviter:{...n,user:o.user}},e.request),e.json(u)}),jt=c("/organization/accept-invitation",{method:"POST",body:M.object({invitationId:M.string()}),use:[x,L]},async e=>{let o=e.context.session,r=_(e.context,e.context.orgOptions),t=await r.findInvitationById(e.body.invitationId);if(!t||t.expiresAt<new Date||t.status!=="pending")throw new T("BAD_REQUEST",{message:"Invitation not found!"});if(t.email!==o.user.email)throw new T("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.updateInvitation({invitationId:e.body.invitationId,status:"accepted"}),i=await r.createMember({id:B(),organizationId:t.organizationId,userId:o.user.id,role:t.role,createdAt:new Date});return await r.setActiveOrganization(o.session.id,t.organizationId),n?e.json({invitation:n,member:i}):e.json(null,{status:400,body:{message:"Invitation not found!"}})}),Nt=c("/organization/reject-invitation",{method:"POST",body:M.object({invitationId:M.string()}),use:[x,L]},async e=>{let o=e.context.session,r=_(e.context,e.context.orgOptions),t=await r.findInvitationById(e.body.invitationId);if(!t||t.expiresAt<new Date||t.status!=="pending")throw new T("BAD_REQUEST",{message:"Invitation not found!"});if(t.email!==o.user.email)throw new T("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.updateInvitation({invitationId:e.body.invitationId,status:"rejected"});return e.json({invitation:n,member:null})}),Vt=c("/organization/cancel-invitation",{method:"POST",body:M.object({invitationId:M.string()}),use:[x,L]},async e=>{let o=e.context.session,r=_(e.context,e.context.orgOptions),t=await r.findInvitationById(e.body.invitationId);if(!t)throw new T("BAD_REQUEST",{message:"Invitation not found!"});let n=await r.findMemberByOrgId({userId:o.user.id,organizationId:t.organizationId});if(!n)throw new T("BAD_REQUEST",{message:"Member not found!"});if(e.context.roles[n.role].authorize({invitation:["cancel"]}).error)throw new T("FORBIDDEN",{message:"You are not allowed to cancel this invitation"});let s=await r.updateInvitation({invitationId:e.body.invitationId,status:"canceled"});return e.json(s)}),Ft=c("/organization/get-invitation",{method:"GET",use:[x],requireHeaders:!0,query:M.object({id:M.string()})},async e=>{let o=await C(e);if(!o)throw new T("UNAUTHORIZED",{message:"Not authenticated"});let r=_(e.context,e.context.orgOptions),t=await r.findInvitationById(e.query.id);if(!t||t.status!=="pending"||t.expiresAt<new Date)throw new T("BAD_REQUEST",{message:"Invitation not found!"});if(t.email!==o.user.email)throw new T("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.findOrganizationById(t.organizationId);if(!n)throw new T("BAD_REQUEST",{message:"Organization not found"});let i=await r.findMemberByOrgId({userId:t.inviterId,organizationId:t.organizationId});if(!i)throw new T("BAD_REQUEST",{message:"Inviter is no longer a member of the organization"});return e.json({...t,organizationName:n.name,organizationSlug:n.slug,inviterEmail:i.user.email})});import{z as ce}from"zod";import{APIError as Ue}from"better-call";var qt=c("/organization/remove-member",{method:"POST",body:ce.object({memberIdOrEmail:ce.string(),organizationId:ce.string().optional()}),use:[x,L]},async e=>{let o=e.context.session,r=e.body.organizationId||o.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"No active organization found!"}});let t=_(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)throw new Ue("BAD_REQUEST",{message:"Member not found!"});let i=e.context.roles[n.role];if(!i)throw new Ue("BAD_REQUEST",{message:"Role not found!"});let s=o.user.email===e.body.memberIdOrEmail||n.id===e.body.memberIdOrEmail;if(s&&n.role===(e.context.orgOptions?.creatorRole||"owner"))throw new Ue("BAD_REQUEST",{message:"You cannot leave the organization as the owner"});if(!(s||i.authorize({member:["delete"]}).success))throw new Ue("UNAUTHORIZED",{message:"You are not allowed to delete this member"});let u=null;if(e.body.memberIdOrEmail.includes("@")?u=await t.findMemberByEmail({email:e.body.memberIdOrEmail,organizationId:r}):u=await t.findMemberById(e.body.memberIdOrEmail),u?.organizationId!==r)throw new Ue("BAD_REQUEST",{message:"Member not found!"});return await t.deleteMember(u.id),o.user.id===u.userId&&o.session.activeOrganizationId===u.organizationId&&await t.setActiveOrganization(o.session.id,null),e.json({member:u})}),Mt=c("/organization/update-member-role",{method:"POST",body:ce.object({role:ce.enum(["admin","member","owner"]),memberId:ce.string(),organizationId:ce.string().optional()}),use:[x,L]},async e=>{let o=e.context.session,r=e.body.organizationId||o.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"No active organization found!"}});let t=_(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)return e.json(null,{status:400,body:{message:"Member not found!"}});let i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({member:["update"]}).error||e.body.role==="owner"&&n.role!=="owner")return e.json(null,{body:{message:"You are not allowed to update this member"},status:403});let a=await t.updateMember(e.body.memberId,e.body.role);return a?e.json(a):e.json(null,{status:400,body:{message:"Member not found!"}})}),$t=c("/organization/get-active-member",{method:"GET",use:[x,L]},async e=>{let o=e.context.session,r=o.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"No active organization found!"}});let n=await _(e.context,e.context.orgOptions).findMemberByOrgId({userId:o.user.id,organizationId:r});return n?e.json(n):e.json(null,{status:400,body:{message:"Member not found!"}})});import{z as I}from"zod";import{APIError as le}from"better-call";var Qt=c("/organization/create",{method:"POST",body:I.object({name:I.string(),slug:I.string(),userId:I.string().optional(),logo:I.string().optional(),metadata:I.record(I.string(),I.any()).optional()}),use:[x,L]},async e=>{let o=e.context.session.user;if(!o)return e.json(null,{status:401});let r=e.context.orgOptions;if(!(typeof r?.allowUserToCreateOrganization=="function"?await r.allowUserToCreateOrganization(o):r?.allowUserToCreateOrganization===void 0?!0:r.allowUserToCreateOrganization))throw new le("FORBIDDEN",{message:"You are not allowed to create an organization"});let n=_(e.context,r),i=await n.listOrganizations(o.id);if(typeof r.organizationLimit=="number"?i.length>=r.organizationLimit:typeof r.organizationLimit=="function"?await r.organizationLimit(o):!1)throw new le("FORBIDDEN",{message:"You have reached the organization limit"});if(await n.findOrganizationBySlug(e.body.slug))throw new le("BAD_REQUEST",{message:"Organization with this slug already exists"});let d=await n.createOrganization({organization:{id:B(),slug:e.body.slug,name:e.body.name,logo:e.body.logo,createdAt:new Date,metadata:e.body.metadata},user:o});return e.json(d)}),Ht=c("/organization/update",{method:"POST",body:I.object({data:I.object({name:I.string().optional(),slug:I.string().optional(),logo:I.string().optional()}).partial(),organizationId:I.string().optional()}),requireHeaders:!0,use:[x]},async e=>{let o=await e.context.getSession(e);if(!o)throw new le("UNAUTHORIZED",{message:"User not found"});let r=e.body.organizationId||o.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"Organization id not found!"}});let t=_(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)return e.json(null,{status:400,body:{message:"User is not a member of this organization!"}});let i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({organization:["update"]}).error)return e.json(null,{body:{message:"You are not allowed to update this organization"},status:403});let a=await t.updateOrganization(r,e.body.data);return e.json(a)}),Wt=c("/organization/delete",{method:"POST",body:I.object({organizationId:I.string()}),requireHeaders:!0,use:[x]},async e=>{let o=await e.context.getSession(e);if(!o)return e.json(null,{status:401});let r=e.body.organizationId;if(!r)return e.json(null,{status:400,body:{message:"Organization id not found!"}});let t=_(e.context,e.context.orgOptions),n=await t.findMemberByOrgId({userId:o.user.id,organizationId:r});if(!n)return e.json(null,{status:400,body:{message:"User is not a member of this organization!"}});let i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({organization:["delete"]}).error)throw new le("FORBIDDEN",{message:"You are not allowed to delete this organization"});return r===o.session.activeOrganizationId&&await t.setActiveOrganization(o.session.id,null),await t.deleteOrganization(r),e.json(r)}),Gt=c("/organization/get-full-organization",{method:"GET",query:I.optional(I.object({organizationId:I.string().optional()})),requireHeaders:!0,use:[x,L]},async e=>{let o=e.context.session,r=e.query?.organizationId||o.session.activeOrganizationId;if(!r)return e.json(null,{status:200});let n=await _(e.context,e.context.orgOptions).findFullOrganization(r,e.context.db||void 0);if(!n)throw new le("BAD_REQUEST",{message:"Organization not found"});return e.json(n)}),Jt=c("/organization/set-active",{method:"POST",body:I.object({organizationId:I.string().nullable().optional()}),use:[L,x]},async e=>{let o=_(e.context,e.context.orgOptions),r=e.context.session,t=e.body.organizationId;if(t===null)return r.session.activeOrganizationId&&await o.setActiveOrganization(r.session.id,null),e.json(null);if(!t){let s=r.session.activeOrganizationId;if(!s)return e.json(null);t=s}if(!await o.findMemberByOrgId({userId:r.user.id,organizationId:t}))throw await o.setActiveOrganization(r.session.id,null),new le("FORBIDDEN",{message:"You are not a member of this organization"});await o.setActiveOrganization(r.session.id,t);let i=await o.findFullOrganization(t,e.context.db||void 0);return e.json(i)}),Kt=c("/organization/list",{method:"GET",use:[x,L]},async e=>{let r=await _(e.context,e.context.orgOptions).listOrganizations(e.context.session.user.id);return e.json(r)});var Rc=e=>{let o={createOrganization:Qt,updateOrganization:Ht,deleteOrganization:Wt,setActiveOrganization:Jt,getFullOrganization:Gt,listOrganization:Kt,createInvitation:Dt,cancelInvitation:Vt,acceptInvitation:jt,getInvitation:Ft,rejectInvitation:Nt,removeMember:qt,updateMemberRole:Mt,getActiveMember:$t},r={...Lt,...e?.roles};return{id:"organization",endpoints:{...xt(o,{orgOptions:e||{},roles:r,getSession:async n=>await C(n)}),hasPermission:c("/organization/has-permission",{method:"POST",requireHeaders:!0,body:Ie.object({permission:Ie.record(Ie.string(),Ie.array(Ie.string()))}),use:[L]},async n=>{if(!n.context.session.session.activeOrganizationId)throw new Zt("BAD_REQUEST",{message:"No active organization"});let s=await _(n.context).findMemberByOrgId({userId:n.context.session.user.id,organizationId:n.context.session.session.activeOrganizationId||""});if(!s)throw new Zt("UNAUTHORIZED",{message:"You are not a member of this organization"});let d=r[s.role].authorize(n.body.permission);return d.error?n.json({error:d.error,success:!1},{status:403}):n.json({error:null,success:!0})})},schema:{session:{fields:{activeOrganizationId:{type:"string",required:!1,fieldName:e?.schema?.session?.fields?.activeOrganizationId}}},organization:{fields:{name:{type:"string",required:!0,fieldName:e?.schema?.organization?.fields?.name},slug:{type:"string",unique:!0,fieldName:e?.schema?.organization?.fields?.slug},logo:{type:"string",required:!1,fieldName:e?.schema?.organization?.fields?.logo},createdAt:{type:"date",required:!0,fieldName:e?.schema?.organization?.fields?.createdAt},metadata:{type:"string",required:!1,fieldName:e?.schema?.organization?.fields?.metadata}}},member:{fields:{organizationId:{type:"string",required:!0,references:{model:"organization",field:"id"},fieldName:e?.schema?.member?.fields?.organizationId},userId:{type:"string",required:!0,fieldName:e?.schema?.member?.fields?.userId},role:{type:"string",required:!0,defaultValue:"member",fieldName:e?.schema?.member?.fields?.role},createdAt:{type:"date",required:!0,fieldName:e?.schema?.member?.fields?.createdAt}}},invitation:{fields:{organizationId:{type:"string",required:!0,references:{model:"organization",field:"id"},fieldName:e?.schema?.invitation?.fields?.organizationId},email:{type:"string",required:!0,fieldName:e?.schema?.invitation?.fields?.email},role:{type:"string",required:!1,fieldName:e?.schema?.invitation?.fields?.role},status:{type:"string",required:!0,defaultValue:"pending",fieldName:e?.schema?.invitation?.fields?.status},expiresAt:{type:"date",required:!0,fieldName:e?.schema?.invitation?.fields?.expiresAt},inviterId:{type:"string",references:{model:"user",field:"id"},fieldName:e?.schema?.invitation?.fields?.inviterId,required:!0}}}},$Infer:{Organization:{},Invitation:{},Member:{},ActiveOrganization:{}}}};import Yt from"uncrypto";function jo(e){return e.toString(2).padStart(8,"0")}function No(e){return[...e].map(o=>jo(o)).join("")}function Xt(e){return parseInt(No(e),2)}function Vo(e){if(e<0||!Number.isInteger(e))throw new Error("Argument 'max' must be an integer greater than or equal to 0");let o=(e-1).toString(2).length,r=o%8,t=new Uint8Array(Math.ceil(o/8));Yt.getRandomValues(t),r!==0&&(t[0]&=(1<<r)-1);let n=Xt(t);for(;n>=e;)Yt.getRandomValues(t),r!==0&&(t[0]&=(1<<r)-1),n=Xt(t);return n}function F(e,o){let r="";for(let t=0;t<e;t++)r+=o[Vo(o.length)];return r}function q(...e){let o=new Set(e),r="";for(let t of o)t==="a-z"?r+="abcdefghijklmnopqrstuvwxyz":t==="A-Z"?r+="ABCDEFGHIJKLMNOPQRSTUVWXYZ":t==="0-9"?r+="0123456789":r+=t;return r}import{z as Ge}from"zod";import{xchacha20poly1305 as tr}from"@noble/ciphers/chacha";import{bytesToHex as Fo,hexToBytes as qo,utf8ToBytes as Mo}from"@noble/ciphers/utils";import{managedNonce as rr}from"@noble/ciphers/webcrypto";import{sha256 as or}from"oslo/crypto";import er from"uncrypto";import{decodeHex as _c,encodeHex as Cc}from"oslo/encoding";import{scryptAsync as xc}from"@noble/hashes/scrypt";import{getRandomValues as Dc}from"uncrypto";async function Te(e,o){let r=new TextEncoder,t={name:"HMAC",hash:"SHA-256"},n=await er.subtle.importKey("raw",r.encode(e),t,!1,["sign","verify"]),i=await er.subtle.sign(t.name,n,r.encode(o));return btoa(String.fromCharCode(...new Uint8Array(i)))}var Z=async({key:e,data:o})=>{let r=await or(new TextEncoder().encode(e)),t=Mo(o),n=rr(tr)(new Uint8Array(r));return Fo(n.encrypt(t))},ne=async({key:e,data:o})=>{let r=await or(new TextEncoder().encode(e)),t=qo(o),n=rr(tr)(new Uint8Array(r));return new TextDecoder().decode(n.decrypt(t))};import{z as Y}from"zod";import{APIError as Se}from"better-call";var $e="two_factor";var Qe="trust_device";import{z as nr}from"zod";var me=S({body:nr.object({trustDevice:nr.boolean().optional()})},async e=>{let o=await C(e);if(!o){let r=e.context.createAuthCookie($e),t=await e.getSignedCookie(r.name,e.context.secret);if(!t)throw new Se("UNAUTHORIZED",{message:"invalid two factor cookie"});let n=await e.context.internalAdapter.findUserById(t);if(!n)throw new Se("UNAUTHORIZED",{message:"invalid two factor cookie"});let i=await e.context.internalAdapter.createSession(t,e.request);if(!i)throw new Se("INTERNAL_SERVER_ERROR",{message:"failed to create session"});return{valid:async()=>{if(await w(e,{session:i,user:n}),e.body.trustDevice){let s=e.context.createAuthCookie(Qe,{maxAge:2592e3}),a=await Te(e.context.secret,`${n.id}!${i.id}`);await e.setSignedCookie(s.name,`${a}!${i.id}`,e.context.secret,s.attributes)}return e.json({session:i,user:n})},invalid:async()=>{throw new Se("UNAUTHORIZED",{message:"invalid two factor authentication"})},session:{id:i.id,userId:i.userId,expiresAt:i.expiresAt,user:n}}}return{valid:async()=>e.json({session:o,user:o.user}),invalid:async()=>{throw new Se("UNAUTHORIZED",{message:"invalid two factor authentication"})},session:o}});import{APIError as Pe}from"better-call";function $o(e){return Array.from({length:e?.amount??10}).fill(null).map(()=>F(e?.length??10,q("a-z","0-9"))).map(o=>`${o.slice(0,5)}-${o.slice(5)}`)}async function ot(e,o){let r=e,t=o?.customBackupCodesGenerate?o.customBackupCodesGenerate():$o(),n=await Z({data:JSON.stringify(t),key:r});return{backupCodes:t,encryptedBackupCodes:n}}async function Qo(e,o){let r=await ir(e.backupCodes,o);return r?{status:r.includes(e.code),updated:r.filter(t=>t!==e.code)}:{status:!1,updated:null}}async function ir(e,o){let r=Buffer.from(await ne({key:o,data:e})).toString("utf-8"),t=JSON.parse(r),n=Y.array(Y.string()).safeParse(t);return n.success?n.data:null}var sr=(e,o)=>({id:"backup_code",endpoints:{verifyBackupCode:c("/two-factor/verify-backup-code",{method:"POST",body:Y.object({code:Y.string(),disableSession:Y.boolean().optional()}),use:[me]},async r=>{let t=r.context.session.user,n=await r.context.adapter.findOne({model:o,where:[{field:"userId",value:t.id}]});if(!n)throw new Pe("BAD_REQUEST",{message:"Backup codes aren't enabled"});let i=await Qo({backupCodes:n.backupCodes,code:r.body.code},r.context.secret);if(!i.status)throw new Pe("UNAUTHORIZED",{message:"Invalid backup code"});let s=await Z({key:r.context.secret,data:JSON.stringify(i.updated)});return await r.context.adapter.update({model:o,update:{backupCodes:s},where:[{field:"userId",value:t.id}]}),r.body.disableSession||await w(r,{session:r.context.session,user:t}),r.json({user:t,session:r.context.session})}),generateBackupCodes:c("/two-factor/generate-backup-codes",{method:"POST",body:Y.object({password:Y.string()}),use:[b]},async r=>{let t=r.context.session.user;if(!t.twoFactorEnabled)throw new Pe("BAD_REQUEST",{message:"Two factor isn't enabled"});await r.context.password.checkPassword(t.id,r);let n=await ot(r.context.secret,e);return await r.context.adapter.update({model:o,update:{backupCodes:n.encryptedBackupCodes},where:[{field:"userId",value:r.context.session.user.id}]}),r.json({status:!0,backupCodes:n.backupCodes})}),viewBackupCodes:c("/two-factor/view-backup-codes",{method:"GET",body:Y.object({userId:Y.string()}),metadata:{SERVER_ONLY:!0}},async r=>{let t=await r.context.adapter.findOne({model:o,where:[{field:"userId",value:r.body.userId}]});if(!t)throw new Pe("BAD_REQUEST",{message:"Backup codes aren't enabled"});let n=await ir(t.backupCodes,r.context.secret);if(!n)throw new Pe("BAD_REQUEST",{message:"Backup codes aren't enabled"});return r.json({status:!0,backupCodes:n})})}});import{APIError as He}from"better-call";import{TOTPController as Ho}from"oslo/otp";import{z as ar}from"zod";import{TimeSpan as Wo}from"oslo";var dr=(e,o)=>{let r={...e,period:new Wo(e?.period||3,"m")},t=new Ho({digits:6,period:r.period}),n=c("/two-factor/send-otp",{method:"POST",use:[me]},async s=>{if(!e||!e.sendOTP)throw s.context.logger.error("send otp isn't configured. Please configure the send otp function on otp options."),new He("BAD_REQUEST",{message:"otp isn't configured"});let a=s.context.session.user,d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d)throw new He("BAD_REQUEST",{message:"OTP isn't enabled"});let u=await t.generate(Buffer.from(d.secret));return await e.sendOTP({user:a,otp:u},s.request),s.json({status:!0})}),i=c("/two-factor/verify-otp",{method:"POST",body:ar.object({code:ar.string()}),use:[me]},async s=>{let a=s.context.session.user;if(!a.twoFactorEnabled)throw new He("BAD_REQUEST",{message:"two factor isn't enabled"});let d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d)throw new He("BAD_REQUEST",{message:"OTP isn't enabled"});return await t.generate(Buffer.from(d.secret))===s.body.code?s.context.valid():s.context.invalid()});return{id:"otp",endpoints:{send2FaOTP:n,verifyOTP:i}}};import{APIError as ke}from"better-call";import{TimeSpan as Go}from"oslo";import{TOTPController as ur,createTOTPKeyURI as Jo}from"oslo/otp";import{z as We}from"zod";var cr=(e,o)=>{let r={...e,digits:6,period:new Go(e?.period||30,"s")},t=c("/totp/generate",{method:"POST",use:[b]},async s=>{if(!e)throw s.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp"),new ke("BAD_REQUEST",{message:"totp isn't configured"});let a=s.context.session.user,d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d)throw new ke("BAD_REQUEST",{message:"totp isn't enabled"});return{code:await new ur(r).generate(Buffer.from(d.secret))}}),n=c("/two-factor/get-totp-uri",{method:"POST",use:[b],body:We.object({password:We.string()})},async s=>{if(!e)throw s.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp"),new ke("BAD_REQUEST",{message:"totp isn't configured"});let a=s.context.session.user,d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d||!a.twoFactorEnabled)throw new ke("BAD_REQUEST",{message:"totp isn't enabled"});return await s.context.password.checkPassword(a.id,s),{totpURI:Jo(e.issuer||s.context.appName,a.email,Buffer.from(d.secret),r)}}),i=c("/two-factor/verify-totp",{method:"POST",body:We.object({code:We.string()}),use:[me]},async s=>{if(!e)throw s.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp"),new ke("BAD_REQUEST",{message:"totp isn't configured"});let a=s.context.session.user,d=await s.context.adapter.findOne({model:o,where:[{field:"userId",value:a.id}]});if(!d)throw new ke("BAD_REQUEST",{message:"totp isn't enabled"});let u=new ur(r),l=await ne({key:s.context.secret,data:d.secret}),m=Buffer.from(l);if(!await u.verify(s.body.code,m))return s.context.invalid();if(!a.twoFactorEnabled){let p=await s.context.internalAdapter.updateUser(a.id,{twoFactorEnabled:!0}),h=await s.context.internalAdapter.createSession(a.id,s.request);await w(s,{session:h,user:p})}return s.context.valid()});return{id:"totp",endpoints:{generateTOTP:t,viewTOTPURI:n,verifyTOTP:i}}};import{APIError as _l}from"better-call";async function nt(e,o){let t=(await e.context.internalAdapter.findAccounts(o.userId))?.find(s=>s.providerId==="credential"),n=t?.password;return!t||!n?!1:await e.context.password.verify(n,o.password)}import{APIError as it}from"better-call";import{createTOTPKeyURI as Ko}from"oslo/otp";import{TimeSpan as Zo}from"oslo";var zl=(e={redirect:!0,twoFactorPage:"/"})=>({id:"two-factor",$InferServerPlugin:{},atomListeners:[{matcher:o=>o.startsWith("/two-factor/"),signal:"$sessionSignal"}],pathMethods:{"/two-factor/disable":"POST","/two-factor/enable":"POST","/two-factor/send-otp":"POST","/two-factor/generate-backup-codes":"POST"},fetchPlugins:[{id:"two-factor",name:"two-factor",hooks:{async onSuccess(o){o.data?.twoFactorRedirect&&(e.redirect||e.twoFactorPage)&&typeof window<"u"&&(window.location.href=e.twoFactorPage)}}}]});var Jl=e=>{let o={twoFactorTable:e?.twoFactorTable||"twoFactor"},r=cr({issuer:e?.issuer,...e?.totpOptions},o.twoFactorTable),t=sr({...e?.backupCodeOptions},o.twoFactorTable),n=dr({...e?.otpOptions},o.twoFactorTable);return{id:"two-factor",endpoints:{...r.endpoints,...n.endpoints,...t.endpoints,enableTwoFactor:c("/two-factor/enable",{method:"POST",body:Ge.object({password:Ge.string().min(8)}),use:[b]},async i=>{let s=i.context.session.user,{password:a}=i.body;if(!await nt(i,{password:a,userId:s.id}))throw new it("BAD_REQUEST",{message:"Invalid password"});let u=F(16,q("a-z","0-9","-")),l=await Z({key:i.context.secret,data:u}),m=await ot(i.context.secret,e?.backupCodeOptions);if(e?.skipVerificationOnEnable){let p=await i.context.internalAdapter.updateUser(s.id,{twoFactorEnabled:!0}),h=await i.context.internalAdapter.createSession(p.id,i.request);await w(i,{session:h,user:s})}await i.context.adapter.deleteMany({model:o.twoFactorTable,where:[{field:"userId",value:s.id}]}),await i.context.adapter.create({model:o.twoFactorTable,data:{id:i.context.uuid(),secret:l,backupCodes:m.encryptedBackupCodes,userId:s.id}});let f=Ko(e?.issuer||"BetterAuth",s.email,Buffer.from(u),{digits:e?.totpOptions?.digits||6,period:new Zo(e?.totpOptions?.period||30,"s")});return i.json({totpURI:f,backupCodes:m.backupCodes})}),disableTwoFactor:c("/two-factor/disable",{method:"POST",body:Ge.object({password:Ge.string().min(8)}),use:[b]},async i=>{let s=i.context.session.user,{password:a}=i.body;if(!await nt(i,{password:a,userId:s.id}))throw new it("BAD_REQUEST",{message:"Invalid password"});return await i.context.internalAdapter.updateUser(s.id,{twoFactorEnabled:!1}),await i.context.adapter.delete({model:o.twoFactorTable,where:[{field:"userId",value:s.id}]}),i.json({status:!0})})},options:e,hooks:{after:[{matcher(i){return i.path==="/sign-in/email"||i.path==="/sign-in/username"},handler:S(async i=>{let s=i.context.returned;if(s instanceof Response&&s?.status!==200||s instanceof it)return;let a=s instanceof Response?await s.clone().json():s;if(!a.user.twoFactorEnabled)return;let d=i.context.createAuthCookie(Qe,{maxAge:30*24*60*60}),u=await i.getSignedCookie(d.name,i.context.secret);if(u){let[f,p]=u.split("!"),h=await Te(i.context.secret,`${a.user.id}!${p}`);if(f===h){let k=await Te(i.context.secret,`${a.user.id}!${a.session.id}`);await i.setSignedCookie(d.name,`${k}!${a.session.id}`,i.context.secret,d.attributes);return}}J(i),await i.context.internalAdapter.deleteSession(a.session.id);let l=i.context.createAuthCookie($e,{maxAge:60*10});return await i.setSignedCookie(l.name,a.user.id,i.context.secret,l.attributes),{response:new Response(JSON.stringify({twoFactorRedirect:!0}),{headers:i.responseHeader})}})}]},schema:{user:{fields:{twoFactorEnabled:{type:"boolean",required:!1,defaultValue:!1,input:!1}}},twoFactor:{tableName:o.twoFactorTable,fields:{secret:{type:"string",required:!0,returned:!1},backupCodes:{type:"string",required:!0,returned:!1},userId:{type:"string",required:!0,returned:!1,references:{model:"user",field:"id"}}}}},rateLimit:[{pathMatcher(i){return i.startsWith("/two-factor/")},window:10,max:3}]}};import{generateAuthenticationOptions as sn,generateRegistrationOptions as an,verifyAuthenticationResponse as dn,verifyRegistrationResponse as un}from"@simplewebauthn/server";import{APIError as G}from"better-call";import{z as X}from"zod";import{WebAuthnError as en,startAuthentication as tn,startRegistration as rn}from"@simplewebauthn/browser";import{createFetch as pm}from"@better-fetch/fetch";import"nanostores";import"@better-fetch/fetch";import{atom as im}from"nanostores";import"@better-fetch/fetch";import{atom as Yo,onMount as Xo}from"nanostores";var st=(e,o,r,t)=>{let n=Yo({data:null,error:null,isPending:!0,isRefetching:!1}),i=()=>{let a=typeof t=="function"?t({data:n.get().data,error:n.get().error,isPending:n.get().isPending}):t;return r(o,{...a,onSuccess:async d=>{n.set({data:d.data,error:null,isPending:!1,isRefetching:!1}),await a?.onSuccess?.(d)},async onError(d){n.set({error:d.error,data:null,isPending:!1,isRefetching:!1}),await a?.onError?.(d)},async onRequest(d){let u=n.get();n.set({isPending:u.data===null,data:u.data,error:null,isRefetching:!0}),await a?.onRequest?.(d)}})};e=Array.isArray(e)?e:[e];let s=!1;for(let a of e)a.subscribe(()=>{s?i():Xo(n,()=>(i(),s=!0,()=>{n.off(),a.off()}))});return n};import{atom as on}from"nanostores";var nn=(e,{$listPasskeys:o})=>({signIn:{passkey:async(n,i)=>{let s=await e("/passkey/generate-authenticate-options",{method:"POST",body:{email:n?.email}});if(!s.data)return s;try{let a=await tn(s.data,n?.autoFill||!1),d=await e("/passkey/verify-authentication",{body:{response:a},...n?.fetchOptions,...i,method:"POST"});if(!d.data)return d}catch{return{data:null,error:{message:"auth cancelled",status:400,statusText:"BAD_REQUEST"}}}}},passkey:{addPasskey:async(n,i)=>{let s=await e("/passkey/generate-register-options",{method:"GET"});if(!s.data)return s;try{let a=await rn(s.data),d=await e("/passkey/verify-registration",{...n?.fetchOptions,...i,body:{response:a,name:n?.name},method:"POST"});if(!d.data)return d;o.set(Math.random())}catch(a){return a instanceof en?a.code==="ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED"?{data:null,error:{message:"previously registered",status:400,statusText:"BAD_REQUEST"}}:a.code==="ERROR_CEREMONY_ABORTED"?{data:null,error:{message:"registration cancelled",status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:a.message,status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:a instanceof Error?a.message:"unknown error",status:500,statusText:"INTERNAL_SERVER_ERROR"}}}}},$Infer:{}}),Bm=()=>{let e=on();return{id:"passkey",$InferServerPlugin:{},getActions:o=>nn(o,{$listPasskeys:e}),getAtoms(o){return{listPasskeys:st(e,"/passkey/list-user-passkeys",o,{method:"GET"}),$listPasskeys:e}},pathMethods:{"/passkey/register":"POST","/passkey/authenticate":"POST"},atomListeners:[{matcher(o){return o==="/passkey/verify-registration"||o==="/passkey/delete-passkey"},signal:"_listPasskeys"}]}};var Wm=e=>{let o=Q.BETTER_AUTH_URL,r=e?.rpID||o?.replace("http://","").replace("https://","").split(":")[0]||"localhost";if(!r)throw new $("passkey rpID not found. Please provide a rpID in the options or set the BETTER_AUTH_URL environment variable.");let t={origin:null,...e,rpID:r,advanced:{webAuthnChallengeCookie:"better-auth-passkey",...e?.advanced}},n=new Date(Date.now()+1e3*60*5),i=new Date,s=Math.floor((n.getTime()-i.getTime())/1e3);return{id:"passkey",endpoints:{generatePasskeyRegistrationOptions:c("/passkey/generate-register-options",{method:"GET",use:[b],metadata:{client:!1}},async a=>{let d=a.context.session,u=await a.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}),l=new Uint8Array(Buffer.from(F(32,q("a-z","0-9")))),m;m=await an({rpName:t.rpName||a.context.appName,rpID:t.rpID,userID:l,userName:d.user.email||d.user.id,attestationType:"none",excludeCredentials:u.map(p=>({id:p.id,transports:p.transports?.split(",")})),authenticatorSelection:{residentKey:"preferred",userVerification:"preferred",authenticatorAttachment:"platform"}});let f=B();return await a.setSignedCookie(t.advanced.webAuthnChallengeCookie,f,a.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:s}),await a.context.internalAdapter.createVerificationValue({identifier:f,value:JSON.stringify({expectedChallenge:m.challenge,userData:{id:d.user.id}}),expiresAt:n}),a.json(m,{status:200})}),generatePasskeyAuthenticationOptions:c("/passkey/generate-authenticate-options",{method:"POST",body:X.object({email:X.string().optional()}).optional()},async a=>{let d=await C(a),u=[];d&&(u=await a.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}));let l=await sn({rpID:t.rpID,userVerification:"preferred",...u.length?{allowCredentials:u.map(p=>({id:p.id,transports:p.transports?.split(",")}))}:{}}),m={expectedChallenge:l.challenge,userData:{id:d?.user.id||""}},f=B();return await a.setSignedCookie(t.advanced.webAuthnChallengeCookie,f,a.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:s}),await a.context.internalAdapter.createVerificationValue({identifier:f,value:JSON.stringify(m),expiresAt:n}),a.json(l,{status:200})}),verifyPasskeyRegistration:c("/passkey/verify-registration",{method:"POST",body:X.object({response:X.any(),name:X.string().optional()}),use:[b]},async a=>{let d=e?.origin||a.headers?.get("origin")||"";if(!d)return a.json(null,{status:400});let u=a.body.response,l=await a.getSignedCookie(t.advanced.webAuthnChallengeCookie,a.context.secret);if(!l)throw new G("BAD_REQUEST",{message:"Challenge not found"});let m=await a.context.internalAdapter.findVerificationValue(l);if(!m)return a.json(null,{status:400});let{expectedChallenge:f,userData:p}=JSON.parse(m.value);if(p.id!==a.context.session.user.id)throw new G("UNAUTHORIZED",{message:"You are not authorized to register this passkey"});try{let h=await un({response:u,expectedChallenge:f,expectedOrigin:d,expectedRPID:e?.rpID}),{verified:k,registrationInfo:R}=h;if(!k||!R)return a.json(null,{status:400});let{credentialID:K,credentialPublicKey:fe,counter:j,credentialDeviceType:Ye,credentialBackedUp:ge}=R,se=Buffer.from(fe).toString("base64"),Xe=B(),wr={name:a.body.name,userId:p.id,webauthnUserID:Xe,id:K,publicKey:se,counter:j,deviceType:Ye,transports:u.response.transports.join(","),backedUp:ge,createdAt:new Date},yr=await a.context.adapter.create({model:"passkey",data:wr});return a.json(yr,{status:200})}catch(h){throw console.log(h),new G("INTERNAL_SERVER_ERROR",{message:"Failed to verify registration"})}}),verifyPasskeyAuthentication:c("/passkey/verify-authentication",{method:"POST",body:X.object({response:X.any()})},async a=>{let d=e?.origin||a.headers?.get("origin")||"";if(!d)throw new G("BAD_REQUEST",{message:"origin missing"});let u=a.body.response,l=await a.getSignedCookie(t.advanced.webAuthnChallengeCookie,a.context.secret);if(!l)throw new G("BAD_REQUEST",{message:"Challenge not found"});let m=await a.context.internalAdapter.findVerificationValue(l);if(!m)throw new G("BAD_REQUEST",{message:"Challenge not found"});let{expectedChallenge:f}=JSON.parse(m.value),p=await a.context.adapter.findOne({model:"passkey",where:[{field:"id",value:u.id}]});if(!p)throw new G("UNAUTHORIZED",{message:"Passkey not found"});try{let h=await dn({response:u,expectedChallenge:f,expectedOrigin:d,expectedRPID:t.rpID,authenticator:{credentialID:p.id,credentialPublicKey:new Uint8Array(Buffer.from(p.publicKey,"base64")),counter:p.counter,transports:p.transports?.split(",")}}),{verified:k}=h;if(!k)throw new G("UNAUTHORIZED",{message:"Authentication failed"});await a.context.adapter.update({model:"passkey",where:[{field:"id",value:p.id}],update:{counter:h.authenticationInfo.newCounter}});let R=await a.context.internalAdapter.createSession(p.userId,a.request);if(!R)throw new G("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});let K=await a.context.internalAdapter.findUserById(p.userId);if(!K)throw new G("INTERNAL_SERVER_ERROR",{message:"User not found"});return await w(a,{session:R,user:K}),a.json({session:R},{status:200})}catch(h){throw a.context.logger.error(h),new G("BAD_REQUEST",{message:"Failed to verify authentication"})}}),listPasskeys:c("/passkey/list-user-passkeys",{method:"GET",use:[b]},async a=>{let d=await a.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:a.context.session.user.id}]});return a.json(d,{status:200})}),deletePasskey:c("/passkey/delete-passkey",{method:"POST",body:X.object({id:X.string()}),use:[b]},async a=>(await a.context.adapter.delete({model:"passkey",where:[{field:"id",value:a.body.id}]}),a.json(null,{status:200})))},schema:{passkey:{fields:{name:{type:"string",required:!1},publicKey:{type:"string",required:!0},userId:{type:"string",references:{model:"user",field:"id"},required:!0},webauthnUserID:{type:"string",required:!0},counter:{type:"number",required:!0},deviceType:{type:"string",required:!0},backedUp:{type:"boolean",required:!0},transports:{type:"string",required:!1},createdAt:{type:"date",defaultValue:new Date,required:!1}}}}}};import{z as Je}from"zod";import{APIError as Ke}from"better-call";var lr=()=>({id:"username",endpoints:{signInUsername:c("/sign-in/username",{method:"POST",body:Je.object({username:Je.string(),password:Je.string(),rememberMe:Je.boolean().optional()})},async e=>{let o=await e.context.adapter.findOne({model:e.context.tables.user.tableName,where:[{field:"username",value:e.body.username}]});if(!o)throw await e.context.password.hash(e.body.password),e.context.logger.error("User not found",{username:lr}),new Ke("UNAUTHORIZED",{message:"Invalid username or password"});let r=await e.context.adapter.findOne({model:e.context.tables.account.tableName,where:[{field:e.context.tables.account.fields.userId.fieldName||"userId",value:o.id},{field:e.context.tables.account.fields.providerId.fieldName||"providerId",value:"credential"}]});if(!r)throw new Ke("UNAUTHORIZED",{message:"Invalid username or password"});let t=r?.password;if(!t)throw e.context.logger.error("Password not found",{username:lr}),new Ke("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(t,e.body.password))throw e.context.logger.error("Invalid password"),new Ke("UNAUTHORIZED",{message:"Invalid username or password"});let i=await e.context.internalAdapter.createSession(o.id,e.request,e.body.rememberMe===!1);return i?(await e.setSignedCookie(e.context.authCookies.sessionToken.name,i.id,e.context.secret,e.body.rememberMe===!1?{...e.context.authCookies.sessionToken.options,maxAge:void 0}:e.context.authCookies.sessionToken.options),e.json({user:o,session:i})):e.json(null,{status:500,body:{message:"Failed to create session",status:500}})})},schema:{user:{fields:{username:{type:"string",required:!1,unique:!0,returned:!0}}}}});import{serializeSigned as cn}from"better-call";var tp=()=>({id:"bearer",hooks:{before:[{matcher(e){return!!(e.request?.headers.get("authorization")||e.headers?.get("authorization"))},handler:async e=>{let o=e.request?.headers.get("authorization")?.replace("Bearer ","")||e.headers?.get("authorization")?.replace("Bearer ","");if(!o)return;let r="";return o.includes(".")?r=o:r=await cn("",o,e.context.secret),e.request&&e.request.headers.set("cookie",`${e.context.authCookies.sessionToken.name}=${r.replace("=","")}`),e.headers&&e.headers.set("cookie",`${e.context.authCookies.sessionToken.name}=${r.replace("=","")}`),{context:e}}}]}});import{z as Oe}from"zod";import{APIError as mr}from"better-call";var dp=e=>({id:"magic-link",endpoints:{signInMagicLink:c("/sign-in/magic-link",{method:"POST",requireHeaders:!0,body:Oe.object({email:Oe.string().email(),callbackURL:Oe.string().optional()})},async o=>{let{email:r}=o.body;if(e.disableSignUp&&!await o.context.internalAdapter.findUserByEmail(r))throw new mr("BAD_REQUEST",{message:"User not found"});let t=F(32,q("a-z","A-Z"));await o.context.internalAdapter.createVerificationValue({identifier:t,value:r,expiresAt:new Date(Date.now()+(e.expiresIn||60*5)*1e3)});let n=`${o.context.baseURL}/magic-link/verify?token=${t}&callbackURL=${o.body.callbackURL||"/"}`;try{await e.sendMagicLink({email:r,url:n,token:t},o.request)}catch(i){throw o.context.logger.error("Failed to send magic link",i),new mr("INTERNAL_SERVER_ERROR",{message:"Failed to send magic link"})}return o.json({status:!0})}),magicLinkVerify:c("/magic-link/verify",{method:"GET",query:Oe.object({token:Oe.string(),callbackURL:Oe.string().optional()}),requireHeaders:!0},async o=>{let{token:r,callbackURL:t}=o.query,n=t?.startsWith("http")?t:t?`${o.context.options.baseURL}${t}`:o.context.options.baseURL,i=await o.context.internalAdapter.findVerificationValue(r);if(!i)throw o.redirect(`${n}?error=INVALID_TOKEN`);if(i.expiresAt<new Date)throw await o.context.internalAdapter.deleteVerificationValue(i.id),o.redirect(`${n}?error=EXPIRED_TOKEN`);await o.context.internalAdapter.deleteVerificationValue(i.id);let s=i.value,a=await o.context.internalAdapter.findUserByEmail(s),d=a?.user.id||"";if(!a){if(e.disableSignUp)throw o.redirect(`${n}?error=USER_NOT_FOUND`);if(d=(await o.context.internalAdapter.createUser({email:s,emailVerified:!0,name:s})).id,!d)throw o.redirect(`${n}?error=USER_NOT_CREATED`)}let u=await o.context.internalAdapter.createSession(d,o.headers);if(!u)throw o.redirect(`${n}?error=SESSION_NOT_CREATED`);if(await w(o,{session:u,user:a?.user}),!t)return o.json({status:!0});throw o.redirect(t)})},rateLimit:[{pathMatcher(o){return o.startsWith("/sign-in/magic-link")||o.startsWith("/magic-link/verify")},window:e.rateLimit?.window||60,max:e.rateLimit?.max||5}]});import{z as pe}from"zod";import{APIError as ie}from"better-call";function ln(e){return F(e,q("0-9"))}var yp=e=>{let o={phoneNumber:"phoneNumber",phoneNumberVerified:"phoneNumberVerified",code:"code",createdAt:"createdAt",expiresIn:e?.expiresIn||300,otpLength:e?.otpLength||6};return{id:"phone-number",endpoints:{sendPhoneNumberOTP:c("/phone-number/send-otp",{method:"POST",body:pe.object({phoneNumber:pe.string()})},async r=>{if(!e?.sendOTP)throw y.warn("sendOTP not implemented"),new ie("NOT_IMPLEMENTED",{message:"sendOTP not implemented"});let t=ln(o.otpLength);return await r.context.internalAdapter.createVerificationValue({value:t,identifier:r.body.phoneNumber,expiresAt:P(o.expiresIn,"sec")}),await e.sendOTP({phoneNumber:r.body.phoneNumber,code:t},r.request),r.json({code:t},{body:{message:"Code sent"}})}),verifyPhoneNumber:c("/phone-number/verify",{method:"POST",body:pe.object({phoneNumber:pe.string(),code:pe.string(),disableSession:pe.boolean().optional(),updatePhoneNumber:pe.boolean().optional()})},async r=>{let t=await r.context.internalAdapter.findVerificationValue(r.body.phoneNumber);if(!t||t.expiresAt<new Date)throw t&&t.expiresAt<new Date?(await r.context.internalAdapter.deleteVerificationValue(t.id),new ie("BAD_REQUEST",{message:"OTP expired"})):new ie("BAD_REQUEST",{message:"OTP not found"});if(t.value!==r.body.code)throw new ie("BAD_REQUEST",{message:"Invalid OTP"});if(await r.context.internalAdapter.deleteVerificationValue(t.id),r.body.updatePhoneNumber){let i=await C(r);if(!i)throw new ie("UNAUTHORIZED",{message:"Session not found"});let s=await r.context.internalAdapter.updateUser(i.user.id,{[o.phoneNumber]:r.body.phoneNumber,[o.phoneNumberVerified]:!0});return r.json({user:s,session:i.session})}let n=await r.context.adapter.findOne({model:r.context.tables.user.tableName,where:[{value:r.body.phoneNumber,field:o.phoneNumber}]});if(await e?.callbackOnVerification?.({phoneNumber:r.body.phoneNumber,user:n},r.request),n)n=await r.context.internalAdapter.updateUser(n.id,{[o.phoneNumberVerified]:!0});else if(e?.signUpOnVerification){if(n=await r.context.internalAdapter.createUser({email:e.signUpOnVerification.getTempEmail(r.body.phoneNumber),name:e.signUpOnVerification.getTempName?e.signUpOnVerification.getTempName(r.body.phoneNumber):r.body.phoneNumber,[o.phoneNumber]:r.body.phoneNumber,[o.phoneNumberVerified]:!0}),!n)throw new ie("INTERNAL_SERVER_ERROR",{message:"Failed to create user"})}else return r.json(null);if(!n)throw new ie("INTERNAL_SERVER_ERROR",{message:"Failed to update user"});if(!r.body.disableSession){let i=await r.context.internalAdapter.createSession(n.id,r.request);if(!i)throw new ie("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await w(r,{session:i,user:n}),r.json({user:n,session:i})}return r.json({user:n,session:null})})},schema:{user:{fields:{phoneNumber:{type:"string",required:!1,unique:!0,returned:!0},phoneNumberVerified:{type:"boolean",required:!1,returned:!0,input:!1}}}}}};import"zod";var Ip=e=>({id:"anonymous",endpoints:{signInAnonymous:c("/sign-in/anonymous",{method:"POST"},async o=>{let{emailDomainName:r=we(o.context.baseURL)}=e||{},t=B(),n=`temp-${t}@${r}`,i=await o.context.internalAdapter.createUser({id:t,email:n,emailVerified:!1,isAnonymous:!0,name:"Anonymous",createdAt:new Date,updatedAt:new Date});if(!i)return o.json(null,{status:500,body:{message:"Failed to create user",status:500}});let s=await o.context.internalAdapter.createSession(i.id,o.request);return s?(await w(o,{session:s,user:i}),o.json({user:i,session:s})):o.json(null,{status:400,body:{message:"Could not create session"}})})},hooks:{after:[{matcher(o){return o.path?.startsWith("/sign-in")||o.path?.startsWith("/sign-up")},async handler(o){let r=o.context.returned;if(!(r instanceof Response))return;let t=r.headers.get("set-cookie"),n=o.context.authCookies.sessionToken.name,i=xe(t||"").get(n)?.value.split(".")[0];if(!i)return;let s=await C(o);if(!(!s||!s.user.isAnonymous)){if(o.path==="/sign-in/anonymous")throw new v("BAD_REQUEST",{message:"Anonymous users cannot sign in again anonymously"});if(e?.onLinkAccount){let a=await o.context.internalAdapter.findSession(i);if(!a)return;await e?.onLinkAccount?.({anonymousUser:s,newUser:a})}e?.disableDeleteAnonymousUser||await o.context.internalAdapter.deleteUser(s.user.id)}}}]},schema:{user:{fields:{isAnonymous:{type:"boolean",required:!1}}}}});import{z as g}from"zod";var zp=e=>{let o={defaultRole:"user",adminRole:"admin",...e},r=S(async t=>{let n=await C(t);if(!n?.session)throw new v("UNAUTHORIZED");let i=n.user;if(!i.role||(Array.isArray(o.adminRole)?!o.adminRole.includes(i.role):i.role!==o.adminRole))throw new v("FORBIDDEN",{message:"Only admins can access this endpoint"});return{session:{user:i,session:n.session}}});return{id:"admin",init(t){return{options:{databaseHooks:{user:{create:{async before(n){if(e?.defaultRole!==!1)return{data:{role:e?.defaultRole??"user",...n}}}}},session:{create:{async before(n){let i=await t.internalAdapter.findUserById(n.userId);if(i.banned){if(i.banExpires&&i.banExpires<Date.now()){await t.internalAdapter.updateUser(n.userId,{banned:!1,banReason:null,banExpires:null});return}return!1}}}}}}}},hooks:{after:[{matcher(t){return t.path==="/list-sessions"},handler:S(async t=>{let n=t.context.returned;if(n instanceof Response){let s=(await n.clone().json()).filter(d=>!d.impersonatedBy),a=new Response(JSON.stringify(s),{status:200,statusText:"OK",headers:n.headers});return t.json({response:a})}})}]},endpoints:{setRole:c("/admin/set-role",{method:"POST",body:g.object({userId:g.string(),role:g.string()}),use:[r]},async t=>{let n=await t.context.internalAdapter.updateUser(t.body.userId,{role:t.body.role});return t.json({user:n})}),createUser:c("/admin/create-user",{method:"POST",body:g.object({email:g.string(),password:g.string(),name:g.string(),role:g.string(),data:g.optional(g.record(g.any()))}),use:[r]},async t=>{if(await t.context.internalAdapter.findUserByEmail(t.body.email))throw new v("BAD_REQUEST",{message:"User already exists"});let i=await t.context.internalAdapter.createUser({email:t.body.email,name:t.body.name,role:t.body.role,...t.body.data});if(!i)throw new v("INTERNAL_SERVER_ERROR",{message:"Failed to create user"});let s=await t.context.password.hash(t.body.password);return await t.context.internalAdapter.linkAccount({accountId:i.id,providerId:"credential",password:s,userId:i.id}),t.json({user:i})}),listUsers:c("/admin/list-users",{method:"GET",use:[r],query:g.object({searchValue:g.string().optional(),searchField:g.enum(["email","name"]).optional(),searchOperator:g.enum(["contains","starts_with","ends_with"]).optional(),limit:g.string().or(g.number()).optional(),offset:g.string().or(g.number()).optional(),sortBy:g.string().optional(),sortDirection:g.enum(["asc","desc"]).optional(),filterField:g.string().optional(),filterValue:g.string().or(g.number()).or(g.boolean()).optional(),filterOperator:g.enum(["eq","ne","lt","lte","gt","gte"]).optional()})},async t=>{let n=[];t.query?.searchValue&&n.push({field:t.query.searchField||"email",operator:t.query.searchOperator||"contains",value:t.query.searchValue}),t.query?.filterValue&&n.push({field:t.query.filterField||"email",operator:t.query.filterOperator||"eq",value:t.query.filterValue});try{let i=await t.context.internalAdapter.listUsers(Number(t.query?.limit)||void 0,Number(t.query?.offset)||void 0,t.query?.sortBy?{field:t.query.sortBy,direction:t.query.sortDirection||"asc"}:void 0,n.length?n:void 0);return t.json({users:i})}catch(i){return console.log(i),t.json({users:[]})}}),listUserSessions:c("/admin/list-user-sessions",{method:"POST",use:[r],body:g.object({userId:g.string()})},async t=>({sessions:await t.context.internalAdapter.listSessions(t.body.userId)})),unbanUser:c("/admin/unban-user",{method:"POST",body:g.object({userId:g.string()}),use:[r]},async t=>{let n=await t.context.internalAdapter.updateUser(t.body.userId,{banned:!1});return t.json({user:n})}),banUser:c("/admin/ban-user",{method:"POST",body:g.object({userId:g.string(),banReason:g.string().optional(),banExpiresIn:g.number().optional()}),use:[r]},async t=>{if(t.body.userId===t.context.session.user.id)throw new v("BAD_REQUEST",{message:"You cannot ban yourself"});let n=await t.context.internalAdapter.updateUser(t.body.userId,{banned:!0,banReason:t.body.banReason||e?.defaultBanReason||"No reason",banExpires:t.body.banExpiresIn?P(t.body.banExpiresIn,"sec"):e?.defaultBanExpiresIn?P(e.defaultBanExpiresIn,"sec"):void 0});return await t.context.internalAdapter.deleteSessions(t.body.userId),t.json({user:n})}),impersonateUser:c("/admin/impersonate-user",{method:"POST",body:g.object({userId:g.string()}),use:[r]},async t=>{let n=await t.context.internalAdapter.findUserById(t.body.userId);if(!n)throw new v("NOT_FOUND",{message:"User not found"});let i=await t.context.internalAdapter.createSession(n.id,void 0,!0,{impersonatedBy:t.context.session.user.id,expiresAt:e?.impersonationSessionDuration?P(e.impersonationSessionDuration,"sec"):P(60*60,"sec")});if(!i)throw new v("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await w(t,{session:i,user:n},!0),t.json({session:i,user:n})}),revokeUserSession:c("/admin/revoke-user-session",{method:"POST",body:g.object({sessionId:g.string()}),use:[r]},async t=>(await t.context.internalAdapter.deleteSession(t.body.sessionId),t.json({success:!0}))),revokeUserSessions:c("/admin/revoke-user-sessions",{method:"POST",body:g.object({userId:g.string()}),use:[r]},async t=>(await t.context.internalAdapter.deleteSessions(t.body.userId),t.json({success:!0}))),removeUser:c("/admin/remove-user",{method:"POST",body:g.object({userId:g.string()}),use:[r]},async t=>(await t.context.internalAdapter.deleteUser(t.body.userId),t.json({success:!0})))},schema:{user:{fields:{role:{type:"string",required:!1,input:!1},banned:{type:"boolean",defaultValue:!1,required:!1,input:!1},banReason:{type:"string",required:!1,input:!1},banExpires:{type:"date",required:!1,input:!1}}},session:{fields:{impersonatedBy:{type:"string",required:!1}}}}}};import{z as ee}from"zod";import{APIError as _e}from"better-call";import{betterFetch as at}from"@better-fetch/fetch";import{parseJWT as mn}from"oslo/jwt";async function pn(e,o,r){if(o==="oidc"&&e.idToken){let n=mn(e.idToken);if(n?.payload)return n.payload}return r?(await at(r,{method:"GET",headers:{Authorization:`Bearer ${e.accessToken}`}})).data:null}var Wp=e=>({id:"generic-oauth",endpoints:{signInWithOAuth2:c("/sign-in/oauth2",{method:"POST",query:ee.object({currentURL:ee.string().optional()}).optional(),body:ee.object({providerId:ee.string(),callbackURL:ee.string().optional()})},async o=>{let{providerId:r}=o.body,t=e.config.find(se=>se.providerId===r);if(!t)throw new _e("BAD_REQUEST",{message:`No config found for provider ${r}`});let{discoveryUrl:n,authorizationUrl:i,tokenUrl:s,clientId:a,clientSecret:d,scopes:u,redirectURI:l,responseType:m,pkce:f,prompt:p,accessType:h}=t,k=i,R=s;if(n){let se=await at(n,{onError(Xe){y.error(Xe.error,{discoveryUrl:n})}});se.data&&(k=se.data.authorization_endpoint,R=se.data.token_endpoint)}if(!k||!R)throw new _e("BAD_REQUEST",{message:"Invalid OAuth configuration."});let K=o.query?.currentURL?new URL(o.query?.currentURL):null,fe=o.body.callbackURL?.startsWith("http")?o.body.callbackURL:`${K?.origin}${o.body.callbackURL||""}`,{state:j,codeVerifier:Ye}=await ye(o),ge=await E({id:r,options:{clientId:a,clientSecret:d,redirectURI:l},authorizationEndpoint:k,state:j,codeVerifier:f?Ye:void 0,scopes:u||[],redirectURI:`${o.context.baseURL}/oauth2/callback/${r}`});return m&&m!=="code"&&ge.searchParams.set("response_type",m),p&&ge.searchParams.set("prompt",p),h&&ge.searchParams.set("access_type",h),o.json({url:ge.toString(),redirect:!0})}),oAuth2Callback:c("/oauth2/callback/:providerId",{method:"GET",query:ee.object({code:ee.string().optional(),error:ee.string().optional(),state:ee.string()})},async o=>{if(o.query.error||!o.query.code)throw o.redirect(`${o.context.baseURL}?error=${o.query.error||"oAuth_code_missing"}`);let r=e.config.find(j=>j.providerId===o.params.providerId);if(!r)throw new _e("BAD_REQUEST",{message:`No config found for provider ${o.params.providerId}`});let t,n=await De(o),{callbackURL:i,codeVerifier:s,errorURL:a}=n,d=o.query.code,u=r.tokenUrl,l=r.userInfoUrl;if(r.discoveryUrl){let j=await at(r.discoveryUrl,{method:"GET"});j.data&&(u=j.data.token_endpoint,l=j.data.userinfo_endpoint)}try{if(!u)throw new _e("BAD_REQUEST",{message:"Invalid OAuth configuration."});t=await O({code:d,codeVerifier:s,redirectURI:`${o.context.baseURL}/oauth2/callback/${r.providerId}`,options:{clientId:r.clientId,clientSecret:r.clientSecret},tokenEndpoint:u})}catch(j){throw o.context.logger.error(j),o.redirect(`${a}?error=oauth_code_verification_failed`)}if(!t)throw new _e("BAD_REQUEST",{message:"Invalid OAuth configuration."});let m=r.getUserInfo?await r.getUserInfo(t):await pn(t,r.type||"oauth2",l),f=B(),p=Ct.safeParse({...m,id:f});if(!m||p.success===!1)throw y.error("Unable to get user info",p.error),o.redirect(`${o.context.baseURL}/error?error=please_restart_the_process`);let h=await be(o,{userInfo:p.data,account:{providerId:r.providerId,accountId:m.id,accessToken:t.accessToken}});function k(j){throw o.redirect(`${a||i||`${o.context.baseURL}/error`}?error=${j}`)}if(h.error)return k(h.error.split(" ").join("_"));let{session:R,user:K}=h.data;await w(o,{session:R,user:K});let fe;try{fe=new URL(i).toString()}catch{fe=i}throw o.redirect(fe)})}});import{z as Ce}from"zod";var pr={jwks:{fields:{publicKey:{type:"string",required:!0},privateKey:{type:"string",required:!0},createdAt:{type:"date",required:!0}}}},Kp=Ce.object({id:Ce.string(),publicKey:Ce.string(),privateKey:Ce.string(),createdAt:Ce.date()});var dt=e=>({getAllKeys:async()=>await e.findMany({model:"jwks"}),getLatestKey:async()=>(await e.findMany({model:"jwks",sortBy:{field:"createdAt",direction:"desc"},limit:1}))[0],createJwk:async o=>await e.create({model:"jwks",data:{...o,createdAt:new Date}})});import{exportJWK as fr,generateKeyPair as fn,importJWK as gn,SignJWT as hn}from"jose";var nf=e=>({id:"jwt",endpoints:{getJwks:c("/jwks",{method:"GET"},async o=>{let t=await dt(o.context.adapter).getAllKeys();return o.json({keys:t.map(n=>({...JSON.parse(n.publicKey),kid:n.id}))})}),getToken:c("/token",{method:"GET",requireHeaders:!0,use:[b]},async o=>{let r=dt(o.context.adapter),t=await r.getLatestKey(),n=!e?.jwks?.disablePrivateKeyEncryption;if(t===void 0){let{publicKey:u,privateKey:l}=await fn(e?.jwks?.keyPairConfig?.alg??"EdDSA",e?.jwks?.keyPairConfig??{crv:"Ed25519"}),m=await fr(u),f=await fr(l),p=JSON.stringify(f),h={id:crypto.randomUUID(),publicKey:JSON.stringify(m),privateKey:n?JSON.stringify(await Z({key:o.context.options.secret,data:p})):p,createdAt:new Date};t=await r.createJwk(h)}let i=n?await ne({key:o.context.options.secret,data:JSON.parse(t.privateKey)}):t.privateKey,s=await gn(JSON.parse(i)),a=e?.jwt?.definePayload?await e?.jwt.definePayload(o.context.session.user):o.context.session.user,d=await new hn({...a,...o.context.session.session.impersonatedBy?{impersonatedBy:o.context.session.session.impersonatedBy}:{}}).setProtectedHeader({alg:e?.jwks?.keyPairConfig?.alg??"EdDSA",kid:t.id}).setIssuedAt().setIssuer(e?.jwt?.issuer??o.context.options.baseURL).setAudience(e?.jwt?.audience??o.context.options.baseURL).setExpirationTime(e?.jwt?.expirationTime??"15m").setSubject(o.context.session.user.id).sign(s);return o.json({token:d})})},schema:pr});import{z as Ze}from"zod";var cf=e=>{let o={maximumSessions:5,...e},r=t=>t.includes("_multi-");return{id:"multi-session",endpoints:{listDeviceSessions:c("/multi-session/list-device-sessions",{method:"GET",requireHeaders:!0},async t=>{let n=t.headers?.get("cookie");if(!n)return t.json([]);let i=Object.fromEntries(Le(n)),s=(await Promise.all(Object.entries(i).filter(([u])=>r(u)).map(async([u])=>await t.getSignedCookie(u,t.context.secret)))).filter(u=>u!==void 0);if(!s.length)return t.json([]);let d=(await t.context.internalAdapter.findSessions(s)).filter(u=>u&&u.session.expiresAt>new Date).filter((u,l,m)=>l===m.findIndex(f=>f.user.id===u.user.id));return Object.entries(i).filter(([u])=>r(u)).forEach(([u,l])=>{d.some(m=>m.session.id===l)||t.setCookie(u,"",{...t.context.authCookies.sessionToken.options,maxAge:0})}),t.json(d)}),setActiveSession:c("/multi-session/set-active",{method:"POST",body:Ze.object({sessionId:Ze.string()}),requireHeaders:!0,use:[b]},async t=>{let n=t.body.sessionId,i=`${t.context.authCookies.sessionToken.name}_multi-${n}`;if(!await t.getSignedCookie(i,t.context.secret))throw new v("UNAUTHORIZED",{message:"Invalid session id"});let a=await t.context.internalAdapter.findSession(n);if(!a||a.session.expiresAt<new Date)throw t.setCookie(i,"",{...t.context.authCookies.sessionToken.options,maxAge:0}),new v("UNAUTHORIZED",{message:"Invalid session id"});return await t.setSignedCookie(t.context.authCookies.sessionToken.name,n,t.context.secret,t.context.authCookies.sessionToken.options),t.json(a)}),revokeDeviceSession:c("/multi-session/revoke",{method:"POST",body:Ze.object({sessionId:Ze.string()}),requireHeaders:!0,use:[b]},async t=>{let n=t.body.sessionId,i=`${t.context.authCookies.sessionToken.name}_multi-${n}`;if(!await t.getSignedCookie(i,t.context.secret))throw new v("UNAUTHORIZED",{message:"Invalid session id"});let a=await t.context.internalAdapter.findSession(n);return t.setCookie(i,"",{...t.context.authCookies.sessionToken.options,maxAge:0}),a?(await t.context.internalAdapter.deleteSession(n),t.json({success:!0})):t.json({success:!0})})},hooks:{after:[{matcher:()=>!0,handler:S(async t=>{if(!t.context.returned||!(t.context.returned instanceof Response))return;let n=t.context.returned.headers.get("set-cookie");if(!n)return;let i=xe(n),s=t.context.authCookies.sessionToken,a=i.get(s.name)?.value;if(!a)return;let d=Le(t.headers?.get("cookie")||""),u=a.split(".")[0],l=`${s.name}_multi-${u}`;if(i.get(l)||d.get(l)||Object.keys(Object.fromEntries(d)).filter(r).length+(n.includes("session_token")?1:0)>o.maximumSessions)return;await t.setSignedCookie(l,u,t.context.secret,s.options);let f=t.context.returned;return f.headers.append("Set-Cookie",t.responseHeader.get("set-cookie")),{response:f}})},{matcher:t=>t.path==="/sign-out",handler:S(async t=>{if(!(t.context.returned instanceof Response))return;let n=t.headers?.get("cookie");if(!n)return;let i=Object.fromEntries(Le(n));await Promise.all(Object.entries(i).map(async([a,d])=>{if(r(a)){t.setCookie(a,"",{maxAge:0});let u=a.split("_multi-")[1];await t.context.internalAdapter.deleteSession(u)}}));let s=t.context.returned;return s.headers.append("Set-Cookie",t.responseHeader.get("set-cookie")),{response:s}})}]}}};import{z as te}from"zod";var bf=e=>{let o={expireIn:300,otpLength:6,...e};return{id:"email-otp",endpoints:{sendVerificationOTP:c("/email-otp/send-verification-otp",{method:"POST",body:te.object({email:te.string(),type:te.enum(["email-verification","sign-in"])})},async r=>{if(!e?.sendVerificationOTP)throw y.error("send email verification is not implemented"),new v("BAD_REQUEST",{message:"send email verification is not implemented"});let t=r.body.email,n=F(o.otpLength,q("0-9"));return await r.context.internalAdapter.createVerificationValue({value:n,identifier:`${r.body.type}-otp-${t}`,expiresAt:P(o.expireIn,"sec")}),await e.sendVerificationOTP({email:t,otp:n,type:r.body.type},r.request),r.json({success:!0})}),verifyEmailOTP:c("/email-otp/verify-email",{method:"POST",body:te.object({email:te.string(),otp:te.string()})},async r=>{let t=r.body.email,n=await r.context.internalAdapter.findVerificationValue(`email-verification-otp-${t}`);if(!n||n.expiresAt<new Date)throw n&&await r.context.internalAdapter.deleteVerificationValue(n.id),new v("BAD_REQUEST",{message:"Invalid OTP"});let i=r.body.otp;if(n.value!==i)throw new v("BAD_REQUEST",{message:"Invalid OTP"});await r.context.internalAdapter.deleteVerificationValue(n.id);let s=await r.context.internalAdapter.findUserByEmail(t);if(!s)throw new v("BAD_REQUEST",{message:"User not found"});let a=await r.context.internalAdapter.updateUser(s.user.id,{email:t,emailVerified:!0});return r.json({user:a})}),signInEmailOTP:c("/sign-in/email-otp",{method:"POST",body:te.object({email:te.string(),otp:te.string()})},async r=>{let t=r.body.email,n=await r.context.internalAdapter.findVerificationValue(`sign-in-otp-${t}`);if(!n||n.expiresAt<new Date)throw n&&await r.context.internalAdapter.deleteVerificationValue(n.id),new v("BAD_REQUEST",{message:"Invalid OTP"});let i=r.body.otp;if(n.value!==i)throw new v("BAD_REQUEST",{message:"Invalid OTP"});await r.context.internalAdapter.deleteVerificationValue(n.id);let s=await r.context.internalAdapter.findUserByEmail(t);if(!s){if(o.disableSignUp)throw new v("BAD_REQUEST",{message:"User not found"});let d=await r.context.internalAdapter.createUser({email:t,emailVerified:!0,name:t}),u=await r.context.internalAdapter.createSession(d.id,r.request);return await w(r,{session:u,user:d}),r.json({user:d,session:u})}let a=await r.context.internalAdapter.createSession(s.user.id,r.request);return await w(r,{session:a,user:s.user}),r.json({session:a,user:s})})},hooks:{after:[{matcher(r){return!!(r.path?.startsWith("/sign-up")&&o.sendVerificationOnSignUp)},async handler(r){let t=r.context.returned;if(t?.status!==200)return;let n=await t.clone().json();if(n.user.email&&n.user.emailVerified===!1){let i=F(o.otpLength,q("0-9"));await r.context.internalAdapter.createVerificationValue({value:i,identifier:`email-verification-otp-${n.user.email}`,expiresAt:P(o.expireIn,"sec")}),await e.sendVerificationOTP({email:n.user.email,otp:i,type:"email-verification"},r.request)}}}]}}};import{z as hr}from"zod";import{betterFetch as wn}from"@better-fetch/fetch";function gr(e){return e==="true"||e===!0}var If=e=>({id:"one-tap",endpoints:{oneTapCallback:c("/one-tap/callback",{method:"POST",body:hr.object({idToken:hr.string()})},async o=>{let{idToken:r}=o.body,{data:t,error:n}=await wn("https://oauth2.googleapis.com/tokeninfo?id_token="+r);if(n)return o.json({error:"Invalid token"});let i=await o.context.internalAdapter.findUserByEmail(t.email);if(!i){if(e?.disableSignup)throw new v("BAD_GATEWAY",{message:"User not found"});let a=await o.context.internalAdapter.createOAuthUser({email:t.email,emailVerified:gr(t.email_verified),name:t.name,image:t.picture},{providerId:"google",accountId:t.sub});if(!a)throw new v("INTERNAL_SERVER_ERROR",{message:"Could not create user"});let d=await o.context.internalAdapter.createSession(a?.user.id,o.request);return await w(o,{user:a.user,session:d}),o.json({session:d,user:a})}let s=await o.context.internalAdapter.createSession(i.user.id,o.request);return await w(o,{user:i.user,session:s}),o.json({session:s,user:i})})}});import{z as ut}from"zod";function yn(){let e=Q.VERCEL_URL,o=Q.NETLIFY_URL,r=Q.RENDER_URL,t=Q.AWS_LAMBDA_FUNCTION_NAME,n=Q.GOOGLE_CLOUD_FUNCTION_NAME,i=Q.AZURE_FUNCTION_NAME;return e||o||r||t||n||i}var Bf=e=>({id:"oauth-proxy",endpoints:{oAuthProxy:c("/oauth-proxy-callback",{method:"GET",query:ut.object({callbackURL:ut.string(),cookies:ut.string()})},async o=>{let r=o.query.cookies,t=await ne({key:o.context.secret,data:r});throw o.setHeader("set-cookie",t),o.redirect(o.query.callbackURL)})},hooks:{after:[{matcher(o){return o.path?.startsWith("/callback")},handler:S(async o=>{let r=o.context.returned;if(!r||!(r instanceof Response))return;let t=r.headers.get("location");if(t?.includes("/oauth-proxy-callback?callbackURL")){if(!t.startsWith("http"))return;let n=new URL(t);if(n.origin===we(o.context.baseURL)){let u=n.searchParams.get("callbackURL");return u?(r.headers.set("location",u),{response:r}):void 0}let s=r.headers.get("set-cookie");if(!s)return;let a=await Z({key:o.context.secret,data:s}),d=`${t}&cookies=${encodeURIComponent(a)}`;return r.headers.set("location",d),{response:r}}})}],before:[{matcher(o){return o.path?.startsWith("/sign-in/social")},async handler(o){let r=new URL(e?.currentURL||o.request?.url||yn()||o.context.baseURL);return o.body.callbackURL=`${r.origin}${o.context.options.basePath||"/api/auth"}/oauth-proxy-callback?callbackURL=${encodeURIComponent(o.body.callbackURL||o.context.baseURL)}`,{context:o}}}]}});export{he as HIDE_METADATA,zp as admin,Ip as anonymous,tp as bearer,c as createAuthEndpoint,S as createAuthMiddleware,bf as emailOTP,Wp as genericOAuth,nn as getPasskeyActions,nf as jwt,dp as magicLink,cf as multiSession,Bf as oAuthProxy,If as oneTap,lt as optionsMiddleware,Rc as organization,Wm as passkey,Bm as passkeyClient,yp as phoneNumber,Jl as twoFactor,zl as twoFactorClient,lr as username};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-auth",
3
- "version": "0.8.3-beta.7",
3
+ "version": "0.8.3",
4
4
  "description": "The most comprehensive authentication library for TypeScript.",
5
5
  "type": "module",
6
6
  "repository": {