Transparency - Government Data Access Platform

Manage Account Page

Overview

The Manage Account page (manage.html) provides a secure self-service portal for users to:

Features

1. Secure Account Verification

How it works:

  1. User enters their email address AND license key
  2. System validates both credentials:
    • Validates license key format (XXXX-XXXX-XXXX-XXXX)
    • Verifies license key is valid via /api/validate
    • Confirms email matches license key via /api/account/status
  3. If authenticated, displays account details:
    • Email address
    • Current tier (FREE or PRO)
    • Subscription renewal date (Pro only)

Security:

2. Tier Management

Visual Design:

Free Tier Card:

Pro Tier Card:

3. License Recovery

How it works:

  1. User clicks “Don’t have your license key? Recover it”
  2. Shows recovery form asking for email only
  3. System finds active license for that email
  4. Resends license key email (free or pro email template)
  5. User receives email with their license key

Security:

4. Actions

For Free Users:

For Pro Users:

Backend API

New Endpoint: /api/account/status

Request:

POST https://transparency-flask.onrender.com/api/account/status
Content-Type: application/json

{
  "email": "user@example.com"
}

Response (Account Found):

{
  "found": true,
  "email": "user@example.com",
  "license_key": "ABC1-DEF2-GHI3-JKL4",
  "tier": "pro",
  "active": true,
  "expiry": null,
  "created_at": "2025-11-23T10:30:00"
}

Response (Not Found):

{
  "found": false,
  "message": "No active license found for this email"
}

Implementation: Added to server/app.py lines 889-921

New Endpoint: /api/recover-license

Request:

POST https://transparency-flask.onrender.com/api/recover-license
Content-Type: application/json

{
  "email": "user@example.com"
}

Response (Success):

{
  "success": true,
  "message": "License key sent to your email"
}

Response (Not Found):

{
  "success": false,
  "error": "No active license found for this email"
}

Implementation: Added to server/app.py lines 977-1015

User Flows

Flow 1: Check Existing Account (Free User)

User → Enter email → Click "Check Account"
  ↓
Backend → Find license (tier='free')
  ↓
Page → Show account details
  ↓
Display: "FREE" badge
Display: License key
Display: Two tier cards (Free = current, Pro = available)
  ↓
User clicks "Upgrade to Pro"
  ↓
Redirect to signup.html?email=user@example.com
  ↓
User completes payment
  ↓
Backend upgrades existing license to Pro (same license key!)

Flow 2: Check Existing Account (Pro User)

User → Enter email → Click "Check Account"
  ↓
Backend → Find license (tier='pro')
  ↓
Page → Show account details
  ↓
Display: "PRO" badge (gradient with glow)
Display: License key
Display: Subscription renewal date
Display: Two tier cards (Pro = current, Free = available)
  ↓
User clicks "Downgrade to Free"
  ↓
Confirmation: "Are you sure? You'll lose Pro features"
  ↓
If confirmed → Redirect to Stripe customer portal to cancel
  ↓
User cancels subscription in Stripe
  ↓
Webhook → Backend downgrades to free automatically

Flow 3: New User Signup

User → Enter email → Click "Check Account"
  ↓
Backend → No license found
  ↓
Page → Show "No account found" message
Page → Show tier selection cards (both available)
  ↓
Option A: User clicks "Get Free License"
  ↓
  Backend → Creates free license
  Backend → Sends email
  Page → Shows success message
  Page → Auto-refreshes account status
  Page → Now shows Free tier as current

Option B: User clicks "Subscribe to Pro"
  ↓
  Redirect to signup.html
  User completes Stripe checkout
  Backend → Creates Pro license

Styling

Desktop View:

Mobile View:

Color Scheme:

Animations:

Integration Points

1. Navigation Menu

Added “Manage Account” link to main navigation:

<li><a href="manage.html">Manage Account</a></li>

Should be added to:

2. Signup Page

The signup page can link to manage account for existing users:

<p>Already have an account? <a href="manage.html">Manage Account</a></p>

3. Extension

Extension can direct users to manage account page:

// In extension popup or settings
chrome.tabs.create({ url: 'https://transparencyai.io/manage.html' });

Stripe Customer Portal

For Pro users who want to downgrade, you need to set up Stripe’s customer portal:

  1. Create Customer Portal:
    • Go to Stripe Dashboard → Settings → Customer Portal
    • Enable portal
    • Configure allowed actions (cancel subscription, update payment method)
    • Get portal configuration ID
  2. Generate Portal Session:

You can either:

Option A: Direct Link (Simple)

// In manage.html
function switchToFree() {
    if (currentAccount && currentAccount.tier === 'pro') {
        // Open Stripe billing portal
        window.location.href = 'https://billing.stripe.com/p/login/YOUR_SESSION_LINK';
    }
}

Option B: Backend Session Generation (Better)

Add endpoint to server/app.py:

@app.route('/api/create-portal-session', methods=['POST'])
def create_portal_session():
    """Create Stripe customer portal session"""
    try:
        data = request.get_json()
        email = data.get('email')

        # Find license
        license_record = License.query.filter_by(email=email, active=True).first()

        if not license_record or not license_record.customer_id:
            return jsonify({'error': 'No subscription found'}), 404

        # Create portal session
        session = stripe.billing_portal.Session.create(
            customer=license_record.customer_id,
            return_url='https://transparencyai.io/manage.html',
        )

        return jsonify({'url': session.url}), 200

    except Exception as e:
        return jsonify({'error': str(e)}), 500

Then update manage.html:

async function switchToFree() {
    if (currentAccount && currentAccount.tier === 'pro') {
        if (confirm('Downgrade to Free? You\'ll lose Pro features.')) {
            const response = await fetch(`${API_URL}/api/create-portal-session`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ email: currentAccount.email })
            });

            const data = await response.json();
            if (response.ok) {
                window.location.href = data.url;
            }
        }
    }
}

Testing

Test Account Status Endpoint

# Test with existing account
curl -X POST https://transparency-flask.onrender.com/api/account/status \
  -H "Content-Type: application/json" \
  -d '{"email": "test@example.com"}'

# Test with non-existent account
curl -X POST https://transparency-flask.onrender.com/api/account/status \
  -H "Content-Type: application/json" \
  -d '{"email": "nonexistent@example.com"}'

Test Manage Page

  1. Open page: https://transparencyai.io/manage.html

  2. Test existing free user:
    • Enter email with free license
    • Should show FREE badge
    • Should show license key
    • “Upgrade to Pro” button should be available
  3. Test existing pro user:
    • Enter email with pro license
    • Should show PRO badge
    • Should show subscription renewal date
    • “Downgrade to Free” button should be available
  4. Test new user:
    • Enter new email
    • Should show “No account found” message
    • Should show both tier options as available
    • Click “Get Free License” → Should create license
  5. Test upgrade flow:
    • From free account, click “Upgrade to Pro”
    • Should redirect to signup.html with email
    • Complete checkout
    • Return to manage.html → Should now show Pro

Security Considerations

No Sensitive Data Exposed

The /api/account/status endpoint returns:

Does NOT return:

Rate Limiting

Consider adding rate limiting to prevent abuse:

from flask_limiter import Limiter

limiter = Limiter(app, key_func=lambda: request.remote_addr)

@app.route('/api/account/status', methods=['POST'])
@limiter.limit("10 per minute")
def account_status():
    # ...

Future Enhancements

  1. Add password reset/change (if implementing auth)
  2. Show usage statistics (searches performed, exports made)
  3. Billing history (via Stripe customer portal)
  4. Referral program (earn free Pro months)
  5. Team/organization accounts
  6. Annual billing option (save 20%)

Files Modified/Created

Created:

  1. manage.html - Complete manage account page
  2. MANAGE_ACCOUNT.md - This documentation

Modified:

  1. ../transparency-chrome/server/app.py - Added /api/account/status endpoint (lines 889-921)

TODO:

  1. Add “Manage Account” link to navigation in:
    • index.html
    • signup.html
    • terms.html
    • privacy.html
  2. Set up Stripe customer portal (for downgrades)

  3. Test end-to-end flows

Status: ✅ Complete and ready for deployment Last Updated: November 23, 2025