@lunora/auth 1.0.0-alpha.14 → 1.0.0-alpha.141
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/LICENSE.md +38 -0
- package/README.md +99 -10
- package/dist/adapter.d.mts +4 -43
- package/dist/adapter.d.ts +4 -43
- package/dist/adapter.mjs +1 -48
- package/dist/audit.d.mts +131 -0
- package/dist/audit.d.ts +131 -0
- package/dist/audit.mjs +12 -0
- package/dist/email-guard.d.mts +127 -0
- package/dist/email-guard.d.ts +127 -0
- package/dist/email-guard.mjs +1 -0
- package/dist/index.d.mts +801 -157
- package/dist/index.d.ts +801 -157
- package/dist/index.mjs +1 -12
- package/dist/middleware.d.mts +167 -156
- package/dist/middleware.d.ts +167 -156
- package/dist/middleware.mjs +1 -53
- package/dist/packem_shared/AUTH_DO_AUDIT_PATH-th2-Hb30.mjs +1 -0
- package/dist/packem_shared/DEFAULT_AUTH_BASE_PATH-DneiLGpv.mjs +1 -0
- package/dist/packem_shared/LunoraAuthAdminError-4r29Kj_y.mjs +1 -0
- package/dist/packem_shared/adapter-CG0Yv85f.mjs +2 -0
- package/dist/packem_shared/adapter.d-BW_ovHul.d.mts +89 -0
- package/dist/packem_shared/adapter.d-BWw-tC_U.d.ts +89 -0
- package/dist/packem_shared/authAuditHook-C9Gt2iYp.mjs +1 -0
- package/dist/packem_shared/authDoColumnAdditions-UwF3Rl41.mjs +1 -0
- package/dist/packem_shared/compileMigrationsSql-Ds2snsWg.mjs +1 -0
- package/dist/packem_shared/create-auth.d-D1CKOFWc.d.mts +142 -0
- package/dist/packem_shared/create-auth.d-D1CKOFWc.d.ts +142 -0
- package/dist/packem_shared/createAuth-8aUw8v8D.mjs +1 -0
- package/dist/packem_shared/createDoAuthWiring-C8BRUjf6.mjs +1 -0
- package/dist/packem_shared/createLunoraAuthClient-DhjhCwmM.mjs +1 -0
- package/dist/packem_shared/createSignUpInvitation-ClvskwuB.mjs +1 -0
- package/dist/packem_shared/emailGateDatabaseHooks-CAygR3iq.mjs +1 -0
- package/dist/packem_shared/invite-only.d-CsPJWAwM.d.ts +126 -0
- package/dist/packem_shared/invite-only.d-DKyHHkkQ.d.mts +126 -0
- package/dist/packem_shared/legacyIssuerCleanupStatements-D9Kf8OD1.mjs +1 -0
- package/dist/packem_shared/on-cloudflare-edge-Dx6gFjBO.mjs +1 -0
- package/dist/packem_shared/quote-identifier-CGiYFBvY.mjs +1 -0
- package/dist/packem_shared/sessionPresets-C867Mlo4.mjs +1 -0
- package/dist/packem_shared/sql-store-CYa4HJsO.mjs +1 -0
- package/dist/packem_shared/uiConfig-B8pN6pks.mjs +1 -0
- package/dist/plugins-client.d.mts +165 -1
- package/dist/plugins-client.d.ts +165 -1
- package/dist/plugins-client.mjs +1 -2
- package/dist/plugins-enterprise-client.d.mts +15 -0
- package/dist/plugins-enterprise-client.d.ts +15 -0
- package/dist/plugins-enterprise-client.mjs +1 -0
- package/dist/plugins-enterprise.d.mts +1670 -0
- package/dist/plugins-enterprise.d.ts +1670 -0
- package/dist/plugins-enterprise.mjs +1 -0
- package/dist/plugins.d.mts +125 -2
- package/dist/plugins.d.ts +125 -2
- package/dist/plugins.mjs +1 -22
- package/dist/schema.d.mts +39 -39
- package/dist/schema.d.ts +39 -39
- package/dist/schema.mjs +1 -62
- package/dist/sql-store.d.mts +28 -28
- package/dist/sql-store.d.ts +28 -28
- package/dist/sql-store.mjs +1 -184
- package/dist/store.d.mts +65 -47
- package/dist/store.d.ts +65 -47
- package/dist/store.mjs +1 -183
- package/dist/turnstile-middleware.d.mts +73 -55
- package/dist/turnstile-middleware.d.ts +73 -55
- package/dist/turnstile-middleware.mjs +1 -45
- package/dist/turnstile.d.mts +42 -59
- package/dist/turnstile.d.ts +42 -59
- package/dist/turnstile.mjs +1 -61
- package/package.json +39 -5
- package/dist/packem_shared/DEFAULT_AUTH_BASE_PATH-DjcUWEQl.mjs +0 -11
- package/dist/packem_shared/LunoraAuthAdminError-BxrfEeA_.mjs +0 -249
- package/dist/packem_shared/compileMigrationsSql-cyE5U18R.mjs +0 -29
- package/dist/packem_shared/create-auth.d-Mwhb4gSc.d.mts +0 -128
- package/dist/packem_shared/create-auth.d-Mwhb4gSc.d.ts +0 -128
- package/dist/packem_shared/createAuth-hRGxUJ9w.mjs +0 -85
- package/dist/packem_shared/sessionPresets-Dwwd74_J.mjs +0 -38
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { BetterAuthPlugin } from 'better-auth';
|
|
2
|
+
import { L as LunoraAuth } from "./create-auth.d-D1CKOFWc.mjs";
|
|
3
|
+
/** One pending or spent sign-up invitation. */
|
|
4
|
+
interface SignUpInvitation {
|
|
5
|
+
/** When an account was created for this address; `null` while the invitation is unspent. */
|
|
6
|
+
acceptedAt: Date | null;
|
|
7
|
+
createdAt: Date;
|
|
8
|
+
/** The invited address, lowercased — the only thing an invitation is matched on. */
|
|
9
|
+
email: string;
|
|
10
|
+
expiresAt: Date;
|
|
11
|
+
id: string;
|
|
12
|
+
/** Free-form attribution (a user id, an operator name); never read by the gate. */
|
|
13
|
+
invitedBy: null | string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* What {@link createSignUpInvitation} hands back: the stored row plus the one
|
|
17
|
+
* and only sight of the plaintext `token`. Nothing reads it back afterwards —
|
|
18
|
+
* the database holds a SHA-256 of it — so an invitation link that is lost is
|
|
19
|
+
* reissued, not recovered.
|
|
20
|
+
*/
|
|
21
|
+
interface IssuedSignUpInvitation extends SignUpInvitation {
|
|
22
|
+
/** Put this in the sign-up link as `?invite=…`. Never stored, never logged, never listed. */
|
|
23
|
+
token: string;
|
|
24
|
+
}
|
|
25
|
+
/** Options for {@link inviteOnly}. */
|
|
26
|
+
interface InviteOnlyOptions {
|
|
27
|
+
/**
|
|
28
|
+
* Let the very first account through uninvited, so a fresh deployment can be
|
|
29
|
+
* bootstrapped without seeding a row.
|
|
30
|
+
*
|
|
31
|
+
* **Off by default.** The check is "the `user` table is empty", which two
|
|
32
|
+
* concurrent sign-ups can both observe, and the window it opens is the gap
|
|
33
|
+
* between deploying and the owner signing up — whoever finds the URL first
|
|
34
|
+
* gets an account on a deployment whose whole point is that nobody does. Seed
|
|
35
|
+
* the first invitation with {@link createSignUpInvitation} instead (a one-off
|
|
36
|
+
* call at worker init, or an internal mutation you run once).
|
|
37
|
+
* @default false
|
|
38
|
+
*/
|
|
39
|
+
allowFirstUser?: boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A better-auth server plugin that refuses to create an account for an address
|
|
43
|
+
* with no unspent invitation, and the `signUpInvitation` table those live in.
|
|
44
|
+
*
|
|
45
|
+
* Issue invitations with {@link createSignUpInvitation}; there is no HTTP
|
|
46
|
+
* endpoint for it on purpose. Who counts as an administrator is your
|
|
47
|
+
* application's question — call it from a mutation you already authorize, the
|
|
48
|
+
* same trust model `createAuthAdmin` documents.
|
|
49
|
+
*
|
|
50
|
+
* The return type is better-auth's own `BetterAuthPlugin` rather than the
|
|
51
|
+
* precise shape of the schema map, for the reason `./ui-config.ts` spells out:
|
|
52
|
+
* an anonymous inferred type is the difference between a build that emits
|
|
53
|
+
* declarations and one that fails in the bundler alone.
|
|
54
|
+
*/
|
|
55
|
+
declare const inviteOnly: (options?: InviteOnlyOptions) => BetterAuthPlugin;
|
|
56
|
+
/**
|
|
57
|
+
* Invite `email` to sign up, or refresh an existing invitation for it.
|
|
58
|
+
*
|
|
59
|
+
* Re-inviting an address updates the row in place — a new expiry, and `acceptedAt`
|
|
60
|
+
* cleared — because `email` is unique. That is also how you re-open a seat after
|
|
61
|
+
* deleting the account that took it.
|
|
62
|
+
*
|
|
63
|
+
* This is a trusted server-side call with no authorization of its own; gate it
|
|
64
|
+
* the way you gate any other administrative action. Delivering the invitation is
|
|
65
|
+
* yours too: nothing here sends mail, so the returned row is the whole handoff.
|
|
66
|
+
*
|
|
67
|
+
* Nothing prunes the table — a spent or expired row stays until you delete it with
|
|
68
|
+
* {@link revokeSignUpInvitation}, which is also what keeps it a record of who was
|
|
69
|
+
* let in.
|
|
70
|
+
*
|
|
71
|
+
* Each call mints a **new token** and returns it in the clear, once. Only its
|
|
72
|
+
* SHA-256 is stored, so re-inviting an address invalidates the previous link, and
|
|
73
|
+
* a link that was never delivered is reissued rather than looked up.
|
|
74
|
+
*/
|
|
75
|
+
declare const createSignUpInvitation: (auth: LunoraAuth, input: {
|
|
76
|
+
email: string;
|
|
77
|
+
expiresInSeconds?: number;
|
|
78
|
+
invitedBy?: string;
|
|
79
|
+
}) => Promise<IssuedSignUpInvitation>;
|
|
80
|
+
/**
|
|
81
|
+
* The most recent invitations, newest first, up to a fixed ceiling of
|
|
82
|
+
* {@link MAX_LISTED}. `pendingOnly` drops the spent and the expired, which is the
|
|
83
|
+
* list an operator usually wants; the unfiltered form doubles as the record of who
|
|
84
|
+
* was let in.
|
|
85
|
+
*
|
|
86
|
+
* Deliberately not paged. "Pending" is two conditions, one of them a comparison
|
|
87
|
+
* against `now`, and filtering those after a page would let page 1 come back empty
|
|
88
|
+
* while pending invitations sat on page 2. An operator list that outgrows the
|
|
89
|
+
* ceiling wants a query against the `signUpInvitation` table, not an offset.
|
|
90
|
+
*/
|
|
91
|
+
declare const listSignUpInvitations: (auth: LunoraAuth, options?: {
|
|
92
|
+
pendingOnly?: boolean;
|
|
93
|
+
}) => Promise<SignUpInvitation[]>;
|
|
94
|
+
/**
|
|
95
|
+
* Withdraw the invitation for `email`. Deletes the row, so it also forgets a spent
|
|
96
|
+
* one — the account it created is untouched, and removing that is
|
|
97
|
+
* `AuthAdmin.removeUser`'s job.
|
|
98
|
+
*
|
|
99
|
+
* Not retroactive, and not atomic against a sign-up already in flight: better-auth
|
|
100
|
+
* creates the user without wrapping the `before` hook and the insert in one
|
|
101
|
+
* transaction, so a revoke landing between the two lets that one account through.
|
|
102
|
+
* There is no conditional consume in the adapter contract to close it with. Treat
|
|
103
|
+
* revocation as "no further sign-ups", and `AuthAdmin.removeUser` as the way to
|
|
104
|
+
* undo one that already happened.
|
|
105
|
+
*/
|
|
106
|
+
declare const revokeSignUpInvitation: (auth: LunoraAuth, input: {
|
|
107
|
+
email: string;
|
|
108
|
+
}) => Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Delete invitations that expired without being used, and report how many went.
|
|
111
|
+
*
|
|
112
|
+
* Only the dead ones: a spent invitation is the record of who was let in, and an
|
|
113
|
+
* unexpired one is still live, so both stay. Nothing calls this for you — an app
|
|
114
|
+
* that invites at any volume should put it on a cron; one that doesn't can leave
|
|
115
|
+
* the rows.
|
|
116
|
+
*
|
|
117
|
+
* Bounded by `limit` and therefore incremental: a backlog larger than one pass
|
|
118
|
+
* takes several. It reads a page and deletes row by row rather than issuing one
|
|
119
|
+
* ranged `deleteMany`, because a `lt` comparison against a `date` column is the
|
|
120
|
+
* kind of thing that behaves differently on each of the three adapters this
|
|
121
|
+
* package ships, and a prune job is not where that should be discovered.
|
|
122
|
+
*/
|
|
123
|
+
declare const pruneSignUpInvitations: (auth: LunoraAuth, options?: {
|
|
124
|
+
limit?: number;
|
|
125
|
+
}) => Promise<number>;
|
|
126
|
+
export { InviteOnlyOptions as I, SignUpInvitation as S, IssuedSignUpInvitation as a, createSignUpInvitation as c, inviteOnly as i, listSignUpInvitations as l, pruneSignUpInvitations as p, revokeSignUpInvitation as r };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{q as r}from"./quote-identifier-CGiYFBvY.mjs";const i="issuer",c=new RegExp(String.raw`\b${i}\b`,"iu"),u=e=>{const s=e.indexOf("(");if(s===-1)return"";let n=0;for(let t=s;t<e.length;t+=1){const o=e[t];if(o==="(")n+=1;else if(o===")"&&(n-=1,n===0))return e.slice(s+1,t)}return""},f=e=>[...e].includes(i),p=e=>[...e].filter(s=>c.test(u(s.sql??""))).map(s=>s.name),l=(e="account",s=[])=>[...[...s].map(n=>`DROP INDEX IF EXISTS ${r(n)}`),`ALTER TABLE ${r(e)} DROP COLUMN ${r(i)}`];export{p as indexesReferencingIssuer,l as legacyIssuerCleanupStatements,f as schemaDeclaresIssuer};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const o=()=>globalThis.navigator?.userAgent==="Cloudflare-Workers";export{o};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const t=e=>`"${e.replaceAll('"','""')}"`;export{t as q};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const t=n=>{const o=["expiresIn","updateAge","freshAge"];for(const s of o){const e=n[s];if(e!==void 0&&(typeof e!="number"||!Number.isFinite(e)||e<0))throw new TypeError(`@lunora/auth: \`session.${s}\` must be a non-negative, finite number of seconds`)}return n},i={longLived:{cookieCache:{enabled:!0,maxAge:60},expiresIn:2592e3,freshAge:86400,updateAge:86400},rolling:{cookieCache:{enabled:!0,maxAge:60},expiresIn:604800,freshAge:86400,updateAge:86400},strict:{cookieCache:{enabled:!1},expiresIn:3600,freshAge:300,updateAge:900}};export{i as sessionPresets,t as validateSessionPolicy};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const T="_creationTime",l=s=>`"${s.replaceAll('"','""')}"`,N=/no such column|column .{0,64}? does not exist/iu,g={params:[],sql:"0"},R=(s,r)=>r?{column:`LOWER(${s})`,placeholder:"LOWER(?)"}:{column:s,placeholder:"?"},M=(s,r,a,c)=>{if(typeof r!="string")return g;const t=R(s,c);return a==="contains"?{params:[r],sql:`instr(${t.column}, ${t.placeholder}) > 0`}:a==="starts_with"?{params:[r],sql:`instr(${t.column}, ${t.placeholder}) = 1`}:{params:[r,r],sql:`substr(${t.column}, -length(?)) = ${t.placeholder}`}},h=(s,r,a,c)=>{if(r===null)return{params:[],sql:`${s} IS ${c?"NOT ":""}NULL`};const t=R(s,a),n=c?"<>":"=";return{params:[r],sql:`${t.column} ${n} ${t.placeholder}`}},O=(s,r,a,c)=>{const t=Array.isArray(r)?r:[];if(t.length===0)return{params:[],sql:a?"1":"0"};const n=R(s,c),e=t.map(()=>n.placeholder).join(", ");return{params:[...t],sql:`${n.column} ${a?"NOT IN":"IN"} (${e})`}},L=s=>{const r=l(s.field),{mode:a,operator:c,value:t}=s,n=a==="insensitive";switch(c){case"contains":case"ends_with":case"starts_with":return M(r,t,c,n);case"gt":return{params:[t],sql:`${r} > ?`};case"gte":return{params:[t],sql:`${r} >= ?`};case"in":return O(r,t,!1,n);case"lt":return{params:[t],sql:`${r} < ?`};case"lte":return{params:[t],sql:`${r} <= ?`};case"ne":return h(r,t,n,!0);case"not_in":return O(r,t,!0,n);default:return h(r,t,n,!1)}},d=(s,r)=>{if(s.length===0)return;const a=s.map(c=>L(c));return{params:a.flatMap(c=>c.params),sql:a.map(c=>`(${c.sql})`).join(` ${r} `)}},E=s=>{const r=[d(s.filter(a=>a.connector!=="OR"),"AND"),d(s.filter(a=>a.connector==="OR"),"OR")].filter(a=>a!==void 0);return r.length===0?{params:[],sql:""}:{params:r.flatMap(a=>a.params),sql:r.map(a=>`(${a.sql})`).join(" AND ")}},$=s=>s.sql?` WHERE ${s.sql}`:"",S=s=>{const r=(t,n)=>{const e=E(n);return s.all(`SELECT * FROM ${l(t)}${$(e)}`,e.params)},a=new Map,c=async t=>{const n=a.get(t);if(n!==void 0)return n;try{await s.all(`SELECT ${l(t)}.${l(T)} FROM ${l(t)} LIMIT 0`,[])}catch(e){return N.test(e instanceof Error?e.message:String(e))&&a.set(t,!1),!1}return a.set(t,!0),!0};return{consumeOne:async(t,n)=>{const e=E(n),o=l(t),[i]=await s.all(`DELETE FROM ${o} WHERE rowid IN (SELECT rowid FROM ${o}${$(e)} LIMIT 1) RETURNING *`,e.params);return i},count:async(t,n)=>{const e=E(n),[o]=await s.all(`SELECT COUNT(*) AS __count FROM ${l(t)}${$(e)}`,e.params);return Number(o?.__count??0)},create:async(t,n)=>{const e=T in n||!await c(t)?n:{[T]:Date.now(),...n},o=Object.keys(e),i=o.map(()=>"?").join(", "),u=`INSERT INTO ${l(t)} (${o.map(m=>l(m)).join(", ")}) VALUES (${i})`;return await s.run(u,o.map(m=>e[m])),{...n}},incrementOne:async(t,n,e,o)=>{const i=l(t),u=Object.keys(e),m=o?Object.keys(o):[],f=E(n);if(u.length===0&&m.length===0){const[p]=await s.all(`SELECT * FROM ${i}${$(f)} LIMIT 1`,f.params);return p}const I=[...u.map(p=>`${l(p)} = COALESCE(${l(p)}, 0) + ?`),...m.map(p=>`${l(p)} = ?`)].join(", "),[w]=await s.all(`UPDATE ${i} SET ${I} WHERE rowid IN (SELECT rowid FROM ${i}${$(f)} LIMIT 1) RETURNING *`,[...u.map(p=>e[p]),...m.map(p=>o[p]),...f.params]);return w},read:async(t,n)=>{const e=E(n.where),o=[...e.params];let i=`SELECT * FROM ${l(t)}${$(e)}`;return n.sortBy&&(i+=` ORDER BY ${l(n.sortBy.field)} ${n.sortBy.direction==="asc"?"ASC":"DESC"}`),n.limit!==void 0&&(i+=" LIMIT ?",o.push(Math.trunc(n.limit))),n.offset&&(i+=`${n.limit===void 0?" LIMIT -1":""} OFFSET ?`,o.push(Math.trunc(n.offset))),s.all(i,o)},remove:async(t,n)=>{const e=E(n);return(await s.all(`DELETE FROM ${l(t)}${$(e)} RETURNING *`,e.params)).length},update:async(t,n,e)=>{const o=Object.keys(e);if(o.length===0)return r(t,n);const i=o.map(m=>`${l(m)} = ?`).join(", "),u=E(n);return s.all(`UPDATE ${l(t)} SET ${i}${$(u)} RETURNING *`,[...o.map(m=>e[m]),...u.params])}}},C=s=>({all:async(r,a)=>(await s.prepare(r).bind(...a).all()).results??[],run:async(r,a)=>{await s.prepare(r).bind(...a).run()}});export{T as C,S as c,C as d};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createAuthEndpoint as c}from"better-auth/api";import{getAuthTables as g}from"better-auth/db";const l=e=>[...e].toSorted((o,i)=>o.localeCompare(i)),m=(e,o={})=>{const i=o.expose??{},a=new Set((e.plugins??[]).map(t=>t.id)),r=e.emailAndPassword?.enabled??!1,s=g(e),n=(e.plugins??[]).find(t=>t.id==="organization")?.options??{},d={allowUserToCreate:typeof n.allowUserToCreateOrganization=="function"?!0:n.allowUserToCreateOrganization!==!1,enabled:a.has("organization"),invitationLimit:n.invitationLimit,limit:n.organizationLimit,membershipLimit:n.membershipLimit,roles:!!s.organizationRole,teams:!!s.team};return{emailAndPassword:r,signUp:r&&e.emailAndPassword?.disableSignUp!==!0,...i.organization===!1?{}:{organization:d},...i.plugins===!1?{}:{plugins:l(a)},...i.socialProviders===!1?{}:{socialProviders:l(new Set([...Object.keys(e.socialProviders??{}),...o.extraProviders??[]]))}}},p=e=>c(e.path??"/ui-config",{metadata:{openapi:{description:"Public description of the enabled auth plugins and social providers.",responses:{200:{description:"The UI configuration."}}}},method:"GET"},o=>{const i=o;return Promise.resolve(i.json(m(i.context.options,e)))}),h=(e={})=>({endpoints:{getUiConfig:p(e)},id:"lunora-ui-config"});export{m as deriveUiConfig,h as uiConfig};
|
|
@@ -1,2 +1,166 @@
|
|
|
1
|
+
import { organizationClient } from 'better-auth/client/plugins';
|
|
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 { apiKeyClient } from '@better-auth/api-key/client';
|
|
4
|
+
export { oauthDeviceAuthorizationClient, oauthProviderClient } from '@better-auth/oauth-provider/client';
|
|
1
5
|
export { passkeyClient } from '@better-auth/passkey/client';
|
|
2
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Which client plugins to include. Each defaults to `false`.
|
|
8
|
+
*
|
|
9
|
+
* These are the same names `@lunora/auth-ui` gates its cards on, so one object
|
|
10
|
+
* can drive both `createLunoraAuthClient` and `registerAuthClientPlugins` — a
|
|
11
|
+
* flow the UI can show but this cannot install would be a card that renders and
|
|
12
|
+
* then fails at call time.
|
|
13
|
+
*
|
|
14
|
+
* `oneTap` is absent on purpose: Google One Tap needs a client id, not a
|
|
15
|
+
* boolean, so it comes in through {@link CreateLunoraAuthClientOptions.oneTapClientId}.
|
|
16
|
+
*/
|
|
17
|
+
interface LunoraAuthPluginToggles {
|
|
18
|
+
admin?: boolean;
|
|
19
|
+
anonymous?: boolean;
|
|
20
|
+
deviceAuthorization?: boolean;
|
|
21
|
+
emailOtp?: boolean;
|
|
22
|
+
lastLoginMethod?: boolean;
|
|
23
|
+
magicLink?: boolean;
|
|
24
|
+
multiSession?: boolean;
|
|
25
|
+
oauthProvider?: boolean;
|
|
26
|
+
organization?: boolean;
|
|
27
|
+
passkey?: boolean;
|
|
28
|
+
phoneNumber?: boolean;
|
|
29
|
+
twoFactor?: boolean;
|
|
30
|
+
username?: boolean;
|
|
31
|
+
}
|
|
32
|
+
type LunoraAuthClientPlugin = ReturnType<typeof organizationClient>;
|
|
33
|
+
declare const lunoraAuthPlugins: (toggles?: LunoraAuthPluginToggles) => LunoraAuthClientPlugin[];
|
|
34
|
+
/** Options for {@link createLunoraAuthClient}; anything else is forwarded to `createAuthClient`. */
|
|
35
|
+
interface CreateLunoraAuthClientOptions {
|
|
36
|
+
[option: string]: unknown;
|
|
37
|
+
/** Defaults to the current origin, which is right for a same-origin app. */
|
|
38
|
+
baseURL?: string;
|
|
39
|
+
/** Your own client plugins, appended after the standard set. */
|
|
40
|
+
extraPlugins?: LunoraAuthClientPlugin[];
|
|
41
|
+
/**
|
|
42
|
+
* Google OAuth client id. Setting it installs the One Tap client plugin —
|
|
43
|
+
* a boolean toggle can't, because the prompt is Google's and needs the id.
|
|
44
|
+
*/
|
|
45
|
+
oneTapClientId?: string;
|
|
46
|
+
/** Which standard client plugins to include. */
|
|
47
|
+
plugins?: LunoraAuthPluginToggles;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Build a better-auth client with Lunora's standard plugin set from toggles.
|
|
51
|
+
*
|
|
52
|
+
* You pass your framework's `createAuthClient` in — `better-auth/react`,
|
|
53
|
+
* `/vue`, `/svelte`, or `/solid` — because the variant has to match the UI
|
|
54
|
+
* framework, and a helper that picked for you would either guess wrong or drag
|
|
55
|
+
* every variant into your bundle.
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* import { createAuthClient } from "better-auth/react";
|
|
59
|
+
* import { createLunoraAuthClient } from "@lunora/auth/plugins/client";
|
|
60
|
+
*
|
|
61
|
+
* export const authClient = createLunoraAuthClient(createAuthClient, {
|
|
62
|
+
* plugins: { organization: true, passkey: true, twoFactor: true },
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* Reach for {@link lunoraAuthPlugins} instead when you want to own the
|
|
67
|
+
* `createAuthClient` call and only borrow the plugin array.
|
|
68
|
+
*/
|
|
69
|
+
declare const createLunoraAuthClient: <TClient>(createAuthClient: (options: Record<string, unknown>) => TClient, options?: CreateLunoraAuthClientOptions) => TClient;
|
|
70
|
+
export {
|
|
71
|
+
/**
|
|
72
|
+
* Client-side counterparts to the server plugins re-exported from
|
|
73
|
+
* `@lunora/auth/plugins`, surfaced under `@lunora/auth/plugins/client`.
|
|
74
|
+
*
|
|
75
|
+
* better-auth plugins come in two halves: a **server** plugin you pass to
|
|
76
|
+
* `betterAuth()` (re-exported from `@lunora/auth/plugins`) and a **client**
|
|
77
|
+
* plugin you pass to `createAuthClient()`. Both halves must be registered for a
|
|
78
|
+
* plugin's endpoints, inferred types, and client actions (e.g.
|
|
79
|
+
* `authClient.twoFactor.*`, `authClient.organization.*`, the `twoFactorRedirect`
|
|
80
|
+
* sign-in flow) to exist. This module is the client half so consumers don't have
|
|
81
|
+
* to reach into better-auth's `better-auth/client/plugins` subpath directly.
|
|
82
|
+
*
|
|
83
|
+
* # Wiring
|
|
84
|
+
*
|
|
85
|
+
* ```ts
|
|
86
|
+
* import { createAuthClient } from "better-auth/client"; // or a framework adapter
|
|
87
|
+
* import { organizationClient, twoFactorClient } from "@lunora/auth/plugins/client";
|
|
88
|
+
*
|
|
89
|
+
* export const authClient = createAuthClient({
|
|
90
|
+
* baseURL: import.meta.env.VITE_AUTH_URL,
|
|
91
|
+
* plugins: [
|
|
92
|
+
* organizationClient(),
|
|
93
|
+
* twoFactorClient({ onTwoFactorRedirect: () => location.assign("/2fa") }),
|
|
94
|
+
* ],
|
|
95
|
+
* });
|
|
96
|
+
* ```
|
|
97
|
+
*
|
|
98
|
+
* Keep the client plugin list in parity with the server `plugins` array passed
|
|
99
|
+
* to `createAuth`: a server plugin without its client counterpart leaves
|
|
100
|
+
* those actions untyped/unavailable, and vice-versa.
|
|
101
|
+
*/
|
|
102
|
+
type CreateLunoraAuthClientOptions,
|
|
103
|
+
/**
|
|
104
|
+
* Client-side counterparts to the server plugins re-exported from
|
|
105
|
+
* `@lunora/auth/plugins`, surfaced under `@lunora/auth/plugins/client`.
|
|
106
|
+
*
|
|
107
|
+
* better-auth plugins come in two halves: a **server** plugin you pass to
|
|
108
|
+
* `betterAuth()` (re-exported from `@lunora/auth/plugins`) and a **client**
|
|
109
|
+
* plugin you pass to `createAuthClient()`. Both halves must be registered for a
|
|
110
|
+
* plugin's endpoints, inferred types, and client actions (e.g.
|
|
111
|
+
* `authClient.twoFactor.*`, `authClient.organization.*`, the `twoFactorRedirect`
|
|
112
|
+
* sign-in flow) to exist. This module is the client half so consumers don't have
|
|
113
|
+
* to reach into better-auth's `better-auth/client/plugins` subpath directly.
|
|
114
|
+
*
|
|
115
|
+
* # Wiring
|
|
116
|
+
*
|
|
117
|
+
* ```ts
|
|
118
|
+
* import { createAuthClient } from "better-auth/client"; // or a framework adapter
|
|
119
|
+
* import { organizationClient, twoFactorClient } from "@lunora/auth/plugins/client";
|
|
120
|
+
*
|
|
121
|
+
* export const authClient = createAuthClient({
|
|
122
|
+
* baseURL: import.meta.env.VITE_AUTH_URL,
|
|
123
|
+
* plugins: [
|
|
124
|
+
* organizationClient(),
|
|
125
|
+
* twoFactorClient({ onTwoFactorRedirect: () => location.assign("/2fa") }),
|
|
126
|
+
* ],
|
|
127
|
+
* });
|
|
128
|
+
* ```
|
|
129
|
+
*
|
|
130
|
+
* Keep the client plugin list in parity with the server `plugins` array passed
|
|
131
|
+
* to `createAuth`: a server plugin without its client counterpart leaves
|
|
132
|
+
* those actions untyped/unavailable, and vice-versa.
|
|
133
|
+
*/
|
|
134
|
+
type LunoraAuthClientPlugin,
|
|
135
|
+
/**
|
|
136
|
+
* Client-side counterparts to the server plugins re-exported from
|
|
137
|
+
* `@lunora/auth/plugins`, surfaced under `@lunora/auth/plugins/client`.
|
|
138
|
+
*
|
|
139
|
+
* better-auth plugins come in two halves: a **server** plugin you pass to
|
|
140
|
+
* `betterAuth()` (re-exported from `@lunora/auth/plugins`) and a **client**
|
|
141
|
+
* plugin you pass to `createAuthClient()`. Both halves must be registered for a
|
|
142
|
+
* plugin's endpoints, inferred types, and client actions (e.g.
|
|
143
|
+
* `authClient.twoFactor.*`, `authClient.organization.*`, the `twoFactorRedirect`
|
|
144
|
+
* sign-in flow) to exist. This module is the client half so consumers don't have
|
|
145
|
+
* to reach into better-auth's `better-auth/client/plugins` subpath directly.
|
|
146
|
+
*
|
|
147
|
+
* # Wiring
|
|
148
|
+
*
|
|
149
|
+
* ```ts
|
|
150
|
+
* import { createAuthClient } from "better-auth/client"; // or a framework adapter
|
|
151
|
+
* import { organizationClient, twoFactorClient } from "@lunora/auth/plugins/client";
|
|
152
|
+
*
|
|
153
|
+
* export const authClient = createAuthClient({
|
|
154
|
+
* baseURL: import.meta.env.VITE_AUTH_URL,
|
|
155
|
+
* plugins: [
|
|
156
|
+
* organizationClient(),
|
|
157
|
+
* twoFactorClient({ onTwoFactorRedirect: () => location.assign("/2fa") }),
|
|
158
|
+
* ],
|
|
159
|
+
* });
|
|
160
|
+
* ```
|
|
161
|
+
*
|
|
162
|
+
* Keep the client plugin list in parity with the server `plugins` array passed
|
|
163
|
+
* to `createAuth`: a server plugin without its client counterpart leaves
|
|
164
|
+
* those actions untyped/unavailable, and vice-versa.
|
|
165
|
+
*/
|
|
166
|
+
type LunoraAuthPluginToggles, createLunoraAuthClient, lunoraAuthPlugins };
|
package/dist/plugins-client.d.ts
CHANGED
|
@@ -1,2 +1,166 @@
|
|
|
1
|
+
import { organizationClient } from 'better-auth/client/plugins';
|
|
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 { apiKeyClient } from '@better-auth/api-key/client';
|
|
4
|
+
export { oauthDeviceAuthorizationClient, oauthProviderClient } from '@better-auth/oauth-provider/client';
|
|
1
5
|
export { passkeyClient } from '@better-auth/passkey/client';
|
|
2
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Which client plugins to include. Each defaults to `false`.
|
|
8
|
+
*
|
|
9
|
+
* These are the same names `@lunora/auth-ui` gates its cards on, so one object
|
|
10
|
+
* can drive both `createLunoraAuthClient` and `registerAuthClientPlugins` — a
|
|
11
|
+
* flow the UI can show but this cannot install would be a card that renders and
|
|
12
|
+
* then fails at call time.
|
|
13
|
+
*
|
|
14
|
+
* `oneTap` is absent on purpose: Google One Tap needs a client id, not a
|
|
15
|
+
* boolean, so it comes in through {@link CreateLunoraAuthClientOptions.oneTapClientId}.
|
|
16
|
+
*/
|
|
17
|
+
interface LunoraAuthPluginToggles {
|
|
18
|
+
admin?: boolean;
|
|
19
|
+
anonymous?: boolean;
|
|
20
|
+
deviceAuthorization?: boolean;
|
|
21
|
+
emailOtp?: boolean;
|
|
22
|
+
lastLoginMethod?: boolean;
|
|
23
|
+
magicLink?: boolean;
|
|
24
|
+
multiSession?: boolean;
|
|
25
|
+
oauthProvider?: boolean;
|
|
26
|
+
organization?: boolean;
|
|
27
|
+
passkey?: boolean;
|
|
28
|
+
phoneNumber?: boolean;
|
|
29
|
+
twoFactor?: boolean;
|
|
30
|
+
username?: boolean;
|
|
31
|
+
}
|
|
32
|
+
type LunoraAuthClientPlugin = ReturnType<typeof organizationClient>;
|
|
33
|
+
declare const lunoraAuthPlugins: (toggles?: LunoraAuthPluginToggles) => LunoraAuthClientPlugin[];
|
|
34
|
+
/** Options for {@link createLunoraAuthClient}; anything else is forwarded to `createAuthClient`. */
|
|
35
|
+
interface CreateLunoraAuthClientOptions {
|
|
36
|
+
[option: string]: unknown;
|
|
37
|
+
/** Defaults to the current origin, which is right for a same-origin app. */
|
|
38
|
+
baseURL?: string;
|
|
39
|
+
/** Your own client plugins, appended after the standard set. */
|
|
40
|
+
extraPlugins?: LunoraAuthClientPlugin[];
|
|
41
|
+
/**
|
|
42
|
+
* Google OAuth client id. Setting it installs the One Tap client plugin —
|
|
43
|
+
* a boolean toggle can't, because the prompt is Google's and needs the id.
|
|
44
|
+
*/
|
|
45
|
+
oneTapClientId?: string;
|
|
46
|
+
/** Which standard client plugins to include. */
|
|
47
|
+
plugins?: LunoraAuthPluginToggles;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Build a better-auth client with Lunora's standard plugin set from toggles.
|
|
51
|
+
*
|
|
52
|
+
* You pass your framework's `createAuthClient` in — `better-auth/react`,
|
|
53
|
+
* `/vue`, `/svelte`, or `/solid` — because the variant has to match the UI
|
|
54
|
+
* framework, and a helper that picked for you would either guess wrong or drag
|
|
55
|
+
* every variant into your bundle.
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* import { createAuthClient } from "better-auth/react";
|
|
59
|
+
* import { createLunoraAuthClient } from "@lunora/auth/plugins/client";
|
|
60
|
+
*
|
|
61
|
+
* export const authClient = createLunoraAuthClient(createAuthClient, {
|
|
62
|
+
* plugins: { organization: true, passkey: true, twoFactor: true },
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* Reach for {@link lunoraAuthPlugins} instead when you want to own the
|
|
67
|
+
* `createAuthClient` call and only borrow the plugin array.
|
|
68
|
+
*/
|
|
69
|
+
declare const createLunoraAuthClient: <TClient>(createAuthClient: (options: Record<string, unknown>) => TClient, options?: CreateLunoraAuthClientOptions) => TClient;
|
|
70
|
+
export {
|
|
71
|
+
/**
|
|
72
|
+
* Client-side counterparts to the server plugins re-exported from
|
|
73
|
+
* `@lunora/auth/plugins`, surfaced under `@lunora/auth/plugins/client`.
|
|
74
|
+
*
|
|
75
|
+
* better-auth plugins come in two halves: a **server** plugin you pass to
|
|
76
|
+
* `betterAuth()` (re-exported from `@lunora/auth/plugins`) and a **client**
|
|
77
|
+
* plugin you pass to `createAuthClient()`. Both halves must be registered for a
|
|
78
|
+
* plugin's endpoints, inferred types, and client actions (e.g.
|
|
79
|
+
* `authClient.twoFactor.*`, `authClient.organization.*`, the `twoFactorRedirect`
|
|
80
|
+
* sign-in flow) to exist. This module is the client half so consumers don't have
|
|
81
|
+
* to reach into better-auth's `better-auth/client/plugins` subpath directly.
|
|
82
|
+
*
|
|
83
|
+
* # Wiring
|
|
84
|
+
*
|
|
85
|
+
* ```ts
|
|
86
|
+
* import { createAuthClient } from "better-auth/client"; // or a framework adapter
|
|
87
|
+
* import { organizationClient, twoFactorClient } from "@lunora/auth/plugins/client";
|
|
88
|
+
*
|
|
89
|
+
* export const authClient = createAuthClient({
|
|
90
|
+
* baseURL: import.meta.env.VITE_AUTH_URL,
|
|
91
|
+
* plugins: [
|
|
92
|
+
* organizationClient(),
|
|
93
|
+
* twoFactorClient({ onTwoFactorRedirect: () => location.assign("/2fa") }),
|
|
94
|
+
* ],
|
|
95
|
+
* });
|
|
96
|
+
* ```
|
|
97
|
+
*
|
|
98
|
+
* Keep the client plugin list in parity with the server `plugins` array passed
|
|
99
|
+
* to `createAuth`: a server plugin without its client counterpart leaves
|
|
100
|
+
* those actions untyped/unavailable, and vice-versa.
|
|
101
|
+
*/
|
|
102
|
+
type CreateLunoraAuthClientOptions,
|
|
103
|
+
/**
|
|
104
|
+
* Client-side counterparts to the server plugins re-exported from
|
|
105
|
+
* `@lunora/auth/plugins`, surfaced under `@lunora/auth/plugins/client`.
|
|
106
|
+
*
|
|
107
|
+
* better-auth plugins come in two halves: a **server** plugin you pass to
|
|
108
|
+
* `betterAuth()` (re-exported from `@lunora/auth/plugins`) and a **client**
|
|
109
|
+
* plugin you pass to `createAuthClient()`. Both halves must be registered for a
|
|
110
|
+
* plugin's endpoints, inferred types, and client actions (e.g.
|
|
111
|
+
* `authClient.twoFactor.*`, `authClient.organization.*`, the `twoFactorRedirect`
|
|
112
|
+
* sign-in flow) to exist. This module is the client half so consumers don't have
|
|
113
|
+
* to reach into better-auth's `better-auth/client/plugins` subpath directly.
|
|
114
|
+
*
|
|
115
|
+
* # Wiring
|
|
116
|
+
*
|
|
117
|
+
* ```ts
|
|
118
|
+
* import { createAuthClient } from "better-auth/client"; // or a framework adapter
|
|
119
|
+
* import { organizationClient, twoFactorClient } from "@lunora/auth/plugins/client";
|
|
120
|
+
*
|
|
121
|
+
* export const authClient = createAuthClient({
|
|
122
|
+
* baseURL: import.meta.env.VITE_AUTH_URL,
|
|
123
|
+
* plugins: [
|
|
124
|
+
* organizationClient(),
|
|
125
|
+
* twoFactorClient({ onTwoFactorRedirect: () => location.assign("/2fa") }),
|
|
126
|
+
* ],
|
|
127
|
+
* });
|
|
128
|
+
* ```
|
|
129
|
+
*
|
|
130
|
+
* Keep the client plugin list in parity with the server `plugins` array passed
|
|
131
|
+
* to `createAuth`: a server plugin without its client counterpart leaves
|
|
132
|
+
* those actions untyped/unavailable, and vice-versa.
|
|
133
|
+
*/
|
|
134
|
+
type LunoraAuthClientPlugin,
|
|
135
|
+
/**
|
|
136
|
+
* Client-side counterparts to the server plugins re-exported from
|
|
137
|
+
* `@lunora/auth/plugins`, surfaced under `@lunora/auth/plugins/client`.
|
|
138
|
+
*
|
|
139
|
+
* better-auth plugins come in two halves: a **server** plugin you pass to
|
|
140
|
+
* `betterAuth()` (re-exported from `@lunora/auth/plugins`) and a **client**
|
|
141
|
+
* plugin you pass to `createAuthClient()`. Both halves must be registered for a
|
|
142
|
+
* plugin's endpoints, inferred types, and client actions (e.g.
|
|
143
|
+
* `authClient.twoFactor.*`, `authClient.organization.*`, the `twoFactorRedirect`
|
|
144
|
+
* sign-in flow) to exist. This module is the client half so consumers don't have
|
|
145
|
+
* to reach into better-auth's `better-auth/client/plugins` subpath directly.
|
|
146
|
+
*
|
|
147
|
+
* # Wiring
|
|
148
|
+
*
|
|
149
|
+
* ```ts
|
|
150
|
+
* import { createAuthClient } from "better-auth/client"; // or a framework adapter
|
|
151
|
+
* import { organizationClient, twoFactorClient } from "@lunora/auth/plugins/client";
|
|
152
|
+
*
|
|
153
|
+
* export const authClient = createAuthClient({
|
|
154
|
+
* baseURL: import.meta.env.VITE_AUTH_URL,
|
|
155
|
+
* plugins: [
|
|
156
|
+
* organizationClient(),
|
|
157
|
+
* twoFactorClient({ onTwoFactorRedirect: () => location.assign("/2fa") }),
|
|
158
|
+
* ],
|
|
159
|
+
* });
|
|
160
|
+
* ```
|
|
161
|
+
*
|
|
162
|
+
* Keep the client plugin list in parity with the server `plugins` array passed
|
|
163
|
+
* to `createAuth`: a server plugin without its client counterpart leaves
|
|
164
|
+
* those actions untyped/unavailable, and vice-versa.
|
|
165
|
+
*/
|
|
166
|
+
type LunoraAuthPluginToggles, createLunoraAuthClient, lunoraAuthPlugins };
|
package/dist/plugins-client.mjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { adminClient, anonymousClient, customSessionClient, deviceAuthorizationClient, emailOTPClient, genericOAuthClient, inferAdditionalFields, inferOrgAdditionalFields, jwtClient, lastLoginMethodClient, magicLinkClient, multiSessionClient, oidcClient, oneTimeTokenClient, organizationClient, phoneNumberClient, siweClient, twoFactorClient, usernameClient } from 'better-auth/client/plugins';
|
|
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};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ssoClient } from '@better-auth/sso/client';
|
|
2
|
+
export type {
|
|
3
|
+
/**
|
|
4
|
+
* Adds `authClient.signIn.sso({ email | domain | providerId })`. Registering the
|
|
5
|
+
* server `sso` plugin without this leaves those actions unavailable and untyped.
|
|
6
|
+
* @experimental
|
|
7
|
+
*/
|
|
8
|
+
ssoClient } from '@better-auth/sso/client';
|
|
9
|
+
/**
|
|
10
|
+
* The plugin instance `ssoClient()` returns. Exported so an app can type the array it
|
|
11
|
+
* passes to `createAuthClient` when it assembles plugins conditionally.
|
|
12
|
+
* @experimental
|
|
13
|
+
*/
|
|
14
|
+
type SSOClientPlugin = ReturnType<typeof ssoClient>;
|
|
15
|
+
export { SSOClientPlugin };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ssoClient } from '@better-auth/sso/client';
|
|
2
|
+
export type {
|
|
3
|
+
/**
|
|
4
|
+
* Adds `authClient.signIn.sso({ email | domain | providerId })`. Registering the
|
|
5
|
+
* server `sso` plugin without this leaves those actions unavailable and untyped.
|
|
6
|
+
* @experimental
|
|
7
|
+
*/
|
|
8
|
+
ssoClient } from '@better-auth/sso/client';
|
|
9
|
+
/**
|
|
10
|
+
* The plugin instance `ssoClient()` returns. Exported so an app can type the array it
|
|
11
|
+
* passes to `createAuthClient` when it assembles plugins conditionally.
|
|
12
|
+
* @experimental
|
|
13
|
+
*/
|
|
14
|
+
type SSOClientPlugin = ReturnType<typeof ssoClient>;
|
|
15
|
+
export { SSOClientPlugin };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ssoClient as r}from"@better-auth/sso/client";export{r as ssoClient};
|