Skip to content

Configurable sliding session lifetime + flattened, on-by-default entitlement freshness (v0.5.0)#111

Merged
sergeychernyshev merged 2 commits into
mainfrom
session-lifetime-config
Jul 3, 2026
Merged

Configurable sliding session lifetime + flattened, on-by-default entitlement freshness (v0.5.0)#111
sergeychernyshev merged 2 commits into
mainfrom
session-lifetime-config

Conversation

@sergeychernyshev

@sergeychernyshev sergeychernyshev commented Jul 3, 2026

Copy link
Copy Markdown
Member

Why

Patreon-logged-in users were forced to re-authenticate roughly daily — a hardcoded 24h session with no renewal. Fixing it surfaced that login lifetime (authentication) and entitlement freshness (authorization) were conflated; this PR separates them and cleans up the freshness config API.

What changed

Sessions

  • Configurable, rolling session TTL via session: { ttl }, default 30 days. Sliding renewal in validateSession pushes expires_at forward once less than half the window remains (≈one write per ½·TTL of activity). Active users effectively never re-login; idle sessions still expire.
  • session_id is now a persistent (Max-Age) cookie and the refreshed Max-Age is re-issued on the proxy hot path. Cookie string centralized in sessionSetCookie.

Entitlement freshness — flatter, on-by-default, time-valued

  • Flattened & renamed (⚠️ breaking vs 0.4.5): freshness: { ttl, cron, webhook } → per-provider entitlementTtl / entitlementCron / entitlementWebhook.
  • entitlementTtl is ON by default for entitlement providers (1 day for Patreon, 15 min otherwise) — every deployment gets a freshness backstop now that sessions are long-lived. entitlementTtl: false disables it (webhook-only).
  • Durations are a time, not a boolean: a named-unit object ({ days: 30 }, { minutes: 15 } — summed) or a plain number of ms, via a shared Duration + durationToMs(). Applied to both session.ttl and entitlementTtl.
createStartupAPI({
  session: { ttl: { days: 30 } },
  providers: {
    patreon: {
      // entitlementTtl defaults to { days: 1 } — omit it, tune it, or set false
      entitlementWebhook: true,
    },
  },
});

Behavior / breaking changes (for release notes)

  • Breaking: freshness.* config removed → entitlementTtl / entitlementCron / entitlementWebhook.
  • entitlementTtl default: off → on (1 day Patreon / 15 min other).
  • Default session lifetime: fixed 24h → rolling 30 days; session_idpersistent cookie.

Tests

139 pass + eslint clean. Coverage added for: custom/sliding/no-renew session TTL (userdo), persistent + renewal Set-Cookie on the proxy path (headers), factory config resolution, 30-day default, named-unit durations, durationToMs (factory), and the on-by-default Patreon 1-day entitlement TTL (entitlement_integration).

Versioning

Bumped 0.4.5 → **0.5.0** — the freshness rename is a breaking config change, so a minor bump (pre-1.0) rather than a patch. Say the word if you'd rather keep freshness as a deprecated alias to avoid the break.

🤖 Generated with Claude Code

…ult (v0.4.6)

Decouple login lifetime (authentication) from entitlement freshness
(authorization), which were previously conflated by a hardcoded 24h
session that forced a daily re-login.

Sessions:
- Session TTL is now configurable via `session: { ttl: { ms } }` in the
  factory config, defaulting to a rolling 30 days.
- Sliding renewal: validateSession extends expires_at once less than half
  the window remains (one DB write per ~half-TTL of activity), so active
  users effectively never re-login while idle sessions still expire.
- `session_id` is now a persistent (Max-Age) cookie so it survives browser
  restarts; the renewed Max-Age is re-issued on the proxy hot path.

Entitlements:
- Patreon's entitlement ttl default (when enabled without an explicit ms)
  is now 1 day instead of the generic 15 min, as a backstop for missed
  webhooks now that sessions are long-lived. Still overridable via ttl.ms.

Centralizes the session cookie string in a sessionSetCookie helper.
Adds tests for custom/sliding session TTL, persistent + renewal cookies,
factory config resolution, and the Patreon 1-day TTL default. All 137 pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 3, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
startup-api a1cc4d7 Jul 03 2026, 07:06 PM

…ation type (v0.5.0)

Refines the config API surface from the initial pass on this branch:

- Flatten `freshness: { ttl, cron, webhook }` into descriptive per-provider
  keys: `entitlementTtl` / `entitlementCron` / `entitlementWebhook`
  (camelCase, matching existing keys). BREAKING vs 0.4.5.
- `entitlementTtl` is now ON by default for entitlement providers (1 day for
  Patreon, 15 min otherwise) instead of opt-in, so every deployment gets a
  freshness backstop now that sessions are long-lived. `false` disables it.
- Durations are expressed as a named-unit object ({ days: 30 }, { minutes: 15 };
  units summed) or a plain number of ms, via a shared Duration type +
  durationToMs(). Applied to both `session.ttl` and `entitlementTtl` — the ttl
  value is a time, no longer a boolean.

Updates README (breaking-change note, new examples), the Draw Leather config,
and tests. Adds durationToMs unit tests and named-unit session coverage.
Bumps to 0.5.0 (breaking config rename). All 139 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sergeychernyshev sergeychernyshev changed the title Configurable sliding session lifetime + Patreon entitlement TTL default (v0.4.6) Configurable sliding session lifetime + flattened, on-by-default entitlement freshness (v0.5.0) Jul 3, 2026
@sergeychernyshev sergeychernyshev merged commit e47cbe6 into main Jul 3, 2026
2 checks passed
@sergeychernyshev sergeychernyshev deleted the session-lifetime-config branch July 3, 2026 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant