@lunora/auth 1.0.0-alpha.87 → 1.0.0-alpha.89
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 +1 -1
- package/dist/index.d.mts +12 -8
- package/dist/index.d.ts +12 -8
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/{LunoraAuthAdminError-C20JtTqI.mjs → LunoraAuthAdminError-gdM6RSXW.mjs} +1 -1
- package/dist/plugins-client.d.mts +2 -1
- package/dist/plugins-client.d.ts +2 -1
- package/dist/plugins-client.mjs +1 -1
- package/dist/plugins-enterprise.d.mts +130 -59
- package/dist/plugins-enterprise.d.ts +130 -59
- package/dist/plugins.d.mts +4 -3
- package/dist/plugins.d.ts +4 -3
- package/dist/plugins.mjs +1 -1
- package/package.json +10 -9
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`, `
|
|
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/*`
|
|
566
|
-
*
|
|
567
|
-
*
|
|
568
|
-
*
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
*
|
|
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/*`
|
|
566
|
-
*
|
|
567
|
-
*
|
|
568
|
-
*
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
*
|
|
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-
|
|
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};
|
package/dist/packem_shared/{LunoraAuthAdminError-C20JtTqI.mjs → LunoraAuthAdminError-gdM6RSXW.mjs}
RENAMED
|
@@ -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 {
|
|
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`.
|
package/dist/plugins-client.d.ts
CHANGED
|
@@ -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 {
|
|
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`.
|
package/dist/plugins-client.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLunoraAuthClient as
|
|
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,
|
|
144
|
-
* advertises `WantAssertionsSigned="true"` and
|
|
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
|
-
/**
|
|
210
|
-
|
|
211
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
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
|
-
*
|
|
235
|
-
*
|
|
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) =>
|
|
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: (
|
|
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) =>
|
|
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: (
|
|
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) =>
|
|
762
|
+
declare const listSSOProviders: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/providers", {
|
|
692
763
|
method: "GET";
|
|
693
|
-
use: (
|
|
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) =>
|
|
833
|
+
declare const getSSOProvider: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/get-provider", {
|
|
763
834
|
method: "GET";
|
|
764
|
-
use: (
|
|
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) =>
|
|
911
|
+
declare const updateSSOProvider: (options: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/update-provider", {
|
|
841
912
|
method: "POST";
|
|
842
|
-
use: (
|
|
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
|
-
|
|
898
|
-
|
|
899
|
-
|
|
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: () =>
|
|
1067
|
+
declare const deleteSSOProvider: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/delete-provider", {
|
|
997
1068
|
method: "POST";
|
|
998
|
-
use: (
|
|
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) =>
|
|
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) =>
|
|
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: (
|
|
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) =>
|
|
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) =>
|
|
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) =>
|
|
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) =>
|
|
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) =>
|
|
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) =>
|
|
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: (
|
|
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,
|
|
144
|
-
* advertises `WantAssertionsSigned="true"` and
|
|
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
|
-
/**
|
|
210
|
-
|
|
211
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
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
|
-
*
|
|
235
|
-
*
|
|
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) =>
|
|
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: (
|
|
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) =>
|
|
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: (
|
|
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) =>
|
|
762
|
+
declare const listSSOProviders: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/providers", {
|
|
692
763
|
method: "GET";
|
|
693
|
-
use: (
|
|
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) =>
|
|
833
|
+
declare const getSSOProvider: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/get-provider", {
|
|
763
834
|
method: "GET";
|
|
764
|
-
use: (
|
|
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) =>
|
|
911
|
+
declare const updateSSOProvider: (options: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/update-provider", {
|
|
841
912
|
method: "POST";
|
|
842
|
-
use: (
|
|
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
|
-
|
|
898
|
-
|
|
899
|
-
|
|
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: () =>
|
|
1067
|
+
declare const deleteSSOProvider: (options?: SSOOptions) => _$better_call0.StrictEndpoint<"/sso/delete-provider", {
|
|
997
1068
|
method: "POST";
|
|
998
|
-
use: (
|
|
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) =>
|
|
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) =>
|
|
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: (
|
|
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) =>
|
|
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) =>
|
|
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) =>
|
|
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) =>
|
|
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) =>
|
|
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) =>
|
|
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: (
|
|
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
|
};
|
package/dist/plugins.d.mts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { BetterAuthPlugin } from 'better-auth';
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
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 {
|
|
3
|
-
export {
|
|
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{
|
|
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.
|
|
3
|
+
"version": "1.0.0-alpha.89",
|
|
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/
|
|
102
|
-
"@better-auth/
|
|
103
|
-
"@better-auth/
|
|
104
|
-
"@better-auth/
|
|
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.
|
|
107
|
+
"@lunora/server": "1.0.0-alpha.80",
|
|
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.
|
|
115
|
-
"@better-auth/sso": ">=1.7.
|
|
116
|
-
"better-auth": ">=1.7.
|
|
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": {
|