Skip to content

make cookie ttl configurable and unlimited by default#105

Merged
Klakurka merged 3 commits intomasterfrom
feat/make-cookie-ttl-configurable-and-unlimited-by-default
Dec 8, 2025
Merged

make cookie ttl configurable and unlimited by default#105
Klakurka merged 3 commits intomasterfrom
feat/make-cookie-ttl-configurable-and-unlimited-by-default

Conversation

@xecdev
Copy link
Collaborator

@xecdev xecdev commented Dec 7, 2025

This PR implements #76 by adding a configurable cookie expiry setting for both login and content unlock sessions.
A new “Login & Content Unlock Cookie Expiry” field has been introduced in Paywall Settings, allowing site admins to define how long user authentication and unlock cookies remain valid. The default value of 0 maintains existing behavior (long-lived almost 1 year, effectively unlimited cookies), while any positive number enforces a custom automatic logout period. Also moved some in-line CSS in the Paywall Settings page to it's seprate CSS file.

Test Plan

  • Install the plugin
  • Goto the Paywall Settings page and scroll down to the Advanced settings
  • Set custom cookie expiry in days
  • Save settings and verify the cookie in the browser's dev tools

Summary by CodeRabbit

  • New Features

    • Added a configurable "Login & Content Unlock Cookie Expiry" setting in Advanced Settings so admins can control how long unlock cookies remain valid.
  • Style

    • Reworked PayButton guide and code-block styling to use class-based styles for improved visual consistency and maintainability.

✏️ Tip: You can customize this high-level summary in your review settings.

Greptile Overview

Greptile Summary

Added configurable cookie TTL setting for login and content unlock sessions, defaulting to unlimited (1 year) with admin-configurable automatic logout periods.

Key Changes:

  • New get_ttl() method in PayButton_State calculates cookie expiry based on admin settings
  • Admin can set custom expiry in days (0 = unlimited, >0 = custom period)
  • Proper input sanitization with negative value handling
  • CSS refactoring: moved inline styles to paybutton-admin.css
  • Default changed from 1 week to 1 year to maintain "unlimited" behavior
  • Includes fallback for DAY_IN_SECONDS constant for compatibility

The implementation is clean, well-documented, and follows WordPress best practices for option handling and input sanitization.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The implementation is straightforward and well-structured. Input sanitization is properly handled with negative value checks. The default behavior preserves existing functionality (long-lived cookies). The code includes proper fallbacks for WordPress constants and follows established patterns in the codebase. CSS refactoring improves maintainability. No security issues or logical errors identified.
  • No files require special attention

Important Files Changed

File Analysis

Filename Score Overview
includes/class-paybutton-state.php 5/5 Added configurable cookie TTL with proper default (1 year), includes fallback for DAY_IN_SECONDS constant, clean implementation
includes/class-paybutton-admin.php 5/5 Added cookie TTL days setting with proper sanitization, negative value handling, and option storage
templates/admin/paywall-settings.php 5/5 Added UI field for cookie expiry with clear description, moved inline styles to CSS file
assets/css/paybutton-admin.css 5/5 Extracted inline styles (.pre-box, .paybutton-guide) to CSS file for better maintainability

Sequence Diagram

sequenceDiagram
    participant Admin as Site Admin
    participant Settings as Paywall Settings Page
    participant DB as WordPress Options
    participant State as PayButton_State
    participant Browser as User Browser

    Admin->>Settings: Configure cookie TTL (days)
    Settings->>DB: save_settings()<br/>update_option('paybutton_cookie_ttl_days', value)
    
    Note over Admin,DB: Cookie TTL stored in database<br/>(0 = unlimited, >0 = custom days)
    
    User->>State: User logs in or unlocks content
    State->>DB: get_option('paybutton_cookie_ttl_days', 0)
    DB-->>State: Returns TTL days
    
    alt TTL days > 0
        State->>State: get_ttl()<br/>Calculate: days * DAY_IN_SECONDS
        Note over State: Custom expiry period
    else TTL days = 0
        State->>State: get_ttl()<br/>Return TTL constant (1 year)
        Note over State: Long-lived "unlimited" cookie
    end
    
    State->>Browser: setcookie()<br/>expires: time() + calculated_ttl
    Browser-->>User: Cookie set with TTL
    
    Note over Browser: Cookie automatically expires<br/>after configured period
Loading

@coderabbitai
Copy link

coderabbitai bot commented Dec 7, 2025

Walkthrough

Adds a configurable cookie TTL option exposed in admin, uses that value to compute cookie expiries in runtime state logic, and replaces inline guide/code-block styling with two new CSS classes used in the admin template.

Changes

Cohort / File(s) Summary
Cookie TTL: admin handling
includes/class-paybutton-admin.php
Adds paybutton_cookie_ttl_days to settings page data, reads/sanitizes $_POST on save, coerces to non-negative integer, and persists via update_option.
Cookie TTL: runtime logic
includes/class-paybutton-state.php
Adds TTL constant and private get_ttl() to compute TTL from paybutton_cookie_ttl_days (days → seconds). Replaces hard-coded expiry calculations in set_address() and add_article() with computed TTL (including legacy Expires header path).
Admin UI & styling
templates/admin/paywall-settings.php, assets/css/paybutton-admin.css
Adds numeric Advanced Settings field paybutton_cookie_ttl_days (min=0). Replaces inline styles in the User-Friendly Setup Guide and code blocks with .paybutton-guide and .pre-box classes; updates template markup accordingly.

Sequence Diagram(s)

sequenceDiagram
    actor Admin
    participant UI as Paywall Settings UI
    participant WP as WordPress Options
    participant State as PayButton_State
    participant Browser as User Browser

    Admin->>UI: submit paybutton_cookie_ttl_days
    UI->>WP: update_option('paybutton_cookie_ttl_days', value)
    WP-->>UI: saved

    Browser->>State: user action (view/unlock)
    State->>WP: get_option('paybutton_cookie_ttl_days')
    WP-->>State: TTL days (or 0)
    State->>State: compute TTL seconds (get_ttl)
    State->>Browser: Set-Cookie / Expires using computed TTL
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Verify days→seconds conversion and handling when option is 0 (semantics for "no automatic logout").
  • Review legacy PHP Expires header calculations for parity with modern cookie-setting branch.
  • Inspect duplicated Advanced Settings insertion points in the template.
  • Confirm .paybutton-guide and .pre-box do not conflict with existing admin styles.

Suggested labels

enhancement (behind the scenes)

Suggested reviewers

  • Klakurka

Poem

🐰 A tiny TTL hops into place,
Days chosen gently by admin's grace,
Cookies set with timed-out cheer,
Guides now tidy, code appears clear.
Hop on, PayButton — cookies dear!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main objective of the pull request—making cookie TTL configurable with an unlimited default.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/make-cookie-ttl-configurable-and-unlimited-by-default

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 84cff14 and 5a95188.

📒 Files selected for processing (1)
  • templates/admin/paywall-settings.php (3 hunks)
🔇 Additional comments (2)
templates/admin/paywall-settings.php (2)

231-231: Good refactor: inline styles moved to CSS class.

Using the .paybutton-guide class improves maintainability by centralizing styling in the CSS file.


248-260: LGTM!

The .pre-box class applied to both code blocks provides consistent styling and aligns with the inline-to-CSS refactoring pattern used elsewhere in this file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@xecdev xecdev self-assigned this Dec 7, 2025
@xecdev xecdev added the enhancement (UI/UX/feature) New feature or request label Dec 7, 2025
@xecdev xecdev linked an issue Dec 7, 2025 that may be closed by this pull request
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
includes/class-paybutton-state.php (1)

12-40: TTL helper implementation looks good; consider tightening the “unlimited” wording

get_ttl() correctly derives a TTL from paybutton_cookie_ttl_days and falls back to TTL = 31536000 when the option is 0/empty. However, the docblock currently calls this an “unlimited default”, while the constant encodes a fixed ~1‑year lifetime. To avoid confusion (especially alongside the admin‑UI text), I’d suggest rephrasing docs to “long‑lived default” or similar rather than “unlimited”.

includes/class-paybutton-admin.php (1)

205-229: TTL days option wiring and sanitization look solid

paybutton_cookie_ttl_days is correctly loaded for the template and, on save, normalized to a non‑negative integer via sanitize_text_field + (int) with a < 0 clamp to 0 before update_option. This gives a clear 0‑or‑more contract to PayButton_State::get_ttl() and keeps unexpected input from breaking cookie expiry logic. If you ever want to be extra defensive, you could also cap very large values (e.g., to align with the 400‑day browser guidance mentioned in PayButton_State::TTL docs), but it’s not strictly necessary.

Also applies to: 290-305

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2596c8e and 6e6ac53.

📒 Files selected for processing (4)
  • assets/css/paybutton-admin.css (1 hunks)
  • includes/class-paybutton-admin.php (3 hunks)
  • includes/class-paybutton-state.php (5 hunks)
  • templates/admin/paywall-settings.php (3 hunks)
🔇 Additional comments (3)
includes/class-paybutton-state.php (1)

135-153: Consistent TTL use across modern and legacy cookie paths

Using a single $ttl = self::get_ttl(); and applying time() + $ttl in both the array‑based setcookie() call and the legacy Expires= header keeps behavior consistent for COOKIE_USER_ADDR and COOKIE_CONTENT. This cleanly wires the new setting into both cookies without changing any other semantics.

Also applies to: 230-249

assets/css/paybutton-admin.css (1)

295-311: New utility classes nicely replace inline styles

.pre-box and .paybutton-guide provide reusable styling for code blocks and the guide panel, which is cleaner than inline styles and keeps the admin UI consistent.

templates/admin/paywall-settings.php (1)

231-267: Guide and code samples refactor is clean

Moving the PayButton public‑key setup guide to use .paybutton-guide and .pre-box instead of inline styles, with esc_url() for the trigger URL and literal JSON shown in <pre>, keeps the markup readable and styling centralized in CSS. No issues here.

@xecdev xecdev requested a review from Klakurka December 7, 2025 14:48
@Klakurka Klakurka merged commit 43b6fd9 into master Dec 8, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement (UI/UX/feature) New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow setting the forced logout timeout in admin

2 participants