@lunora/auth 1.0.0-alpha.47 → 1.0.0-alpha.49

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.
@@ -0,0 +1 @@
1
+ import{sso as s}from"@better-auth/sso";export{s as sso};
@@ -1,5 +1,8 @@
1
+ export { mcp, mcpHandler, requireMcpAuth } from '@better-auth/mcp';
2
+ export { oauthProvider } from '@better-auth/oauth-provider';
1
3
  export { passkey } from '@better-auth/passkey';
2
- export { captcha, mcp, withMcpAuth } from 'better-auth/plugins';
4
+ export { scim } from '@better-auth/scim';
5
+ export { captcha } from 'better-auth/plugins';
3
6
  export { createAccessControl } from 'better-auth/plugins/access';
4
7
  export { admin } from 'better-auth/plugins/admin';
5
8
  export { anonymous } from 'better-auth/plugins/anonymous';
@@ -13,7 +16,6 @@ export { jwt } from 'better-auth/plugins/jwt';
13
16
  export { magicLink } from 'better-auth/plugins/magic-link';
14
17
  export { multiSession } from 'better-auth/plugins/multi-session';
15
18
  export { oAuthProxy } from 'better-auth/plugins/oauth-proxy';
16
- export { oidcProvider } from 'better-auth/plugins/oidc-provider';
17
19
  export { oneTimeToken } from 'better-auth/plugins/one-time-token';
18
20
  export { organization } from 'better-auth/plugins/organization';
19
21
  export { phoneNumber } from 'better-auth/plugins/phone-number';
package/dist/plugins.d.ts CHANGED
@@ -1,5 +1,8 @@
1
+ export { mcp, mcpHandler, requireMcpAuth } from '@better-auth/mcp';
2
+ export { oauthProvider } from '@better-auth/oauth-provider';
1
3
  export { passkey } from '@better-auth/passkey';
2
- export { captcha, mcp, withMcpAuth } from 'better-auth/plugins';
4
+ export { scim } from '@better-auth/scim';
5
+ export { captcha } from 'better-auth/plugins';
3
6
  export { createAccessControl } from 'better-auth/plugins/access';
4
7
  export { admin } from 'better-auth/plugins/admin';
5
8
  export { anonymous } from 'better-auth/plugins/anonymous';
@@ -13,7 +16,6 @@ export { jwt } from 'better-auth/plugins/jwt';
13
16
  export { magicLink } from 'better-auth/plugins/magic-link';
14
17
  export { multiSession } from 'better-auth/plugins/multi-session';
15
18
  export { oAuthProxy } from 'better-auth/plugins/oauth-proxy';
16
- export { oidcProvider } from 'better-auth/plugins/oidc-provider';
17
19
  export { oneTimeToken } from 'better-auth/plugins/one-time-token';
18
20
  export { organization } from 'better-auth/plugins/organization';
19
21
  export { phoneNumber } from 'better-auth/plugins/phone-number';
package/dist/plugins.mjs CHANGED
@@ -1 +1 @@
1
- import{passkey as e}from"@better-auth/passkey";import{captcha as m,mcp as p,withMcpAuth as x}from"better-auth/plugins";import{createAccessControl as i}from"better-auth/plugins/access";import{admin as a}from"better-auth/plugins/admin";import{anonymous as s}from"better-auth/plugins/anonymous";import{bearer as h}from"better-auth/plugins/bearer";import{customSession as w}from"better-auth/plugins/custom-session";import{deviceAuthorization as P}from"better-auth/plugins/device-authorization";import{emailOTP as k}from"better-auth/plugins/email-otp";import{genericOAuth as v}from"better-auth/plugins/generic-oauth";import{haveIBeenPwned as T}from"better-auth/plugins/haveibeenpwned";import{jwt as z}from"better-auth/plugins/jwt";import{magicLink as S}from"better-auth/plugins/magic-link";import{multiSession as B}from"better-auth/plugins/multi-session";import{oAuthProxy as F}from"better-auth/plugins/oauth-proxy";import{oidcProvider as L}from"better-auth/plugins/oidc-provider";import{oneTimeToken as N}from"better-auth/plugins/one-time-token";import{organization as D}from"better-auth/plugins/organization";import{phoneNumber as G}from"better-auth/plugins/phone-number";import{siwe as J}from"better-auth/plugins/siwe";import{twoFactor as Q}from"better-auth/plugins/two-factor";import{username as U}from"better-auth/plugins/username";export{a as admin,s as anonymous,h as bearer,m as captcha,i as createAccessControl,w as customSession,P as deviceAuthorization,k as emailOTP,v as genericOAuth,T as haveIBeenPwned,z as jwt,S as magicLink,p as mcp,B as multiSession,F as oAuthProxy,L as oidcProvider,N as oneTimeToken,D as organization,e as passkey,G as phoneNumber,J as siwe,Q as twoFactor,U as username,x as withMcpAuth};
1
+ import{mcp as e,mcpHandler as t,requireMcpAuth as m}from"@better-auth/mcp";import{oauthProvider as x}from"@better-auth/oauth-provider";import{passkey as i}from"@better-auth/passkey";import{scim as a}from"@better-auth/scim";import{captcha as s}from"better-auth/plugins";import{createAccessControl as h}from"better-auth/plugins/access";import{admin as A}from"better-auth/plugins/admin";import{anonymous as w}from"better-auth/plugins/anonymous";import{bearer as g}from"better-auth/plugins/bearer";import{customSession as v}from"better-auth/plugins/custom-session";import{deviceAuthorization as T}from"better-auth/plugins/device-authorization";import{emailOTP as z}from"better-auth/plugins/email-otp";import{genericOAuth as S}from"better-auth/plugins/generic-oauth";import{haveIBeenPwned as q}from"better-auth/plugins/haveibeenpwned";import{jwt as C}from"better-auth/plugins/jwt";import{magicLink as H}from"better-auth/plugins/magic-link";import{multiSession as L}from"better-auth/plugins/multi-session";import{oAuthProxy as N}from"better-auth/plugins/oauth-proxy";import{oneTimeToken as E}from"better-auth/plugins/one-time-token";import{organization as J}from"better-auth/plugins/organization";import{phoneNumber as Q}from"better-auth/plugins/phone-number";import{siwe as U}from"better-auth/plugins/siwe";import{twoFactor as W}from"better-auth/plugins/two-factor";import{username as Y}from"better-auth/plugins/username";export{A as admin,w as anonymous,g as bearer,s as captcha,h as createAccessControl,v as customSession,T as deviceAuthorization,z as emailOTP,S as genericOAuth,q as haveIBeenPwned,C as jwt,H as magicLink,e as mcp,t as mcpHandler,L as multiSession,N as oAuthProxy,x as oauthProvider,E as oneTimeToken,J as organization,i as passkey,Q as phoneNumber,m as requireMcpAuth,a as scim,U as siwe,W as twoFactor,Y as username};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/auth",
3
- "version": "1.0.0-alpha.47",
3
+ "version": "1.0.0-alpha.49",
4
4
  "description": "Auth for Lunora — a thin better-auth wrapper: email/password, OAuth, plugins, D1-backed",
5
5
  "keywords": [
6
6
  "auth",
@@ -48,6 +48,14 @@
48
48
  "types": "./dist/plugins-client.d.ts",
49
49
  "import": "./dist/plugins-client.mjs"
50
50
  },
51
+ "./plugins/enterprise": {
52
+ "types": "./dist/plugins-enterprise.d.ts",
53
+ "import": "./dist/plugins-enterprise.mjs"
54
+ },
55
+ "./plugins/enterprise/client": {
56
+ "types": "./dist/plugins-enterprise-client.d.ts",
57
+ "import": "./dist/plugins-enterprise-client.mjs"
58
+ },
51
59
  "./middleware": {
52
60
  "types": "./dist/middleware.d.ts",
53
61
  "import": "./dist/middleware.mjs"
@@ -90,15 +98,27 @@
90
98
  "access": "public"
91
99
  },
92
100
  "dependencies": {
93
- "@better-auth/passkey": "1.6.23",
101
+ "@better-auth/core": "1.7.0-rc.2",
102
+ "@better-auth/mcp": "1.7.0-rc.2",
103
+ "@better-auth/oauth-provider": "1.7.0-rc.2",
104
+ "@better-auth/passkey": "1.7.0-rc.2",
105
+ "@better-auth/scim": "1.7.0-rc.2",
94
106
  "@lunora/errors": "1.0.0-alpha.8",
95
- "@lunora/server": "1.0.0-alpha.41",
107
+ "@lunora/server": "1.0.0-alpha.43",
96
108
  "@lunora/values": "1.0.0-alpha.11",
97
109
  "@visulima/disposable-email-domains": "1.0.1",
98
110
  "@visulima/email-verifier": "1.0.1",
99
111
  "@visulima/free-email-domains": "1.0.0",
100
112
  "@visulima/redact": "3.0.0",
101
- "better-auth": "1.6.23"
113
+ "better-auth": "1.7.0-rc.2"
114
+ },
115
+ "peerDependencies": {
116
+ "@better-auth/sso": "1.7.0-rc.2"
117
+ },
118
+ "peerDependenciesMeta": {
119
+ "@better-auth/sso": {
120
+ "optional": true
121
+ }
102
122
  },
103
123
  "engines": {
104
124
  "node": "^22.15.0 || >=24.11.0"
@@ -1 +0,0 @@
1
- import{LunoraError as S}from"@lunora/errors";import{getAuthTables as A}from"better-auth/db";class p extends S{constructor(u,w){super(w,u,{name:"LunoraAuthAdminError"})}}const O=50,M=500,z=3600,R=z*24,D=100*365*24*60*60,U=2880*60*1e3,N=new Set(["accessToken","backupCodes","idToken","password","publicKey","refreshToken","secret","token"]),k=s=>Math.min(Math.max(Math.trunc(s??O),1),M),T=s=>Math.max(0,Math.trunc(s??0)),c=s=>{const u={};for(const[w,m]of Object.entries(s))N.has(w)||(u[w]=m instanceof Date?m.getTime():m);return u},I=s=>Array.isArray(s)?s.join(","):s,b=s=>s.toLowerCase().replaceAll(/[^\da-z]+/g,"-").replaceAll(/^-|-$/g,""),x=new Set(["banExpires","banned","banReason","createdAt","email","emailVerified","id","name","role","updatedAt"]),E={displayUsername:"username",phoneNumber:"phone-number",phoneNumberVerified:"phone-number",username:"username"},_=s=>s==="boolean"?"boolean":s==="date"?"date":s==="number"?"number":"string",L=s=>{const u=[];for(const[w,m]of Object.entries(s))m.input===!1||m.references!==void 0||x.has(w)||u.push({name:w,plugin:E[w],required:m.required===!0,type:_(m.type),unique:m.unique===!0});return u},P=s=>{if(s instanceof p)return s;const u=s,w=u?.body?.code??u?.code??"AUTH_ADMIN_ERROR",m=u?.body?.message??u?.message??"auth admin operation failed";return new p(m,w)},F=(s,u={})=>{const w=s.$context,m=u.features??{},y=e=>{const a=new Set((e.plugins??[]).map(i=>i.id)),t=i=>a.has(i);return{accounts:m.accounts??!0,admin:m.admin??t("admin"),organization:m.organization??t("organization"),passkey:m.passkey??t("passkey"),twoFactor:m.twoFactor??t("two-factor")}},r=async e=>{try{return await e(await w)}catch(a){throw P(a)}},h=e=>c(e),g=async(e,a,t)=>{const i=t.where&&t.where.length>0?t.where:void 0,[n,o]=await Promise.all([e.adapter.findMany({limit:k(t.limit),model:a,offset:T(t.offset),sortBy:t.sortBy,where:i}),e.adapter.count({model:a,where:i})]);return{rows:n.map(d=>c(d)),total:o}};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 p("expiresInSeconds must be a positive finite integer","INVALID_BAN_SECONDS");const d=Math.min(e,D);n=new Date(Date.now()+d*1e3)}const o=await i.internalAdapter.updateUser(t,{banExpires:n,banned:!0,banReason:a??"No reason"});return await i.internalAdapter.deleteUserSessions(t),h(o)}),cancelInvitation:({invitationId:e})=>r(async a=>{await a.adapter.delete({model:"invitation",where:[{field:"id",value:e}]})}),capabilities:()=>r(e=>Promise.resolve(y(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 c(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 c(i)}),config:()=>r(e=>{const a=e.options,t=y(a),i=new Set((a.plugins??[]).map(l=>l.id)),n=A(a),o=a.session??{},d=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((l,f)=>l.localeCompare(f)),rateLimit:{enabled:d.enabled??!1,max:d.max,window:d.window},session:{cookieCache:o.cookieCache?.enabled,expiresIn:o.expiresIn,freshAge:o.freshAge,updateAge:o.updateAge},socialProviders:Object.keys(a.socialProviders??{}).toSorted((l,f)=>l.localeCompare(f)),userFields:L(n.user?.fields??{})})}),createOrganization:({logo:e,metadata:a,name:t,ownerId:i,slug:n})=>r(async o=>{const d=b(n!==void 0&&n!==""?n:t);if(d==="")throw new p("could not derive a slug from the organization name","ORG_SLUG_INVALID");if(await o.adapter.findOne({model:"organization",where:[{field:"slug",value:d}]}))throw new p("an organization with this slug already exists","ORG_SLUG_TAKEN");const l=await o.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:d},model:"organization"});return i!==void 0&&i!==""&&await o.adapter.create({data:{createdAt:new Date,organizationId:l.id,role:"owner",userId:i},model:"member"}),c(l)}),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 c(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 c(i)}),deleteOrganization:({organizationId:e})=>r(async a=>{const t=A(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 o=a;if(o===void 0||o===""){const l=await n.adapter.findMany({model:"member",where:[{field:"organizationId",value:t}]});o=(l.find(f=>typeof f.role=="string"&&f.role.includes("owner"))??l[0])?.userId}if(o===void 0||o==="")throw new p("provide an inviter — the organization has no members to attribute the invitation to","INVITER_REQUIRED");const d=await n.adapter.create({data:{createdAt:new Date,email:e.toLowerCase(),expiresAt:new Date(Date.now()+U),inviterId:o,organizationId:t,role:i===void 0||i===""?"member":i,status:"pending"},model:"invitation"});return c(d)}),listOrgRoles:({limit:e,offset:a,organizationId:t})=>r(i=>g(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=>g(i,"teamMember",{limit:e,offset:a,where:[{field:"teamId",value:t}]})),listTeams:({limit:e,offset:a,organizationId:t})=>r(i=>g(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:I(a)},where:[{field:"id",value:e}]});return c(i??{id:e,role:I(a)})}),updateOrganization:({logo:e,metadata:a,name:t,organizationId:i,slug:n})=>r(async o=>{const d={};if(t!==void 0&&(d.name=t),n!==void 0&&n!==""&&(d.slug=b(n)),e!==void 0&&(d.logo=e===""?void 0:e),a!==void 0&&(d.metadata=JSON.stringify(a)),Object.keys(d).length===0)return c({id:i});const l=await o.adapter.update({model:"organization",update:d,where:[{field:"id",value:i}]});return c(l??{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 c(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 c(i??{id:a,name:e})}),createUser:({data:e,email:a,name:t,password:i,role:n})=>r(async o=>{const d=a.toLowerCase();if(await o.internalAdapter.findUserByEmail(d))throw new p("a user with this email already exists","USER_ALREADY_EXISTS");const l=await o.internalAdapter.createUser({email:d,name:t,role:n===void 0?void 0:I(n),...e});if(i!==void 0&&i!==""){const f=await o.password.hash(i);await o.internalAdapter.linkAccount({accountId:l.id,password:f,providerId:"credential",userId:l.id})}return h(l)}),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 p("user not found","USER_NOT_FOUND");const i=u.impersonationSeconds;let n=z;if(i!==void 0){if(!Number.isInteger(i)||!Number.isFinite(i)||i<=0)throw new p("impersonationSeconds must be a positive finite integer","INVALID_IMPERSONATION_SECONDS");n=Math.min(i,R)}const o=new Date(Date.now()+n*1e3),d=await a.internalAdapter.createSession(e,!0,{expiresAt:o,impersonatedBy:u.impersonatedBy??e},!0);return{expiresAt:d.expiresAt instanceof Date?d.expiresAt.getTime():o.getTime(),token:d.token,user:h(t)}}),listAccounts:({userId:e})=>r(async a=>(await a.adapter.findMany({model:"account",where:[{field:"userId",value:e}]})).map(t=>c(t))),listInvitations:({limit:e,offset:a,organizationId:t})=>r(i=>g(i,"invitation",{limit:e,offset:a,where:[{field:"organizationId",value:t}]})),listMembers:({limit:e,offset:a,organizationId:t})=>r(i=>g(i,"member",{limit:e,offset:a,sortBy:{direction:"desc",field:"createdAt"},where:[{field:"organizationId",value:t}]})),listOrganizations:({limit:e,offset:a})=>r(t=>g(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(t=>c(t))),listSessions:({limit:e,offset:a,userId:t})=>r(i=>g(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:o,sortBy:d,sortDirection:l})=>r(f=>{const v=[];return n!==void 0&&n!==""&&v.push({field:o??"email",operator:"contains",value:n}),a!==void 0&&v.push({field:e??"email",operator:"eq",value:a}),g(f,"user",{limit:t,offset:i,sortBy:{direction:l??"desc",field:d??"createdAt"},where:v})}),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:I(e)});return h(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 p(`password must be at least ${i.toString()} characters`,"PASSWORD_TOO_SHORT");if(e.length>n)throw new p(`password must be at most ${n.toString()} characters`,"PASSWORD_TOO_LONG");const o=await t.password.hash(e);await t.internalAdapter.updatePassword(a,o)}),unbanUser:({userId:e})=>r(async a=>{const t=await a.internalAdapter.updateUser(e,{banExpires:null,banned:!1,banReason:null});return h(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 h(i)})}};export{p as LunoraAuthAdminError,F as createAuthAdmin};
@@ -1 +0,0 @@
1
- import{getMigrations as e}from"better-auth/db/migration";import{resolveAuthOptions as s}from"./createAuth-DS6PL8Mb.mjs";const o=new WeakMap,g=async i=>{const{options:t}=i,n=o.get(t);if(n){await n;return}const r=(async()=>{const{runMigrations:a}=await e(t);await a()})();o.set(t,r);try{await r}catch(a){throw o.delete(t),a}},w=async i=>{const{compileMigrations:t}=await e(s(i));return t()};export{w as compileMigrationsSql,g as ensureMigrated};