# Session Expiration Analysis
**Date:** 2026-01-12
**Issue:** Session did not expire after over 1 day (user 161, organization 1)
**Status:** ⚠️ **WORKING AS DESIGNED** (but needs review)

---

## Issue Summary

User reported remaining logged in for over 1 day without session expiration. After investigation, this is **working as intended** due to the "Remember Me" functionality.

---

## Root Cause Analysis

### 1. Session Configuration

**File:** `config/session.php`

```php
'lifetime' => env('SESSION_LIFETIME', 480),  // Default: 480 minutes (8 hours)
'expire_on_close' => false,
```

**Environment:** `.env`
```
SESSION_LIFETIME=120  // 2 hours
```

**Expected Behavior:** Sessions should expire after 120 minutes (2 hours) of inactivity.

### 2. Remember Me Functionality

**File:** `resources/views/auth/login.blade.php` (line ~X)

```blade
<label for="remember_me" class="flex items-center">
    <x-jetstream.checkbox id="remember_me" name="remember" />
    {{ __('Remember me for :period', ['period' => daysToHumanReadable(timebank_config('auth.remember_me_days', 90))]) }}
```

**Configuration:** `config/timebank_cc.php` and `config/timebank-default.php`

```php
'remember_me_days' => 90, // Number of days the "Remember me" checkbox will keep users logged in
```

**Duration:** 90 days = **129,600 minutes** (60 × 24 × 90)

### 3. How Remember Me Works

When a user checks "Remember me" during login:

1. Laravel creates a `remember_token` in the user's database record
2. A cookie is set with this token lasting 90 days
3. Even if the session expires (after 2 hours), the remember token keeps the user logged in
4. The user remains authenticated for the full 90-day period

**This is standard Laravel behavior** and is working as designed.

---

## Current Configuration Summary

| Setting | Value | Duration | Purpose |
|---------|-------|----------|---------|
| `SESSION_LIFETIME` | 120 | 2 hours | Session expires after 2 hours of inactivity |
| `remember_me_days` | 90 | 90 days | Remember Me cookie duration |
| `password_timeout` | 10800 | 3 hours | Password confirmation timeout |
| `expire_on_close` | false | - | Session persists after browser close |

---

## Security Implications

### ✅ Current Security Measures

1. **Session Encryption:** `SESSION_ENCRYPT=true`
2. **HTTP Only Cookies:** `http_only => true` (prevents JavaScript access)
3. **Secure Cookies:** `secure => env('SESSION_SECURE_COOKIE')` (HTTPS only)
4. **Same-Site Policy:** `same_site => 'lax'` (CSRF protection)
5. **Database Sessions:** Stored in database, not filesystem
6. **IP Tracking:** Last login IP stored for security monitoring

### ⚠️ Potential Security Concerns

1. **Long Remember Duration (90 days)**
   - If a device is lost/stolen, attacker has 90-day access
   - User may forget they're logged in on shared computers
   - No mechanism to revoke all remember tokens globally

2. **No Idle Timeout for Remember Me**
   - Regular sessions expire after 2 hours of inactivity
   - Remember Me bypasses this completely
   - User could be inactive for 89 days and still be logged in on day 90

3. **Profile Switching Session Variables**
   - When switching to organization profile, session variables stored:
     - `activeProfileType`
     - `activeProfileId`
     - `active_guard`
   - These persist for the remember token duration (90 days)
   - No separate timeout for elevated guard sessions

4. **Shared Computer Risk**
   - User logs in on public computer with "Remember Me" checked
   - Forgets to log out
   - Next person has 90-day access to that account

---

## Privacy Policy Implications

The current privacy policy states:

> **File:** `references/gdpr/timebank_cc/2026-01-01/privacy-policy-FULL-en.md`
>
> Section 9. Security
> - "2-hour session timeouts"

**Issue:** This is **misleading** because:
- Sessions timeout after 2 hours of inactivity (correct)
- **BUT** Remember Me keeps users logged in for 90 days (not mentioned)
- Users may think they're protected by 2-hour timeout when they're not

---

## Recommendations

### Option 1: Reduce Remember Me Duration ⭐ **RECOMMENDED**

**Change remember_me_days from 90 to 14 or 30 days**

**Pros:**
- Still convenient for users
- Significantly reduces risk window
- Industry standard (many sites use 14-30 days)

**Implementation:**
```php
// config/timebank_cc.php
'remember_me_days' => 14, // Reduced from 90 to 14 days
```

### Option 2: Add Idle Timeout for Remember Me

**Implement additional check for last activity**

**Pros:**
- Remember Me users still logout after extended inactivity
- Combines convenience with security

**Implementation:**
- Add middleware to check last activity timestamp
- If last activity > X days ago (e.g., 7 days), force re-authentication
- Update remember token on each login to track last activity

**Example Middleware Logic:**
```php
// Check if user hasn't been active in 7 days
if (Auth::user()->last_activity_at < now()->subDays(7)) {
    Auth::logout();
    return redirect()->route('login')->with('message', 'Session expired due to inactivity');
}
```

### Option 3: Separate Session Lifetime for Elevated Guards

**Different timeouts for regular vs elevated sessions**

**Configuration:**
```php
'auth' => [
    'remember_me_days' => 14, // Regular user sessions
    'elevated_session_lifetime' => 60, // 1 hour for bank/admin/org profiles
],
```

**Pros:**
- Organizations/Banks/Admins have shorter session lifetime
- Regular users maintain convenience
- Better security for privileged accounts

### Option 4: Update Privacy Policy ⭐ **REQUIRED**

**Add disclosure about Remember Me functionality**

**Add to Section 9 (Security):**
```markdown
## Session Security
- Regular sessions expire after 2 hours of inactivity
- "Remember Me" feature (optional) keeps you logged in for 90 days
  - Use only on trusted personal devices
  - Always log out on shared or public computers
  - You can revoke access by logging out from your account settings
```

**Add to Section 3.4 (Technical Data):**
```markdown
- **Authentication tokens** (for "Remember Me" feature)
  - Optional remember me token (stored for 90 days if enabled)
  - Automatically deleted when you log out or token expires
```

### Option 5: Add "Trusted Device" Management

**Allow users to view and revoke remember tokens**

**Features:**
- Show list of devices where user is "remembered"
- Display: Device type, IP address, last activity, location
- "Revoke access" button to delete remember token
- "Log out all devices" option

**Implementation:**
```php
// User can revoke specific device
User::find($userId)->remember_tokens()->where('id', $tokenId)->delete();

// User can revoke all devices
User::find($userId)->remember_tokens()->delete();
```

---

## Comparison with Industry Standards

| Service | Remember Me Duration | Session Timeout |
|---------|---------------------|-----------------|
| **Timebank.cc (current)** | 90 days | 2 hours |
| GitHub | 30 days | 2 weeks (idle) |
| Google | "Forever" (until revoked) | Variable |
| Facebook | 90 days | 30 days (idle) |
| Banking sites | Not offered | 5-15 minutes |
| AWS Console | 12 hours | 12 hours |

**Analysis:** 90 days is on the longer side but not unprecedented. However, for a financial platform (time banking involves transactions), this may be too long.

---

## Immediate Actions Required

### 1. ✅ Document Current Behavior
- [x] Analyze session configuration
- [x] Identify remember me functionality
- [x] Document security implications

### 2. ⚠️ Update Privacy Policy **URGENT**
- [ ] Add Remember Me disclosure to Section 9 (Security)
- [ ] Add authentication tokens to Section 3.4 (Technical Data)
- [ ] Update all language versions (EN, NL, DE, FR, ES)

### 3. 🔍 Security Review **RECOMMENDED**
- [ ] Assess if 90 days is appropriate for timebank platform
- [ ] Consider reducing to 14-30 days
- [ ] Evaluate implementing idle timeout for remember me
- [ ] Consider separate timeouts for elevated guards (org/bank/admin)

### 4. 🛠️ Feature Enhancements **OPTIONAL**
- [ ] Add "Trusted Devices" management page
- [ ] Show active sessions with revoke capability
- [ ] Add "Log out all devices" option
- [ ] Display warning on login page about Remember Me duration

---

## Testing Checklist

To verify session behavior:

### Test 1: Regular Session (No Remember Me)
```bash
# 1. Log in without checking "Remember Me"
# 2. Wait 2 hours (or set SESSION_LIFETIME=1 for testing)
# 3. Refresh page
# Expected: User is logged out
```

### Test 2: Remember Me Session
```bash
# 1. Log in WITH "Remember Me" checked
# 2. Close browser completely
# 3. Reopen browser and visit site
# Expected: User still logged in
# 4. Check database for remember_token in users table
```

### Test 3: Profile Switch Persistence
```bash
# 1. Log in as user 161 with Remember Me
# 2. Switch to organization profile 1
# 3. Close browser
# 4. Reopen browser
# Expected: Still logged in as organization 1
```

### Test 4: Token Expiration
```bash
# 1. Log in with Remember Me
# 2. Wait 90 days (or modify remember_me_days for testing)
# 3. Try to access site
# Expected: User is logged out, prompted to login
```

---

## Proposed Configuration Changes

### Recommended New Values

**File:** `config/timebank_cc.php`

```php
'auth' => [
    // Reduced from 90 to 14 days for better security
    'remember_me_days' => 14,

    // NEW: Maximum idle time for remember me (7 days)
    'remember_me_max_idle_days' => 7,

    // NEW: Separate timeout for elevated guards (1 hour)
    'elevated_guard_timeout' => 60,
],
```

**File:** `.env`

```
# Regular session timeout (unchanged)
SESSION_LIFETIME=120

# NEW: Force re-authentication for sensitive operations
PASSWORD_CONFIRMATION_TIMEOUT=900
```

---

## Database Schema for Trusted Devices (Optional Enhancement)

```sql
CREATE TABLE trusted_devices (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    user_id BIGINT UNSIGNED NOT NULL,
    device_name VARCHAR(255),
    ip_address VARCHAR(45),
    user_agent TEXT,
    remember_token VARCHAR(100) NOT NULL,
    last_activity_at TIMESTAMP NULL,
    expires_at TIMESTAMP NULL,
    created_at TIMESTAMP NULL,
    updated_at TIMESTAMP NULL,

    INDEX idx_user_id (user_id),
    INDEX idx_remember_token (remember_token),
    INDEX idx_expires_at (expires_at),

    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
```

---

## Conclusion

**The session not expiring is WORKING AS DESIGNED** due to the Remember Me functionality. However, this behavior:

1. ⚠️ **Not clearly communicated** to users in privacy policy
2. ⚠️ **May be too permissive** for a financial platform (90 days is long)
3. ⚠️ **Lacks advanced controls** (no device management, no idle timeout)

### Recommended Next Steps (Priority Order)

1. **HIGH PRIORITY:** Update privacy policy to disclose Remember Me behavior
2. **MEDIUM PRIORITY:** Reduce `remember_me_days` from 90 to 14-30 days
3. **MEDIUM PRIORITY:** Implement idle timeout for remember me sessions
4. **LOW PRIORITY:** Add trusted device management page
5. **LOW PRIORITY:** Separate session lifetimes for elevated guards

---

**Report Generated:** 2026-01-12
**Issue Status:** Working as designed (requires policy update)
**Security Risk:** Medium (long remember me duration)
**Action Required:** Update privacy policy + consider reducing remember me duration
