Legal Pages #

Guide to customizing and managing Terms of Service and Privacy Policy pages that integrate with the signup flow.

Overview #

ServerMonitor includes built-in legal pages that automatically integrate with the SaasBase signup flow. These pages are:

  • Terms of Service (/legal/terms)
  • Privacy Policy (/legal/privacy)

The pages are currently pre-configured for Pulsey but can be customized for your deployment.

Route Configuration #

Automatic Routes:

// Registered in Plugin.php boot() method
Route::group(['prefix' => 'legal'], function() {
    Route::get('terms', function() {
        $controller = new Legal;
        return $controller->run('terms');
    });

    Route::get('privacy', function() {
        $controller = new Legal;
        return $controller->run('privacy');
    });
});

Public Access:

// Legal controller allows public access
public $publicActions = ['terms', 'privacy'];

No authentication required - these pages are accessible to anyone.

Default Content Structure #

Terms of Service Page:

  • Service description and acceptance
  • User responsibilities and restrictions
  • Content ownership and licensing
  • Payment and subscription terms
  • Termination procedures
  • Limitation of liability
  • Contact information

Privacy Policy Page:

  • Data collection practices
  • Cookie usage
  • Payment information handling
  • Data usage and sharing policies
  • Data retention periods
  • Security measures
  • GDPR/CCPA compliance statements
  • User rights and contact information

Branding Integration #

Automatic Branding #

Brand Variables:

// Brand configuration passed to legal pages
$this->vars['brand'] = Config::get('albrightlabs.saasbase::config.brand', []);

Available Brand Variables:

  • brand.name - Service name (e.g., "Pulsey")
  • brand.company_name - Company name
  • brand.support_email - Support email address
  • brand.support_phone - Support phone number
  • brand.company_address - Company address
  • brand.logo - Brand logo URL

Usage in Templates:

<!-- Example from terms page -->
<h3>{{ brand.name }} Terms of Service</h3>
<p>Welcome to {{ brand.name }}! Before you get started...</p>

<!-- Contact section -->
<p>Contact us at <a href="mailto:{{ brand.support_email }}">{{ brand.support_email }}</a></p>

Layout Integration #

Shared Layout:

// Uses signup layout for consistency
$this->layout = 'signup';
$this->bodyClass = 'signup-page';

Responsive Design:

.signup-page .form {
    max-width: 600px; /* Optimal reading width */
}

Customization Options #

Option 1: Override Controller Views #

Create Custom Views:

plugins/yourcompany/yourplugin/
├── controllers/
│   └── legal/
│       ├── terms.htm
│       └── privacy.htm

Custom Terms Content:

<!-- plugins/yourcompany/yourplugin/controllers/legal/terms.htm -->
<?php Block::put('body') ?>

<?= $this->makePartial('$/albrightlabs/saasbase/controllers/account/_branding.php', ['brand' => $brand]) ?>

<div class="form mt-5">
    <h3 class="mb-3 text-center">{{ brand.name }} Terms of Service</h3>

    <!-- Your custom terms content -->
    <p>Welcome to {{ brand.name }}! Your custom terms here...</p>

    <!-- Keep standard sections or customize -->
    <h6 class="mb-2">1. Service Description</h6>
    <p>{{ brand.name }} provides monitoring services for...</p>

    <!-- Contact section with brand variables -->
    <p>Contact us at <a href="mailto:{{ brand.support_email }}">{{ brand.support_email }}</a></p>
</div>

<?php Block::endPut() ?>

Option 2: Override Controller #

Create Custom Legal Controller:

<?php namespace YourCompany\YourPlugin\Controllers;

use Config;
use Backend\Classes\Controller;

class Legal extends Controller
{
    public $publicActions = ['terms', 'privacy'];

    public function __construct()
    {
        parent::__construct();
        $this->layout = 'signup';
    }

    public function terms()
    {
        $this->bodyClass = 'signup-page';
        $this->pageTitle = 'Terms of Service';

        // Pass custom data to view
        $this->vars['brand'] = Config::get('albrightlabs.saasbase::config.brand', []);
        $this->vars['customData'] = $this->getCustomTermsData();
    }

    public function privacy()
    {
        $this->bodyClass = 'signup-page';
        $this->pageTitle = 'Privacy Policy';

        $this->vars['brand'] = Config::get('albrightlabs.saasbase::config.brand', []);
        $this->vars['customData'] = $this->getCustomPrivacyData();
    }

    protected function getCustomTermsData()
    {
        return [
            'service_type' => 'Infrastructure Monitoring',
            'data_retention' => '90 days',
            'liability_limit' => '$10,000',
        ];
    }
}

Register Custom Routes:

// In your plugin's boot() method
Route::group(['prefix' => 'legal'], function() {
    Route::get('terms', [\YourCompany\YourPlugin\Controllers\Legal::class, 'terms']);
    Route::get('privacy', [\YourCompany\YourPlugin\Controllers\Legal::class, 'privacy']);
});

Configure External URLs:

# Point to external legal pages
LEGAL_TOS_URL="https://yourcompany.com/terms"
LEGAL_PRIVACY_URL="https://yourcompany.com/privacy"

SaasBase Integration:

// SaasBase will use these URLs in signup flow
$tosUrl = env('LEGAL_TOS_URL', '/legal/terms');
$privacyUrl = env('LEGAL_PRIVACY_URL', '/legal/privacy');

Content Customization Examples #

Technology-Specific Terms #

SaaS Monitoring Service:

<h6 class="mb-2">2. Service Description</h6>
<p>{{ brand.name }} provides automated monitoring services for web applications,
servers, and online services. Our platform checks your endpoints at regular
intervals and provides notifications when issues are detected.</p>

<h6 class="mb-2">3. Service Availability</h6>
<p>We strive to maintain 99.9% uptime for our monitoring service. However,
we do not guarantee continuous, uninterrupted access to the service.</p>

Data Processing Terms:

<h6 class="mb-2">4. Data Collection and Processing</h6>
<p>By using {{ brand.name }}, you consent to our collection and processing of:</p>
<ul>
    <li>Server endpoint URLs and response data</li>
    <li>User contact information for notifications</li>
    <li>Usage analytics to improve our service</li>
</ul>

Industry-Specific Privacy #

Healthcare Compliance:

<h6 class="mb-2">HIPAA Compliance</h6>
<p>If you use {{ brand.name }} to monitor healthcare-related systems,
you acknowledge that you are responsible for ensuring compliance with
HIPAA regulations. We provide security measures but cannot guarantee
HIPAA compliance without a signed Business Associate Agreement.</p>

Financial Services:

<h6 class="mb-2">Financial Data</h6>
<p>{{ brand.name }} does not collect, store, or process financial data
from the systems we monitor. We only collect HTTP response codes and
basic availability metrics.</p>

Multi-Deployment Considerations #

Pulsey (Business Focus):

<p>{{ brand.name }} is designed for growing businesses that need reliable
monitoring of their online services. Our platform provides enterprise-grade
monitoring with an easy-to-use interface.</p>

Heartbeat (Developer Focus):

<p>{{ brand.name }} is built by developers, for developers. We understand
the need for simple, effective monitoring that gets out of your way and
just works.</p>

Enterprise Focus:

<p>{{ brand.name }} provides enterprise-grade infrastructure monitoring
with advanced features for mission-critical systems. Our platform is
designed to meet the needs of large organizations.</p>

Jurisdiction-Specific Content #

US-Based Service:

<h6 class="mb-2">8. Governing Law</h6>
<p>These terms are governed by the laws of the Commonwealth of Pennsylvania,
United States, without regard to conflict of law principles.</p>

International Service:

<h6 class="mb-2">8. International Users</h6>
<p>If you are accessing {{ brand.name }} from outside the United States,
you agree that your data may be transferred to and processed in the
United States.</p>

Integration with Signup Flow #

SaasBase Integration #

Automatic Linking:

  • Terms checkbox in signup form automatically links to /legal/terms
  • Privacy policy referenced in data collection notices
  • Footer links generated automatically

Checkbox Implementation:

<!-- In SaasBase signup form -->
<label>
    <input type="checkbox" name="agree_to_terms" required>
    I agree to the <a href="/legal/terms" target="_blank">Terms of Service</a>
    and <a href="/legal/privacy" target="_blank">Privacy Policy</a>
</label>

Validation:

// SaasBase validates terms acceptance
$rules['agree_to_terms'] = 'required|accepted';

Email Integration #

Welcome Email References:

<!-- In welcome email template -->
<p>By signing up, you've agreed to our
<a href="{{ url('/legal/terms') }}">Terms of Service</a> and
<a href="{{ url('/legal/privacy') }}">Privacy Policy</a>.</p>

Notification Footer:

<!-- In notification emails -->
<p class="legal-footer">
This notification is sent in accordance with our
<a href="{{ url('/legal/privacy') }}">Privacy Policy</a>.
To manage your notification preferences, visit your account settings.
</p>

SEO and Accessibility #

Search Engine Optimization #

Meta Tags:

<head>
    <title>{{ brand.name }} Terms of Service</title>
    <meta name="description" content="Terms of Service for {{ brand.name }} monitoring platform">
    <meta name="robots" content="index, follow">
</head>

Structured Data:

<script type="application/ld+json">
{
    "@context": "https://schema.org",
    "@type": "WebPage",
    "name": "{{ brand.name }} Terms of Service",
    "description": "Legal terms for using {{ brand.name }} monitoring service",
    "publisher": {
        "@type": "Organization",
        "name": "{{ brand.company_name }}"
    }
}
</script>

Accessibility #

Semantic HTML:

<main role="main">
    <article>
        <h1>{{ brand.name }} Terms of Service</h1>

        <nav aria-label="Terms of Service Contents">
            <ol>
                <li><a href="#acceptance">Acceptance of Terms</a></li>
                <li><a href="#description">Service Description</a></li>
                <!-- ... -->
            </ol>
        </nav>

        <section id="acceptance">
            <h2>1. Acceptance of Terms</h2>
            <!-- Content -->
        </section>
    </article>
</main>

WCAG Compliance:

  • Use proper heading hierarchy (h1 → h2 → h3)
  • Ensure sufficient color contrast
  • Provide keyboard navigation
  • Include alt text for any images
  • Use descriptive link text

Version Control #

Track Legal Changes:

legal-versions/
├── terms-v1.0-2024-01-01.html
├── terms-v1.1-2024-06-01.html
├── privacy-v1.0-2024-01-01.html
└── privacy-v1.1-2024-06-01.html

Change Notification:

// Notify users of legal changes
Event::listen('legal.terms.updated', function($version) {
    $users = User::where('notify_legal_changes', true)->get();

    foreach ($users as $user) {
        Mail::send('legal.change_notification', [
            'user' => $user,
            'version' => $version,
            'changes' => $version->changes
        ], function($message) use ($user) {
            $message->to($user->email);
            $message->subject('Terms of Service Updated');
        });
    }
});

Review Checklist:

  • [ ] Legal counsel review - Have attorney review changes
  • [ ] Brand compliance - Ensure brand-specific content is accurate
  • [ ] Technical accuracy - Verify service descriptions match features
  • [ ] Jurisdiction compliance - Check local law requirements
  • [ ] User notification - Plan communication for significant changes

Approval Workflow:

  1. Draft changes in staging environment
  2. Legal counsel review and approval
  3. Business stakeholder review
  4. Technical accuracy verification
  5. Deploy to production
  6. Notify users if required

Functional Testing #

Page Load Testing:

# Test legal page accessibility
curl -I https://yoursite.com/legal/terms
curl -I https://yoursite.com/legal/privacy

# Check for proper HTTP headers
curl -H "Accept: text/html" https://yoursite.com/legal/terms | grep "<title>"

Branding Verification:

// Test brand variable substitution
$response = $this->get('/legal/terms');
$response->assertSee($brandName);
$response->assertSee($supportEmail);

Integration Testing #

Signup Flow Testing:

// Test that terms checkbox works
$response = $this->post('/register', [
    'name' => 'Test User',
    'email' => 'test@example.com',
    'password' => 'password',
    'agree_to_terms' => false // Should fail
]);
$response->assertSessionHasErrors('agree_to_terms');

Link Verification:

# Check all legal links are working
linkchecker https://yoursite.com/legal/terms
linkchecker https://yoursite.com/legal/privacy

Compliance Considerations #

Required Disclosures #

Service-Specific Disclosures:

  • Data collection practices
  • Third-party integrations (Twilio, email services)
  • International data transfers
  • Retention policies
  • User rights and contact procedures

Jurisdiction Requirements:

  • EU/GDPR: Right to erasure, data portability, consent management
  • California/CCPA: Right to know, delete, opt-out of sale
  • Canada/PIPEDA: Purpose limitation, consent requirements

Regular Updates #

Annual Review:

  • Review service descriptions for accuracy
  • Update contact information
  • Verify compliance with new regulations
  • Check third-party service changes

Trigger Events for Updates:

  • New features that affect data collection
  • Changes to third-party services
  • New legal requirements
  • Business model changes

Previous: ← Security | Next: Migration Guide →