Skip to content

Latest commit

 

History

History
451 lines (339 loc) · 11.4 KB

File metadata and controls

451 lines (339 loc) · 11.4 KB

EduLift Deep Link Configuration Guide

Overview

This guide explains how to configure and manage the EduLift deep link system across different environments. The system uses a three-tier fallback strategy to ensure reliable URL generation for mobile app deep linking and web fallbacks.

Architecture Overview

Environment Types

  • Development: Local development with custom protocol
  • E2E Testing: Automated testing environment
  • Staging: Pre-production testing on real infrastructure
  • Production: Live production environment

URL Types

  1. DEEP_LINK_BASE_URL: Primary deep link URL for mobile apps
  2. FRONTEND_URL: Web fallback URL
  3. Emergency Fallback: localhost URL for development

Environment Configuration

Development Environment

Purpose: Local development and testing

Configuration:

# .env.development
NODE_ENV=development
DEEP_LINK_BASE_URL=edulift://
FRONTEND_URL=http://localhost:3000

Behavior:

  • Uses edulift:// custom protocol for mobile app deep linking
  • Falls back to http://localhost:3000 for web access
  • Enables debug logging for URL generation troubleshooting

Use Cases:

  • Local development with mobile app simulator
  • Testing deep link functionality
  • Debugging URL generation logic

E2E Testing Environment

Purpose: Automated end-to-end testing

Configuration:

# .env.e2e
NODE_ENV=e2e
DEEP_LINK_BASE_URL=edulift://
FRONTEND_URL=http://localhost:3000

Behavior:

  • Same as development for consistency in automated tests
  • Optimized for CI/CD pipeline integration
  • Mock mobile app behavior for testing

Use Cases:

  • Automated testing of deep link flows
  • CI/CD pipeline integration
  • Regression testing

Staging Environment

Purpose: Pre-production testing on real infrastructure

Configuration:

# Generated by Ansible
NODE_ENV=staging
DEEP_LINK_BASE_URL=https://transport.tanjama.fr:50443/
FRONTEND_URL=https://transport.tanjama.fr:50443

Behavior:

  • Uses HTTPS with custom port (50443) for staging
  • Real infrastructure testing with production-like setup
  • Allows testing on physical mobile devices

Use Cases:

  • User acceptance testing (UAT)
  • Mobile device testing on real hardware
  • Performance and load testing

Production Environment

Purpose: Live production deployment

Configuration:

# Generated by Ansible
NODE_ENV=production
DEEP_LINK_BASE_URL=https://transport.tanjama.fr/
FRONTEND_URL=https://transport.tanjama.fr

Behavior:

  • Standard HTTPS on port 443
  • Optimized for production mobile app experience
  • Enhanced security validation

Use Cases:

  • Live user interactions
  • Production mobile app deep linking
  • Real-world usage scenarios

Configuration Methods

1. Ansible Template System (Recommended)

File: deploy/ansible/templates/_url_macros.j2

The deep link URLs are generated dynamically using Jinja2 macros:

{% macro deep_link_url(environment) -%}
{% if environment in ['development', 'e2e'] %}
edulift://
{% elif environment == 'staging' %}
{{ protocol }}://{{ base_domain }}:50443/
{% elif environment == 'production' %}
{{ protocol }}://{{ base_domain }}{% if https_port != 443 %}:{{ https_port }}{% endif %}/
{% endif %}
{%- endmacro %}

Usage in Environment Template:

{# deploy/ansible/templates/env.j2 #}
{% set deep_link_base_url = url.deep_link_url(deployment_environment) %}
DEEP_LINK_BASE_URL={{ deep_link_base_url }}

2. Manual Override via Ansible Inventory

File: inventory/group_vars/all.yml

edulift_deployment:
  urls:
    deep_link_base: "https://custom.example.com/"
    frontend: "https://custom.example.com"
    backend: "https://api.custom.example.com"
    traefik_dashboard: "https://traefik.custom.example.com"

Priority: Manual overrides take precedence over generated URLs

3. Environment Variables (Local Development)

File: .env.local

# Override for local testing
DEEP_LINK_BASE_URL=https://dev.example.com/
FRONTEND_URL=https://dev.example.com

Use Case: Temporary local testing with specific configuration

URL Generation Logic

Fallback Strategy

The system uses a three-tier fallback approach:

  1. Primary: DEEP_LINK_BASE_URL (environment-specific)
  2. Secondary: FRONTEND_URL (web fallback)
  3. Tertiary: http://localhost:3000 (emergency fallback)

Implementation

// BaseEmailService.generateUrl()
protected generateUrl(path: string, params?: URLSearchParams): string {
  const candidateUrls = [
    process.env.DEEP_LINK_BASE_URL,
    process.env.FRONTEND_URL,
    'http://localhost:3000'
  ];

  // Try each URL until finding a valid one
  for (let i = 0; i < candidateUrls.length; i++) {
    const candidateUrl = candidateUrls[i];
    if (candidateUrl && this.validateDeepLinkUrl(candidateUrl)) {
      urlSource = i === 0 ? 'DEEP_LINK_BASE_URL' :
                  i === 1 ? 'FRONTEND_URL' :
                  'localhost fallback';
      return this.buildUrl(candidateUrl, path, params);
    }
  }
}

Security Configuration

URL Validation

All URLs undergo comprehensive security validation:

// Security checks performed
- Protocol validation (http, https, edulift)
- Hostname security validation
- Private IP blocking in production
- XSS and injection pattern detection
- Format validation

Environment-Specific Security

Development/E2E:

  • Allows localhost and private IPs
  • Relaxed security for local testing
  • Debug logging enabled

Staging/Production:

  • Blocks private IP addresses
  • Enhanced hostname validation
  • Suspicious pattern detection
  • Production logging only

Testing Configuration

Unit Testing

File: backend/src/services/__tests__/BaseEmailService.test.ts

describe('Deep Link URL Generation', () => {
  test('generates correct URLs for each environment', () => {
    // Test development URLs
    process.env.DEEP_LINK_BASE_URL = 'edulift://';
    const devUrl = emailService.generateUrl('groups/join', params);
    expect(devUrl).toBe('edulift://groups/join?code=ABC123');

    // Test staging URLs
    process.env.DEEP_LINK_BASE_URL = 'https://staging.example.com/';
    const stagingUrl = emailService.generateUrl('groups/join', params);
    expect(stagingUrl).toBe('https://staging.example.com/groups/join?code=ABC123');
  });
});

Integration Testing

Test Environment Setup:

# Set up test environment
export NODE_ENV=test
export DEEP_LINK_BASE_URL=https://test.example.com/
export FRONTEND_URL=https://test.example.com

# Run integration tests
npm run test:integration

Troubleshooting Guide

Common Issues

1. Deep Links Not Opening on Mobile

Symptoms:

  • Mobile app doesn't open when clicking deep links
  • Links open in web browser instead of app

Solutions:

  1. Verify app association with edulift:// protocol
  2. Check universal link configuration for HTTPS URLs
  3. Ensure mobile app is properly installed
  4. Test with different mobile devices

Verification Commands:

# Test deep link URL format
curl -I "edulift://groups/join?code=TEST123"

# Test HTTPS deep link
curl -I "https://transport.tanjama.fr/groups/join?code=TEST123"

2. Fallback URLs Not Working

Symptoms:

  • Primary deep link fails but fallback doesn't work
  • Broken links in email notifications

Solutions:

  1. Verify FRONTEND_URL configuration
  2. Check network connectivity to fallback URLs
  3. Test URL validation logic
  4. Verify Ansible template generation

Debug Steps:

# Check environment variables
echo $DEEP_LINK_BASE_URL
echo $FRONTEND_URL

# Test URL generation
npm run test:unit -- --testNamePattern="generateUrl"

3. Security Validation Failures

Symptoms:

  • URLs rejected by security validation
  • Console warnings about invalid URLs

Solutions:

  1. Review URL format and protocol
  2. Check for suspicious patterns in hostname
  3. Verify environment-specific security rules
  4. Update validation rules if needed

Debug Logging:

// Enable debug logging
process.env.NODE_ENV = 'development';
// Check console for validation details

Debug Tools

Environment Debugging

# Show current configuration
echo "Node Environment: $NODE_ENV"
echo "Deep Link Base URL: $DEEP_LINK_BASE_URL"
echo "Frontend URL: $FRONTEND_URL"

# Test URL generation
node -e "
const { BaseEmailService } = require('./dist/services/base/BaseEmailService');
console.log('Generated URL:', new TestEmailService().generateUrl('test'));
"

Ansible Template Debugging

# Test template generation
ansible-playbook -i inventory/test playbooks/deploy.yml \
  --tags=debug \
  --extra-vars="deployment_environment=staging"

# Show rendered environment file
cat .generated/env-staging.txt

Migration Guide

From Legacy Platform System

Old Configuration:

# Legacy system
PLATFORM=fcm
INVITE_BASE_URL=https://app.example.com/invite

New Configuration:

# New deep link system
DEEP_LINK_BASE_URL=https://app.example.com/
FRONTEND_URL=https://app.example.com

Migration Steps:

  1. Update Ansible templates
  2. Modify environment configuration files
  3. Update application code to use generateUrl()
  4. Test all deep link flows
  5. Update documentation

Version Compatibility

  • v1.x: Legacy platform-based system
  • v2.x: Current deep link system with fallbacks
  • v3.x: Future enhancements (planned)

Best Practices

Configuration Management

  1. Use Ansible Templates: Avoid hardcoded URLs
  2. Environment-Specific: Different configurations per environment
  3. Override Support: Allow manual overrides when needed
  4. Validation: Always validate URLs before deployment

Security

  1. Protocol Validation: Only allow approved protocols
  2. Hostname Security: Block suspicious hostnames
  3. Environment Isolation: Different security rules per environment
  4. Regular Audits: Review URL validation rules

Testing

  1. Unit Tests: Test URL generation logic
  2. Integration Tests: Test end-to-end flows
  3. Environment Testing: Test all environments
  4. Mobile Testing: Test on real mobile devices

Monitoring

  1. URL Generation Logs: Monitor URL source and validation
  2. Error Tracking: Track failed URL generation
  3. Performance: Monitor URL generation performance
  4. Usage Analytics: Track deep link usage patterns

Reference

File Locations

  • URL Macros: deploy/ansible/templates/_url_macros.j2
  • Environment Template: deploy/ansible/templates/env.j2
  • Base Email Service: backend/src/services/base/BaseEmailService.ts
  • Unit Tests: backend/src/services/__tests__/BaseEmailService.test.ts

Configuration Variables

Variable Purpose Example
DEEP_LINK_BASE_URL Primary deep link URL edulift://
FRONTEND_URL Web fallback URL https://app.example.com
NODE_ENV Environment identifier production
https_port HTTPS port configuration 443
base_domain Base domain name transport.tanjama.fr

Command Reference

# Generate configuration for specific environment
ansible-playbook -i inventory/production playbooks/configure.yml \
  --extra-vars="deployment_environment=production"

# Test URL generation locally
npm run test:unit -- --testNamePattern="Deep Link"

# Validate Ansible templates
ansible-playbook -i inventory/test playbooks/deploy.yml \
  --check --diff --tags=templates