Overview
The Document Download Frontend uses Flask’s Blueprint system to organize routes. All routes are defined in themain Blueprint within app/main/views/index.py.
Health Check Routes
Status Endpoint
Route:GET /_status
Function: status() (index.py:23)
Purpose: Health check endpoint for monitoring
Response:
200
Legacy API Redirect Routes
Services Endpoints
Routes:GET /services/_statusGET /services/<uuid:service_id>/documents/<uuid:document_id>GET /services/<uuid:service_id>/documents/<uuid:document_id>.<extension>GET /services/<uuid:service_id>/documents/<uuid:document_id>/check
services() (index.py:30)
Purpose: Legacy endpoints that redirect to the Document Download API
Parameters:
service_id(UUID, optional): Service identifierdocument_id(UUID, optional): Document identifierextension(string, optional): File extension
301 (Permanent Redirect)
Security Policy Routes
Security.txt
Routes:GET /.well-known/security.txtGET /security.txt
security_policy() (index.py:44)
Purpose: Implements GDS Way security vulnerability disclosure policy
Reference: GDS Way Security Standards
Behavior: Redirects to Cabinet Office VDP security.txt
Document Download Routes
Landing Page
Route:GET /d/<base64_uuid:service_id>/<base64_uuid:document_id>
Function: landing() (index.py:52)
Purpose: Initial landing page when user clicks document link
Parameters:
service_id(base64-encoded UUID): Service that sent the documentdocument_id(base64-encoded UUID): Document identifierkey(query parameter, required): Decryption key for the document
- Validates
keyquery parameter exists (404 if missing) - Fetches service information via
ServiceApiClient - Retrieves document metadata from Document Download API
- Checks if email confirmation is required via
confirm_emailmetadata field - Routes to appropriate next step:
- If
confirm_emailisTrue: redirects to email confirmation - Otherwise: redirects to download page
- If
- Returns
file-unavailable.htmltemplate for 404/410 errors - Aborts with 404 if
keyparameter missing
views/landing.html
Example:
Email Confirmation
Route:GET|POST /d/<base64_uuid:service_id>/<base64_uuid:document_id>/confirm-email-address
Function: confirm_email_address() (index.py:102)
Purpose: Verify user’s email address before allowing download
Parameters:
service_id(base64-encoded UUID): Service identifierdocument_id(base64-encoded UUID): Document identifierkey(query parameter, required): Decryption key
- Validates
keyexists (404 if missing) - Fetches service information
- Retrieves document metadata
- If
confirm_emailisFalse, redirects to download page - Displays email confirmation form
- Validates email address using
EmailAddressForm - Authenticates email via Document Download API
- On success:
- Sets
document_access_signed_datacookie with authentication token - Cookie configured with proper domain, path, and security flags
- Redirects to download page
- Sets
- On failure:
- Returns error message:
- Returns 429 error if too many authentication attempts
views/confirm-email-address.html
Status Codes:
200: Form displayed successfully400: Form validation errors429: Too many requests
Download Page
Route:GET /d/<base64_uuid:service_id>/<base64_uuid:document_id>/download
Function: download_document() (index.py:185)
Purpose: Display download page with file information and download link
Parameters:
service_id(base64-encoded UUID): Service identifierdocument_id(base64-encoded UUID): Document identifierkey(query parameter, required): Decryption key
- Validates
keyparameter (404 if missing) - Fetches service information
- Retrieves document metadata including:
direct_file_url: Pre-signed download URLsize_in_bytes: File sizefile_extension: File typeavailable_until: Expiry timestamp
- Formats display information:
- File size: via
format_file_size() - File type: via
format_file_type() - Expiry date: via
_format_file_expiry_date()
- File size: via
download_link: Direct URL to download filefile_size: Human-readable file size (e.g., “2.5 MB”)file_type: Human-readable file type (e.g., “PDF”)service_name: Name of sending serviceservice_contact_info: Support contactcontact_info_type: Type of contact (link, email, phone)file_expiry_date: Formatted expiry date
views/download.html
Helper Functions
Format File Expiry Date
Function:_format_file_expiry_date() (index.py:221)
Purpose: Format ISO timestamp into user-friendly date
Parameters:
available_until(str): ISO 8601 timestamp
- Within 30 days:
"Monday 15 March 2026" - After 30 days:
"15 March 2026"
Get Service
Function:_get_service_or_raise_error() (index.py:234)
Purpose: Fetch service details from Notify API
Parameters:
service_id: Service UUID
Get Document Metadata
Function:_get_document_metadata() (index.py:241)
Purpose: Retrieve document metadata from Document Download API
Parameters:
service_id: Service UUIDdocument_id: Document UUIDkey: Decryption key
400with “decryption key” or “Forbidden” in error message → 404403or404→ 404410→ 410 (Gone)- Missing
available_untilor expired document → 410
Authenticate Document Access
Function:_authenticate_access_to_document() (index.py:276)
Purpose: Verify email address with Document Download API
Parameters:
service_id: Service UUIDdocument_id: Document UUIDkey: Decryption keyemail_address: Email to verify
signed_data and cookie_path, or None on auth failure
API Endpoint:
429→ RaisesTooManyRequestsexception400or403→ ReturnsNone(authentication failed)- Other errors → Raises for 500 handler
URL Converters
The application uses custom URL converters for base64-encoded UUIDs: Converter:base64_uuid
Purpose: Decode base64-encoded UUIDs from URL paths
Usage: