@gauts/auth 0.9.0 → 0.10.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 +88 -78
- package/SECURITY.md +8 -4
- package/dist/adapters/express/index.d.ts +7 -13
- package/dist/adapters/express/index.d.ts.map +1 -1
- package/dist/adapters/express/index.js +6 -6
- package/dist/adapters/express/index.js.map +1 -1
- package/dist/adapters/fastify/index.d.ts +7 -13
- package/dist/adapters/fastify/index.d.ts.map +1 -1
- package/dist/adapters/fastify/index.js +5 -5
- package/dist/adapters/fastify/index.js.map +1 -1
- package/dist/adapters/hono/index.d.ts +7 -13
- package/dist/adapters/hono/index.d.ts.map +1 -1
- package/dist/adapters/hono/index.js +5 -5
- package/dist/adapters/hono/index.js.map +1 -1
- package/dist/adapters/next/index.d.ts +1 -1
- package/dist/adapters/next/index.d.ts.map +1 -1
- package/dist/adapters/next/index.js +7 -3
- package/dist/adapters/next/index.js.map +1 -1
- package/dist/adapters/utils/session.d.ts.map +1 -1
- package/dist/adapters/utils/session.js +70 -78
- package/dist/adapters/utils/session.js.map +1 -1
- package/dist/adapters/utils/types.d.ts +3 -9
- package/dist/adapters/utils/types.d.ts.map +1 -1
- package/dist/config.d.ts +1 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -2
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/session/cookie.d.ts +6 -8
- package/dist/session/cookie.d.ts.map +1 -1
- package/dist/session/cookie.js +7 -24
- package/dist/session/cookie.js.map +1 -1
- package/dist/session/state.d.ts +41 -0
- package/dist/session/state.d.ts.map +1 -0
- package/dist/session/state.js +192 -0
- package/dist/session/state.js.map +1 -0
- package/package.json +1 -1
- package/dist/session/cache.d.ts +0 -32
- package/dist/session/cache.d.ts.map +0 -1
- package/dist/session/cache.js +0 -138
- package/dist/session/cache.js.map +0 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Database-backed password authentication, opaque browser sessions, and optional s
|
|
|
12
12
|
| bcrypt password hashing | ✅ | Opt-in |
|
|
13
13
|
| Opaque server-side sessions | ✅ | Enabled |
|
|
14
14
|
| Database-backed validation | ✅ | Enabled |
|
|
15
|
-
|
|
|
15
|
+
| Automatic sliding renewal | ✅ | Every 24 hours |
|
|
16
16
|
| Absolute session lifetime | ✅ | 30 days |
|
|
17
17
|
| Signed browser cache | ✅ | Disabled |
|
|
18
18
|
| Full User-Agent validation | ✅ | Enabled |
|
|
@@ -35,11 +35,11 @@ Database-backed password authentication, opaque browser sessions, and optional s
|
|
|
35
35
|
| OTP and transactional email | ❌ | Application-owned |
|
|
36
36
|
| Route roles and permissions | ❌ | Application-owned |
|
|
37
37
|
|
|
38
|
-
“Session renewal” extends the existing session expiry when activity continues. It is not a refresh-token flow and does not rotate the opaque browser token.
|
|
38
|
+
“Session renewal” extends the existing session expiry when authenticated activity continues. Framework middleware performs it inline when due. It is not a refresh-token flow and does not rotate the opaque browser token.
|
|
39
39
|
|
|
40
40
|
## Quick start
|
|
41
41
|
|
|
42
|
-
The application defines its credential login,
|
|
42
|
+
The application defines its credential login, logout, protected endpoints, and the optional explicit renewal endpoint used by server-rendered frontends. Optional addons are configured separately after this base setup.
|
|
43
43
|
|
|
44
44
|
### 1. Install the package
|
|
45
45
|
|
|
@@ -147,6 +147,14 @@ export const authDb = createDrizzleAdapter({
|
|
|
147
147
|
|
|
148
148
|
This Hono example is identical for Prisma and Drizzle:
|
|
149
149
|
|
|
150
|
+
Generate one high-entropy API secret and keep it server-side:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
openssl rand -base64 48
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Store the result as `AUTH_SECRET` in the API environment. Do not expose it through a public frontend variable.
|
|
157
|
+
|
|
150
158
|
```ts
|
|
151
159
|
import { createHonoAuth } from "@gauts/auth/hono";
|
|
152
160
|
|
|
@@ -154,6 +162,7 @@ import { authDb } from "./authDb.js";
|
|
|
154
162
|
|
|
155
163
|
export const auth = createHonoAuth({
|
|
156
164
|
db: authDb,
|
|
165
|
+
secret: process.env.AUTH_SECRET!,
|
|
157
166
|
});
|
|
158
167
|
```
|
|
159
168
|
|
|
@@ -166,7 +175,7 @@ renewal every 24 hours
|
|
|
166
175
|
max lifetime 30 days
|
|
167
176
|
validation User-Agent
|
|
168
177
|
cache disabled
|
|
169
|
-
cookies __ses,
|
|
178
|
+
cookies __ses, __ctx
|
|
170
179
|
```
|
|
171
180
|
|
|
172
181
|
Mount the application-owned login routes and the package middleware:
|
|
@@ -274,7 +283,7 @@ export const proxy = async (request: NextRequest) => {
|
|
|
274
283
|
};
|
|
275
284
|
```
|
|
276
285
|
|
|
277
|
-
The application owns the redirect URL. When `unauthorizedUrl` is provided, the adapter creates the redirect and copies every API `Set-Cookie` header to it before returning the final response. The frontend does not receive `AUTH_SECRET`;
|
|
286
|
+
The application owns the redirect URL. When `unauthorizedUrl` is provided, the adapter creates the redirect and copies every API `Set-Cookie` header to it before returning the final response. The frontend does not receive `AUTH_SECRET`; it reads only untrusted scheduling dates from `__ctx`. The API verifies the signature and remains responsible for session validation.
|
|
278
287
|
|
|
279
288
|
## Requirements and package entry points
|
|
280
289
|
|
|
@@ -311,7 +320,7 @@ The application owns the redirect URL. When `unauthorizedUrl` is provided, the a
|
|
|
311
320
|
| `session` | `SessionConfig` | ❌ | Session defaults | Expiry, renewal, and client validation configuration. |
|
|
312
321
|
| `cookie` | `HonoCookieConfig` | ❌ | Cookie defaults | Names, domain, path, SameSite, and Secure settings. |
|
|
313
322
|
| `cache` | `{ ttl: number }` | ❌ | Disabled | Enables the short signed browser cache. |
|
|
314
|
-
| `secret` | `string` |
|
|
323
|
+
| `secret` | `string` | ✅ | — | HMAC secret for signed session context and optional social data. Minimum 32 UTF-8 bytes. |
|
|
315
324
|
| `social` | `SocialConfig` | ❌ | Disabled | Enables configured social providers, redirects, and optional registration. |
|
|
316
325
|
|
|
317
326
|
```ts
|
|
@@ -404,17 +413,16 @@ renew_at = min((updated_at ?? created_at) + renewInterval, maxExpiresAt)
|
|
|
404
413
|
|
|
405
414
|
### Cookies
|
|
406
415
|
|
|
407
|
-
| Property | Type / allowed values | Default | Description
|
|
408
|
-
| ------------- | ----------------------------- | ----------------- |
|
|
409
|
-
| `sessionName` | Valid cookie name | `"__ses"` | Contains the opaque token. This is the only authenticating cookie.
|
|
410
|
-
| `
|
|
411
|
-
| `
|
|
412
|
-
| `
|
|
413
|
-
| `
|
|
414
|
-
| `
|
|
415
|
-
| `secure` | `boolean` | `true` | Requires HTTPS when enabled. Set `false` only for local HTTP development. |
|
|
416
|
+
| Property | Type / allowed values | Default | Description |
|
|
417
|
+
| ------------- | ----------------------------- | ----------------- | --------------------------------------------------------------------------------------------- |
|
|
418
|
+
| `sessionName` | Valid cookie name | `"__ses"` | Contains the opaque token. This is the only authenticating cookie. |
|
|
419
|
+
| `contextName` | Valid cookie name | `"__ctx"` | Contains signed renewal scheduling and the optional short cache. It never authenticates alone. |
|
|
420
|
+
| `domain` | `string` | Browser host only | Optional cookie domain. |
|
|
421
|
+
| `path` | String beginning with `/` | `"/"` | Cookie path. |
|
|
422
|
+
| `sameSite` | `"Strict" \| "Lax" \| "None"` | `"Lax"` | Browser SameSite policy. |
|
|
423
|
+
| `secure` | `boolean` | `true` | Requires HTTPS when enabled. Set `false` only for local HTTP development. |
|
|
416
424
|
|
|
417
|
-
|
|
425
|
+
Both cookies are always `HttpOnly`, expire with the authoritative session, and must use unique names. Deleting `__ctx` does not log the user out: the next authenticated API request validates `__ses` through the database and rebuilds the signed context. Deleting `__ses` ends browser authentication because `__ctx` is never accepted on its own.
|
|
418
426
|
|
|
419
427
|
Cookie prefix rules are enforced:
|
|
420
428
|
|
|
@@ -434,53 +442,50 @@ The resolved names are available through:
|
|
|
434
442
|
|
|
435
443
|
```ts
|
|
436
444
|
auth.cookie.sessionName; // "__ses"
|
|
437
|
-
auth.cookie.
|
|
438
|
-
auth.cookie.renewName; // "__ren"
|
|
445
|
+
auth.cookie.contextName; // "__ctx"
|
|
439
446
|
```
|
|
440
447
|
|
|
441
|
-
### Signed
|
|
448
|
+
### Signed session context
|
|
442
449
|
|
|
443
|
-
| Property | Type / allowed values | Default | Description
|
|
444
|
-
| ----------- | ----------------------------------- | -------- |
|
|
445
|
-
| `
|
|
446
|
-
| `
|
|
450
|
+
| Property | Type / allowed values | Default | Description |
|
|
451
|
+
| ----------- | ----------------------------------- | -------- | ------------------------------------------------------------------ |
|
|
452
|
+
| `secret` | String with at least 32 UTF-8 bytes | Required | Signs `__ctx` with HMAC-SHA-256 and binds it to the opaque token. |
|
|
453
|
+
| `cache.ttl` | Integer `1` to `session.ttl` | Disabled | Enables cached account/session data for at most this many seconds. |
|
|
447
454
|
|
|
448
|
-
The
|
|
455
|
+
The signed context always contains the session expiry and next renewal time. When caching is configured, it may also contain the selected account and session data. The context:
|
|
449
456
|
|
|
450
|
-
- is cryptographically bound to
|
|
451
|
-
- is
|
|
452
|
-
-
|
|
453
|
-
-
|
|
454
|
-
-
|
|
457
|
+
- is cryptographically bound to `__ses` and cannot authenticate without it;
|
|
458
|
+
- is verified by the API before any cached data is trusted;
|
|
459
|
+
- exposes untrusted `renew` and `exp` scheduling values to the Next.js adapter without exposing `AUTH_SECRET`;
|
|
460
|
+
- uses cached data only for `GET` and `HEAD`;
|
|
461
|
+
- never extends the authoritative database session by itself;
|
|
462
|
+
- bypasses cached data for unsafe methods, renewal, logout, WebSockets, and core calls;
|
|
463
|
+
- triggers normal database authentication and a fresh signed context when absent, expired, malformed, altered, or bound to another token.
|
|
455
464
|
|
|
456
|
-
The
|
|
465
|
+
The context is signed but not encrypted. Do not place passwords, password hashes, raw session tokens, or application secrets in selected account/session data.
|
|
457
466
|
|
|
458
467
|
<details>
|
|
459
|
-
<summary>Internal
|
|
468
|
+
<summary>Internal signed context payload</summary>
|
|
460
469
|
|
|
461
470
|
```ts
|
|
462
471
|
{
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
created_at,
|
|
477
|
-
exp: expiresAt,
|
|
478
|
-
ren: renewAt,
|
|
479
|
-
},
|
|
472
|
+
cache: {
|
|
473
|
+
data: {
|
|
474
|
+
account,
|
|
475
|
+
session: {
|
|
476
|
+
client,
|
|
477
|
+
created,
|
|
478
|
+
id,
|
|
479
|
+
},
|
|
480
|
+
},
|
|
481
|
+
exp: cacheExpiresAt,
|
|
482
|
+
} | null,
|
|
483
|
+
exp: sessionExpiresAt,
|
|
484
|
+
renew: renewAt,
|
|
480
485
|
}
|
|
481
486
|
```
|
|
482
487
|
|
|
483
|
-
`session.account_id` is reconstructed from `
|
|
488
|
+
The payload is encoded as `base64url(payload).signature`. The Next.js adapter may decode `exp` and `renew` only as scheduling hints. The API verifies the signature against the current opaque token before using any value. `session.account_id` is reconstructed from `account.id` after verification.
|
|
484
489
|
|
|
485
490
|
</details>
|
|
486
491
|
|
|
@@ -623,6 +628,7 @@ export const auth = createHonoAuth({
|
|
|
623
628
|
users: { table: users },
|
|
624
629
|
},
|
|
625
630
|
}),
|
|
631
|
+
secret: process.env.AUTH_SECRET!,
|
|
626
632
|
});
|
|
627
633
|
```
|
|
628
634
|
|
|
@@ -678,11 +684,11 @@ export const nextAuth = createNextAuth({
|
|
|
678
684
|
});
|
|
679
685
|
```
|
|
680
686
|
|
|
681
|
-
| Property | Type / allowed values | Required | Default | Description
|
|
682
|
-
| -------------------- | -------------------------------- | :------: | --------- |
|
|
683
|
-
| `renewUrl` | Absolute `http:` or `https:` URL | ✅ | — | Trusted private API renewal endpoint.
|
|
684
|
-
| `cookie.sessionName` | Valid cookie name | ❌ | `"__ses"` | Session cookie read and forwarded to the API.
|
|
685
|
-
| `cookie.
|
|
687
|
+
| Property | Type / allowed values | Required | Default | Description |
|
|
688
|
+
| -------------------- | -------------------------------- | :------: | --------- | -------------------------------------------------------- |
|
|
689
|
+
| `renewUrl` | Absolute `http:` or `https:` URL | ✅ | — | Trusted private API renewal endpoint. |
|
|
690
|
+
| `cookie.sessionName` | Valid cookie name | ❌ | `"__ses"` | Session cookie read and forwarded to the API. |
|
|
691
|
+
| `cookie.contextName` | Valid cookie name | ❌ | `"__ctx"` | Signed context decoded only to schedule SSR renewal. |
|
|
686
692
|
|
|
687
693
|
## Session flow
|
|
688
694
|
|
|
@@ -695,8 +701,8 @@ credentials accepted
|
|
|
695
701
|
-> load current account and owning user
|
|
696
702
|
-> apply configured account/user access rules
|
|
697
703
|
-> write __ses
|
|
698
|
-
-> write
|
|
699
|
-
-> optionally
|
|
704
|
+
-> write signed __ctx with renewal schedule
|
|
705
|
+
-> optionally include short cached data inside __ctx
|
|
700
706
|
```
|
|
701
707
|
|
|
702
708
|
Only the raw browser token authenticates. The database stores only its SHA-256 hash.
|
|
@@ -704,12 +710,16 @@ Only the raw browser token authenticates. The database stores only its SHA-256 h
|
|
|
704
710
|
### Protected `GET` or `HEAD`
|
|
705
711
|
|
|
706
712
|
```text
|
|
707
|
-
|
|
708
|
-
->
|
|
709
|
-
-> yes:
|
|
710
|
-
-> no:
|
|
713
|
+
__ses + __ctx
|
|
714
|
+
-> renewal due?
|
|
715
|
+
-> yes: validate and renew through DB, then write both cookies
|
|
716
|
+
-> no: valid signed cache?
|
|
717
|
+
-> yes: expose cached account and session
|
|
718
|
+
-> no: validate through DB and write a fresh signed context
|
|
711
719
|
```
|
|
712
720
|
|
|
721
|
+
Renewal happens inside the same protected API request. A client-side fetch does not need a second renewal request.
|
|
722
|
+
|
|
713
723
|
### Unsafe request
|
|
714
724
|
|
|
715
725
|
```text
|
|
@@ -717,22 +727,22 @@ session token
|
|
|
717
727
|
-> SHA-256 hash
|
|
718
728
|
-> indexed DB lookup
|
|
719
729
|
-> validate expiry, revocation, account/user access, and client
|
|
720
|
-
->
|
|
730
|
+
-> write signed context without cached account data
|
|
721
731
|
-> continue
|
|
722
732
|
```
|
|
723
733
|
|
|
724
|
-
###
|
|
734
|
+
### Next.js SSR renewal
|
|
725
735
|
|
|
726
736
|
```text
|
|
727
|
-
Next
|
|
728
|
-
-> future
|
|
737
|
+
Next decodes renew and exp from __ctx as untrusted hints
|
|
738
|
+
-> future timestamps: no renewal request
|
|
729
739
|
-> missing, invalid, or due: POST /auth/renew
|
|
730
740
|
-> API validates through DB
|
|
731
741
|
-> update expires_at when renewal is due
|
|
732
|
-
-> Set-Cookie with the same token
|
|
742
|
+
-> Set-Cookie with the same token and fresh signed context
|
|
733
743
|
```
|
|
734
744
|
|
|
735
|
-
`auth.session.resolve()` is always DB-backed and read-only.
|
|
745
|
+
`auth.session.resolve()` is always DB-backed and read-only. `auth.session.renew()` performs the authoritative renewal. Framework `requireSession` calls it automatically when the verified context says renewal is due; the explicit endpoint gives Next.js the same behavior during SSR navigation.
|
|
736
746
|
|
|
737
747
|
## Hono adapter
|
|
738
748
|
|
|
@@ -793,7 +803,7 @@ await auth.createSession({
|
|
|
793
803
|
| Method | Purpose |
|
|
794
804
|
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
795
805
|
| `auth.createSession({ account_id, context, country? })` | Creates the DB session and writes the browser cookies. `country` is optional login-time metadata. |
|
|
796
|
-
| `auth.resolveSession(context)` | Resolves a request and returns the selected account and session.
|
|
806
|
+
| `auth.resolveSession(context)` | Resolves a request, renews inline when due, and returns the selected account and session. |
|
|
797
807
|
| `auth.renewSession(context)` | Performs DB validation, renews when due, and writes authoritative cookies. |
|
|
798
808
|
| `auth.revokeSession(context)` | Revokes the current DB session and clears cookies. |
|
|
799
809
|
| `auth.clearSession(context)` | Clears browser cookies without revoking the DB session. |
|
|
@@ -807,7 +817,7 @@ await auth.createSession({
|
|
|
807
817
|
```ts
|
|
808
818
|
import { createExpressAuth, type ExpressAuthLocals } from "@gauts/auth/express";
|
|
809
819
|
|
|
810
|
-
const auth = createExpressAuth({ db });
|
|
820
|
+
const auth = createExpressAuth({ db, secret: process.env.AUTH_SECRET! });
|
|
811
821
|
|
|
812
822
|
app.get("/account", auth.requireSession, (_request, response) => {
|
|
813
823
|
const { account, session, user } = response.locals as ExpressAuthLocals;
|
|
@@ -818,7 +828,7 @@ app.get("/account", auth.requireSession, (_request, response) => {
|
|
|
818
828
|
| Method | Purpose |
|
|
819
829
|
| ----------------------------------------------------------------- | ---------------------------------------------------- |
|
|
820
830
|
| `auth.createSession({ account_id, request, response, country? })` | Creates the DB session and writes cookies. |
|
|
821
|
-
| `auth.resolveSession({ request, response })` | Resolves
|
|
831
|
+
| `auth.resolveSession({ request, response })` | Resolves and automatically renews when due. |
|
|
822
832
|
| `auth.renewSession({ request, response })` | Renews when due and writes authoritative cookies. |
|
|
823
833
|
| `auth.revokeSession({ request, response })` | Revokes the current session and clears cookies. |
|
|
824
834
|
| `auth.clearSession(response)` | Clears cookies without revoking the DB session. |
|
|
@@ -834,7 +844,7 @@ Register the request decorators once before declaring routes:
|
|
|
834
844
|
```ts
|
|
835
845
|
import { createFastifyAuth } from "@gauts/auth/fastify";
|
|
836
846
|
|
|
837
|
-
const auth = createFastifyAuth({ db });
|
|
847
|
+
const auth = createFastifyAuth({ db, secret: process.env.AUTH_SECRET! });
|
|
838
848
|
|
|
839
849
|
auth.decorate(app);
|
|
840
850
|
|
|
@@ -849,7 +859,7 @@ app.get("/account", { preHandler: auth.requireSession }, (request) => ({
|
|
|
849
859
|
| -------------------------------------------------------------- | -------------------------------------------------------------- |
|
|
850
860
|
| `auth.decorate(app)` | Declares the native request decorators once at startup. |
|
|
851
861
|
| `auth.createSession({ account_id, request, reply, country? })` | Creates the DB session and writes cookies. |
|
|
852
|
-
| `auth.resolveSession({ request, reply })` | Resolves
|
|
862
|
+
| `auth.resolveSession({ request, reply })` | Resolves and automatically renews when due. |
|
|
853
863
|
| `auth.renewSession({ request, reply })` | Renews when due and writes authoritative cookies. |
|
|
854
864
|
| `auth.revokeSession({ request, reply })` | Revokes the current session and clears cookies. |
|
|
855
865
|
| `auth.clearSession(reply)` | Clears cookies without revoking the DB session. |
|
|
@@ -1187,12 +1197,13 @@ import { createHonoAdapter } from "@gauts/auth/hono";
|
|
|
1187
1197
|
const core = createAuth({ db });
|
|
1188
1198
|
const hono = createHonoAdapter({
|
|
1189
1199
|
auth: core,
|
|
1200
|
+
secret: process.env.AUTH_SECRET!,
|
|
1190
1201
|
});
|
|
1191
1202
|
```
|
|
1192
1203
|
|
|
1193
1204
|
## Next.js adapter
|
|
1194
1205
|
|
|
1195
|
-
The Next.js adapter schedules renewal; it does not authenticate pages or API requests.
|
|
1206
|
+
The Next.js adapter schedules SSR renewal; it does not authenticate pages or API requests. Normal API middleware independently verifies `__ctx` and renews inline, including requests made directly by client-side SWR or `fetch`.
|
|
1196
1207
|
|
|
1197
1208
|
```ts
|
|
1198
1209
|
import type { NextRequest } from "next/server";
|
|
@@ -1218,13 +1229,13 @@ Result values:
|
|
|
1218
1229
|
|
|
1219
1230
|
| `attempted` | `status` | Meaning |
|
|
1220
1231
|
| :---------: | ----------: | --------------------------------------------------------------- |
|
|
1221
|
-
| `false` | `null` | Session token
|
|
1232
|
+
| `false` | `null` | Session token and context schedule exist; renewal is not due. |
|
|
1222
1233
|
| `false` | `401` | Session token is missing or malformed; no API request occurred. |
|
|
1223
1234
|
| `true` | HTTP status | The renewal endpoint was called and returned this status. |
|
|
1224
1235
|
|
|
1225
1236
|
`unauthorizedUrl` is optional. When provided, the adapter redirects a `401` to that relative or absolute URL and transfers every returned `Set-Cookie` header to the redirect. Without it, the original response is returned with `status: 401` as before.
|
|
1226
1237
|
|
|
1227
|
-
The adapter forwards only the session cookie and controlled client/origin headers required by the private API. Other cookies, authorization headers, and arbitrary headers are not forwarded.
|
|
1238
|
+
The adapter forwards only the session cookie and controlled client/origin headers required by the private API. `__ctx` is not forwarded because the API renewal endpoint always validates the opaque token through the database and returns a new signed context. Other cookies, authorization headers, and arbitrary headers are not forwarded.
|
|
1228
1239
|
|
|
1229
1240
|
`buildForwardHeaders()` and `FORWARD_HEADERS` are exported from `@gauts/auth/next` for application fetchers that need the same controlled forwarding rules:
|
|
1230
1241
|
|
|
@@ -1241,7 +1252,7 @@ Safe client and proxy metadata is copied by default. Credentials such as `cookie
|
|
|
1241
1252
|
|
|
1242
1253
|
When `Origin` is absent and trusted `X-Forwarded-Proto` and `X-Forwarded-Host` headers exist, the adapter reconstructs the public origin from them. It never derives a public origin from the internal Next.js request URL. The deployment proxy must overwrite forwarded headers received from untrusted clients.
|
|
1243
1254
|
|
|
1244
|
-
Apply renewal only to protected routes or skip public routes before calling `nextAuth.renew()`.
|
|
1255
|
+
Apply renewal only to protected routes or skip public routes before calling `nextAuth.renew()`. The adapter calls the API only when `__ctx` is missing, malformed, expired, or its decoded renewal time is due. Those decoded dates are untrusted scheduling hints; they never authenticate the request.
|
|
1245
1256
|
|
|
1246
1257
|
## Core session API
|
|
1247
1258
|
|
|
@@ -1306,9 +1317,9 @@ The Prisma and Drizzle adapters implement both `DbAdapter` and `SocialDbAdapter`
|
|
|
1306
1317
|
|
|
1307
1318
|
The package contains no Redis or in-process cache.
|
|
1308
1319
|
|
|
1309
|
-
Without the optional browser cache, each `requireSession` performs an indexed database lookup through `account_sessions.token_hash`.
|
|
1320
|
+
Without the optional browser cache, each `requireSession` performs an indexed database lookup through `account_sessions.token_hash`. When renewal is due, that same request also updates the authoritative expiry and returns refreshed cookies; there is no additional client-side API call.
|
|
1310
1321
|
|
|
1311
|
-
With
|
|
1322
|
+
With valid cached data inside `__ctx`, `GET` and `HEAD` skip the lookup until `cache.ttl` expires. Unsafe methods always use current database state. Renewal still validates through the database even if cached data is present.
|
|
1312
1323
|
|
|
1313
1324
|
The tradeoff is explicit: revocation and selected account or relation changes made elsewhere may remain visible to safe cached requests until the short TTL expires. A 60-second TTL limits this stale-read window to one minute. Disable cache when immediate read revocation is required.
|
|
1314
1325
|
|
|
@@ -1360,7 +1371,6 @@ The package provides authentication primitives, not a complete application secur
|
|
|
1360
1371
|
- TLS and trusted-proxy configuration;
|
|
1361
1372
|
- CSRF, CORS, host, and origin validation;
|
|
1362
1373
|
- login and renewal rate limiting;
|
|
1363
|
-
- equivalent password verification work for unknown accounts;
|
|
1364
1374
|
- route roles and authorization;
|
|
1365
1375
|
- re-authentication for sensitive operations;
|
|
1366
1376
|
- database migrations and session cleanup;
|
package/SECURITY.md
CHANGED
|
@@ -29,20 +29,24 @@ Security reports may cover the password service, session core, database adapters
|
|
|
29
29
|
|
|
30
30
|
Application-specific authorization, rate limiting, CSRF, CORS, proxy trust, deployment, and database access policies remain the consuming application's responsibility unless the vulnerability is caused by package behavior.
|
|
31
31
|
|
|
32
|
-
## Signed session
|
|
32
|
+
## Signed session context
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
Browser integration uses an opaque session-token cookie and a signed context cookie. The context is signed with HMAC-SHA-256 using an API-only application secret of at least 32 bytes and is cryptographically bound to the opaque token. It contains session expiry and renewal scheduling plus optional short cached account/session data. It never authenticates without the opaque token.
|
|
35
35
|
|
|
36
|
-
The
|
|
36
|
+
The API verifies the context signature before trusting any cached value. Missing, malformed, expired, altered, or incorrectly bound context data causes normal database validation and a new context cookie. It does not revoke an otherwise valid opaque session. The Next.js adapter may decode the expiry and renewal values without the secret, but treats them only as untrusted scheduling hints.
|
|
37
|
+
|
|
38
|
+
The optional browser cache is disabled when omitted. When configured, it is accepted only for `GET` and `HEAD` requests and remains bound to its own expiry, the authoritative session expiry, and the configured client fields.
|
|
37
39
|
|
|
38
40
|
Cookie caching introduces a bounded consistency window. A session revoked on another device, or selected account or relation access changed in the database, may remain readable until the cache TTL expires. Unsafe methods, renewal, logout, WebSockets, and direct core calls always validate through the database. Applications requiring immediate cross-device read revocation must leave the cache disabled or provide shared server-side enforcement outside this package.
|
|
39
41
|
|
|
40
|
-
Keep `AUTH_SECRET` in the API environment. Do not expose it to browser code or share it with a frontend merely to inspect
|
|
42
|
+
Keep `AUTH_SECRET` in the API environment. Do not expose it to browser code or share it with a frontend merely to inspect scheduling values. Those values are intentionally untrusted and never authenticate or renew a session by themselves.
|
|
41
43
|
|
|
42
44
|
## Session lifetime
|
|
43
45
|
|
|
44
46
|
Sliding renewal is limited by `session.maxLifetime`, which defaults to 30 days from the original login. The maximum expiry is derived from the immutable session `created_at` value and enforced by the core during resolution and renewal. Browser cookies and cached session data never outlive the authoritative session expiry.
|
|
45
47
|
|
|
48
|
+
Framework middleware renews inline when the verified context says renewal is due. The explicit renewal endpoint performs the same database-backed operation for server-rendered navigation. Both paths retain the same opaque token and rewrite the session and context cookie expiries.
|
|
49
|
+
|
|
46
50
|
Activity and possession of the session token cannot extend this absolute limit. After it is reached, the user must authenticate again and receive a new session token.
|
|
47
51
|
|
|
48
52
|
## Social authentication
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { Request, RequestHandler, Response } from "express";
|
|
2
2
|
import { type Auth, type AuthDeps } from "../../auth.js";
|
|
3
|
-
import type { SessionCacheConfig } from "../../session/cache.js";
|
|
4
3
|
import type { SessionCookieNames } from "../../session/cookie.js";
|
|
4
|
+
import type { SessionCacheConfig } from "../../session/state.js";
|
|
5
5
|
import type { AuthAccount, DbAdapter, ResolvedSession, Session } from "../../session/types.js";
|
|
6
6
|
import type { SocialConfig, SocialDbAdapter } from "../../social/types.js";
|
|
7
7
|
import type { HttpCookieConfig } from "../utils/types.js";
|
|
8
8
|
import { type ExpressSocial } from "./social.js";
|
|
9
|
-
export type { SessionCacheConfig } from "../../session/
|
|
9
|
+
export type { SessionCacheConfig } from "../../session/state.js";
|
|
10
10
|
export type { ExpressSocial, ExpressSocialLocals } from "./social.js";
|
|
11
11
|
export type ExpressAuthLocals<TAccount extends AuthAccount = AuthAccount> = {
|
|
12
12
|
account: TAccount;
|
|
@@ -15,35 +15,29 @@ export type ExpressAuthLocals<TAccount extends AuthAccount = AuthAccount> = {
|
|
|
15
15
|
};
|
|
16
16
|
export type ExpressCookieConfig = HttpCookieConfig;
|
|
17
17
|
export type ExpressGetIp = (request: Request) => Promise<string | null | undefined> | string | null | undefined;
|
|
18
|
-
type ExpressCacheOptions = {
|
|
19
|
-
cache: SessionCacheConfig;
|
|
20
|
-
secret: string;
|
|
21
|
-
} | {
|
|
22
|
-
cache?: undefined;
|
|
23
|
-
secret?: string;
|
|
24
|
-
};
|
|
25
18
|
export type ExpressAdapterConfig<TAccount extends AuthAccount = AuthAccount> = {
|
|
26
19
|
auth: Auth<TAccount>;
|
|
27
20
|
cache?: SessionCacheConfig;
|
|
28
21
|
cookie?: ExpressCookieConfig;
|
|
29
22
|
getIp?: ExpressGetIp;
|
|
30
|
-
secret
|
|
23
|
+
secret: string;
|
|
31
24
|
};
|
|
32
25
|
type ExpressAuthBase<TAccount extends AuthAccount> = Omit<AuthDeps<TAccount>, "db"> & {
|
|
26
|
+
cache?: SessionCacheConfig;
|
|
33
27
|
cookie?: ExpressCookieConfig;
|
|
34
28
|
db: DbAdapter<TAccount>;
|
|
35
29
|
getIp?: ExpressGetIp;
|
|
30
|
+
secret: string;
|
|
36
31
|
};
|
|
37
32
|
type ExpressSocialOptions<TAccount extends AuthAccount, TData> = {
|
|
38
33
|
db: DbAdapter<TAccount> & SocialDbAdapter<TAccount>;
|
|
39
|
-
secret: string;
|
|
40
34
|
social: SocialConfig<TData>;
|
|
41
35
|
} | {
|
|
42
36
|
db: DbAdapter<TAccount>;
|
|
43
37
|
social?: undefined;
|
|
44
38
|
};
|
|
45
|
-
export type ExpressAuthConfig<TAccount extends AuthAccount = AuthAccount, TData = undefined> = Omit<ExpressAuthBase<TAccount>, "db"> &
|
|
46
|
-
type ExpressAuthOptions<TAccount extends AuthAccount> = Omit<ExpressAuthBase<TAccount>, "db"
|
|
39
|
+
export type ExpressAuthConfig<TAccount extends AuthAccount = AuthAccount, TData = undefined> = Omit<ExpressAuthBase<TAccount>, "db"> & ExpressSocialOptions<TAccount, TData>;
|
|
40
|
+
type ExpressAuthOptions<TAccount extends AuthAccount> = Omit<ExpressAuthBase<TAccount>, "db">;
|
|
47
41
|
type DbAccount<TDb> = TDb extends DbAdapter<infer TAccount> ? TAccount : never;
|
|
48
42
|
type ExpressRequestInput = {
|
|
49
43
|
request: Request;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/express/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAc,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/express/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,17 +5,17 @@ import { createHttpSession } from "../utils/session.js";
|
|
|
5
5
|
import { createExpressSocial } from "./social.js";
|
|
6
6
|
export const createExpressAdapter = ({ auth, cache, cookie, getIp, secret, }) => {
|
|
7
7
|
const session = createHttpSession({
|
|
8
|
+
auth,
|
|
9
|
+
secret,
|
|
10
|
+
framework: "Express",
|
|
8
11
|
appendSetCookie: ({ response, value }) => {
|
|
9
12
|
response.append("Set-Cookie", value);
|
|
10
13
|
},
|
|
11
|
-
|
|
14
|
+
getHeader: ({ name, request }) => request.get(name),
|
|
15
|
+
getMethod: (request) => request.method,
|
|
12
16
|
...(cache === undefined ? {} : { cache }),
|
|
13
17
|
...(cookie === undefined ? {} : { cookie }),
|
|
14
|
-
framework: "Express",
|
|
15
|
-
getHeader: ({ name, request }) => request.get(name),
|
|
16
18
|
...(getIp === undefined ? {} : { getIp }),
|
|
17
|
-
getMethod: (request) => request.method,
|
|
18
|
-
...(secret === undefined ? {} : { secret }),
|
|
19
19
|
});
|
|
20
20
|
const resolveSession = (input) => {
|
|
21
21
|
return session.resolveSession(input);
|
|
@@ -47,10 +47,10 @@ const createExpressAuthImpl = ({ cache, cookie, db, getIp, password, secret, ses
|
|
|
47
47
|
});
|
|
48
48
|
const adapter = createExpressAdapter({
|
|
49
49
|
auth,
|
|
50
|
+
secret,
|
|
50
51
|
...(cache === undefined ? {} : { cache }),
|
|
51
52
|
...(cookie === undefined ? {} : { cookie }),
|
|
52
53
|
...(getIp === undefined ? {} : { getIp }),
|
|
53
|
-
...(secret === undefined ? {} : { secret }),
|
|
54
54
|
});
|
|
55
55
|
if (social === undefined) {
|
|
56
56
|
return { ...auth, ...adapter };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/express/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAA4B,MAAM,eAAe,CAAC;AAKrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,mBAAmB,EAAsB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/express/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
|
2
2
|
import { type Auth, type AuthDeps } from "../../auth.js";
|
|
3
|
-
import type { SessionCacheConfig } from "../../session/cache.js";
|
|
4
3
|
import type { SessionCookieNames } from "../../session/cookie.js";
|
|
4
|
+
import type { SessionCacheConfig } from "../../session/state.js";
|
|
5
5
|
import type { AuthAccount, DbAdapter, ResolvedSession, Session } from "../../session/types.js";
|
|
6
6
|
import type { SocialConfig, SocialDbAdapter } from "../../social/types.js";
|
|
7
7
|
import type { HttpCookieConfig } from "../utils/types.js";
|
|
8
8
|
import { type FastifySocial } from "./social.js";
|
|
9
|
-
export type { SessionCacheConfig } from "../../session/
|
|
9
|
+
export type { SessionCacheConfig } from "../../session/state.js";
|
|
10
10
|
export type { FastifySocial, FastifySocialHandler } from "./social.js";
|
|
11
11
|
export type FastifyAuthContext<TAccount extends AuthAccount = AuthAccount> = {
|
|
12
12
|
account: TAccount;
|
|
@@ -15,35 +15,29 @@ export type FastifyAuthContext<TAccount extends AuthAccount = AuthAccount> = {
|
|
|
15
15
|
};
|
|
16
16
|
export type FastifyCookieConfig = HttpCookieConfig;
|
|
17
17
|
export type FastifyGetIp = (request: FastifyRequest) => Promise<string | null | undefined> | string | null | undefined;
|
|
18
|
-
type FastifyCacheOptions = {
|
|
19
|
-
cache: SessionCacheConfig;
|
|
20
|
-
secret: string;
|
|
21
|
-
} | {
|
|
22
|
-
cache?: undefined;
|
|
23
|
-
secret?: string;
|
|
24
|
-
};
|
|
25
18
|
export type FastifyAdapterConfig<TAccount extends AuthAccount = AuthAccount> = {
|
|
26
19
|
auth: Auth<TAccount>;
|
|
27
20
|
cache?: SessionCacheConfig;
|
|
28
21
|
cookie?: FastifyCookieConfig;
|
|
29
22
|
getIp?: FastifyGetIp;
|
|
30
|
-
secret
|
|
23
|
+
secret: string;
|
|
31
24
|
};
|
|
32
25
|
type FastifyAuthBase<TAccount extends AuthAccount> = Omit<AuthDeps<TAccount>, "db"> & {
|
|
26
|
+
cache?: SessionCacheConfig;
|
|
33
27
|
cookie?: FastifyCookieConfig;
|
|
34
28
|
db: DbAdapter<TAccount>;
|
|
35
29
|
getIp?: FastifyGetIp;
|
|
30
|
+
secret: string;
|
|
36
31
|
};
|
|
37
32
|
type FastifySocialOptions<TAccount extends AuthAccount, TData> = {
|
|
38
33
|
db: DbAdapter<TAccount> & SocialDbAdapter<TAccount>;
|
|
39
|
-
secret: string;
|
|
40
34
|
social: SocialConfig<TData>;
|
|
41
35
|
} | {
|
|
42
36
|
db: DbAdapter<TAccount>;
|
|
43
37
|
social?: undefined;
|
|
44
38
|
};
|
|
45
|
-
export type FastifyAuthConfig<TAccount extends AuthAccount = AuthAccount, TData = undefined> = Omit<FastifyAuthBase<TAccount>, "db"> &
|
|
46
|
-
type FastifyAuthOptions<TAccount extends AuthAccount> = Omit<FastifyAuthBase<TAccount>, "db"
|
|
39
|
+
export type FastifyAuthConfig<TAccount extends AuthAccount = AuthAccount, TData = undefined> = Omit<FastifyAuthBase<TAccount>, "db"> & FastifySocialOptions<TAccount, TData>;
|
|
40
|
+
type FastifyAuthOptions<TAccount extends AuthAccount> = Omit<FastifyAuthBase<TAccount>, "db">;
|
|
47
41
|
type DbAccount<TDb> = TDb extends DbAdapter<infer TAccount> ? TAccount : never;
|
|
48
42
|
type FastifyRequestInput = {
|
|
49
43
|
reply: FastifyReply;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/fastify/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAc,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/fastify/index.ts"],"names":[],"mappings":"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"}
|