@ingram-tech/nk-auth 0.4.1 → 0.5.0
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 +65 -0
- package/dist/middleware.d.ts +20 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +60 -0
- package/dist/middleware.js.map +1 -0
- package/dist/server.d.ts +24 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +58 -0
- package/dist/server.js.map +1 -0
- package/package.json +14 -1
package/README.md
CHANGED
|
@@ -17,6 +17,8 @@ only what you need from focused subpaths.
|
|
|
17
17
|
| `createAuthPool` (`./pool`) | `pg` Pool with optional SSL CA verification |
|
|
18
18
|
| `bcryptPassword`, `makeEmailSenders`, `makePasskeyOptions`, `uuidGenerateId` (`./`) | password migration, email hooks, passkeys, UUID ids |
|
|
19
19
|
| `createServerSupabase` (`./`) | RLS-aware supabase-js client (attaches the session JWT) |
|
|
20
|
+
| `createAuthHelpers` (`./server`) | validated App Router session helpers: `getSession` / `getUser` / `requireUser` / `redirectIfAuthenticated` |
|
|
21
|
+
| `createAuthMiddleware` (`./middleware`) | loop-safe edge middleware that only gates *unauthenticated* users off protected paths |
|
|
20
22
|
|
|
21
23
|
> **Supabase Auth → Better Auth + RLS migration?** Read
|
|
22
24
|
> [`docs/better-auth-migration.md`](../../docs/better-auth-migration.md) — the
|
|
@@ -176,6 +178,69 @@ export const authClient = createAuthClient({
|
|
|
176
178
|
// authClient.signIn.email(...), signIn.social(...), useSession(), passkey.*
|
|
177
179
|
```
|
|
178
180
|
|
|
181
|
+
## 5. Gate routes (without the redirect loop)
|
|
182
|
+
|
|
183
|
+
Two layers, **one rule that keeps them from fighting**: only the *validated*
|
|
184
|
+
layer may redirect a request *away from* the sign-in page.
|
|
185
|
+
|
|
186
|
+
The validated layer (server helpers) — bind once to your instance:
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
// lib/auth/session.ts
|
|
190
|
+
import { createAuthHelpers } from "@ingram-tech/nk-auth/server";
|
|
191
|
+
import { auth } from "@/lib/auth";
|
|
192
|
+
|
|
193
|
+
export const { getSession, getUser, requireUser, redirectIfAuthenticated } =
|
|
194
|
+
createAuthHelpers(auth);
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
```tsx
|
|
198
|
+
// app/dashboard/page.tsx — gate a protected page (validated, DB-backed).
|
|
199
|
+
import { requireUser } from "@/lib/auth/session";
|
|
200
|
+
export default async function Dashboard() {
|
|
201
|
+
const user = await requireUser(); // -> /login when signed out
|
|
202
|
+
return <main>Hi {user.email}</main>;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// app/login/page.tsx — gate the sign-in page HERE, never in middleware.
|
|
206
|
+
import { redirectIfAuthenticated } from "@/lib/auth/session";
|
|
207
|
+
import { LoginForm } from "./login-form";
|
|
208
|
+
export default async function Login() {
|
|
209
|
+
await redirectIfAuthenticated("/dashboard"); // validated: a stale cookie
|
|
210
|
+
return <LoginForm />; // resolves to "signed out" and falls through to the form
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
The optimistic layer (middleware) is a fast edge short-circuit on cookie
|
|
215
|
+
*presence*. It can save a render for users with no cookie at all — but it must
|
|
216
|
+
never decide the sign-in page, because a present-but-invalid cookie there is
|
|
217
|
+
exactly what loops. `createAuthMiddleware` enforces that **at construction**: it
|
|
218
|
+
throws if you try to protect or front-door the sign-in path.
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
// middleware.ts
|
|
222
|
+
import { createAuthMiddleware } from "@ingram-tech/nk-auth/middleware";
|
|
223
|
+
|
|
224
|
+
export const middleware = createAuthMiddleware({
|
|
225
|
+
protectedPaths: ["/dashboard", "/memory"], // cookie-less -> signInPath
|
|
226
|
+
signInPath: "/login",
|
|
227
|
+
frontDoorPaths: ["/"], // optional: cookie-bearing "/" -> signedInRedirect
|
|
228
|
+
signedInRedirect: "/dashboard",
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
export const config = {
|
|
232
|
+
matcher: ["/((?!_next/static|_next/image|favicon.ico|.*\\.svg).*)"],
|
|
233
|
+
};
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Why the split: middleware runs before render and can't afford a DB lookup, so it
|
|
237
|
+
can only trust the cookie *exists*. The server helpers hit `auth.api.getSession`
|
|
238
|
+
and check the session *contents*. When those disagree (revoked session, rotated
|
|
239
|
+
secret, wiped DB) the validated layer wins and parks the user on `/login` — and
|
|
240
|
+
because middleware refuses to bounce `/login`, the form renders instead of
|
|
241
|
+
ping-ponging. Middleware is optional; sites that prefer one source of truth can
|
|
242
|
+
use the server helpers alone.
|
|
243
|
+
|
|
179
244
|
## RLS bridge (the important part)
|
|
180
245
|
|
|
181
246
|
`auth.uid()` reads the `sub` claim of the JWT PostgREST receives. The `jwt`
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type NextRequest, NextResponse } from "next/server";
|
|
2
|
+
export interface AuthMiddlewareConfig {
|
|
3
|
+
/**
|
|
4
|
+
* Path prefixes that require a session. A request without a session cookie
|
|
5
|
+
* to any of these is redirected to `signInPath`. Matched with `startsWith`.
|
|
6
|
+
*/
|
|
7
|
+
protectedPaths: string[];
|
|
8
|
+
/** Where unauthenticated users are sent. Default `/login`. */
|
|
9
|
+
signInPath?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Optional front-door redirect: when a session cookie is present and the
|
|
12
|
+
* path *exactly* equals one of these, redirect to `signedInRedirect`. Safe
|
|
13
|
+
* because it never targets the sign-in path. Typically `["/"]`.
|
|
14
|
+
*/
|
|
15
|
+
frontDoorPaths?: string[];
|
|
16
|
+
/** Destination for the front-door redirect. Required when `frontDoorPaths` is set. */
|
|
17
|
+
signedInRedirect?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function createAuthMiddleware(config: AuthMiddlewareConfig): (request: NextRequest) => NextResponse;
|
|
20
|
+
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,KAAK,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE7D,MAAM,WAAW,oBAAoB;IACpC;;;OAGG;IACH,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,sFAAsF;IACtF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,IAwBrC,SAAS,WAAW,KAAG,YAAY,CAyB9D"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A loop-safe Next.js auth middleware factory, at
|
|
3
|
+
* "@ingram-tech/nk-auth/middleware". Middleware runs at the edge before a route
|
|
4
|
+
* renders, so it can only afford an **optimistic** check — the presence of a
|
|
5
|
+
* session cookie (`getSessionCookie`), not a database-validated session.
|
|
6
|
+
*
|
|
7
|
+
* That optimism is exactly what makes naive auth middleware loop. The validated
|
|
8
|
+
* server guard (see "@ingram-tech/nk-auth/server") sends an invalid-but-present
|
|
9
|
+
* session to the sign-in page; if the optimistic layer then bounces the sign-in
|
|
10
|
+
* page back ("you have a cookie, go to the app"), a stale cookie ping-pongs
|
|
11
|
+
* forever — and an RSC render can't clear the cookie to break out.
|
|
12
|
+
*
|
|
13
|
+
* So this factory enforces the one safe invariant *at construction*:
|
|
14
|
+
*
|
|
15
|
+
* The sign-in path is never the target of an optimistic redirect.
|
|
16
|
+
*
|
|
17
|
+
* It will only ever (a) push *cookie-less* requests off `protectedPaths`, and
|
|
18
|
+
* optionally (b) push *cookie-bearing* requests off a front door to the app. It
|
|
19
|
+
* refuses to protect or front-door the sign-in path, because either would
|
|
20
|
+
* reintroduce the loop. Sending a *signed-in* user away from /login is the job
|
|
21
|
+
* of `redirectIfAuthenticated` in the server helpers, which validates first.
|
|
22
|
+
*/
|
|
23
|
+
import { getSessionCookie } from "better-auth/cookies";
|
|
24
|
+
import { NextResponse } from "next/server";
|
|
25
|
+
export function createAuthMiddleware(config) {
|
|
26
|
+
const signInPath = config.signInPath ?? "/login";
|
|
27
|
+
const frontDoorPaths = config.frontDoorPaths ?? [];
|
|
28
|
+
// Loop-safety, enforced once at construction rather than hoped-for per
|
|
29
|
+
// request. The sign-in path is where the validated guard parks an
|
|
30
|
+
// invalid-but-present session; it must never be the target of an optimistic
|
|
31
|
+
// redirect, or a stale cookie loops.
|
|
32
|
+
if (config.protectedPaths.some((p) => signInPath.startsWith(p))) {
|
|
33
|
+
throw new Error(`@ingram-tech/nk-auth: signInPath "${signInPath}" must not fall under protectedPaths — a cookie-less visit would redirect to itself forever.`);
|
|
34
|
+
}
|
|
35
|
+
if (frontDoorPaths.includes(signInPath)) {
|
|
36
|
+
throw new Error(`@ingram-tech/nk-auth: signInPath "${signInPath}" must not be a frontDoorPath — it would reintroduce the stale-cookie redirect loop.`);
|
|
37
|
+
}
|
|
38
|
+
if (frontDoorPaths.length > 0 && !config.signedInRedirect) {
|
|
39
|
+
throw new Error("@ingram-tech/nk-auth: signedInRedirect is required when frontDoorPaths is set.");
|
|
40
|
+
}
|
|
41
|
+
return function middleware(request) {
|
|
42
|
+
const hasSessionCookie = !!getSessionCookie(request);
|
|
43
|
+
const path = request.nextUrl.pathname;
|
|
44
|
+
if (!hasSessionCookie &&
|
|
45
|
+
config.protectedPaths.some((p) => path.startsWith(p))) {
|
|
46
|
+
const url = request.nextUrl.clone();
|
|
47
|
+
url.pathname = signInPath;
|
|
48
|
+
return NextResponse.redirect(url);
|
|
49
|
+
}
|
|
50
|
+
if (hasSessionCookie &&
|
|
51
|
+
config.signedInRedirect &&
|
|
52
|
+
frontDoorPaths.includes(path)) {
|
|
53
|
+
const url = request.nextUrl.clone();
|
|
54
|
+
url.pathname = config.signedInRedirect;
|
|
55
|
+
return NextResponse.redirect(url);
|
|
56
|
+
}
|
|
57
|
+
return NextResponse.next();
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAoB,YAAY,EAAE,MAAM,aAAa,CAAC;AAoB7D,MAAM,UAAU,oBAAoB,CAAC,MAA4B;IAChE,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,QAAQ,CAAC;IACjD,MAAM,cAAc,GAAG,MAAM,CAAC,cAAc,IAAI,EAAE,CAAC;IAEnD,uEAAuE;IACvE,kEAAkE;IAClE,4EAA4E;IAC5E,qCAAqC;IACrC,IAAI,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CACd,qCAAqC,UAAU,8FAA8F,CAC7I,CAAC;IACH,CAAC;IACD,IAAI,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CACd,qCAAqC,UAAU,sFAAsF,CACrI,CAAC;IACH,CAAC;IACD,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CACd,gFAAgF,CAChF,CAAC;IACH,CAAC;IAED,OAAO,SAAS,UAAU,CAAC,OAAoB;QAC9C,MAAM,gBAAgB,GAAG,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACrD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC;QAEtC,IACC,CAAC,gBAAgB;YACjB,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EACpD,CAAC;YACF,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACpC,GAAG,CAAC,QAAQ,GAAG,UAAU,CAAC;YAC1B,OAAO,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACnC,CAAC;QAED,IACC,gBAAgB;YAChB,MAAM,CAAC,gBAAgB;YACvB,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC5B,CAAC;YACF,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACpC,GAAG,CAAC,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CAAC;YACvC,OAAO,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,YAAY,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC,CAAC;AACH,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** The shape we need from a session: anything carrying a `user`. */
|
|
2
|
+
interface SessionLike {
|
|
3
|
+
user: unknown;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* The slice of a Better Auth instance these helpers touch. Generic over the
|
|
7
|
+
* site's session type `S`, so `getSession`/`getUser` return the site's fully
|
|
8
|
+
* inferred user shape (additional fields, org id, …) — no `any`, no casts.
|
|
9
|
+
*/
|
|
10
|
+
interface AuthLike<S extends SessionLike> {
|
|
11
|
+
api: {
|
|
12
|
+
getSession: (input: {
|
|
13
|
+
headers: Headers;
|
|
14
|
+
}) => Promise<S | null>;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export declare function createAuthHelpers<S extends SessionLike>(auth: AuthLike<S>): {
|
|
18
|
+
getSession: () => Promise<S | null>;
|
|
19
|
+
getUser: () => Promise<S["user"] | null>;
|
|
20
|
+
requireUser: (redirectTo?: string) => Promise<S["user"]>;
|
|
21
|
+
redirectIfAuthenticated: (to: string) => Promise<void>;
|
|
22
|
+
};
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAwBA,oEAAoE;AACpE,UAAU,WAAW;IACpB,IAAI,EAAE,OAAO,CAAC;CACd;AAED;;;;GAIG;AACH,UAAU,QAAQ,CAAC,CAAC,SAAS,WAAW;IACvC,GAAG,EAAE;QACJ,UAAU,EAAE,CAAC,KAAK,EAAE;YAAE,OAAO,EAAE,OAAO,CAAA;SAAE,KAAK,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;KAC/D,CAAC;CACF;AAED,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,WAAW,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;sBAE5C,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;mBAKpB,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;0CAUA,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;kCAa1B,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;EAKjE"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side session helpers for the App Router, at
|
|
3
|
+
* "@ingram-tech/nk-auth/server" so the framework-agnostic core entry never
|
|
4
|
+
* pulls in `next`. A site binds these once to its own Better Auth instance:
|
|
5
|
+
*
|
|
6
|
+
* // lib/auth/session.ts
|
|
7
|
+
* import { createAuthHelpers } from "@ingram-tech/nk-auth/server";
|
|
8
|
+
* import { auth } from "@/lib/auth";
|
|
9
|
+
*
|
|
10
|
+
* export const { getSession, getUser, requireUser, redirectIfAuthenticated } =
|
|
11
|
+
* createAuthHelpers(auth);
|
|
12
|
+
*
|
|
13
|
+
* These are the **validated** authority: every call hits `auth.api.getSession`,
|
|
14
|
+
* which checks the session against the database — not merely the presence of a
|
|
15
|
+
* cookie. That distinction is the whole point. The optimistic, cookie-presence
|
|
16
|
+
* check belongs in middleware (see "@ingram-tech/nk-auth/middleware"); it may
|
|
17
|
+
* only ever push *unauthenticated* users off protected routes. The decision to
|
|
18
|
+
* send a signed-in user *away* from the sign-in page must run through
|
|
19
|
+
* `redirectIfAuthenticated` here, so a stale or revoked cookie resolves to "no
|
|
20
|
+
* session" and falls through to the form instead of ping-ponging forever.
|
|
21
|
+
*/
|
|
22
|
+
import { headers } from "next/headers";
|
|
23
|
+
import { redirect } from "next/navigation";
|
|
24
|
+
export function createAuthHelpers(auth) {
|
|
25
|
+
/** The validated session ({ user, session, … }) or null. */
|
|
26
|
+
async function getSession() {
|
|
27
|
+
return auth.api.getSession({ headers: await headers() });
|
|
28
|
+
}
|
|
29
|
+
/** The authenticated user, or null. */
|
|
30
|
+
async function getUser() {
|
|
31
|
+
const session = await getSession();
|
|
32
|
+
return session?.user ?? null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Require a signed-in user or redirect. Returns the user (non-null) so
|
|
36
|
+
* callers keep their `const user = await requireUser()` shape. `redirect()`
|
|
37
|
+
* throws, so control never returns when signed out.
|
|
38
|
+
*/
|
|
39
|
+
async function requireUser(redirectTo = "/login") {
|
|
40
|
+
const user = await getUser();
|
|
41
|
+
// redirect() is typed `never`, so `user` narrows to non-null below.
|
|
42
|
+
if (!user)
|
|
43
|
+
redirect(redirectTo);
|
|
44
|
+
return user;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Redirect an already-signed-in user away (e.g. /login -> /dashboard). This
|
|
48
|
+
* is the *correct* place to gate the sign-in page: because it validates the
|
|
49
|
+
* session, a present-but-invalid cookie is treated as signed-out and the
|
|
50
|
+
* page renders instead of looping. Never do this in middleware.
|
|
51
|
+
*/
|
|
52
|
+
async function redirectIfAuthenticated(to) {
|
|
53
|
+
if (await getSession())
|
|
54
|
+
redirect(to);
|
|
55
|
+
}
|
|
56
|
+
return { getSession, getUser, requireUser, redirectIfAuthenticated };
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAkB3C,MAAM,UAAU,iBAAiB,CAAwB,IAAiB;IACzE,4DAA4D;IAC5D,KAAK,UAAU,UAAU;QACxB,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,MAAM,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,uCAAuC;IACvC,KAAK,UAAU,OAAO;QACrB,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;QACnC,OAAO,OAAO,EAAE,IAAI,IAAI,IAAI,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACH,KAAK,UAAU,WAAW,CAAC,UAAU,GAAG,QAAQ;QAC/C,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAC7B,oEAAoE;QACpE,IAAI,CAAC,IAAI;YAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;OAKG;IACH,KAAK,UAAU,uBAAuB,CAAC,EAAU;QAChD,IAAI,MAAM,UAAU,EAAE;YAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,CAAC;AACtE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ingram-tech/nk-auth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "The Ingram Better Auth foundation: composable presets (org, dual-shape JWT, Supabase RLS bridge, active-org hooks, pg pool) for Next.js sites.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -41,6 +41,14 @@
|
|
|
41
41
|
"types": "./dist/paths.d.ts",
|
|
42
42
|
"import": "./dist/paths.js"
|
|
43
43
|
},
|
|
44
|
+
"./server": {
|
|
45
|
+
"types": "./dist/server.d.ts",
|
|
46
|
+
"import": "./dist/server.js"
|
|
47
|
+
},
|
|
48
|
+
"./middleware": {
|
|
49
|
+
"types": "./dist/middleware.d.ts",
|
|
50
|
+
"import": "./dist/middleware.js"
|
|
51
|
+
},
|
|
44
52
|
"./client": {
|
|
45
53
|
"types": "./dist/client.d.ts",
|
|
46
54
|
"import": "./dist/client.js"
|
|
@@ -62,6 +70,7 @@
|
|
|
62
70
|
"@better-auth/passkey": "^1.6.0",
|
|
63
71
|
"@supabase/supabase-js": ">=2.0.0",
|
|
64
72
|
"better-auth": "^1.6.0",
|
|
73
|
+
"next": "^15.0.0 || ^16.0.0",
|
|
65
74
|
"pg": "^8.13.0",
|
|
66
75
|
"react": "^18.0.0 || ^19.0.0"
|
|
67
76
|
},
|
|
@@ -72,6 +81,9 @@
|
|
|
72
81
|
"@supabase/supabase-js": {
|
|
73
82
|
"optional": true
|
|
74
83
|
},
|
|
84
|
+
"next": {
|
|
85
|
+
"optional": true
|
|
86
|
+
},
|
|
75
87
|
"pg": {
|
|
76
88
|
"optional": true
|
|
77
89
|
},
|
|
@@ -88,6 +100,7 @@
|
|
|
88
100
|
"@types/pg": "^8.11.0",
|
|
89
101
|
"@types/react": "^19.0.0",
|
|
90
102
|
"better-auth": "^1.6.0",
|
|
103
|
+
"next": "^16.2.9",
|
|
91
104
|
"pg": "^8.13.0",
|
|
92
105
|
"react": "^19.0.0",
|
|
93
106
|
"typescript": "^6.0.3",
|