@lunora/auth 1.0.0-alpha.86 → 1.0.0-alpha.88

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/README.md CHANGED
@@ -84,7 +84,7 @@ The runtime resolves the inbound session and stamps `ctx.auth` on every `query`
84
84
 
85
85
  ### Plugins & CAPTCHA
86
86
 
87
- better-auth's plugin factories are re-exported from `@lunora/auth/plugins` (so you don't need better-auth's deep import paths): `admin`, `anonymous`, `bearer`, `captcha`, `createAccessControl`, `customSession`, `deviceAuthorization`, `emailOTP`, `genericOAuth`, `haveIBeenPwned`, `jwt`, `magicLink`, `mcp`, `mcpHandler`, `multiSession`, `oAuthProxy`, `oauthProvider`, `oneTimeToken`, `organization`, `passkey`, `phoneNumber`, `requireMcpAuth`, `scim`, `siwe`, `twoFactor`, and `username`. Enterprise SSO ships separately as `sso` from `@lunora/auth/plugins/enterprise` (an optional peer — see the docs).
87
+ better-auth's plugin factories are re-exported from `@lunora/auth/plugins` (so you don't need better-auth's deep import paths): `admin`, `anonymous`, `bearer`, `captcha`, `createAccessControl`, `createMcpProtectedRequestHandler`, `customSession`, `deviceAuthorization`, `emailOTP`, `genericOAuth`, `haveIBeenPwned`, `jwt`, `lastLoginMethod`, `magicLink`, `mcp`, `multiSession`, `oAuthProxy`, `oauthDeviceAuthorization`, `oauthProvider`, `oneTap`, `oneTimeToken`, `organization`, `passkey`, `phoneNumber`, `requireMcpAuth`, `scim`, `siwe`, `twoFactor`, and `username`. Enterprise SSO ships separately as `sso` from `@lunora/auth/plugins/enterprise` (an optional peer — see the docs).
88
88
 
89
89
  For Cloudflare Turnstile on the **auth flow**, use the `captcha` plugin (`captcha({ provider: "cloudflare-turnstile", secretKey: env.TURNSTILE_SECRET_KEY })`); it reads the token from the `x-captcha-response` header. For **non-auth** procedures, the package root also exports standalone helpers — `verifyTurnstile` (pure `siteverify`) and `verifyTurnstileMiddleware` (a `.use()` middleware that takes the token from the function args).
90
90
 
package/dist/index.d.mts CHANGED
@@ -562,14 +562,18 @@ interface AuditHookContext {
562
562
  * (`/sign-in/email`, `/sign-in/username`, `/sign-in/phone-number`, …) as
563
563
  * plain `sign-in`. They were NOT recorded at all before this change.
564
564
  *
565
- * `/oauth2/callback/*` is deliberately NOT matched here: it does not exist as
566
- * an endpoint in the pinned `1.7.0-rc.2` (checked against the installed
567
- * `better-auth` and `@better-auth/*` dist generic-oauth reuses the core
568
- * `/callback/:id` endpoint, it does not register its own path). `@better-auth/sso`
569
- * does expose its own `/sso/callback/:providerId`, but `@lunora/auth`'s
570
- * `plugins.ts` does not currently re-export `sso` recorded as a gap for a
571
- * follow-up (plan 280 §9 Q1), not matched here since it is unreachable through
572
- * this package today.
565
+ * There is no dedicated `/oauth2/callback/*` branch because the generic
566
+ * `/callback/` check above already covers it, and covering it is CORRECT: an
567
+ * OAuth callback is a completed sign-in whatever path prefix it arrives on. The
568
+ * same substring also catches `@better-auth/sso`'s `/sso/callback/:providerId`,
569
+ * so if `plugins.ts` ever re-exports `sso` (plan 280 §9 Q1) that endpoint is
570
+ * classified rather than silently unrecorded. Checked against the installed
571
+ * `better-auth` and `@better-auth/*` dist for 1.7.1: generic-oauth reuses the
572
+ * core `/callback/:id` endpoint rather than registering its own, and the one
573
+ * dist hit for a literal `/oauth2/callback/` is inside
574
+ * `better-auth/plugins/oauth-popup`, which `plugins.ts` does not re-export —
575
+ * so today the branch fires for the core callback, and stays correct if either
576
+ * of the others becomes reachable. `__tests__/audit.test.ts` pins all three.
573
577
  */
574
578
  declare const eventForPath: (path: string) => AuthAuditEvent | undefined;
575
579
  /**
package/dist/index.d.ts CHANGED
@@ -562,14 +562,18 @@ interface AuditHookContext {
562
562
  * (`/sign-in/email`, `/sign-in/username`, `/sign-in/phone-number`, …) as
563
563
  * plain `sign-in`. They were NOT recorded at all before this change.
564
564
  *
565
- * `/oauth2/callback/*` is deliberately NOT matched here: it does not exist as
566
- * an endpoint in the pinned `1.7.0-rc.2` (checked against the installed
567
- * `better-auth` and `@better-auth/*` dist generic-oauth reuses the core
568
- * `/callback/:id` endpoint, it does not register its own path). `@better-auth/sso`
569
- * does expose its own `/sso/callback/:providerId`, but `@lunora/auth`'s
570
- * `plugins.ts` does not currently re-export `sso` recorded as a gap for a
571
- * follow-up (plan 280 §9 Q1), not matched here since it is unreachable through
572
- * this package today.
565
+ * There is no dedicated `/oauth2/callback/*` branch because the generic
566
+ * `/callback/` check above already covers it, and covering it is CORRECT: an
567
+ * OAuth callback is a completed sign-in whatever path prefix it arrives on. The
568
+ * same substring also catches `@better-auth/sso`'s `/sso/callback/:providerId`,
569
+ * so if `plugins.ts` ever re-exports `sso` (plan 280 §9 Q1) that endpoint is
570
+ * classified rather than silently unrecorded. Checked against the installed
571
+ * `better-auth` and `@better-auth/*` dist for 1.7.1: generic-oauth reuses the
572
+ * core `/callback/:id` endpoint rather than registering its own, and the one
573
+ * dist hit for a literal `/oauth2/callback/` is inside
574
+ * `better-auth/plugins/oauth-popup`, which `plugins.ts` does not re-export —
575
+ * so today the branch fires for the core callback, and stays correct if either
576
+ * of the others becomes reachable. `__tests__/audit.test.ts` pins all three.
573
577
  */
574
578
  declare const eventForPath: (path: string) => AuthAuditEvent | undefined;
575
579
  /**
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{l as r,a as o,b as a}from"./packem_shared/adapter-DA8DdALX.mjs";import{LunoraAuthAdminError as u,createAuthAdmin as i}from"./packem_shared/LunoraAuthAdminError-C20JtTqI.mjs";import{AUTH_AUDIT_TABLE as m,appendAuthAuditEntry as l,createAuthAuditReader as d,ensureAuthAuditTable as h,readAuthAuditLog as E}from"./audit.mjs";import{authAuditHook as p,buildAuditEntry as T,eventForPath as f,withAuthAudit as _}from"./packem_shared/authAuditHook-DOd5YOTL.mjs";import{READ_AUDIT_PATH as D,INTERNAL_SECRET_HEADER as S,RESOLVE_SESSION_PATH as H,LunoraAuthDO as c}from"./packem_shared/AUTH_DO_AUDIT_PATH-WJbI0Bpc.mjs";import{createAuth as L,resolveAuthOptions as P}from"./packem_shared/createAuth-DYFhkI1U.mjs";import{authDoColumnAdditions as I,authDoSchemaStatements as O}from"./packem_shared/authDoColumnAdditions-BCSs7qaN.mjs";import{createDoAuthWiring as N}from"./packem_shared/createDoAuthWiring-C7uxkces.mjs";import{emailGateDatabaseHooks as b,withEmailGate as g}from"./packem_shared/emailGateDatabaseHooks-CAygR3iq.mjs";import{assertEmailAllowed as M,classifyEmail as q,emailGateMiddleware as C,loadEmailDomainLists as F}from"./email-guard.mjs";import{DEFAULT_AUTH_BASE_PATH as k,handleAuthRequest as B}from"./packem_shared/DEFAULT_AUTH_BASE_PATH-C7moXiBA.mjs";import{LunoraAuthHeadersError as W,withAuthPlugins as Y}from"./middleware.mjs";import{compileMigrationsSql as z,ensureMigrated as J}from"./packem_shared/compileMigrationsSql-Y1YB3maO.mjs";import{default as Q}from"./schema.mjs";import{sessionPresets as Z,validateSessionPolicy as $}from"./packem_shared/sessionPresets-C867Mlo4.mjs";import{createSqlAuthStore as te,d1Executor as re}from"./sql-store.mjs";import{createMemoryAuthStore as ae,matchesWhere as Ae}from"./store.mjs";import{TURNSTILE_VERIFY_ENDPOINT as ie,verifyTurnstile as se}from"./turnstile.mjs";import{verifyTurnstileMiddleware as le}from"./turnstile-middleware.mjs";export{m as AUTH_AUDIT_TABLE,D as AUTH_DO_AUDIT_PATH,S as AUTH_DO_SECRET_HEADER,H as AUTH_DO_SESSION_PATH,k as DEFAULT_AUTH_BASE_PATH,u as LunoraAuthAdminError,c as LunoraAuthDO,W as LunoraAuthHeadersError,ie as TURNSTILE_VERIFY_ENDPOINT,l as appendAuthAuditEntry,M as assertEmailAllowed,p as authAuditHook,I as authDoColumnAdditions,O as authDoSchemaStatements,Q as authTables,T as buildAuditEntry,q as classifyEmail,z as compileMigrationsSql,L as createAuth,i as createAuthAdmin,d as createAuthAuditReader,N as createDoAuthWiring,ae as createMemoryAuthStore,te as createSqlAuthStore,re as d1Executor,b as emailGateDatabaseHooks,C as emailGateMiddleware,h as ensureAuthAuditTable,J as ensureMigrated,f as eventForPath,B as handleAuthRequest,F as loadEmailDomainLists,r as lunoraAuthAdapter,o as lunoraD1Adapter,a as lunoraDoAdapter,Ae as matchesWhere,E as readAuthAuditLog,P as resolveAuthOptions,Z as sessionPresets,$ as validateSessionPolicy,se as verifyTurnstile,le as verifyTurnstileMiddleware,_ as withAuthAudit,Y as withAuthPlugins,g as withEmailGate};
1
+ import{l as r,a as o,b as a}from"./packem_shared/adapter-DA8DdALX.mjs";import{LunoraAuthAdminError as u,createAuthAdmin as i}from"./packem_shared/LunoraAuthAdminError-gdM6RSXW.mjs";import{AUTH_AUDIT_TABLE as m,appendAuthAuditEntry as l,createAuthAuditReader as d,ensureAuthAuditTable as h,readAuthAuditLog as E}from"./audit.mjs";import{authAuditHook as p,buildAuditEntry as T,eventForPath as f,withAuthAudit as _}from"./packem_shared/authAuditHook-DOd5YOTL.mjs";import{READ_AUDIT_PATH as D,INTERNAL_SECRET_HEADER as S,RESOLVE_SESSION_PATH as H,LunoraAuthDO as c}from"./packem_shared/AUTH_DO_AUDIT_PATH-WJbI0Bpc.mjs";import{createAuth as L,resolveAuthOptions as P}from"./packem_shared/createAuth-DYFhkI1U.mjs";import{authDoColumnAdditions as I,authDoSchemaStatements as O}from"./packem_shared/authDoColumnAdditions-BCSs7qaN.mjs";import{createDoAuthWiring as N}from"./packem_shared/createDoAuthWiring-C7uxkces.mjs";import{emailGateDatabaseHooks as b,withEmailGate as g}from"./packem_shared/emailGateDatabaseHooks-CAygR3iq.mjs";import{assertEmailAllowed as M,classifyEmail as q,emailGateMiddleware as C,loadEmailDomainLists as F}from"./email-guard.mjs";import{DEFAULT_AUTH_BASE_PATH as k,handleAuthRequest as B}from"./packem_shared/DEFAULT_AUTH_BASE_PATH-C7moXiBA.mjs";import{LunoraAuthHeadersError as W,withAuthPlugins as Y}from"./middleware.mjs";import{compileMigrationsSql as z,ensureMigrated as J}from"./packem_shared/compileMigrationsSql-Y1YB3maO.mjs";import{default as Q}from"./schema.mjs";import{sessionPresets as Z,validateSessionPolicy as $}from"./packem_shared/sessionPresets-C867Mlo4.mjs";import{createSqlAuthStore as te,d1Executor as re}from"./sql-store.mjs";import{createMemoryAuthStore as ae,matchesWhere as Ae}from"./store.mjs";import{TURNSTILE_VERIFY_ENDPOINT as ie,verifyTurnstile as se}from"./turnstile.mjs";import{verifyTurnstileMiddleware as le}from"./turnstile-middleware.mjs";export{m as AUTH_AUDIT_TABLE,D as AUTH_DO_AUDIT_PATH,S as AUTH_DO_SECRET_HEADER,H as AUTH_DO_SESSION_PATH,k as DEFAULT_AUTH_BASE_PATH,u as LunoraAuthAdminError,c as LunoraAuthDO,W as LunoraAuthHeadersError,ie as TURNSTILE_VERIFY_ENDPOINT,l as appendAuthAuditEntry,M as assertEmailAllowed,p as authAuditHook,I as authDoColumnAdditions,O as authDoSchemaStatements,Q as authTables,T as buildAuditEntry,q as classifyEmail,z as compileMigrationsSql,L as createAuth,i as createAuthAdmin,d as createAuthAuditReader,N as createDoAuthWiring,ae as createMemoryAuthStore,te as createSqlAuthStore,re as d1Executor,b as emailGateDatabaseHooks,C as emailGateMiddleware,h as ensureAuthAuditTable,J as ensureMigrated,f as eventForPath,B as handleAuthRequest,F as loadEmailDomainLists,r as lunoraAuthAdapter,o as lunoraD1Adapter,a as lunoraDoAdapter,Ae as matchesWhere,E as readAuthAuditLog,P as resolveAuthOptions,Z as sessionPresets,$ as validateSessionPolicy,se as verifyTurnstile,le as verifyTurnstileMiddleware,_ as withAuthAudit,Y as withAuthPlugins,g as withEmailGate};
@@ -1 +1 @@
1
- import{createLocalAccountIssuer as M}from"@better-auth/core/db";import{LunoraError as I}from"@lunora/errors";import{getAuthTables as S}from"better-auth/db";class f extends I{constructor(m,w){super(w,m,{name:"LunoraAuthAdminError"})}}const N=50,R=500,O=3600,U=O*24,D=100*365*24*60*60,E=2880*60*1e3,T=new Set(["accessToken","backupCodes","idToken","password","publicKey","refreshToken","secret","token"]),z=d=>Math.min(Math.max(Math.trunc(d??N),1),R),L=d=>Math.max(0,Math.trunc(d??0)),u=d=>{const m={};for(const[w,l]of Object.entries(d))T.has(w)||(m[w]=l instanceof Date?l.getTime():l);return m},A=d=>Array.isArray(d)?d.join(","):d,g=d=>d.toLowerCase().replaceAll(/[^\da-z]+/g,"-").replaceAll(/^-|-$/g,""),k=new Set(["banExpires","banned","banReason","createdAt","email","emailVerified","id","name","role","updatedAt"]),P={displayUsername:"username",phoneNumber:"phone-number",phoneNumberVerified:"phone-number",username:"username"},B=d=>d==="boolean"||d==="date"||d==="number"?d:"string",C=d=>{const m=[];for(const[w,l]of Object.entries(d))l.input===!1||l.references!==void 0||k.has(w)||m.push({name:w,plugin:P[w],required:l.required===!0,type:B(l.type),unique:l.unique===!0});return m},F=d=>{if(d instanceof f)return d;const m=d,w=m?.body?.code??m?.code??"AUTH_ADMIN_ERROR",l=m?.body?.message??m?.message??"auth admin operation failed";return new f(l,w)},j=(d,m={})=>{const w=d.$context,l=m.features??{},b=e=>{const a=new Set((e.plugins??[]).map(i=>i.id)),t=i=>a.has(i);return{accounts:l.accounts??!0,admin:l.admin??t("admin"),organization:l.organization??t("organization"),passkey:l.passkey??t("passkey"),twoFactor:l.twoFactor??t("two-factor")}},r=async e=>{try{return await e(await w)}catch(a){throw F(a)}},v=e=>u(e),h=async(e,a,t)=>{const i=t.where&&t.where.length>0?t.where:void 0,[n,s]=await Promise.all([e.adapter.findMany({limit:z(t.limit),model:a,offset:L(t.offset),sortBy:t.sortBy,where:i}),e.adapter.count({model:a,where:i})]);return{rows:n.map(o=>u(o)),total:s}};return{banUser:({expiresInSeconds:e,reason:a,userId:t})=>r(async i=>{let n=null;if(e!==void 0){if(!Number.isInteger(e)||e<=0)throw new f("expiresInSeconds must be a positive finite integer","INVALID_BAN_SECONDS");const o=Math.min(e,D);n=new Date(Date.now()+o*1e3)}const s=await i.internalAdapter.updateUser(t,{banExpires:n,banned:!0,banReason:a??"No reason"});return await i.internalAdapter.deleteUserSessions(t),v(s)}),cancelInvitation:({invitationId:e})=>r(async a=>{await a.adapter.delete({model:"invitation",where:[{field:"id",value:e}]})}),capabilities:()=>r(e=>Promise.resolve(b(e.options))),addMember:({organizationId:e,role:a,userId:t})=>r(async i=>{const n=await i.adapter.create({data:{createdAt:new Date,organizationId:e,role:a===void 0||a===""?"member":a,userId:t},model:"member"});return u(n)}),addTeamMember:({teamId:e,userId:a})=>r(async t=>{const i=await t.adapter.create({data:{createdAt:new Date,teamId:e,userId:a},model:"teamMember"});return u(i)}),config:()=>r(e=>{const a=e.options,t=b(a),i=new Set((a.plugins??[]).map(c=>c.id)),n=S(a),s=a.session??{},o=a.rateLimit??{};return Promise.resolve({capabilities:t,emailAndPassword:a.emailAndPassword?.enabled??!1,organization:{enabled:t.organization,roles:!!n.organizationRole,teams:!!n.team},plugins:[...i].toSorted((c,p)=>c.localeCompare(p)),rateLimit:{enabled:o.enabled??!1,max:o.max,window:o.window},session:{cookieCache:s.cookieCache?.enabled,expiresIn:s.expiresIn,freshAge:s.freshAge,updateAge:s.updateAge},socialProviders:Object.keys(a.socialProviders??{}).toSorted((c,p)=>c.localeCompare(p)),userFields:C(n.user?.fields??{})})}),createOrganization:({logo:e,metadata:a,name:t,ownerId:i,slug:n})=>r(async s=>{const o=g(n!==void 0&&n!==""?n:t);if(o==="")throw new f("could not derive a slug from the organization name","ORG_SLUG_INVALID");if(await s.adapter.findOne({model:"organization",where:[{field:"slug",value:o}]}))throw new f("an organization with this slug already exists","ORG_SLUG_TAKEN");const p=await s.adapter.create({data:{createdAt:new Date,logo:e===void 0||e===""?void 0:e,metadata:a===void 0?void 0:JSON.stringify(a),name:t,slug:o},model:"organization"});return i!==void 0&&i!==""&&await s.adapter.create({data:{createdAt:new Date,organizationId:p.id,role:"owner",userId:i},model:"member"}),u(p)}),createOrgRole:({organizationId:e,permission:a,role:t})=>r(async i=>{const n=await i.adapter.create({data:{createdAt:new Date,organizationId:e,permission:JSON.stringify(a),role:t},model:"organizationRole"});return u(n)}),createTeam:({name:e,organizationId:a})=>r(async t=>{const i=await t.adapter.create({data:{createdAt:new Date,name:e,organizationId:a},model:"team"});return u(i)}),deleteOrganization:({organizationId:e})=>r(async a=>{const t=S(a.options);if(await a.adapter.deleteMany({model:"member",where:[{field:"organizationId",value:e}]}),await a.adapter.deleteMany({model:"invitation",where:[{field:"organizationId",value:e}]}),t.team){const i=await a.adapter.findMany({model:"team",where:[{field:"organizationId",value:e}]});for(const n of i)await a.adapter.deleteMany({model:"teamMember",where:[{field:"teamId",value:n.id}]});await a.adapter.deleteMany({model:"team",where:[{field:"organizationId",value:e}]})}t.organizationRole&&await a.adapter.deleteMany({model:"organizationRole",where:[{field:"organizationId",value:e}]}),await a.adapter.delete({model:"organization",where:[{field:"id",value:e}]})}),deleteOrgRole:({roleId:e})=>r(async a=>{await a.adapter.delete({model:"organizationRole",where:[{field:"id",value:e}]})}),inviteMember:({email:e,inviterId:a,organizationId:t,role:i})=>r(async n=>{let s=a;if(s===void 0||s===""){const c=await n.adapter.findMany({model:"member",where:[{field:"organizationId",value:t}]});s=(c.find(y=>typeof y.role=="string"&&y.role.includes("owner"))??c[0])?.userId}if(s===void 0||s==="")throw new f("provide an inviter — the organization has no members to attribute the invitation to","INVITER_REQUIRED");const o=await n.adapter.create({data:{createdAt:new Date,email:e.toLowerCase(),expiresAt:new Date(Date.now()+E),inviterId:s,organizationId:t,role:i===void 0||i===""?"member":i,status:"pending"},model:"invitation"});return u(o)}),listOrgRoles:({limit:e,offset:a,organizationId:t})=>r(i=>h(i,"organizationRole",{limit:e,offset:a,sortBy:{direction:"desc",field:"createdAt"},where:[{field:"organizationId",value:t}]})),listTeamMembers:({limit:e,offset:a,teamId:t})=>r(i=>h(i,"teamMember",{limit:e,offset:a,where:[{field:"teamId",value:t}]})),listTeams:({limit:e,offset:a,organizationId:t})=>r(i=>h(i,"team",{limit:e,offset:a,sortBy:{direction:"desc",field:"createdAt"},where:[{field:"organizationId",value:t}]})),removeTeam:({teamId:e})=>r(async a=>{await a.adapter.deleteMany({model:"teamMember",where:[{field:"teamId",value:e}]}),await a.adapter.delete({model:"team",where:[{field:"id",value:e}]})}),removeTeamMember:({teamMemberId:e})=>r(async a=>{await a.adapter.delete({model:"teamMember",where:[{field:"id",value:e}]})}),updateMemberRole:({memberId:e,role:a})=>r(async t=>{const i=await t.adapter.update({model:"member",update:{role:A(a)},where:[{field:"id",value:e}]});return u(i??{id:e,role:A(a)})}),updateOrganization:({logo:e,metadata:a,name:t,organizationId:i,slug:n})=>r(async s=>{const o={};if(t!==void 0&&(o.name=t),n!==void 0&&n!==""&&(o.slug=g(n)),e!==void 0&&(o.logo=e===""?void 0:e),a!==void 0&&(o.metadata=JSON.stringify(a)),Object.keys(o).length===0)return u({id:i});const c=await s.adapter.update({model:"organization",update:o,where:[{field:"id",value:i}]});return u(c??{id:i})}),updateOrgRole:({permission:e,roleId:a})=>r(async t=>{const i=await t.adapter.update({model:"organizationRole",update:{permission:JSON.stringify(e),updatedAt:new Date},where:[{field:"id",value:a}]});return u(i??{id:a,permission:JSON.stringify(e)})}),updateTeam:({name:e,teamId:a})=>r(async t=>{const i=await t.adapter.update({model:"team",update:{name:e,updatedAt:new Date},where:[{field:"id",value:a}]});return u(i??{id:a,name:e})}),createUser:({data:e,email:a,name:t,password:i,role:n})=>r(async s=>{const o=a.toLowerCase();if(await s.internalAdapter.findUserByEmail(o))throw new f("a user with this email already exists","USER_ALREADY_EXISTS");const c=await s.internalAdapter.createUser({email:o,name:t,role:n===void 0?void 0:A(n),...e},{method:"admin"});if(i!==void 0&&i!==""){const p=await s.password.hash(i);await s.internalAdapter.linkAccount({issuer:M("credential"),password:p,providerAccountId:c.id,providerId:"credential",userId:c.id})}return v(c)}),deletePasskey:({passkeyId:e})=>r(async a=>{await a.adapter.delete({model:"passkey",where:[{field:"id",value:e}]})}),disableTwoFactor:({userId:e})=>r(async a=>{await a.adapter.deleteMany({model:"twoFactor",where:[{field:"userId",value:e}]}),await a.internalAdapter.updateUser(e,{twoFactorEnabled:!1})}),impersonateUser:({userId:e})=>r(async a=>{const t=await a.internalAdapter.findUserById(e);if(!t)throw new f("user not found","USER_NOT_FOUND");const i=m.impersonationSeconds;let n=O;if(i!==void 0){if(!Number.isInteger(i)||!Number.isFinite(i)||i<=0)throw new f("impersonationSeconds must be a positive finite integer","INVALID_IMPERSONATION_SECONDS");n=Math.min(i,U)}const s=new Date(Date.now()+n*1e3),o=await a.internalAdapter.createSession(e,!0,{expiresAt:s,impersonatedBy:m.impersonatedBy??e},!0);return{expiresAt:o.expiresAt instanceof Date?o.expiresAt.getTime():s.getTime(),token:o.token,user:v(t)}}),listAccounts:({userId:e})=>r(async a=>(await a.adapter.findMany({model:"account",where:[{field:"userId",value:e}]})).map(i=>u(i))),listInvitations:({limit:e,offset:a,organizationId:t})=>r(i=>h(i,"invitation",{limit:e,offset:a,where:[{field:"organizationId",value:t}]})),listMembers:({limit:e,offset:a,organizationId:t})=>r(i=>h(i,"member",{limit:e,offset:a,sortBy:{direction:"desc",field:"createdAt"},where:[{field:"organizationId",value:t}]})),listOrganizations:({limit:e,offset:a})=>r(t=>h(t,"organization",{limit:e,offset:a,sortBy:{direction:"desc",field:"createdAt"}})),listPasskeys:({userId:e})=>r(async a=>(await a.adapter.findMany({model:"passkey",where:[{field:"userId",value:e}]})).map(i=>u(i))),listSessions:({limit:e,offset:a,userId:t})=>r(i=>h(i,"session",{limit:e,offset:a,sortBy:{direction:"desc",field:"createdAt"},where:t===void 0||t===""?void 0:[{field:"userId",value:t}]})),listUsers:({filterField:e,filterValue:a,limit:t,offset:i,search:n,searchField:s,sortBy:o,sortDirection:c})=>r(p=>{const y=[];return n!==void 0&&n!==""&&y.push({field:s??"email",operator:"contains",value:n}),a!==void 0&&y.push({field:e??"email",operator:"eq",value:a}),h(p,"user",{limit:t,offset:i,sortBy:{direction:c??"desc",field:o??"createdAt"},where:y})}),removeMember:({memberId:e})=>r(async a=>{await a.adapter.delete({model:"member",where:[{field:"id",value:e}]})}),removeUser:({userId:e})=>r(async a=>{await a.internalAdapter.deleteUserSessions(e),await a.internalAdapter.deleteUser(e)}),revokeUserSession:({sessionId:e})=>r(async a=>{const t=await a.adapter.findOne({model:"session",where:[{field:"id",value:e}]});t?.token&&await a.internalAdapter.deleteSession(t.token)}),revokeUserSessions:({userId:e})=>r(async a=>{await a.internalAdapter.deleteUserSessions(e)}),setRole:({role:e,userId:a})=>r(async t=>{const i=await t.internalAdapter.updateUser(a,{role:A(e)});return v(i)}),setUserPassword:({newPassword:e,userId:a})=>r(async t=>{const i=t.password.config.minPasswordLength,n=t.password.config.maxPasswordLength;if(e.length<i)throw new f(`password must be at least ${i.toString()} characters`,"PASSWORD_TOO_SHORT");if(e.length>n)throw new f(`password must be at most ${n.toString()} characters`,"PASSWORD_TOO_LONG");const s=await t.password.hash(e);await t.internalAdapter.updatePassword(a,s)}),unbanUser:({userId:e})=>r(async a=>{const t=await a.internalAdapter.updateUser(e,{banExpires:null,banned:!1,banReason:null});return v(t)}),unlinkAccount:({accountId:e,userId:a})=>r(async t=>{await t.adapter.delete({model:"account",where:[{field:"id",value:e},{connector:"AND",field:"userId",value:a}]})}),updateUser:({data:e,userId:a})=>r(async t=>{const i=await t.internalAdapter.updateUser(a,e);return v(i)})}};export{f as LunoraAuthAdminError,j as createAuthAdmin};
1
+ import{createLocalAccountIssuer as M}from"@better-auth/core/db";import{LunoraError as I}from"@lunora/errors";import{getAuthTables as S}from"better-auth/db";class f extends I{constructor(m,w){super(w,m,{name:"LunoraAuthAdminError"})}}const N=50,R=500,O=3600,U=O*24,D=100*365*24*60*60,E=2880*60*1e3,T=new Set(["accessToken","backupCodes","idToken","password","publicKey","refreshToken","secret","token"]),z=d=>Math.min(Math.max(Math.trunc(d??N),1),R),L=d=>Math.max(0,Math.trunc(d??0)),u=d=>{const m={};for(const[w,l]of Object.entries(d))T.has(w)||(m[w]=l instanceof Date?l.getTime():l);return m},A=d=>Array.isArray(d)?d.join(","):d,g=d=>d.toLowerCase().replaceAll(/[^\da-z]+/g,"-").replaceAll(/^-|-$/g,""),k=new Set(["banExpires","banned","banReason","createdAt","email","emailVerified","id","name","role","updatedAt"]),P={displayUsername:"username",phoneNumber:"phone-number",phoneNumberVerified:"phone-number",username:"username"},B=d=>d==="boolean"||d==="date"||d==="number"?d:"string",C=d=>{const m=[];for(const[w,l]of Object.entries(d))l.input===!1||l.references!==void 0||k.has(w)||m.push({name:w,plugin:P[w],required:l.required===!0,type:B(l.type),unique:l.unique===!0});return m},F=d=>{if(d instanceof f)return d;const m=d,w=m?.body?.code??m?.code??"AUTH_ADMIN_ERROR",l=m?.body?.message??m?.message??"auth admin operation failed";return new f(l,w)},j=(d,m={})=>{const w=d.$context,l=m.features??{},b=e=>{const a=new Set((e.plugins??[]).map(i=>i.id)),t=i=>a.has(i);return{accounts:l.accounts??!0,admin:l.admin??t("admin"),organization:l.organization??t("organization"),passkey:l.passkey??t("passkey"),twoFactor:l.twoFactor??t("two-factor")}},r=async e=>{try{return await e(await w)}catch(a){throw F(a)}},v=e=>u(e),h=async(e,a,t)=>{const i=t.where&&t.where.length>0?t.where:void 0,[n,s]=await Promise.all([e.adapter.findMany({limit:z(t.limit),model:a,offset:L(t.offset),sortBy:t.sortBy,where:i}),e.adapter.count({model:a,where:i})]);return{rows:n.map(o=>u(o)),total:s}};return{banUser:({expiresInSeconds:e,reason:a,userId:t})=>r(async i=>{let n=null;if(e!==void 0){if(!Number.isInteger(e)||e<=0)throw new f("expiresInSeconds must be a positive finite integer","INVALID_BAN_SECONDS");const o=Math.min(e,D);n=new Date(Date.now()+o*1e3)}const s=await i.internalAdapter.updateUser(t,{banExpires:n,banned:!0,banReason:a??"No reason"});return await i.internalAdapter.deleteUserSessions(t),v(s)}),cancelInvitation:({invitationId:e})=>r(async a=>{await a.adapter.delete({model:"invitation",where:[{field:"id",value:e}]})}),capabilities:()=>r(e=>Promise.resolve(b(e.options))),addMember:({organizationId:e,role:a,userId:t})=>r(async i=>{const n=await i.adapter.create({data:{createdAt:new Date,organizationId:e,role:a===void 0||a===""?"member":a,userId:t},model:"member"});return u(n)}),addTeamMember:({teamId:e,userId:a})=>r(async t=>{const i=await t.adapter.create({data:{createdAt:new Date,teamId:e,userId:a},model:"teamMember"});return u(i)}),config:()=>r(e=>{const a=e.options,t=b(a),i=new Set((a.plugins??[]).map(c=>c.id)),n=S(a),s=a.session??{},o=a.rateLimit??{};return Promise.resolve({capabilities:t,emailAndPassword:a.emailAndPassword?.enabled??!1,organization:{enabled:t.organization,roles:!!n.organizationRole,teams:!!n.team},plugins:[...i].toSorted((c,p)=>c.localeCompare(p)),rateLimit:{enabled:o.enabled??!1,max:o.max,window:o.window},session:{cookieCache:s.cookieCache?.enabled,expiresIn:s.expiresIn,freshAge:s.freshAge,updateAge:s.updateAge},socialProviders:Object.keys(a.socialProviders??{}).toSorted((c,p)=>c.localeCompare(p)),userFields:C(n.user?.fields??{})})}),createOrganization:({logo:e,metadata:a,name:t,ownerId:i,slug:n})=>r(async s=>{const o=g(n!==void 0&&n!==""?n:t);if(o==="")throw new f("could not derive a slug from the organization name","ORG_SLUG_INVALID");if(await s.adapter.findOne({model:"organization",where:[{field:"slug",value:o}]}))throw new f("an organization with this slug already exists","ORG_SLUG_TAKEN");const p=await s.adapter.create({data:{createdAt:new Date,logo:e===void 0||e===""?void 0:e,metadata:a===void 0?void 0:JSON.stringify(a),name:t,slug:o},model:"organization"});return i!==void 0&&i!==""&&await s.adapter.create({data:{createdAt:new Date,organizationId:p.id,role:"owner",userId:i},model:"member"}),u(p)}),createOrgRole:({organizationId:e,permission:a,role:t})=>r(async i=>{const n=await i.adapter.create({data:{createdAt:new Date,organizationId:e,permission:JSON.stringify(a),role:t},model:"organizationRole"});return u(n)}),createTeam:({name:e,organizationId:a})=>r(async t=>{const i=await t.adapter.create({data:{createdAt:new Date,name:e,organizationId:a},model:"team"});return u(i)}),deleteOrganization:({organizationId:e})=>r(async a=>{const t=S(a.options);if(await a.adapter.deleteMany({model:"member",where:[{field:"organizationId",value:e}]}),await a.adapter.deleteMany({model:"invitation",where:[{field:"organizationId",value:e}]}),t.team){const i=await a.adapter.findMany({model:"team",where:[{field:"organizationId",value:e}]});for(const n of i)await a.adapter.deleteMany({model:"teamMember",where:[{field:"teamId",value:n.id}]});await a.adapter.deleteMany({model:"team",where:[{field:"organizationId",value:e}]})}t.organizationRole&&await a.adapter.deleteMany({model:"organizationRole",where:[{field:"organizationId",value:e}]}),await a.adapter.delete({model:"organization",where:[{field:"id",value:e}]})}),deleteOrgRole:({roleId:e})=>r(async a=>{await a.adapter.delete({model:"organizationRole",where:[{field:"id",value:e}]})}),inviteMember:({email:e,inviterId:a,organizationId:t,role:i})=>r(async n=>{let s=a;if(s===void 0||s===""){const c=await n.adapter.findMany({model:"member",where:[{field:"organizationId",value:t}]});s=(c.find(y=>typeof y.role=="string"&&y.role.includes("owner"))??c[0])?.userId}if(s===void 0||s==="")throw new f("provide an inviter — the organization has no members to attribute the invitation to","INVITER_REQUIRED");const o=await n.adapter.create({data:{createdAt:new Date,email:e.toLowerCase(),expiresAt:new Date(Date.now()+E),inviterId:s,organizationId:t,role:i===void 0||i===""?"member":i,status:"pending"},model:"invitation"});return u(o)}),listOrgRoles:({limit:e,offset:a,organizationId:t})=>r(i=>h(i,"organizationRole",{limit:e,offset:a,sortBy:{direction:"desc",field:"createdAt"},where:[{field:"organizationId",value:t}]})),listTeamMembers:({limit:e,offset:a,teamId:t})=>r(i=>h(i,"teamMember",{limit:e,offset:a,where:[{field:"teamId",value:t}]})),listTeams:({limit:e,offset:a,organizationId:t})=>r(i=>h(i,"team",{limit:e,offset:a,sortBy:{direction:"desc",field:"createdAt"},where:[{field:"organizationId",value:t}]})),removeTeam:({teamId:e})=>r(async a=>{await a.adapter.deleteMany({model:"teamMember",where:[{field:"teamId",value:e}]}),await a.adapter.delete({model:"team",where:[{field:"id",value:e}]})}),removeTeamMember:({teamMemberId:e})=>r(async a=>{await a.adapter.delete({model:"teamMember",where:[{field:"id",value:e}]})}),updateMemberRole:({memberId:e,role:a})=>r(async t=>{const i=await t.adapter.update({model:"member",update:{role:A(a)},where:[{field:"id",value:e}]});return u(i??{id:e,role:A(a)})}),updateOrganization:({logo:e,metadata:a,name:t,organizationId:i,slug:n})=>r(async s=>{const o={};if(t!==void 0&&(o.name=t),n!==void 0&&n!==""&&(o.slug=g(n)),e!==void 0&&(o.logo=e===""?void 0:e),a!==void 0&&(o.metadata=JSON.stringify(a)),Object.keys(o).length===0)return u({id:i});const c=await s.adapter.update({model:"organization",update:o,where:[{field:"id",value:i}]});return u(c??{id:i})}),updateOrgRole:({permission:e,roleId:a})=>r(async t=>{const i=await t.adapter.update({model:"organizationRole",update:{permission:JSON.stringify(e),updatedAt:new Date},where:[{field:"id",value:a}]});return u(i??{id:a,permission:JSON.stringify(e)})}),updateTeam:({name:e,teamId:a})=>r(async t=>{const i=await t.adapter.update({model:"team",update:{name:e,updatedAt:new Date},where:[{field:"id",value:a}]});return u(i??{id:a,name:e})}),createUser:({data:e,email:a,name:t,password:i,role:n})=>r(async s=>{const o=a.toLowerCase();if(await s.internalAdapter.findUserByEmail(o))throw new f("a user with this email already exists","USER_ALREADY_EXISTS");const c=await s.internalAdapter.createUser({email:o,name:t,role:n===void 0?void 0:A(n),...e},{method:"admin"});if(i!==void 0&&i!==""){const p=await s.password.hash(i);await s.internalAdapter.linkAccount({accountId:c.id,issuer:M("credential"),password:p,providerId:"credential",userId:c.id})}return v(c)}),deletePasskey:({passkeyId:e})=>r(async a=>{await a.adapter.delete({model:"passkey",where:[{field:"id",value:e}]})}),disableTwoFactor:({userId:e})=>r(async a=>{await a.adapter.deleteMany({model:"twoFactor",where:[{field:"userId",value:e}]}),await a.internalAdapter.updateUser(e,{twoFactorEnabled:!1})}),impersonateUser:({userId:e})=>r(async a=>{const t=await a.internalAdapter.findUserById(e);if(!t)throw new f("user not found","USER_NOT_FOUND");const i=m.impersonationSeconds;let n=O;if(i!==void 0){if(!Number.isInteger(i)||!Number.isFinite(i)||i<=0)throw new f("impersonationSeconds must be a positive finite integer","INVALID_IMPERSONATION_SECONDS");n=Math.min(i,U)}const s=new Date(Date.now()+n*1e3),o=await a.internalAdapter.createSession(e,!0,{expiresAt:s,impersonatedBy:m.impersonatedBy??e},!0);return{expiresAt:o.expiresAt instanceof Date?o.expiresAt.getTime():s.getTime(),token:o.token,user:v(t)}}),listAccounts:({userId:e})=>r(async a=>(await a.adapter.findMany({model:"account",where:[{field:"userId",value:e}]})).map(i=>u(i))),listInvitations:({limit:e,offset:a,organizationId:t})=>r(i=>h(i,"invitation",{limit:e,offset:a,where:[{field:"organizationId",value:t}]})),listMembers:({limit:e,offset:a,organizationId:t})=>r(i=>h(i,"member",{limit:e,offset:a,sortBy:{direction:"desc",field:"createdAt"},where:[{field:"organizationId",value:t}]})),listOrganizations:({limit:e,offset:a})=>r(t=>h(t,"organization",{limit:e,offset:a,sortBy:{direction:"desc",field:"createdAt"}})),listPasskeys:({userId:e})=>r(async a=>(await a.adapter.findMany({model:"passkey",where:[{field:"userId",value:e}]})).map(i=>u(i))),listSessions:({limit:e,offset:a,userId:t})=>r(i=>h(i,"session",{limit:e,offset:a,sortBy:{direction:"desc",field:"createdAt"},where:t===void 0||t===""?void 0:[{field:"userId",value:t}]})),listUsers:({filterField:e,filterValue:a,limit:t,offset:i,search:n,searchField:s,sortBy:o,sortDirection:c})=>r(p=>{const y=[];return n!==void 0&&n!==""&&y.push({field:s??"email",operator:"contains",value:n}),a!==void 0&&y.push({field:e??"email",operator:"eq",value:a}),h(p,"user",{limit:t,offset:i,sortBy:{direction:c??"desc",field:o??"createdAt"},where:y})}),removeMember:({memberId:e})=>r(async a=>{await a.adapter.delete({model:"member",where:[{field:"id",value:e}]})}),removeUser:({userId:e})=>r(async a=>{await a.internalAdapter.deleteUserSessions(e),await a.internalAdapter.deleteUser(e)}),revokeUserSession:({sessionId:e})=>r(async a=>{const t=await a.adapter.findOne({model:"session",where:[{field:"id",value:e}]});t?.token&&await a.internalAdapter.deleteSession(t.token)}),revokeUserSessions:({userId:e})=>r(async a=>{await a.internalAdapter.deleteUserSessions(e)}),setRole:({role:e,userId:a})=>r(async t=>{const i=await t.internalAdapter.updateUser(a,{role:A(e)});return v(i)}),setUserPassword:({newPassword:e,userId:a})=>r(async t=>{const i=t.password.config.minPasswordLength,n=t.password.config.maxPasswordLength;if(e.length<i)throw new f(`password must be at least ${i.toString()} characters`,"PASSWORD_TOO_SHORT");if(e.length>n)throw new f(`password must be at most ${n.toString()} characters`,"PASSWORD_TOO_LONG");const s=await t.password.hash(e);await t.internalAdapter.updatePassword(a,s)}),unbanUser:({userId:e})=>r(async a=>{const t=await a.internalAdapter.updateUser(e,{banExpires:null,banned:!1,banReason:null});return v(t)}),unlinkAccount:({accountId:e,userId:a})=>r(async t=>{await t.adapter.delete({model:"account",where:[{field:"id",value:e},{connector:"AND",field:"userId",value:a}]})}),updateUser:({data:e,userId:a})=>r(async t=>{const i=await t.internalAdapter.updateUser(a,e);return v(i)})}};export{f as LunoraAuthAdminError,j as createAuthAdmin};
@@ -1,6 +1,7 @@
1
1
  import { organizationClient } from 'better-auth/client/plugins';
2
2
  export { adminClient, anonymousClient, customSessionClient, deviceAuthorizationClient, emailOTPClient, inferAdditionalFields, inferOrgAdditionalFields, jwtClient, lastLoginMethodClient, magicLinkClient, multiSessionClient, oneTapClient, oneTimeTokenClient, organizationClient, phoneNumberClient, siweClient, twoFactorClient, usernameClient } from 'better-auth/client/plugins';
3
- export { oauthProviderClient } from '@better-auth/oauth-provider/client';
3
+ export { apiKeyClient } from '@better-auth/api-key/client';
4
+ export { oauthDeviceAuthorizationClient, oauthProviderClient } from '@better-auth/oauth-provider/client';
4
5
  export { passkeyClient } from '@better-auth/passkey/client';
5
6
  /**
6
7
  * Which client plugins to include. Each defaults to `false`.
@@ -1,6 +1,7 @@
1
1
  import { organizationClient } from 'better-auth/client/plugins';
2
2
  export { adminClient, anonymousClient, customSessionClient, deviceAuthorizationClient, emailOTPClient, inferAdditionalFields, inferOrgAdditionalFields, jwtClient, lastLoginMethodClient, magicLinkClient, multiSessionClient, oneTapClient, oneTimeTokenClient, organizationClient, phoneNumberClient, siweClient, twoFactorClient, usernameClient } from 'better-auth/client/plugins';
3
- export { oauthProviderClient } from '@better-auth/oauth-provider/client';
3
+ export { apiKeyClient } from '@better-auth/api-key/client';
4
+ export { oauthDeviceAuthorizationClient, oauthProviderClient } from '@better-auth/oauth-provider/client';
4
5
  export { passkeyClient } from '@better-auth/passkey/client';
5
6
  /**
6
7
  * Which client plugins to include. Each defaults to `false`.
@@ -1 +1 @@
1
- import{createLunoraAuthClient as n,lunoraAuthPlugins as t}from"./packem_shared/createLunoraAuthClient-DhjhCwmM.mjs";import{oauthProviderClient as l}from"@better-auth/oauth-provider/client";import{passkeyClient as C}from"@better-auth/passkey/client";import{adminClient as s,anonymousClient as m,customSessionClient as u,deviceAuthorizationClient as d,emailOTPClient as p,inferAdditionalFields as f,inferOrgAdditionalFields as h,jwtClient as c,lastLoginMethodClient as g,magicLinkClient as A,multiSessionClient as x,oneTapClient as T,oneTimeTokenClient as k,organizationClient as w,phoneNumberClient as F,siweClient as L,twoFactorClient as P,usernameClient as v}from"better-auth/client/plugins";export{s as adminClient,m as anonymousClient,n as createLunoraAuthClient,u as customSessionClient,d as deviceAuthorizationClient,p as emailOTPClient,f as inferAdditionalFields,h as inferOrgAdditionalFields,c as jwtClient,g as lastLoginMethodClient,t as lunoraAuthPlugins,A as magicLinkClient,x as multiSessionClient,l as oauthProviderClient,T as oneTapClient,k as oneTimeTokenClient,w as organizationClient,C as passkeyClient,F as phoneNumberClient,L as siweClient,P as twoFactorClient,v as usernameClient};
1
+ import{createLunoraAuthClient as t,lunoraAuthPlugins as n}from"./packem_shared/createLunoraAuthClient-DhjhCwmM.mjs";import{apiKeyClient as l}from"@better-auth/api-key/client";import{oauthDeviceAuthorizationClient as a,oauthProviderClient as C}from"@better-auth/oauth-provider/client";import{passkeyClient as s}from"@better-auth/passkey/client";import{adminClient as d,anonymousClient as p,customSessionClient as h,deviceAuthorizationClient as f,emailOTPClient as c,inferAdditionalFields as A,inferOrgAdditionalFields as g,jwtClient as x,lastLoginMethodClient as T,magicLinkClient as k,multiSessionClient as v,oneTapClient as w,oneTimeTokenClient as y,organizationClient as z,phoneNumberClient as F,siweClient as L,twoFactorClient as P,usernameClient as O}from"better-auth/client/plugins";export{d as adminClient,p as anonymousClient,l as apiKeyClient,t as createLunoraAuthClient,h as customSessionClient,f as deviceAuthorizationClient,c as emailOTPClient,A as inferAdditionalFields,g as inferOrgAdditionalFields,x as jwtClient,T as lastLoginMethodClient,n as lunoraAuthPlugins,k as magicLinkClient,v as multiSessionClient,a as oauthDeviceAuthorizationClient,C as oauthProviderClient,w as oneTapClient,y as oneTimeTokenClient,z as organizationClient,s as passkeyClient,F as phoneNumberClient,L as siweClient,P as twoFactorClient,O as usernameClient};
@@ -1,6 +1,7 @@
1
1
  import * as z from 'zod';
2
2
  import { DBFieldAttribute, RemoveFieldsWithReturnedFalse, FieldAttributeToObject, InferAdditionalFieldsFromPluginOptions } from 'better-auth/db';
3
3
  import { DBTransactionAdapter, Awaitable, User, OAuth2Tokens } from 'better-auth';
4
+ import * as _$better_call0 from 'better-call';
4
5
  type DeprecatedAlgorithmBehavior = "reject" | "warn" | "allow";
5
6
  interface AlgorithmValidationOptions {
6
7
  onDeprecated?: DeprecatedAlgorithmBehavior;
@@ -140,9 +141,10 @@ interface SAMLConfig {
140
141
  encPrivateKeyPass?: string | undefined;
141
142
  };
142
143
  /**
143
- * Request signed assertions from the IdP. When true, the SP metadata
144
- * advertises `WantAssertionsSigned="true"` and samlify will reject
145
- * unsigned assertions.
144
+ * Request and require signed assertions from the IdP. When true, generated
145
+ * SP metadata advertises `WantAssertionsSigned="true"` and the ACS rejects
146
+ * unsigned assertions. Custom SP metadata supplies the effective policy and
147
+ * accepts the XML Schema boolean forms `true`, `false`, `1`, and `0`.
146
148
  */
147
149
  wantAssertionsSigned?: boolean | undefined;
148
150
  authnRequestsSigned?: boolean | undefined;
@@ -206,37 +208,106 @@ type SSOProviderUserProfile = {
206
208
  name: string;
207
209
  image?: string | null | undefined;
208
210
  } & Record<string, unknown>;
209
- /** OIDC identity and profile data available to an application's SSO resolver. */
210
- interface SSOUserResolutionInput {
211
- protocol: "oidc";
211
+ /**
212
+ * Opaque reference to the SSO provider configuration accepted for the current
213
+ * authentication flow.
214
+ *
215
+ * This reference is a transient authentication fence. Applications must not
216
+ * persist it as a tenant or user binding.
217
+ */
218
+ interface SSOProviderReference {
219
+ providerId: string;
220
+ source: {
221
+ type: "configured";
222
+ } | {
223
+ type: "persisted";
224
+ recordId: string;
225
+ };
226
+ authenticationConfigurationFingerprint: string;
227
+ }
228
+ interface BaseSSOUserResolutionInput {
212
229
  providerId: string;
213
230
  accountKey: {
214
231
  issuer: string;
215
- providerAccountId: string;
232
+ accountId: string;
216
233
  };
217
234
  providerUser: SSOProviderUserProfile;
235
+ providerReference: SSOProviderReference;
236
+ }
237
+ /** OIDC identity and profile data available to an application's SSO resolver. */
238
+ interface SSOOIDCUserResolutionInput extends BaseSSOUserResolutionInput {
239
+ protocol: "oidc";
240
+ /** Raw claims from UserInfo, or the verified ID Token when UserInfo is absent. */
218
241
  providerClaims: Record<string, unknown>;
242
+ /** Claims from the cryptographically verified ID Token. */
243
+ verifiedIdTokenClaims: Record<string, unknown>;
244
+ }
245
+ /** SAML identity and assertion data available to an application's SSO resolver. */
246
+ interface SSOSAMLUserResolutionInput extends BaseSSOUserResolutionInput {
247
+ protocol: "saml";
248
+ /**
249
+ * Attributes from the verified assertion. Multi-valued attributes remain
250
+ * arrays and all scalar values remain strings.
251
+ */
252
+ providerAttributes: Record<string, string | readonly string[]>;
219
253
  }
254
+ /** Verified SSO identity and provider data available to an application resolver. */
255
+ type SSOUserResolutionInput = SSOOIDCUserResolutionInput | SSOSAMLUserResolutionInput;
220
256
  /** Transaction-bound capabilities available while resolving an SSO user. */
221
257
  interface SSOUserResolutionContext {
222
258
  database: DBTransactionAdapter;
223
259
  }
260
+ interface BaseSSOProviderMutationGuardInput {
261
+ provider: {
262
+ id: string;
263
+ providerId: string;
264
+ organizationId: string | null;
265
+ };
266
+ /**
267
+ * Opaque reference to the exact locked provider configuration.
268
+ *
269
+ * This value is transient and must not be persisted as a tenant binding.
270
+ */
271
+ providerReference: SSOProviderReference;
272
+ }
273
+ /** Mutation attempted against one exact persisted SSO provider row. */
274
+ type SSOProviderMutationGuardInput = (BaseSSOProviderMutationGuardInput & {
275
+ action: "update";
276
+ /**
277
+ * True when the validated proposal changes provider identity,
278
+ * routing, or verification policy used to authenticate accounts.
279
+ */
280
+ isAuthenticationBoundaryChange: boolean;
281
+ }) | (BaseSSOProviderMutationGuardInput & {
282
+ action: "delete";
283
+ });
284
+ /** Transaction-bound context for guarding a persisted provider mutation. */
285
+ interface SSOProviderMutationGuardContext {
286
+ database: DBTransactionAdapter;
287
+ }
224
288
  interface SSOOptions {
225
289
  /**
226
290
  * Resolve a verified provider identity to a Better Auth user.
227
291
  *
228
- * Currently invoked for OIDC callbacks only.
229
- *
230
- * TODO: Invoke this resolver for SAML callbacks after normalizing the verified
231
- * IdP entity ID as `accountKey.issuer` and the signed NameID as
232
- * `accountKey.providerAccountId`.
292
+ * For OIDC, `accountKey` is derived from the validated ID Token. For SAML,
293
+ * it contains the verified IdP entity ID and signed NameID. Profile fields,
294
+ * raw OIDC claims, and SAML assertion attributes are protocol-accepted
295
+ * provider data and may require application-level validation.
233
296
  *
234
- * `accountKey` is derived from the validated ID Token. Profile fields and raw
235
- * claims are protocol-accepted provider data and may require application-level
236
- * validation. The callback runs on every OIDC sign-in inside the same native
237
- * database transaction as account finalization and session creation.
297
+ * The callback runs on every SSO sign-in inside the same native database
298
+ * transaction as account finalization and session creation.
238
299
  */
239
300
  resolveUser?: ((input: SSOUserResolutionInput, context: SSOUserResolutionContext) => Awaitable<SSOUserResolution>) | undefined;
301
+ /**
302
+ * Guards updates and deletion of an exact persisted SSO provider.
303
+ *
304
+ * The callback runs after the provider row is locked and before any provider
305
+ * or linked Account mutation. Update inputs disclose only whether the
306
+ * validated proposal changes the authentication boundary; proposed secrets
307
+ * and configuration values are never exposed. Throw to reject the mutation.
308
+ * Better Auth converts callback failures into a stable conflict response.
309
+ */
310
+ guardProviderMutation?: ((input: SSOProviderMutationGuardInput, context: SSOProviderMutationGuardContext) => Awaitable<void>) | undefined;
240
311
  /**
241
312
  * custom function to provision a user when they sign in with an SSO provider.
242
313
  */
@@ -543,7 +614,7 @@ interface SSOOptions {
543
614
  */
544
615
  maxResponseSize?: number;
545
616
  /**
546
- * Maximum allowed size for IdP metadata XML in bytes.
617
+ * Maximum allowed size for IdP or SP metadata XML in bytes.
547
618
  *
548
619
  * @default 102400 (100KB)
549
620
  */
@@ -577,7 +648,7 @@ interface SSOOptions {
577
648
  }
578
649
  //#endregion
579
650
  //#region src/routes/domain-verification.d.ts
580
- declare const requestDomainVerification: (options: SSOOptions) => import("better-call").StrictEndpoint<"/sso/request-domain-verification", {
651
+ declare const requestDomainVerification: (options: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/request-domain-verification", {
581
652
  method: "POST";
582
653
  body: z.ZodObject<{
583
654
  providerId: z.ZodString;
@@ -599,7 +670,7 @@ declare const requestDomainVerification: (options: SSOOptions) => import("better
599
670
  };
600
671
  };
601
672
  };
602
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
673
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<{
603
674
  session: {
604
675
  session: Record<string, any> & {
605
676
  id: string;
@@ -621,11 +692,11 @@ declare const requestDomainVerification: (options: SSOOptions) => import("better
621
692
  image?: string | null | undefined;
622
693
  };
623
694
  };
624
- }>)[];
695
+ }>>[];
625
696
  }, {
626
697
  domainVerificationToken: string;
627
698
  }>;
628
- declare const verifyDomain: (options: SSOOptions) => import("better-call").StrictEndpoint<"/sso/verify-domain", {
699
+ declare const verifyDomain: (options: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/verify-domain", {
629
700
  method: "POST";
630
701
  body: z.ZodObject<{
631
702
  providerId: z.ZodString;
@@ -650,7 +721,7 @@ declare const verifyDomain: (options: SSOOptions) => import("better-call").Stric
650
721
  };
651
722
  };
652
723
  };
653
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
724
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<{
654
725
  session: {
655
726
  session: Record<string, any> & {
656
727
  id: string;
@@ -672,7 +743,7 @@ declare const verifyDomain: (options: SSOOptions) => import("better-call").Stric
672
743
  image?: string | null | undefined;
673
744
  };
674
745
  };
675
- }>)[];
746
+ }>>[];
676
747
  }, void>;
677
748
  //#endregion
678
749
  //#region src/utils.d.ts
@@ -688,9 +759,9 @@ type ParsedCert = ReturnType<typeof parseCertificate>;
688
759
  type SanitizedCert = ParsedCert | {
689
760
  error: string;
690
761
  };
691
- declare const listSSOProviders: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/providers", {
762
+ declare const listSSOProviders: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/providers", {
692
763
  method: "GET";
693
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
764
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<{
694
765
  session: {
695
766
  session: Record<string, any> & {
696
767
  id: string;
@@ -712,7 +783,7 @@ declare const listSSOProviders: (options?: SSOOptions) => import("better-call").
712
783
  image?: string | null | undefined;
713
784
  };
714
785
  };
715
- }>)[];
786
+ }>>[];
716
787
  metadata: {
717
788
  openapi: {
718
789
  operationId: string;
@@ -759,9 +830,9 @@ declare const listSSOProviders: (options?: SSOOptions) => import("better-call").
759
830
  spMetadataUrl: string;
760
831
  }[];
761
832
  }>;
762
- declare const getSSOProvider: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/get-provider", {
833
+ declare const getSSOProvider: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/get-provider", {
763
834
  method: "GET";
764
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
835
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<{
765
836
  session: {
766
837
  session: Record<string, any> & {
767
838
  id: string;
@@ -783,7 +854,7 @@ declare const getSSOProvider: (options?: SSOOptions) => import("better-call").St
783
854
  image?: string | null | undefined;
784
855
  };
785
856
  };
786
- }>)[];
857
+ }>>[];
787
858
  query: z.ZodObject<{
788
859
  providerId: z.ZodString;
789
860
  }, z.core.$strip>;
@@ -837,9 +908,9 @@ declare const getSSOProvider: (options?: SSOOptions) => import("better-call").St
837
908
  } | undefined;
838
909
  spMetadataUrl: string;
839
910
  }>;
840
- declare const updateSSOProvider: (options: SSOOptions) => import("better-call").StrictEndpoint<"/sso/update-provider", {
911
+ declare const updateSSOProvider: (options: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/update-provider", {
841
912
  method: "POST";
842
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
913
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<{
843
914
  session: {
844
915
  session: Record<string, any> & {
845
916
  id: string;
@@ -861,7 +932,7 @@ declare const updateSSOProvider: (options: SSOOptions) => import("better-call").
861
932
  image?: string | null | undefined;
862
933
  };
863
934
  };
864
- }>)[];
935
+ }>>[];
865
936
  body: z.ZodObject<{
866
937
  issuer: z.ZodOptional<z.ZodString>;
867
938
  domain: z.ZodOptional<z.ZodString>;
@@ -894,9 +965,15 @@ declare const updateSSOProvider: (options: SSOOptions) => import("better-call").
894
965
  }, z.core.$strip>>;
895
966
  samlConfig: z.ZodOptional<z.ZodObject<{
896
967
  audience: z.ZodOptional<z.ZodOptional<z.ZodString>>;
897
- cert: z.ZodOptional<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>>;
898
- entryPoint: z.ZodOptional<z.ZodString>;
899
- callbackUrl: z.ZodOptional<z.ZodOptional<z.ZodString>>;
968
+ mapping: z.ZodOptional<z.ZodOptional<z.ZodObject<{
969
+ email: z.ZodString;
970
+ emailVerified: z.ZodOptional<z.ZodString>;
971
+ name: z.ZodString;
972
+ firstName: z.ZodOptional<z.ZodString>;
973
+ lastName: z.ZodOptional<z.ZodString>;
974
+ extraFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
975
+ }, z.core.$strict>>>;
976
+ privateKey: z.ZodOptional<z.ZodOptional<z.ZodString>>;
900
977
  spMetadata: z.ZodOptional<z.ZodOptional<z.ZodObject<{
901
978
  metadata: z.ZodOptional<z.ZodString>;
902
979
  entityID: z.ZodOptional<z.ZodString>;
@@ -907,20 +984,14 @@ declare const updateSSOProvider: (options: SSOOptions) => import("better-call").
907
984
  encPrivateKey: z.ZodOptional<z.ZodString>;
908
985
  encPrivateKeyPass: z.ZodOptional<z.ZodString>;
909
986
  }, z.core.$strip>>>;
987
+ cert: z.ZodOptional<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>>;
988
+ entryPoint: z.ZodOptional<z.ZodString>;
989
+ callbackUrl: z.ZodOptional<z.ZodOptional<z.ZodString>>;
910
990
  wantAssertionsSigned: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
911
991
  authnRequestsSigned: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
912
992
  signatureAlgorithm: z.ZodOptional<z.ZodOptional<z.ZodString>>;
913
993
  digestAlgorithm: z.ZodOptional<z.ZodOptional<z.ZodString>>;
914
994
  identifierFormat: z.ZodOptional<z.ZodOptional<z.ZodString>>;
915
- privateKey: z.ZodOptional<z.ZodOptional<z.ZodString>>;
916
- mapping: z.ZodOptional<z.ZodOptional<z.ZodObject<{
917
- email: z.ZodString;
918
- emailVerified: z.ZodOptional<z.ZodString>;
919
- name: z.ZodString;
920
- firstName: z.ZodOptional<z.ZodString>;
921
- lastName: z.ZodOptional<z.ZodString>;
922
- extraFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
923
- }, z.core.$strict>>>;
924
995
  idpInitiatedCallbackUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
925
996
  idpMetadata: z.ZodOptional<z.ZodObject<{
926
997
  cert: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
@@ -993,9 +1064,9 @@ declare const updateSSOProvider: (options: SSOOptions) => import("better-call").
993
1064
  } | undefined;
994
1065
  spMetadataUrl: string;
995
1066
  }>;
996
- declare const deleteSSOProvider: () => import("better-call").StrictEndpoint<"/sso/delete-provider", {
1067
+ declare const deleteSSOProvider: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/delete-provider", {
997
1068
  method: "POST";
998
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
1069
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<{
999
1070
  session: {
1000
1071
  session: Record<string, any> & {
1001
1072
  id: string;
@@ -1017,7 +1088,7 @@ declare const deleteSSOProvider: () => import("better-call").StrictEndpoint<"/ss
1017
1088
  image?: string | null | undefined;
1018
1089
  };
1019
1090
  };
1020
- }>)[];
1091
+ }>>[];
1021
1092
  body: z.ZodObject<{
1022
1093
  providerId: z.ZodString;
1023
1094
  }, z.core.$strip>;
@@ -1044,7 +1115,7 @@ declare const deleteSSOProvider: () => import("better-call").StrictEndpoint<"/ss
1044
1115
  }>;
1045
1116
  //#endregion
1046
1117
  //#region src/routes/sso.d.ts
1047
- declare const spMetadata: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/saml2/sp/metadata", {
1118
+ declare const spMetadata: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/saml2/sp/metadata", {
1048
1119
  method: "GET";
1049
1120
  query: z.ZodObject<{
1050
1121
  providerId: z.ZodString;
@@ -1062,12 +1133,12 @@ declare const spMetadata: (options?: SSOOptions) => import("better-call").Strict
1062
1133
  };
1063
1134
  };
1064
1135
  }, Response>;
1065
- declare const registerSSOProvider: <O extends SSOOptions>(options: O) => import("better-call").StrictEndpoint<"/sso/register", {
1136
+ declare const registerSSOProvider: <O extends SSOOptions>(options: O) => _$better_call0.StrictEndpoint<"/sso/register", {
1066
1137
  method: "POST";
1067
1138
  body: z.ZodObject<{
1068
1139
  [x: string]: z.ZodOptional<z.ZodAny>;
1069
1140
  }, z.core.$strip>;
1070
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
1141
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<{
1071
1142
  session: {
1072
1143
  session: Record<string, any> & {
1073
1144
  id: string;
@@ -1089,7 +1160,7 @@ declare const registerSSOProvider: <O extends SSOOptions>(options: O) => import(
1089
1160
  image?: string | null | undefined;
1090
1161
  };
1091
1162
  };
1092
- }>)[];
1163
+ }>>[];
1093
1164
  metadata: {
1094
1165
  $Infer: {
1095
1166
  body: Record<string, any> & SSOProviderAdditionalFieldsInput<O>;
@@ -1264,7 +1335,7 @@ declare const registerSSOProvider: <O extends SSOOptions>(options: O) => import(
1264
1335
  oidcConfig: OIDCConfig | null;
1265
1336
  samlConfig: SAMLConfig | null;
1266
1337
  } & Omit<InferSSOProvider<O>, "samlConfig" | "oidcConfig">>;
1267
- declare const signInSSO: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sign-in/sso", {
1338
+ declare const signInSSO: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sign-in/sso", {
1268
1339
  method: "POST";
1269
1340
  body: z.ZodObject<{
1270
1341
  email: z.ZodOptional<z.ZodString>;
@@ -1386,7 +1457,7 @@ declare const signInSSO: (options?: SSOOptions) => import("better-call").StrictE
1386
1457
  url: string;
1387
1458
  redirect: boolean;
1388
1459
  }>;
1389
- declare const callbackSSO: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/callback/:providerId", {
1460
+ declare const callbackSSO: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/callback/:providerId", {
1390
1461
  method: "GET";
1391
1462
  query: z.ZodObject<{
1392
1463
  code: z.ZodOptional<z.ZodString>;
@@ -1414,7 +1485,7 @@ declare const callbackSSO: (options?: SSOOptions) => import("better-call").Stric
1414
1485
  * Used when `options.redirectURI` is set — the `providerId` is read from
1415
1486
  * the OAuth state instead of the URL path.
1416
1487
  */
1417
- declare const callbackSSOShared: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/callback", {
1488
+ declare const callbackSSOShared: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/callback", {
1418
1489
  metadata: {
1419
1490
  openapi: {
1420
1491
  operationId: string;
@@ -1437,7 +1508,7 @@ declare const callbackSSOShared: (options?: SSOOptions) => import("better-call")
1437
1508
  }, z.core.$strip>;
1438
1509
  allowedMediaTypes: readonly ["application/x-www-form-urlencoded", "application/json"];
1439
1510
  }, void>;
1440
- declare const acsEndpoint: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/saml2/sp/acs/:providerId", {
1511
+ declare const acsEndpoint: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/saml2/sp/acs/:providerId", {
1441
1512
  method: ("GET" | "POST")[];
1442
1513
  body: z.ZodOptional<z.ZodObject<{
1443
1514
  SAMLResponse: z.ZodString;
@@ -1467,7 +1538,7 @@ declare const acsEndpoint: (options?: SSOOptions) => import("better-call").Stric
1467
1538
  scope: "server";
1468
1539
  };
1469
1540
  }, never>;
1470
- declare const sloEndpoint: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/saml2/sp/slo/:providerId", {
1541
+ declare const sloEndpoint: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/saml2/sp/slo/:providerId", {
1471
1542
  method: ("GET" | "POST")[];
1472
1543
  body: z.ZodOptional<z.ZodObject<{
1473
1544
  SAMLRequest: z.ZodOptional<z.ZodString>;
@@ -1488,12 +1559,12 @@ declare const sloEndpoint: (options?: SSOOptions) => import("better-call").Stric
1488
1559
  scope: "server";
1489
1560
  };
1490
1561
  }, void | Response>;
1491
- declare const initiateSLO: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/saml2/logout/:providerId", {
1562
+ declare const initiateSLO: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/saml2/logout/:providerId", {
1492
1563
  method: "POST";
1493
1564
  body: z.ZodObject<{
1494
1565
  callbackURL: z.ZodOptional<z.ZodString>;
1495
1566
  }, z.core.$strip>;
1496
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
1567
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<{
1497
1568
  session: {
1498
1569
  session: Record<string, any> & {
1499
1570
  id: string;
@@ -1515,7 +1586,7 @@ declare const initiateSLO: (options?: SSOOptions) => import("better-call").Stric
1515
1586
  image?: string | null | undefined;
1516
1587
  };
1517
1588
  };
1518
- }>)[];
1589
+ }>>[];
1519
1590
  metadata: {
1520
1591
  readonly scope: "server";
1521
1592
  };
@@ -1,6 +1,7 @@
1
1
  import * as z from 'zod';
2
2
  import { DBFieldAttribute, RemoveFieldsWithReturnedFalse, FieldAttributeToObject, InferAdditionalFieldsFromPluginOptions } from 'better-auth/db';
3
3
  import { DBTransactionAdapter, Awaitable, User, OAuth2Tokens } from 'better-auth';
4
+ import * as _$better_call0 from 'better-call';
4
5
  type DeprecatedAlgorithmBehavior = "reject" | "warn" | "allow";
5
6
  interface AlgorithmValidationOptions {
6
7
  onDeprecated?: DeprecatedAlgorithmBehavior;
@@ -140,9 +141,10 @@ interface SAMLConfig {
140
141
  encPrivateKeyPass?: string | undefined;
141
142
  };
142
143
  /**
143
- * Request signed assertions from the IdP. When true, the SP metadata
144
- * advertises `WantAssertionsSigned="true"` and samlify will reject
145
- * unsigned assertions.
144
+ * Request and require signed assertions from the IdP. When true, generated
145
+ * SP metadata advertises `WantAssertionsSigned="true"` and the ACS rejects
146
+ * unsigned assertions. Custom SP metadata supplies the effective policy and
147
+ * accepts the XML Schema boolean forms `true`, `false`, `1`, and `0`.
146
148
  */
147
149
  wantAssertionsSigned?: boolean | undefined;
148
150
  authnRequestsSigned?: boolean | undefined;
@@ -206,37 +208,106 @@ type SSOProviderUserProfile = {
206
208
  name: string;
207
209
  image?: string | null | undefined;
208
210
  } & Record<string, unknown>;
209
- /** OIDC identity and profile data available to an application's SSO resolver. */
210
- interface SSOUserResolutionInput {
211
- protocol: "oidc";
211
+ /**
212
+ * Opaque reference to the SSO provider configuration accepted for the current
213
+ * authentication flow.
214
+ *
215
+ * This reference is a transient authentication fence. Applications must not
216
+ * persist it as a tenant or user binding.
217
+ */
218
+ interface SSOProviderReference {
219
+ providerId: string;
220
+ source: {
221
+ type: "configured";
222
+ } | {
223
+ type: "persisted";
224
+ recordId: string;
225
+ };
226
+ authenticationConfigurationFingerprint: string;
227
+ }
228
+ interface BaseSSOUserResolutionInput {
212
229
  providerId: string;
213
230
  accountKey: {
214
231
  issuer: string;
215
- providerAccountId: string;
232
+ accountId: string;
216
233
  };
217
234
  providerUser: SSOProviderUserProfile;
235
+ providerReference: SSOProviderReference;
236
+ }
237
+ /** OIDC identity and profile data available to an application's SSO resolver. */
238
+ interface SSOOIDCUserResolutionInput extends BaseSSOUserResolutionInput {
239
+ protocol: "oidc";
240
+ /** Raw claims from UserInfo, or the verified ID Token when UserInfo is absent. */
218
241
  providerClaims: Record<string, unknown>;
242
+ /** Claims from the cryptographically verified ID Token. */
243
+ verifiedIdTokenClaims: Record<string, unknown>;
244
+ }
245
+ /** SAML identity and assertion data available to an application's SSO resolver. */
246
+ interface SSOSAMLUserResolutionInput extends BaseSSOUserResolutionInput {
247
+ protocol: "saml";
248
+ /**
249
+ * Attributes from the verified assertion. Multi-valued attributes remain
250
+ * arrays and all scalar values remain strings.
251
+ */
252
+ providerAttributes: Record<string, string | readonly string[]>;
219
253
  }
254
+ /** Verified SSO identity and provider data available to an application resolver. */
255
+ type SSOUserResolutionInput = SSOOIDCUserResolutionInput | SSOSAMLUserResolutionInput;
220
256
  /** Transaction-bound capabilities available while resolving an SSO user. */
221
257
  interface SSOUserResolutionContext {
222
258
  database: DBTransactionAdapter;
223
259
  }
260
+ interface BaseSSOProviderMutationGuardInput {
261
+ provider: {
262
+ id: string;
263
+ providerId: string;
264
+ organizationId: string | null;
265
+ };
266
+ /**
267
+ * Opaque reference to the exact locked provider configuration.
268
+ *
269
+ * This value is transient and must not be persisted as a tenant binding.
270
+ */
271
+ providerReference: SSOProviderReference;
272
+ }
273
+ /** Mutation attempted against one exact persisted SSO provider row. */
274
+ type SSOProviderMutationGuardInput = (BaseSSOProviderMutationGuardInput & {
275
+ action: "update";
276
+ /**
277
+ * True when the validated proposal changes provider identity,
278
+ * routing, or verification policy used to authenticate accounts.
279
+ */
280
+ isAuthenticationBoundaryChange: boolean;
281
+ }) | (BaseSSOProviderMutationGuardInput & {
282
+ action: "delete";
283
+ });
284
+ /** Transaction-bound context for guarding a persisted provider mutation. */
285
+ interface SSOProviderMutationGuardContext {
286
+ database: DBTransactionAdapter;
287
+ }
224
288
  interface SSOOptions {
225
289
  /**
226
290
  * Resolve a verified provider identity to a Better Auth user.
227
291
  *
228
- * Currently invoked for OIDC callbacks only.
229
- *
230
- * TODO: Invoke this resolver for SAML callbacks after normalizing the verified
231
- * IdP entity ID as `accountKey.issuer` and the signed NameID as
232
- * `accountKey.providerAccountId`.
292
+ * For OIDC, `accountKey` is derived from the validated ID Token. For SAML,
293
+ * it contains the verified IdP entity ID and signed NameID. Profile fields,
294
+ * raw OIDC claims, and SAML assertion attributes are protocol-accepted
295
+ * provider data and may require application-level validation.
233
296
  *
234
- * `accountKey` is derived from the validated ID Token. Profile fields and raw
235
- * claims are protocol-accepted provider data and may require application-level
236
- * validation. The callback runs on every OIDC sign-in inside the same native
237
- * database transaction as account finalization and session creation.
297
+ * The callback runs on every SSO sign-in inside the same native database
298
+ * transaction as account finalization and session creation.
238
299
  */
239
300
  resolveUser?: ((input: SSOUserResolutionInput, context: SSOUserResolutionContext) => Awaitable<SSOUserResolution>) | undefined;
301
+ /**
302
+ * Guards updates and deletion of an exact persisted SSO provider.
303
+ *
304
+ * The callback runs after the provider row is locked and before any provider
305
+ * or linked Account mutation. Update inputs disclose only whether the
306
+ * validated proposal changes the authentication boundary; proposed secrets
307
+ * and configuration values are never exposed. Throw to reject the mutation.
308
+ * Better Auth converts callback failures into a stable conflict response.
309
+ */
310
+ guardProviderMutation?: ((input: SSOProviderMutationGuardInput, context: SSOProviderMutationGuardContext) => Awaitable<void>) | undefined;
240
311
  /**
241
312
  * custom function to provision a user when they sign in with an SSO provider.
242
313
  */
@@ -543,7 +614,7 @@ interface SSOOptions {
543
614
  */
544
615
  maxResponseSize?: number;
545
616
  /**
546
- * Maximum allowed size for IdP metadata XML in bytes.
617
+ * Maximum allowed size for IdP or SP metadata XML in bytes.
547
618
  *
548
619
  * @default 102400 (100KB)
549
620
  */
@@ -577,7 +648,7 @@ interface SSOOptions {
577
648
  }
578
649
  //#endregion
579
650
  //#region src/routes/domain-verification.d.ts
580
- declare const requestDomainVerification: (options: SSOOptions) => import("better-call").StrictEndpoint<"/sso/request-domain-verification", {
651
+ declare const requestDomainVerification: (options: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/request-domain-verification", {
581
652
  method: "POST";
582
653
  body: z.ZodObject<{
583
654
  providerId: z.ZodString;
@@ -599,7 +670,7 @@ declare const requestDomainVerification: (options: SSOOptions) => import("better
599
670
  };
600
671
  };
601
672
  };
602
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
673
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<{
603
674
  session: {
604
675
  session: Record<string, any> & {
605
676
  id: string;
@@ -621,11 +692,11 @@ declare const requestDomainVerification: (options: SSOOptions) => import("better
621
692
  image?: string | null | undefined;
622
693
  };
623
694
  };
624
- }>)[];
695
+ }>>[];
625
696
  }, {
626
697
  domainVerificationToken: string;
627
698
  }>;
628
- declare const verifyDomain: (options: SSOOptions) => import("better-call").StrictEndpoint<"/sso/verify-domain", {
699
+ declare const verifyDomain: (options: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/verify-domain", {
629
700
  method: "POST";
630
701
  body: z.ZodObject<{
631
702
  providerId: z.ZodString;
@@ -650,7 +721,7 @@ declare const verifyDomain: (options: SSOOptions) => import("better-call").Stric
650
721
  };
651
722
  };
652
723
  };
653
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
724
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<{
654
725
  session: {
655
726
  session: Record<string, any> & {
656
727
  id: string;
@@ -672,7 +743,7 @@ declare const verifyDomain: (options: SSOOptions) => import("better-call").Stric
672
743
  image?: string | null | undefined;
673
744
  };
674
745
  };
675
- }>)[];
746
+ }>>[];
676
747
  }, void>;
677
748
  //#endregion
678
749
  //#region src/utils.d.ts
@@ -688,9 +759,9 @@ type ParsedCert = ReturnType<typeof parseCertificate>;
688
759
  type SanitizedCert = ParsedCert | {
689
760
  error: string;
690
761
  };
691
- declare const listSSOProviders: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/providers", {
762
+ declare const listSSOProviders: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/providers", {
692
763
  method: "GET";
693
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
764
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<{
694
765
  session: {
695
766
  session: Record<string, any> & {
696
767
  id: string;
@@ -712,7 +783,7 @@ declare const listSSOProviders: (options?: SSOOptions) => import("better-call").
712
783
  image?: string | null | undefined;
713
784
  };
714
785
  };
715
- }>)[];
786
+ }>>[];
716
787
  metadata: {
717
788
  openapi: {
718
789
  operationId: string;
@@ -759,9 +830,9 @@ declare const listSSOProviders: (options?: SSOOptions) => import("better-call").
759
830
  spMetadataUrl: string;
760
831
  }[];
761
832
  }>;
762
- declare const getSSOProvider: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/get-provider", {
833
+ declare const getSSOProvider: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/get-provider", {
763
834
  method: "GET";
764
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
835
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<{
765
836
  session: {
766
837
  session: Record<string, any> & {
767
838
  id: string;
@@ -783,7 +854,7 @@ declare const getSSOProvider: (options?: SSOOptions) => import("better-call").St
783
854
  image?: string | null | undefined;
784
855
  };
785
856
  };
786
- }>)[];
857
+ }>>[];
787
858
  query: z.ZodObject<{
788
859
  providerId: z.ZodString;
789
860
  }, z.core.$strip>;
@@ -837,9 +908,9 @@ declare const getSSOProvider: (options?: SSOOptions) => import("better-call").St
837
908
  } | undefined;
838
909
  spMetadataUrl: string;
839
910
  }>;
840
- declare const updateSSOProvider: (options: SSOOptions) => import("better-call").StrictEndpoint<"/sso/update-provider", {
911
+ declare const updateSSOProvider: (options: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/update-provider", {
841
912
  method: "POST";
842
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
913
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<{
843
914
  session: {
844
915
  session: Record<string, any> & {
845
916
  id: string;
@@ -861,7 +932,7 @@ declare const updateSSOProvider: (options: SSOOptions) => import("better-call").
861
932
  image?: string | null | undefined;
862
933
  };
863
934
  };
864
- }>)[];
935
+ }>>[];
865
936
  body: z.ZodObject<{
866
937
  issuer: z.ZodOptional<z.ZodString>;
867
938
  domain: z.ZodOptional<z.ZodString>;
@@ -894,9 +965,15 @@ declare const updateSSOProvider: (options: SSOOptions) => import("better-call").
894
965
  }, z.core.$strip>>;
895
966
  samlConfig: z.ZodOptional<z.ZodObject<{
896
967
  audience: z.ZodOptional<z.ZodOptional<z.ZodString>>;
897
- cert: z.ZodOptional<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>>;
898
- entryPoint: z.ZodOptional<z.ZodString>;
899
- callbackUrl: z.ZodOptional<z.ZodOptional<z.ZodString>>;
968
+ mapping: z.ZodOptional<z.ZodOptional<z.ZodObject<{
969
+ email: z.ZodString;
970
+ emailVerified: z.ZodOptional<z.ZodString>;
971
+ name: z.ZodString;
972
+ firstName: z.ZodOptional<z.ZodString>;
973
+ lastName: z.ZodOptional<z.ZodString>;
974
+ extraFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
975
+ }, z.core.$strict>>>;
976
+ privateKey: z.ZodOptional<z.ZodOptional<z.ZodString>>;
900
977
  spMetadata: z.ZodOptional<z.ZodOptional<z.ZodObject<{
901
978
  metadata: z.ZodOptional<z.ZodString>;
902
979
  entityID: z.ZodOptional<z.ZodString>;
@@ -907,20 +984,14 @@ declare const updateSSOProvider: (options: SSOOptions) => import("better-call").
907
984
  encPrivateKey: z.ZodOptional<z.ZodString>;
908
985
  encPrivateKeyPass: z.ZodOptional<z.ZodString>;
909
986
  }, z.core.$strip>>>;
987
+ cert: z.ZodOptional<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>>;
988
+ entryPoint: z.ZodOptional<z.ZodString>;
989
+ callbackUrl: z.ZodOptional<z.ZodOptional<z.ZodString>>;
910
990
  wantAssertionsSigned: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
911
991
  authnRequestsSigned: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
912
992
  signatureAlgorithm: z.ZodOptional<z.ZodOptional<z.ZodString>>;
913
993
  digestAlgorithm: z.ZodOptional<z.ZodOptional<z.ZodString>>;
914
994
  identifierFormat: z.ZodOptional<z.ZodOptional<z.ZodString>>;
915
- privateKey: z.ZodOptional<z.ZodOptional<z.ZodString>>;
916
- mapping: z.ZodOptional<z.ZodOptional<z.ZodObject<{
917
- email: z.ZodString;
918
- emailVerified: z.ZodOptional<z.ZodString>;
919
- name: z.ZodString;
920
- firstName: z.ZodOptional<z.ZodString>;
921
- lastName: z.ZodOptional<z.ZodString>;
922
- extraFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
923
- }, z.core.$strict>>>;
924
995
  idpInitiatedCallbackUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
925
996
  idpMetadata: z.ZodOptional<z.ZodObject<{
926
997
  cert: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
@@ -993,9 +1064,9 @@ declare const updateSSOProvider: (options: SSOOptions) => import("better-call").
993
1064
  } | undefined;
994
1065
  spMetadataUrl: string;
995
1066
  }>;
996
- declare const deleteSSOProvider: () => import("better-call").StrictEndpoint<"/sso/delete-provider", {
1067
+ declare const deleteSSOProvider: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/delete-provider", {
997
1068
  method: "POST";
998
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
1069
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<{
999
1070
  session: {
1000
1071
  session: Record<string, any> & {
1001
1072
  id: string;
@@ -1017,7 +1088,7 @@ declare const deleteSSOProvider: () => import("better-call").StrictEndpoint<"/ss
1017
1088
  image?: string | null | undefined;
1018
1089
  };
1019
1090
  };
1020
- }>)[];
1091
+ }>>[];
1021
1092
  body: z.ZodObject<{
1022
1093
  providerId: z.ZodString;
1023
1094
  }, z.core.$strip>;
@@ -1044,7 +1115,7 @@ declare const deleteSSOProvider: () => import("better-call").StrictEndpoint<"/ss
1044
1115
  }>;
1045
1116
  //#endregion
1046
1117
  //#region src/routes/sso.d.ts
1047
- declare const spMetadata: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/saml2/sp/metadata", {
1118
+ declare const spMetadata: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/saml2/sp/metadata", {
1048
1119
  method: "GET";
1049
1120
  query: z.ZodObject<{
1050
1121
  providerId: z.ZodString;
@@ -1062,12 +1133,12 @@ declare const spMetadata: (options?: SSOOptions) => import("better-call").Strict
1062
1133
  };
1063
1134
  };
1064
1135
  }, Response>;
1065
- declare const registerSSOProvider: <O extends SSOOptions>(options: O) => import("better-call").StrictEndpoint<"/sso/register", {
1136
+ declare const registerSSOProvider: <O extends SSOOptions>(options: O) => _$better_call0.StrictEndpoint<"/sso/register", {
1066
1137
  method: "POST";
1067
1138
  body: z.ZodObject<{
1068
1139
  [x: string]: z.ZodOptional<z.ZodAny>;
1069
1140
  }, z.core.$strip>;
1070
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
1141
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<{
1071
1142
  session: {
1072
1143
  session: Record<string, any> & {
1073
1144
  id: string;
@@ -1089,7 +1160,7 @@ declare const registerSSOProvider: <O extends SSOOptions>(options: O) => import(
1089
1160
  image?: string | null | undefined;
1090
1161
  };
1091
1162
  };
1092
- }>)[];
1163
+ }>>[];
1093
1164
  metadata: {
1094
1165
  $Infer: {
1095
1166
  body: Record<string, any> & SSOProviderAdditionalFieldsInput<O>;
@@ -1264,7 +1335,7 @@ declare const registerSSOProvider: <O extends SSOOptions>(options: O) => import(
1264
1335
  oidcConfig: OIDCConfig | null;
1265
1336
  samlConfig: SAMLConfig | null;
1266
1337
  } & Omit<InferSSOProvider<O>, "samlConfig" | "oidcConfig">>;
1267
- declare const signInSSO: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sign-in/sso", {
1338
+ declare const signInSSO: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sign-in/sso", {
1268
1339
  method: "POST";
1269
1340
  body: z.ZodObject<{
1270
1341
  email: z.ZodOptional<z.ZodString>;
@@ -1386,7 +1457,7 @@ declare const signInSSO: (options?: SSOOptions) => import("better-call").StrictE
1386
1457
  url: string;
1387
1458
  redirect: boolean;
1388
1459
  }>;
1389
- declare const callbackSSO: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/callback/:providerId", {
1460
+ declare const callbackSSO: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/callback/:providerId", {
1390
1461
  method: "GET";
1391
1462
  query: z.ZodObject<{
1392
1463
  code: z.ZodOptional<z.ZodString>;
@@ -1414,7 +1485,7 @@ declare const callbackSSO: (options?: SSOOptions) => import("better-call").Stric
1414
1485
  * Used when `options.redirectURI` is set — the `providerId` is read from
1415
1486
  * the OAuth state instead of the URL path.
1416
1487
  */
1417
- declare const callbackSSOShared: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/callback", {
1488
+ declare const callbackSSOShared: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/callback", {
1418
1489
  metadata: {
1419
1490
  openapi: {
1420
1491
  operationId: string;
@@ -1437,7 +1508,7 @@ declare const callbackSSOShared: (options?: SSOOptions) => import("better-call")
1437
1508
  }, z.core.$strip>;
1438
1509
  allowedMediaTypes: readonly ["application/x-www-form-urlencoded", "application/json"];
1439
1510
  }, void>;
1440
- declare const acsEndpoint: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/saml2/sp/acs/:providerId", {
1511
+ declare const acsEndpoint: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/saml2/sp/acs/:providerId", {
1441
1512
  method: ("GET" | "POST")[];
1442
1513
  body: z.ZodOptional<z.ZodObject<{
1443
1514
  SAMLResponse: z.ZodString;
@@ -1467,7 +1538,7 @@ declare const acsEndpoint: (options?: SSOOptions) => import("better-call").Stric
1467
1538
  scope: "server";
1468
1539
  };
1469
1540
  }, never>;
1470
- declare const sloEndpoint: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/saml2/sp/slo/:providerId", {
1541
+ declare const sloEndpoint: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/saml2/sp/slo/:providerId", {
1471
1542
  method: ("GET" | "POST")[];
1472
1543
  body: z.ZodOptional<z.ZodObject<{
1473
1544
  SAMLRequest: z.ZodOptional<z.ZodString>;
@@ -1488,12 +1559,12 @@ declare const sloEndpoint: (options?: SSOOptions) => import("better-call").Stric
1488
1559
  scope: "server";
1489
1560
  };
1490
1561
  }, void | Response>;
1491
- declare const initiateSLO: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/saml2/logout/:providerId", {
1562
+ declare const initiateSLO: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/saml2/logout/:providerId", {
1492
1563
  method: "POST";
1493
1564
  body: z.ZodObject<{
1494
1565
  callbackURL: z.ZodOptional<z.ZodString>;
1495
1566
  }, z.core.$strip>;
1496
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
1567
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<{
1497
1568
  session: {
1498
1569
  session: Record<string, any> & {
1499
1570
  id: string;
@@ -1515,7 +1586,7 @@ declare const initiateSLO: (options?: SSOOptions) => import("better-call").Stric
1515
1586
  image?: string | null | undefined;
1516
1587
  };
1517
1588
  };
1518
- }>)[];
1589
+ }>>[];
1519
1590
  metadata: {
1520
1591
  readonly scope: "server";
1521
1592
  };
@@ -1,9 +1,10 @@
1
1
  import { BetterAuthPlugin } from 'better-auth';
2
- export { mcp, mcpHandler, requireMcpAuth } from '@better-auth/mcp';
3
- export { oauthProvider } from '@better-auth/oauth-provider';
2
+ export { apiKey } from '@better-auth/api-key';
3
+ export { createMcpProtectedRequestHandler, mcp, requireMcpAuth } from '@better-auth/mcp';
4
+ export { oauthDeviceAuthorization, oauthProvider } from '@better-auth/oauth-provider';
4
5
  export { passkey } from '@better-auth/passkey';
5
6
  export { scim } from '@better-auth/scim';
6
- export { captcha } from 'better-auth/plugins';
7
+ export { captcha, lastLoginMethod, oneTap } from 'better-auth/plugins';
7
8
  export { createAccessControl } from 'better-auth/plugins/access';
8
9
  export { admin } from 'better-auth/plugins/admin';
9
10
  export { anonymous } from 'better-auth/plugins/anonymous';
package/dist/plugins.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import { BetterAuthPlugin } from 'better-auth';
2
- export { mcp, mcpHandler, requireMcpAuth } from '@better-auth/mcp';
3
- export { oauthProvider } from '@better-auth/oauth-provider';
2
+ export { apiKey } from '@better-auth/api-key';
3
+ export { createMcpProtectedRequestHandler, mcp, requireMcpAuth } from '@better-auth/mcp';
4
+ export { oauthDeviceAuthorization, oauthProvider } from '@better-auth/oauth-provider';
4
5
  export { passkey } from '@better-auth/passkey';
5
6
  export { scim } from '@better-auth/scim';
6
- export { captcha } from 'better-auth/plugins';
7
+ export { captcha, lastLoginMethod, oneTap } from 'better-auth/plugins';
7
8
  export { createAccessControl } from 'better-auth/plugins/access';
8
9
  export { admin } from 'better-auth/plugins/admin';
9
10
  export { anonymous } from 'better-auth/plugins/anonymous';
package/dist/plugins.mjs CHANGED
@@ -1 +1 @@
1
- import{uiConfig as e}from"./packem_shared/uiConfig-B8pN6pks.mjs";import{mcp as m,mcpHandler as p,requireMcpAuth as f}from"@better-auth/mcp";import{oauthProvider as i}from"@better-auth/oauth-provider";import{passkey as a}from"@better-auth/passkey";import{scim as s}from"@better-auth/scim";import{captcha as h}from"better-auth/plugins";import{createAccessControl as A}from"better-auth/plugins/access";import{admin as l}from"better-auth/plugins/admin";import{anonymous as P}from"better-auth/plugins/anonymous";import{bearer as v}from"better-auth/plugins/bearer";import{customSession as T}from"better-auth/plugins/custom-session";import{deviceAuthorization as z}from"better-auth/plugins/device-authorization";import{emailOTP as O}from"better-auth/plugins/email-otp";import{genericOAuth as j}from"better-auth/plugins/generic-oauth";import{haveIBeenPwned as B}from"better-auth/plugins/haveibeenpwned";import{jwt as H}from"better-auth/plugins/jwt";import{magicLink as L}from"better-auth/plugins/magic-link";import{multiSession as N}from"better-auth/plugins/multi-session";import{oAuthProxy as E}from"better-auth/plugins/oauth-proxy";import{oneTimeToken as J}from"better-auth/plugins/one-time-token";import{organization as Q}from"better-auth/plugins/organization";import{phoneNumber as U}from"better-auth/plugins/phone-number";import{siwe as W}from"better-auth/plugins/siwe";import{twoFactor as Y}from"better-auth/plugins/two-factor";import{username as _}from"better-auth/plugins/username";export{l as admin,P as anonymous,v as bearer,h as captcha,A as createAccessControl,T as customSession,z as deviceAuthorization,O as emailOTP,j as genericOAuth,B as haveIBeenPwned,H as jwt,L as magicLink,m as mcp,p as mcpHandler,N as multiSession,E as oAuthProxy,i as oauthProvider,J as oneTimeToken,Q as organization,a as passkey,U as phoneNumber,f as requireMcpAuth,s as scim,W as siwe,Y as twoFactor,e as uiConfig,_ as username};
1
+ import{uiConfig as e}from"./packem_shared/uiConfig-B8pN6pks.mjs";import{apiKey as m}from"@better-auth/api-key";import{createMcpProtectedRequestHandler as f,mcp as x,requireMcpAuth as i}from"@better-auth/mcp";import{oauthDeviceAuthorization as n,oauthProvider as c}from"@better-auth/oauth-provider";import{passkey as u}from"@better-auth/passkey";import{scim as d}from"@better-auth/scim";import{captcha as g,lastLoginMethod as l,oneTap as P}from"better-auth/plugins";import{createAccessControl as w}from"better-auth/plugins/access";import{admin as T}from"better-auth/plugins/admin";import{anonymous as z}from"better-auth/plugins/anonymous";import{bearer as b}from"better-auth/plugins/bearer";import{customSession as C}from"better-auth/plugins/custom-session";import{deviceAuthorization as O}from"better-auth/plugins/device-authorization";import{emailOTP as j}from"better-auth/plugins/email-otp";import{genericOAuth as D}from"better-auth/plugins/generic-oauth";import{haveIBeenPwned as H}from"better-auth/plugins/haveibeenpwned";import{jwt as K}from"better-auth/plugins/jwt";import{magicLink as R}from"better-auth/plugins/magic-link";import{multiSession as G}from"better-auth/plugins/multi-session";import{oAuthProxy as Q}from"better-auth/plugins/oauth-proxy";import{oneTimeToken as V}from"better-auth/plugins/one-time-token";import{organization as X}from"better-auth/plugins/organization";import{phoneNumber as Z}from"better-auth/plugins/phone-number";import{siwe as $}from"better-auth/plugins/siwe";import{twoFactor as ro}from"better-auth/plugins/two-factor";import{username as to}from"better-auth/plugins/username";export{T as admin,z as anonymous,m as apiKey,b as bearer,g as captcha,w as createAccessControl,f as createMcpProtectedRequestHandler,C as customSession,O as deviceAuthorization,j as emailOTP,D as genericOAuth,H as haveIBeenPwned,K as jwt,l as lastLoginMethod,R as magicLink,x as mcp,G as multiSession,Q as oAuthProxy,n as oauthDeviceAuthorization,c as oauthProvider,P as oneTap,V as oneTimeToken,X as organization,u as passkey,Z as phoneNumber,i as requireMcpAuth,d as scim,$ as siwe,ro as twoFactor,e as uiConfig,to as username};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/auth",
3
- "version": "1.0.0-alpha.86",
3
+ "version": "1.0.0-alpha.88",
4
4
  "description": "Auth for Lunora — a thin better-auth wrapper: email/password, OAuth, plugins, D1-backed",
5
5
  "keywords": [
6
6
  "auth",
@@ -98,12 +98,13 @@
98
98
  "access": "public"
99
99
  },
100
100
  "dependencies": {
101
- "@better-auth/mcp": "1.7.0-rc.2",
102
- "@better-auth/oauth-provider": "1.7.0-rc.2",
103
- "@better-auth/passkey": "1.7.0-rc.2",
104
- "@better-auth/scim": "1.7.0-rc.2",
101
+ "@better-auth/api-key": "1.7.1",
102
+ "@better-auth/mcp": "1.7.1",
103
+ "@better-auth/oauth-provider": "1.7.1",
104
+ "@better-auth/passkey": "1.7.1",
105
+ "@better-auth/scim": "1.7.1",
105
106
  "@lunora/errors": "1.0.0-alpha.22",
106
- "@lunora/server": "1.0.0-alpha.78",
107
+ "@lunora/server": "1.0.0-alpha.79",
107
108
  "@lunora/values": "1.0.0-alpha.27",
108
109
  "@visulima/disposable-email-domains": "1.1.0",
109
110
  "@visulima/email-verifier": "1.0.2",
@@ -111,9 +112,9 @@
111
112
  "@visulima/redact": "4.0.0"
112
113
  },
113
114
  "peerDependencies": {
114
- "@better-auth/core": ">=1.7.0-rc.2 <2.0.0-0",
115
- "@better-auth/sso": ">=1.7.0-rc.2 <2.0.0-0",
116
- "better-auth": ">=1.7.0-rc.2 <2.0.0-0"
115
+ "@better-auth/core": ">=1.7.1 <2.0.0-0",
116
+ "@better-auth/sso": ">=1.7.1 <2.0.0-0",
117
+ "better-auth": ">=1.7.1 <2.0.0-0"
117
118
  },
118
119
  "peerDependenciesMeta": {
119
120
  "@better-auth/sso": {