style(13-03): apply Prettier formatting across repo

Mechanical reformat — no logic changes. 398 files changed, 19125
insertions(+), 16457 deletions(-). Prettier 3.8.4 with .prettierrc
(singleQuote:true, semi:true, tabWidth:2, trailingComma:all,
printWidth:100). Isolated per D-13-08 for reviewability.
This commit is contained in:
Lucas Berger
2026-06-11 20:35:18 -04:00
parent 4bc0445173
commit 982438dc10
398 changed files with 19050 additions and 16382 deletions
@@ -16,27 +16,27 @@ must_haves:
- "When @hono/oidc-auth produces a valid session this request (c.get('oidcAuthJwt') is truthy), the response re-sets the oidc-auth cookie with a persistent Max-Age so the browser keeps it across PWA/tab close"
- "When no valid session JWT is on context (logged-out / deleted / never-set request, c.get('oidcAuthJwt') is falsy), NO oidc-auth Set-Cookie is emitted — the middleware never resurrects a deleted or absent cookie (the critical correctness/security guard)"
- "The re-issued cookie carries httpOnly:true, secure:true, sameSite:'Lax', and the domain attribute only when OIDC_COOKIE_DOMAIN is set, mirroring the library's conditional-domain logic"
- "pnpm --filter @familysync/api typecheck exits 0"
- 'pnpm --filter @familysync/api typecheck exits 0'
artifacts:
- path: "apps/api/src/auth/persistSessionCookie.ts"
provides: "persistSessionCookie() Hono MiddlewareHandler that upgrades the session-scoped oidc-auth cookie to a persistent one"
exports: ["persistSessionCookie"]
- path: 'apps/api/src/auth/persistSessionCookie.ts'
provides: 'persistSessionCookie() Hono MiddlewareHandler that upgrades the session-scoped oidc-auth cookie to a persistent one'
exports: ['persistSessionCookie']
min_lines: 25
- path: "apps/api/tests/auth/persistSessionCookie.test.ts"
provides: "Vitest unit tests for the persist + guard behaviors"
contains: "persistSessionCookie"
- path: "apps/api/src/index.ts"
provides: "Mounting of persistSessionCookie immediately after oidcAuthMiddleware inside the !devBypassActive block"
contains: "persistSessionCookie"
- path: 'apps/api/tests/auth/persistSessionCookie.test.ts'
provides: 'Vitest unit tests for the persist + guard behaviors'
contains: 'persistSessionCookie'
- path: 'apps/api/src/index.ts'
provides: 'Mounting of persistSessionCookie immediately after oidcAuthMiddleware inside the !devBypassActive block'
contains: 'persistSessionCookie'
key_links:
- from: "apps/api/src/index.ts"
to: "apps/api/src/auth/persistSessionCookie.ts"
- from: 'apps/api/src/index.ts'
to: 'apps/api/src/auth/persistSessionCookie.ts'
via: "import + app.use('/api/*', persistSessionCookie()) inside if (!devBypassActive)"
pattern: "persistSessionCookie\\(\\)"
- from: "apps/api/src/auth/persistSessionCookie.ts"
to: "oidcAuthJwt context var (set by @hono/oidc-auth)"
- from: 'apps/api/src/auth/persistSessionCookie.ts'
to: 'oidcAuthJwt context var (set by @hono/oidc-auth)'
via: "c.get('oidcAuthJwt') read; cookie re-issued only when truthy"
pattern: "oidcAuthJwt"
pattern: 'oidcAuthJwt'
---
<objective>
@@ -63,11 +63,17 @@ Output: New middleware file + its tests, wired into index.ts.
@apps/api/tests/auth/devBypass.test.ts
# Ground truth on the library's cookie + context behavior (do NOT edit the library):
# - @hono/oidc-auth/dist/index.js sets a session-scoped cookie via
# setCookie(c, OIDC_COOKIE_NAME, session_jwt, { path, httpOnly:true, secure:true [, domain if OIDC_COOKIE_DOMAIN] })
# with NO maxAge/expires, then immediately calls c.set('oidcAuthJwt', session_jwt).
# setCookie(c, OIDC_COOKIE_NAME, session_jwt, { path, httpOnly:true, secure:true [, domain if OIDC_COOKIE_DOMAIN] })
# with NO maxAge/expires, then immediately calls c.set('oidcAuthJwt', session_jwt).
# - oidcAuthJwt is set ONLY on requests where a valid session is created/refreshed.
# Logged-out / no-session requests do NOT set it. This is the guard signal.
# Logged-out / no-session requests do NOT set it. This is the guard signal.
</context>
<tasks>
@@ -99,6 +105,7 @@ Output: New middleware file + its tests, wired into index.ts.
4. Then `await next()`.
Keep it tiny. Do NOT import or call into @hono/oidc-auth. Do NOT add new dependencies (hono/cookie ships with hono, already a dependency). Do NOT place fenced code blocks in production comments.
</action>
<verify>
<automated>pnpm --filter @familysync/api typecheck</automated>
@@ -123,6 +130,7 @@ Output: New middleware file + its tests, wired into index.ts.
- Test B (guard path — the security property): build a Hono app that does NOT set oidcAuthJwt, run `persistSessionCookie()`, hit a GET /api/test. Assert `res.headers.get('set-cookie')` is null OR does not contain the oidc-auth cookie name — i.e. no resurrection when there is no session JWT.
- Read the cookie NAME the same way the implementation does (`process.env.OIDC_COOKIE_NAME ?? 'oidc-auth'`) so the test stays correct if the env override is set; default 'oidc-auth' otherwise.
Do NOT call the real @hono/oidc-auth in the test — set the context var directly. Do NOT add DB/integration setup (keep it a pure unit test so it runs under the tests/auth/ filter without MariaDB).
</action>
<verify>
<automated>pnpm --filter @familysync/api typecheck && pnpm --filter @familysync/api exec vitest run tests/auth/</automated>
@@ -140,10 +148,11 @@ Output: New middleware file + its tests, wired into index.ts.
</verification>
<success_criteria>
- A logged-in member who closes the PWA and reopens it later (within OIDC_AUTH_EXPIRES) is NOT bounced to Authelia — the oidc-auth cookie now has a Max-Age and persists.
- A logged-out / no-session request never receives an oidc-auth Set-Cookie from this middleware (no resurrection).
- No changes to @hono/oidc-auth, package.json, or .env.
</success_criteria>
</success_criteria>
<notes>
- Tuning the session lifetime is config-only, no code change: raising `OIDC_AUTH_EXPIRES` in .env (e.g. `2592000` for 30 days) extends both the server-side JWT lifetime AND the persisted cookie's Max-Age — the new middleware reads `OIDC_AUTH_EXPIRES` for maxAge automatically. The effective ceiling is still bounded by Authelia's refresh_token_lifespan.
@@ -37,14 +37,15 @@ metrics:
## Tasks Completed
| Task | Name | Commit | Files |
|------|------|--------|-------|
| 1 | Create persistSessionCookie() middleware | aabcb5d | apps/api/src/auth/persistSessionCookie.ts |
| 2 | Wire into index.ts + unit tests | 8343fad | apps/api/src/index.ts, apps/api/tests/auth/persistSessionCookie.test.ts |
| Task | Name | Commit | Files |
| ---- | ---------------------------------------- | ------- | ----------------------------------------------------------------------- |
| 1 | Create persistSessionCookie() middleware | aabcb5d | apps/api/src/auth/persistSessionCookie.ts |
| 2 | Wire into index.ts + unit tests | 8343fad | apps/api/src/index.ts, apps/api/tests/auth/persistSessionCookie.test.ts |
## Verification Results
### typecheck
```
$ pnpm --filter @familysync/api typecheck
$ tsc --noEmit
@@ -52,6 +53,7 @@ $ tsc --noEmit
```
### vitest run tests/auth/
```
RUN v4.1.8 /home/luc/Projects/familysync/apps/api
@@ -62,6 +64,7 @@ $ tsc --noEmit
```
All 3 auth test files pass (devBypass, user, persistSessionCookie). 14/14 tests green including:
- Test A (persist path): truthy oidcAuthJwt → Set-Cookie with Max-Age, SameSite=Lax, HttpOnly, Secure
- Test B (guard path): absent oidcAuthJwt → no oidc-auth Set-Cookie emitted
- Guard variant: empty string oidcAuthJwt → no resurrection
@@ -17,39 +17,39 @@ overrides_applied: 0
### Observable Truths
| # | Truth | Status | Evidence |
|---|-------|--------|----------|
| 1 | Truthy oidcAuthJwt → response re-sets oidc-auth cookie with Max-Age, SameSite=Lax, HttpOnly, Secure | VERIFIED | `persistSessionCookie.ts` lines 4776: guard passes, `setCookie(c, name, jwt, { httpOnly:true, secure:true, sameSite:'Lax', maxAge, ... })` called before `await next()` |
| 2 | Falsy/absent oidcAuthJwt → NO oidc-auth Set-Cookie emitted (no resurrection guard) | VERIFIED | Lines 4750: `if (!jwt) { await next(); return }` — hard early exit before any `setCookie` call; covered by Test B (absent) and guard variant (empty string), both passing |
| 3 | Cookie carries httpOnly:true, secure:true, sameSite:'Lax'; domain included only when OIDC_COOKIE_DOMAIN set | VERIFIED | Options object built lines 6369 (always includes httpOnly/secure/sameSite); `if (process.env.OIDC_COOKIE_DOMAIN)` guard at line 71 adds domain key only when env var is set — key absent (not undefined) when unset |
| 4 | `pnpm --filter @familysync/api typecheck` exits 0 | VERIFIED | Run output: `$ tsc --noEmit` — exit 0, no diagnostic output |
| # | Truth | Status | Evidence |
| --- | ----------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Truthy oidcAuthJwt → response re-sets oidc-auth cookie with Max-Age, SameSite=Lax, HttpOnly, Secure | VERIFIED | `persistSessionCookie.ts` lines 4776: guard passes, `setCookie(c, name, jwt, { httpOnly:true, secure:true, sameSite:'Lax', maxAge, ... })` called before `await next()` |
| 2 | Falsy/absent oidcAuthJwt → NO oidc-auth Set-Cookie emitted (no resurrection guard) | VERIFIED | Lines 4750: `if (!jwt) { await next(); return }` — hard early exit before any `setCookie` call; covered by Test B (absent) and guard variant (empty string), both passing |
| 3 | Cookie carries httpOnly:true, secure:true, sameSite:'Lax'; domain included only when OIDC_COOKIE_DOMAIN set | VERIFIED | Options object built lines 6369 (always includes httpOnly/secure/sameSite); `if (process.env.OIDC_COOKIE_DOMAIN)` guard at line 71 adds domain key only when env var is set — key absent (not undefined) when unset |
| 4 | `pnpm --filter @familysync/api typecheck` exits 0 | VERIFIED | Run output: `$ tsc --noEmit` — exit 0, no diagnostic output |
**Score:** 4/4 truths verified
### Required Artifacts
| Artifact | Expected | Status | Details |
|----------|----------|--------|---------|
| `apps/api/src/auth/persistSessionCookie.ts` | persistSessionCookie() MiddlewareHandler; min 25 lines | VERIFIED | 81 lines; exports `persistSessionCookie(): MiddlewareHandler`; imports only `hono` and `hono/cookie` — no new dependencies |
| `apps/api/tests/auth/persistSessionCookie.test.ts` | Vitest unit tests; contains "persistSessionCookie" | VERIFIED | 123 lines; 4 tests across 2 describe groups; pure unit test (no MariaDB, no @hono/oidc-auth import) |
| `apps/api/src/index.ts` | Mounts persistSessionCookie immediately after oidcAuthMiddleware inside !devBypassActive | VERIFIED | Line 14: import present; lines 5254: `app.use('/api/*', oidcAuthMiddleware())` followed immediately by `app.use('/api/*', persistSessionCookie())` — both inside `if (!devBypassActive)` block |
| Artifact | Expected | Status | Details |
| -------------------------------------------------- | ---------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `apps/api/src/auth/persistSessionCookie.ts` | persistSessionCookie() MiddlewareHandler; min 25 lines | VERIFIED | 81 lines; exports `persistSessionCookie(): MiddlewareHandler`; imports only `hono` and `hono/cookie` — no new dependencies |
| `apps/api/tests/auth/persistSessionCookie.test.ts` | Vitest unit tests; contains "persistSessionCookie" | VERIFIED | 123 lines; 4 tests across 2 describe groups; pure unit test (no MariaDB, no @hono/oidc-auth import) |
| `apps/api/src/index.ts` | Mounts persistSessionCookie immediately after oidcAuthMiddleware inside !devBypassActive | VERIFIED | Line 14: import present; lines 5254: `app.use('/api/*', oidcAuthMiddleware())` followed immediately by `app.use('/api/*', persistSessionCookie())` — both inside `if (!devBypassActive)` block |
### Key Link Verification
| From | To | Via | Status | Details |
|------|----|-----|--------|---------|
| `apps/api/src/index.ts` | `apps/api/src/auth/persistSessionCookie.ts` | `import { persistSessionCookie } from './auth/persistSessionCookie.js'` + `app.use('/api/*', persistSessionCookie())` inside `if (!devBypassActive)` | VERIFIED | Import at line 14; usage at line 54; ordering correct — line 53 oidcAuthMiddleware, line 54 persistSessionCookie |
| `apps/api/src/auth/persistSessionCookie.ts` | oidcAuthJwt context var (@hono/oidc-auth) | `c.get('oidcAuthJwt' as never)` read; cookie re-issued only when truthy | VERIFIED | Line 40: `const jwt = c.get('oidcAuthJwt' as never) as string | undefined`; line 47: falsy guard; no import of @hono/oidc-auth |
| From | To | Via | Status | Details |
| ------------------------------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
| `apps/api/src/index.ts` | `apps/api/src/auth/persistSessionCookie.ts` | `import { persistSessionCookie } from './auth/persistSessionCookie.js'` + `app.use('/api/*', persistSessionCookie())` inside `if (!devBypassActive)` | VERIFIED | Import at line 14; usage at line 54; ordering correct — line 53 oidcAuthMiddleware, line 54 persistSessionCookie |
| `apps/api/src/auth/persistSessionCookie.ts` | oidcAuthJwt context var (@hono/oidc-auth) | `c.get('oidcAuthJwt' as never)` read; cookie re-issued only when truthy | VERIFIED | Line 40: `const jwt = c.get('oidcAuthJwt' as never) as string | undefined`; line 47: falsy guard; no import of @hono/oidc-auth |
### Behavioral Spot-Checks (Vitest)
| Behavior | Command | Result | Status |
|----------|---------|--------|--------|
| Full tests/auth/ suite | `pnpm --filter @familysync/api exec vitest run tests/auth/` | 3 test files, 14 tests, all passed | PASS |
| Test A — persist path (Max-Age + SameSite=Lax + HttpOnly + Secure present) | included in suite above | passes | PASS |
| Test A variant — same JWT value re-issued unchanged | included in suite above | passes | PASS |
| Test B — guard path (absent oidcAuthJwt → no Set-Cookie) | included in suite above | passes | PASS |
| Test B variant — empty string oidcAuthJwt → no resurrection | included in suite above | passes | PASS |
| Behavior | Command | Result | Status |
| -------------------------------------------------------------------------- | ----------------------------------------------------------- | ---------------------------------- | ------ |
| Full tests/auth/ suite | `pnpm --filter @familysync/api exec vitest run tests/auth/` | 3 test files, 14 tests, all passed | PASS |
| Test A — persist path (Max-Age + SameSite=Lax + HttpOnly + Secure present) | included in suite above | passes | PASS |
| Test A variant — same JWT value re-issued unchanged | included in suite above | passes | PASS |
| Test B — guard path (absent oidcAuthJwt → no Set-Cookie) | included in suite above | passes | PASS |
| Test B variant — empty string oidcAuthJwt → no resurrection | included in suite above | passes | PASS |
### Anti-Patterns Found
@@ -57,12 +57,12 @@ None. No TBD/FIXME/XXX markers, no placeholder returns, no empty handlers, no ha
### Scope Constraint Verification
| Constraint | Status | Evidence |
|------------|--------|----------|
| No changes to @hono/oidc-auth | VERIFIED | Only files modified: persistSessionCookie.ts (new), index.ts (import + 2 lines), persistSessionCookie.test.ts (new) |
| No changes to package.json | VERIFIED | No package.json in modified files list; only `hono/cookie` used, which ships with the existing `hono` dependency |
| No changes to .env | VERIFIED | Not in modified files list |
| Cookie set BEFORE await next() | VERIFIED | `setCookie(c, name, jwt, options)` at line 76; `await next()` at line 78 |
| Constraint | Status | Evidence |
| --------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| No changes to @hono/oidc-auth | VERIFIED | Only files modified: persistSessionCookie.ts (new), index.ts (import + 2 lines), persistSessionCookie.test.ts (new) |
| No changes to package.json | VERIFIED | No package.json in modified files list; only `hono/cookie` used, which ships with the existing `hono` dependency |
| No changes to .env | VERIFIED | Not in modified files list |
| Cookie set BEFORE await next() | VERIFIED | `setCookie(c, name, jwt, options)` at line 76; `await next()` at line 78 |
| Middleware NOT mounted under dev bypass | VERIFIED | Both `oidcAuthMiddleware()` and `persistSessionCookie()` registrations are inside `if (!devBypassActive)` block (index.ts lines 5155) |
### Human Verification Required