@ingram-tech/nk-auth 0.17.0 → 0.18.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 CHANGED
@@ -15,6 +15,7 @@ exactly one Better Auth copy in the app.
15
15
  | `nkOrganizationDefaults`, `lastActiveOrganizationHooks`, `lastActiveOrganizationUserField` (`./organization`) | org-plugin defaults + active-org restore/persist |
16
16
  | `createAuthPool` (`./pool`) | **deprecated** — alias of `createPool` from [`@ingram-tech/nk-db`](../nk-db); inject your app's shared pool instead |
17
17
  | `makeEmailSenders`, `makePasskeyOptions`, `passkeyOptionsForBaseUrl`, `uuidGenerateId` (`./`) | email hooks, passkeys (`passkeyOptionsForBaseUrl` derives `rpID`/`origin` from a single base URL), UUID ids |
18
+ | `sessionLifetime` (`./`) | Better Auth plugin capping a sliding session at `createdAt + maxAge`; see [Gate routes](#5-gate-routes-without-the-redirect-loop), "Session lifetime" |
18
19
  | `bcryptPassword` (`./`) | **legacy only** — bcrypt verifier for apps with pre-existing bcrypt hashes. New apps omit it (Better Auth defaults to scrypt). See [Migrating bcrypt passwords to scrypt](#migrating-bcrypt-passwords-to-scrypt) |
19
20
  | `createAuthHelpers`, `safeNext` (`./server`) | validated App Router session helpers (`getSession` / `getUser` / `requireSession` / `requireUser` / `signInTarget` / `redirectIfAuthenticated`), request-memoized via React `cache()`, with automatic `next` + stale-cookie signalling; `safeNext` validates a `?next=` param |
20
21
  | `createAuthMiddleware`, `withAuthPathHeader`, `clearStaleSession` (`./middleware`) | loop-safe edge middleware: gates unauthenticated users off protected paths, preserves `next`, and clears a stale session cookie so a bad session self-heals; the last two are its `next`-header and stale-cookie halves, for a site with its own proxy |
@@ -429,6 +430,26 @@ marker and bounces to a clean `/login?next=…`; signing in returns them to
429
430
  the cookie-present case the guard reads it from the `x-nk-auth-path` header
430
431
  middleware injects.
431
432
 
433
+ **Session lifetime.** Better Auth refreshes a session on read (at most once
434
+ per `session.updateAge`), moving the row's `expiresAt` and re-issuing the cookie
435
+ with a fresh max-age. A server component cannot set cookies, so the server
436
+ helpers read with `disableRefresh`: refreshing there would extend the row while
437
+ the cookie still dies on its sign-in max-age, and users get signed out
438
+ `expiresIn` after sign-in however active they are. The refresh belongs to the
439
+ browser: mount `authClient.useSession()` in the signed-in shell (it hits
440
+ `/auth/get-session` on load and on tab focus, and that route handler can set the
441
+ cookie). To still end a sign-in eventually, add `sessionLifetime({ maxAge })`
442
+ to the instance's `plugins`: refreshes are clamped to `createdAt + maxAge`.
443
+
444
+ ```tsx
445
+ // app/(app)/SessionRenewal.tsx
446
+ "use client";
447
+ export const SessionRenewal = () => {
448
+ authClient.useSession();
449
+ return null;
450
+ };
451
+ ```
452
+
432
453
  **Your own proxy.** An app that composes its own proxy (locale routing, tenant
433
454
  pinning, …) keeps validated gating from the server helpers, but the guards can
434
455
  only preserve `next` if something sets that header. Both halves of the
package/dist/chain.d.ts CHANGED
@@ -1,7 +1,12 @@
1
1
  import { type MigrationStatus } from "@ingram-tech/nk-db/migrate";
2
2
  import type { Pool } from "pg";
3
- /** The migration chain this package ships (`migrations/` next to `dist/`). */
4
- export declare const AUTH_MIGRATIONS_FOLDER: string;
3
+ /**
4
+ * The migration chain this package ships: `migrations/` in the installed
5
+ * package. Resolved through the package manifest, at call time, so a bundler
6
+ * that rewrites `import.meta.url` (Next's server build) still lands on the
7
+ * folder under `node_modules`, and never sees a URL it would try to inline.
8
+ */
9
+ export declare const authMigrationsFolder: () => string;
5
10
  /** The journal table the README tells a site to record the chain in. */
6
11
  export declare const AUTH_MIGRATIONS_TABLE = "__nkauth_migrations";
7
12
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"chain.d.ts","sourceRoot":"","sources":["../src/chain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAErF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,8EAA8E;AAC9E,eAAO,MAAM,sBAAsB,EAAE,MAEpC,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,wBAAwB,CAAC;AAS3D;;;;;;GAMG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;IAClD,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,YAAY,OAAO,EAAE,SAAS,MAAM,EAAE,EAMrC;CACD;AAED,MAAM,WAAW,qBAAqB;IACrC,sFAAsF;IACtF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sBAAsB,SAC5B,IAAI,YACD,qBAAqB,KAC5B,OAAO,CAAC,eAAe,GAAG,IAAI,CAkBhC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,aAChB,OAAO,YACR,qBAAqB,KAC5B,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAOtB,CAAC"}
1
+ {"version":3,"file":"chain.d.ts","sourceRoot":"","sources":["../src/chain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAGrF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,QAAO,MAOtC,CAAC;AAEH,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,wBAAwB,CAAC;AAS3D;;;;;;GAMG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;IAClD,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,YAAY,OAAO,EAAE,SAAS,MAAM,EAAE,EAMrC;CACD;AAED,MAAM,WAAW,qBAAqB;IACrC,sFAAsF;IACtF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sBAAsB,SAC5B,IAAI,YACD,qBAAqB,KAC5B,OAAO,CAAC,eAAe,GAAG,IAAI,CAkBhC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,aAChB,OAAO,YACR,qBAAqB,KAC5B,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAOtB,CAAC"}
package/dist/chain.js CHANGED
@@ -1,7 +1,13 @@
1
1
  import { inspectMigrations } from "@ingram-tech/nk-db/migrate";
2
- import { fileURLToPath } from "node:url";
3
- /** The migration chain this package ships (`migrations/` next to `dist/`). */
4
- export const AUTH_MIGRATIONS_FOLDER = fileURLToPath(new URL("../migrations", import.meta.url));
2
+ import { createRequire } from "node:module";
3
+ import { dirname } from "node:path";
4
+ /**
5
+ * The migration chain this package ships: `migrations/` in the installed
6
+ * package. Resolved through the package manifest, at call time, so a bundler
7
+ * that rewrites `import.meta.url` (Next's server build) still lands on the
8
+ * folder under `node_modules`, and never sees a URL it would try to inline.
9
+ */
10
+ export const authMigrationsFolder = () => dirname(dirname(createRequire(import.meta.url).resolve("@ingram-tech/nk-auth/migrations/meta/_journal.json")));
5
11
  /** The journal table the README tells a site to record the chain in. */
6
12
  export const AUTH_MIGRATIONS_TABLE = "__nkauth_migrations";
7
13
  /** The shape of a `pg` Pool as far as the chain check needs it. */
@@ -45,7 +51,7 @@ export const assertAuthChainApplied = async (pool, options = {}) => {
45
51
  return null;
46
52
  const status = await inspectMigrations({
47
53
  pool,
48
- migrationsFolder: AUTH_MIGRATIONS_FOLDER,
54
+ migrationsFolder: authMigrationsFolder(),
49
55
  migrationsSchema: schema,
50
56
  migrationsTable: table,
51
57
  });
package/dist/chain.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"chain.js","sourceRoot":"","sources":["../src/chain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAwB,MAAM,4BAA4B,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,8EAA8E;AAC9E,MAAM,CAAC,MAAM,sBAAsB,GAAW,aAAa,CAC1D,IAAI,GAAG,CAAC,eAAe,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CACzC,CAAC;AAEF,wEAAwE;AACxE,MAAM,CAAC,MAAM,qBAAqB,GAAG,qBAAqB,CAAC;AAE3D,mEAAmE;AACnE,MAAM,MAAM,GAAG,CAAC,KAAc,EAAiB,EAAE,CAChD,OAAO,KAAK,KAAK,QAAQ;IACzB,KAAK,KAAK,IAAI;IACd,OAAQ,KAA6B,CAAC,KAAK,KAAK,UAAU;IAC1D,OAAQ,KAA+B,CAAC,OAAO,KAAK,UAAU,CAAC;AAEhE;;;;;;GAMG;AACH,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IACzC,OAAO,CAAoB;IACpC,YAAY,OAA0B;QACrC,KAAK,CACJ,yBAAyB,OAAO,CAAC,MAAM,6EAA6E,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,0GAA0G,qBAAqB,kCAAkC,CACvS,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;CACD;AASD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EAC1C,IAAU,EACV,OAAO,GAA0B,EAAE,EACD,EAAE;IACpC,MAAM,MAAM,GAAG,OAAO,CAAC,gBAAgB,IAAI,SAAS,CAAC;IACrD,MAAM,KAAK,GAAG,OAAO,CAAC,eAAe,IAAI,qBAAqB,CAAC;IAC/D,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAChC,mCAAmC,EACnC,CAAC,IAAI,MAAM,MAAM,KAAK,GAAG,CAAC,CAC1B,CAAC;IACF,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC7E,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC;QACtC,IAAI;QACJ,gBAAgB,EAAE,sBAAsB;QACxC,gBAAgB,EAAE,MAAM;QACxB,eAAe,EAAE,KAAK;KACtB,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,wBAAwB,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC7B,QAAiB,EACjB,OAAO,GAA0B,EAAE,EACX,EAAE;IAC1B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC;IAC7C,IAAI,OAAkC,CAAC;IACvC,OAAO,GAAG,EAAE;QACX,OAAO,KAAK,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC5E,OAAO,OAAO,CAAC;IAChB,CAAC,CAAC;AACH,CAAC,CAAC"}
1
+ {"version":3,"file":"chain.js","sourceRoot":"","sources":["../src/chain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAwB,MAAM,4BAA4B,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAW,EAAE,CAChD,OAAO,CACN,OAAO,CACN,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CACrC,oDAAoD,CACpD,CACD,CACD,CAAC;AAEH,wEAAwE;AACxE,MAAM,CAAC,MAAM,qBAAqB,GAAG,qBAAqB,CAAC;AAE3D,mEAAmE;AACnE,MAAM,MAAM,GAAG,CAAC,KAAc,EAAiB,EAAE,CAChD,OAAO,KAAK,KAAK,QAAQ;IACzB,KAAK,KAAK,IAAI;IACd,OAAQ,KAA6B,CAAC,KAAK,KAAK,UAAU;IAC1D,OAAQ,KAA+B,CAAC,OAAO,KAAK,UAAU,CAAC;AAEhE;;;;;;GAMG;AACH,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IACzC,OAAO,CAAoB;IACpC,YAAY,OAA0B;QACrC,KAAK,CACJ,yBAAyB,OAAO,CAAC,MAAM,6EAA6E,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,0GAA0G,qBAAqB,kCAAkC,CACvS,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;CACD;AASD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EAC1C,IAAU,EACV,OAAO,GAA0B,EAAE,EACD,EAAE;IACpC,MAAM,MAAM,GAAG,OAAO,CAAC,gBAAgB,IAAI,SAAS,CAAC;IACrD,MAAM,KAAK,GAAG,OAAO,CAAC,eAAe,IAAI,qBAAqB,CAAC;IAC/D,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAChC,mCAAmC,EACnC,CAAC,IAAI,MAAM,MAAM,KAAK,GAAG,CAAC,CAC1B,CAAC;IACF,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC7E,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC;QACtC,IAAI;QACJ,gBAAgB,EAAE,oBAAoB,EAAE;QACxC,gBAAgB,EAAE,MAAM;QACxB,eAAe,EAAE,KAAK;KACtB,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,wBAAwB,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC7B,QAAiB,EACjB,OAAO,GAA0B,EAAE,EACX,EAAE;IAC1B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC;IAC7C,IAAI,OAAkC,CAAC;IACvC,OAAO,GAAG,EAAE;QACX,OAAO,KAAK,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC5E,OAAO,OAAO,CAAC;IAChB,CAAC,CAAC;AACH,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { assertAuthChainApplied, AUTH_MIGRATIONS_FOLDER, AUTH_MIGRATIONS_TABLE, type AuthChainCheckOptions, AuthChainNotAppliedError, } from "./chain.js";
1
+ export { assertAuthChainApplied, authMigrationsFolder, AUTH_MIGRATIONS_TABLE, type AuthChainCheckOptions, AuthChainNotAppliedError, } from "./chain.js";
2
2
  export { type BackendJwtConfig, backendJwtOptions, verifyBackendJwt } from "./jwt.js";
3
3
  export { base58Id, fromPrefixedId, toPrefixedId, uuidGenerateId } from "./id.js";
4
4
  export { type AuthEnv, authEnv, authSecret, isConfigured } from "./keys.js";
@@ -7,4 +7,5 @@ export { lastActiveOrganizationHooks, lastActiveOrganizationUserField, nkOrganiz
7
7
  export { CREDENTIAL_PROVIDER_ID, DEFAULT_MAX_PASSWORD_LENGTH, DEFAULT_MIN_PASSWORD_LENGTH, type PasswordPolicy, passwordSchema, type ResetPasswordError, type ResetPasswordErrorCode, validateNewPassword, } from "./password.js";
8
8
  export { authBasePath } from "./paths.js";
9
9
  export { createAuthPool } from "./pool.js";
10
+ export { sessionLifetime } from "./session-lifetime.js";
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACN,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,qBAAqB,EAC1B,wBAAwB,GACxB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACtF,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACjF,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC5E,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,aAAa,EAClB,wBAAwB,EACxB,KAAK,SAAS,GACd,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,2BAA2B,EAC3B,+BAA+B,EAC/B,sBAAsB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAC3B,KAAK,cAAc,EACnB,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,mBAAmB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACN,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,KAAK,qBAAqB,EAC1B,wBAAwB,GACxB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACtF,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACjF,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC5E,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,aAAa,EAClB,wBAAwB,EACxB,KAAK,SAAS,GACd,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,2BAA2B,EAC3B,+BAA+B,EAC/B,sBAAsB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAC3B,KAAK,cAAc,EACnB,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,mBAAmB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // "@ingram-tech/nk-auth/client" so importing the server presets never pulls in
3
3
  // React. Focused subpaths (./jwt, ./organization, ./pool) let a site import
4
4
  // only what it needs (e.g. avoid bcrypt when it doesn't use passwords).
5
- export { assertAuthChainApplied, AUTH_MIGRATIONS_FOLDER, AUTH_MIGRATIONS_TABLE, AuthChainNotAppliedError, } from "./chain.js";
5
+ export { assertAuthChainApplied, authMigrationsFolder, AUTH_MIGRATIONS_TABLE, AuthChainNotAppliedError, } from "./chain.js";
6
6
  export { backendJwtOptions, verifyBackendJwt } from "./jwt.js";
7
7
  export { base58Id, fromPrefixedId, toPrefixedId, uuidGenerateId } from "./id.js";
8
8
  export { authEnv, authSecret, isConfigured } from "./keys.js";
@@ -11,4 +11,5 @@ export { lastActiveOrganizationHooks, lastActiveOrganizationUserField, nkOrganiz
11
11
  export { CREDENTIAL_PROVIDER_ID, DEFAULT_MAX_PASSWORD_LENGTH, DEFAULT_MIN_PASSWORD_LENGTH, passwordSchema, validateNewPassword, } from "./password.js";
12
12
  export { authBasePath } from "./paths.js";
13
13
  export { createAuthPool } from "./pool.js";
14
+ export { sessionLifetime } from "./session-lifetime.js";
14
15
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AAExE,OAAO,EACN,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EAErB,wBAAwB,GACxB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAyB,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACtF,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACjF,OAAO,EAAgB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC5E,OAAO,EAIN,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAElB,wBAAwB,GAExB,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,2BAA2B,EAC3B,+BAA+B,EAC/B,sBAAsB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAE3B,cAAc,EAGd,mBAAmB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AAExE,OAAO,EACN,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EAErB,wBAAwB,GACxB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAyB,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACtF,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACjF,OAAO,EAAgB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC5E,OAAO,EAIN,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAElB,wBAAwB,GAExB,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,2BAA2B,EAC3B,+BAA+B,EAC/B,sBAAsB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAE3B,cAAc,EAGd,mBAAmB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/server.d.ts CHANGED
@@ -54,6 +54,9 @@ interface AuthLike<S extends SessionLike> {
54
54
  api: {
55
55
  getSession: (input: {
56
56
  headers: Headers;
57
+ query?: {
58
+ disableRefresh?: boolean;
59
+ };
57
60
  }) => Promise<S | null>;
58
61
  /**
59
62
  * Better Auth's `/list-accounts`: the auth methods linked to the current
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,KAAK,qBAAqB,EAAkB,MAAM,YAAY,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAItD,OAAO,EAEN,KAAK,gBAAgB,EAErB,MAAM,uBAAuB,CAAC;AAG/B;;;;GAIG;AACH,OAAO,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAClE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,oEAAoE;AACpE,UAAU,WAAW;IACpB,IAAI,EAAE,OAAO,CAAC;CACd;AAED;;;;GAIG;AACH,UAAU,QAAQ,CAAC,CAAC,SAAS,WAAW;IACvC;;;OAGG;IACH,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACjC,GAAG,EAAE;QACJ,UAAU,EAAE,CAAC,KAAK,EAAE;YAAE,OAAO,EAAE,OAAO,CAAA;SAAE,KAAK,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC/D;;;;;WAKG;QACH,gBAAgB,EAAE,CAAC,KAAK,EAAE;YACzB,OAAO,EAAE,OAAO,CAAC;SACjB,KAAK,OAAO,CAAC,KAAK,CAAC;YAAE,UAAU,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC,CAAC;KAC7C,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,YAAY,CAAC,EAAE,QAAQ,CAAC;CACxB;AAED,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC3D,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,KAAK,GAAG,qBAAqB,CAAC;CAC3C;AAKD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,WAAW,EACrD,OAAO,EAAE,CAAC,EACV,GAAG,EAAE,UAAU,GACb,CAAC,CAyBH;AAED,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,WAAW,EACtD,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,EACjB,OAAO,GAAE,kBAAuB;sBAqBG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;mBAS1B,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;0BA+DlB,OAAO,CAAC,CAAC,CAAC;uBAXb,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;wBA3BjB,OAAO,CAAC,MAAM,CAAC;kCAkDH,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;8BAU5B,OAAO,CAAC,MAAM,EAAE,CAAC;gCAcf,OAAO,CAAC,OAAO,CAAC;EAevD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,KAAK,qBAAqB,EAAkB,MAAM,YAAY,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAItD,OAAO,EAEN,KAAK,gBAAgB,EAErB,MAAM,uBAAuB,CAAC;AAG/B;;;;GAIG;AACH,OAAO,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAClE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,oEAAoE;AACpE,UAAU,WAAW;IACpB,IAAI,EAAE,OAAO,CAAC;CACd;AAED;;;;GAIG;AACH,UAAU,QAAQ,CAAC,CAAC,SAAS,WAAW;IACvC;;;OAGG;IACH,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACjC,GAAG,EAAE;QACJ,UAAU,EAAE,CAAC,KAAK,EAAE;YACnB,OAAO,EAAE,OAAO,CAAC;YACjB,KAAK,CAAC,EAAE;gBAAE,cAAc,CAAC,EAAE,OAAO,CAAA;aAAE,CAAC;SACrC,KAAK,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACxB;;;;;WAKG;QACH,gBAAgB,EAAE,CAAC,KAAK,EAAE;YACzB,OAAO,EAAE,OAAO,CAAC;SACjB,KAAK,OAAO,CAAC,KAAK,CAAC;YAAE,UAAU,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC,CAAC;KAC7C,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,YAAY,CAAC,EAAE,QAAQ,CAAC;CACxB;AAED,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC3D,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,KAAK,GAAG,qBAAqB,CAAC;CAC3C;AAKD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,WAAW,EACrD,OAAO,EAAE,CAAC,EACV,GAAG,EAAE,UAAU,GACb,CAAC,CAyBH;AAED,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,WAAW,EACtD,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,EACjB,OAAO,GAAE,kBAAuB;sBAqBG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;mBAgB1B,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;0BA+DlB,OAAO,CAAC,CAAC,CAAC;uBAXb,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;wBA3BjB,OAAO,CAAC,MAAM,CAAC;kCAkDH,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;8BAU5B,OAAO,CAAC,MAAM,EAAE,CAAC;gCAcf,OAAO,CAAC,OAAO,CAAC;EAevD"}
package/dist/server.js CHANGED
@@ -86,7 +86,14 @@ export function createAuthHelpers(auth, options = {}) {
86
86
  : authChainCheck(auth.options?.database, options.chainCheck);
87
87
  const getSession = cache(async () => {
88
88
  await ensureChain();
89
- const session = await auth.api.getSession({ headers: await headers() });
89
+ // Never refresh here: a refresh extends the row and re-issues the cookie,
90
+ // and a server component cannot set cookies, so the row would outlive a
91
+ // cookie that still expires on its sign-in max-age. Refreshes belong to
92
+ // the client's `/get-session` (see README, "Session lifetime").
93
+ const session = await auth.api.getSession({
94
+ headers: await headers(),
95
+ query: { disableRefresh: true },
96
+ });
90
97
  return session && options.ids
91
98
  ? encodeSessionIds(session, options.ids)
92
99
  : session;
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { BetterAuthPlugin } from "better-auth";
2
+ /**
3
+ * A hard ceiling on how long one sign-in lasts, however active the user stays.
4
+ * Better Auth's own session is sliding: each refresh (at most once per
5
+ * `session.updateAge`) moves `expiresAt` to now + `session.expiresIn`, forever.
6
+ * This clamps every refresh to `createdAt + maxAge`, so a session idles out
7
+ * after `expiresIn` and ends outright `maxAge` after sign-in.
8
+ *
9
+ * plugins: [sessionLifetime({ maxAge: 60 * 60 * 24 * 90 })],
10
+ *
11
+ * Suite apps sharing one session table must pass the same `maxAge`: whichever
12
+ * instance refreshes the row applies its own.
13
+ */
14
+ export declare function sessionLifetime(options: {
15
+ /** Seconds from sign-in after which the session can no longer be refreshed. */
16
+ maxAge: number;
17
+ }): BetterAuthPlugin;
18
+ //# sourceMappingURL=session-lifetime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-lifetime.d.ts","sourceRoot":"","sources":["../src/session-lifetime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE;IACxC,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAC;CACf,GAAG,gBAAgB,CA4BnB"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * A hard ceiling on how long one sign-in lasts, however active the user stays.
3
+ * Better Auth's own session is sliding: each refresh (at most once per
4
+ * `session.updateAge`) moves `expiresAt` to now + `session.expiresIn`, forever.
5
+ * This clamps every refresh to `createdAt + maxAge`, so a session idles out
6
+ * after `expiresIn` and ends outright `maxAge` after sign-in.
7
+ *
8
+ * plugins: [sessionLifetime({ maxAge: 60 * 60 * 24 * 90 })],
9
+ *
10
+ * Suite apps sharing one session table must pass the same `maxAge`: whichever
11
+ * instance refreshes the row applies its own.
12
+ */
13
+ export function sessionLifetime(options) {
14
+ return {
15
+ id: "nk-session-lifetime",
16
+ init: () => ({
17
+ options: {
18
+ databaseHooks: {
19
+ session: {
20
+ update: {
21
+ before: async (data, ctx) => {
22
+ const createdAt = ctx?.context.session?.session.createdAt;
23
+ if (!(data.expiresAt instanceof Date) || !createdAt) {
24
+ return;
25
+ }
26
+ const ceiling = new Date(new Date(createdAt).getTime() +
27
+ options.maxAge * 1000);
28
+ if (data.expiresAt > ceiling) {
29
+ return { data: { ...data, expiresAt: ceiling } };
30
+ }
31
+ },
32
+ },
33
+ },
34
+ },
35
+ },
36
+ }),
37
+ };
38
+ }
39
+ //# sourceMappingURL=session-lifetime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-lifetime.js","sourceRoot":"","sources":["../src/session-lifetime.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,OAG/B;IACA,OAAO;QACN,EAAE,EAAE,qBAAqB;QACzB,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;YACZ,OAAO,EAAE;gBACR,aAAa,EAAE;oBACd,OAAO,EAAE;wBACR,MAAM,EAAE;4BACP,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;gCAC3B,MAAM,SAAS,GACd,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC;gCACzC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,YAAY,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;oCACrD,OAAO;gCACR,CAAC;gCACD,MAAM,OAAO,GAAG,IAAI,IAAI,CACvB,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;oCAC5B,OAAO,CAAC,MAAM,GAAG,IAAI,CACtB,CAAC;gCACF,IAAI,IAAI,CAAC,SAAS,GAAG,OAAO,EAAE,CAAC;oCAC9B,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,CAAC;gCAClD,CAAC;4BACF,CAAC;yBACD;qBACD;iBACD;aACD;SACD,CAAC;KACF,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ingram-tech/nk-auth",
3
- "version": "0.17.0",
3
+ "version": "0.18.0",
4
4
  "description": "The Ingram Better Auth foundation: composable presets (org, dual-shape JWT, active-org hooks, pg pool) for Next.js sites.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -60,7 +60,8 @@
60
60
  "types": "./dist/client.d.ts",
61
61
  "import": "./dist/client.js"
62
62
  },
63
- "./migrations/*": "./migrations/*"
63
+ "./migrations/*": "./migrations/*",
64
+ "./package.json": "./package.json"
64
65
  },
65
66
  "scripts": {
66
67
  "build": "rm -rf dist *.tsbuildinfo && tsc -p tsconfig.build.json",
@@ -68,7 +69,7 @@
68
69
  "test": "vitest run"
69
70
  },
70
71
  "dependencies": {
71
- "@ingram-tech/nk-db": "^2.1.3",
72
+ "@ingram-tech/nk-db": "^2.2.0",
72
73
  "bcrypt": "^6.0.0",
73
74
  "jose": "^6.2.12",
74
75
  "zod": "^4.6.4"
@@ -96,7 +97,7 @@
96
97
  },
97
98
  "devDependencies": {
98
99
  "@better-auth/passkey": "1.7.4",
99
- "@ingram-tech/nk-dev": "0.17.0",
100
+ "@ingram-tech/nk-dev": "0.18.0",
100
101
  "@types/bcrypt": "^6.0.0",
101
102
  "@types/node": "^26.5.1",
102
103
  "@types/pg": "^8.23.1",
package/src/chain.ts CHANGED
@@ -1,11 +1,22 @@
1
1
  import { inspectMigrations, type MigrationStatus } from "@ingram-tech/nk-db/migrate";
2
- import { fileURLToPath } from "node:url";
2
+ import { createRequire } from "node:module";
3
+ import { dirname } from "node:path";
3
4
  import type { Pool } from "pg";
4
5
 
5
- /** The migration chain this package ships (`migrations/` next to `dist/`). */
6
- export const AUTH_MIGRATIONS_FOLDER: string = fileURLToPath(
7
- new URL("../migrations", import.meta.url),
8
- );
6
+ /**
7
+ * The migration chain this package ships: `migrations/` in the installed
8
+ * package. Resolved through the package manifest, at call time, so a bundler
9
+ * that rewrites `import.meta.url` (Next's server build) still lands on the
10
+ * folder under `node_modules`, and never sees a URL it would try to inline.
11
+ */
12
+ export const authMigrationsFolder = (): string =>
13
+ dirname(
14
+ dirname(
15
+ createRequire(import.meta.url).resolve(
16
+ "@ingram-tech/nk-auth/migrations/meta/_journal.json",
17
+ ),
18
+ ),
19
+ );
9
20
 
10
21
  /** The journal table the README tells a site to record the chain in. */
11
22
  export const AUTH_MIGRATIONS_TABLE = "__nkauth_migrations";
@@ -68,7 +79,7 @@ export const assertAuthChainApplied = async (
68
79
  if (rows[0]?.present === null || rows[0]?.present === undefined) return null;
69
80
  const status = await inspectMigrations({
70
81
  pool,
71
- migrationsFolder: AUTH_MIGRATIONS_FOLDER,
82
+ migrationsFolder: authMigrationsFolder(),
72
83
  migrationsSchema: schema,
73
84
  migrationsTable: table,
74
85
  });
package/src/index.ts CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  export {
7
7
  assertAuthChainApplied,
8
- AUTH_MIGRATIONS_FOLDER,
8
+ authMigrationsFolder,
9
9
  AUTH_MIGRATIONS_TABLE,
10
10
  type AuthChainCheckOptions,
11
11
  AuthChainNotAppliedError,
@@ -41,3 +41,4 @@ export {
41
41
  } from "./password.js";
42
42
  export { authBasePath } from "./paths.js";
43
43
  export { createAuthPool } from "./pool.js";
44
+ export { sessionLifetime } from "./session-lifetime.js";
package/src/server.ts CHANGED
@@ -61,7 +61,10 @@ interface AuthLike<S extends SessionLike> {
61
61
  */
62
62
  options?: { database?: unknown };
63
63
  api: {
64
- getSession: (input: { headers: Headers }) => Promise<S | null>;
64
+ getSession: (input: {
65
+ headers: Headers;
66
+ query?: { disableRefresh?: boolean };
67
+ }) => Promise<S | null>;
65
68
  /**
66
69
  * Better Auth's `/list-accounts`: the auth methods linked to the current
67
70
  * session's user, each `{ providerId }` ("credential" for email/password,
@@ -175,7 +178,14 @@ export function createAuthHelpers<S extends SessionLike>(
175
178
  : authChainCheck(auth.options?.database, options.chainCheck);
176
179
  const getSession = cache(async (): Promise<S | null> => {
177
180
  await ensureChain();
178
- const session = await auth.api.getSession({ headers: await headers() });
181
+ // Never refresh here: a refresh extends the row and re-issues the cookie,
182
+ // and a server component cannot set cookies, so the row would outlive a
183
+ // cookie that still expires on its sign-in max-age. Refreshes belong to
184
+ // the client's `/get-session` (see README, "Session lifetime").
185
+ const session = await auth.api.getSession({
186
+ headers: await headers(),
187
+ query: { disableRefresh: true },
188
+ });
179
189
  return session && options.ids
180
190
  ? encodeSessionIds(session, options.ids)
181
191
  : session;
@@ -0,0 +1,46 @@
1
+ import type { BetterAuthPlugin } from "better-auth";
2
+
3
+ /**
4
+ * A hard ceiling on how long one sign-in lasts, however active the user stays.
5
+ * Better Auth's own session is sliding: each refresh (at most once per
6
+ * `session.updateAge`) moves `expiresAt` to now + `session.expiresIn`, forever.
7
+ * This clamps every refresh to `createdAt + maxAge`, so a session idles out
8
+ * after `expiresIn` and ends outright `maxAge` after sign-in.
9
+ *
10
+ * plugins: [sessionLifetime({ maxAge: 60 * 60 * 24 * 90 })],
11
+ *
12
+ * Suite apps sharing one session table must pass the same `maxAge`: whichever
13
+ * instance refreshes the row applies its own.
14
+ */
15
+ export function sessionLifetime(options: {
16
+ /** Seconds from sign-in after which the session can no longer be refreshed. */
17
+ maxAge: number;
18
+ }): BetterAuthPlugin {
19
+ return {
20
+ id: "nk-session-lifetime",
21
+ init: () => ({
22
+ options: {
23
+ databaseHooks: {
24
+ session: {
25
+ update: {
26
+ before: async (data, ctx) => {
27
+ const createdAt =
28
+ ctx?.context.session?.session.createdAt;
29
+ if (!(data.expiresAt instanceof Date) || !createdAt) {
30
+ return;
31
+ }
32
+ const ceiling = new Date(
33
+ new Date(createdAt).getTime() +
34
+ options.maxAge * 1000,
35
+ );
36
+ if (data.expiresAt > ceiling) {
37
+ return { data: { ...data, expiresAt: ceiling } };
38
+ }
39
+ },
40
+ },
41
+ },
42
+ },
43
+ },
44
+ }),
45
+ };
46
+ }