# Registration API Implementation This document describes the complete implementation of the user registration feature for the MaplePress frontend, integrated with the MaplePress backend API. ## Overview The registration feature allows new users to create an account and automatically sets up their tenant (organization) in a single step. Upon successful registration, users receive authentication tokens and are automatically logged in. ## Backend API Endpoint **Endpoint**: `POST /api/v1/register` **Authentication**: None required (public endpoint) **Documentation**: `/cloud/maplepress-backend/docs/API.md` (lines 66-166) ### Request Structure ```json { "email": "user@example.com", "password": "SecurePassword123!", "confirm_password": "SecurePassword123!", "first_name": "John", "last_name": "Doe", "tenant_name": "Acme Corporation", "timezone": "America/New_York", "agree_terms_of_service": true, "agree_promotions": false, "agree_to_tracking_across_third_party_apps_and_services": false } ``` ### Response Structure ```json { "user_id": "550e8400-e29b-41d4-a716-446655440000", "user_email": "user@example.com", "user_name": "John Doe", "user_role": "manager", "tenant_id": "650e8400-e29b-41d4-a716-446655440000", "tenant_name": "Acme Corporation", "tenant_slug": "acme-corp", "session_id": "750e8400-e29b-41d4-a716-446655440000", "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "access_expiry": "2024-10-24T12:00:00Z", "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refresh_expiry": "2024-11-24T00:00:00Z", "created_at": "2024-10-24T00:00:00Z" } ``` ## Frontend Implementation ### 1. RegisterService (`src/services/API/RegisterService.js`) Handles direct communication with the backend registration API. **Key Features:** - Request validation (required fields, terms agreement) - Request body formatting (snake_case for backend) - Response transformation (camelCase for frontend) - User-friendly error message mapping - Tenant slug validation and generation utilities **Methods:** - `register(data)` - Main registration method - `validateTenantSlug(slug)` - Validate slug format - `generateTenantSlug(name)` - Auto-generate slug from name **Usage:** ```javascript import RegisterService from './services/API/RegisterService'; const response = await RegisterService.register({ email: "user@example.com", password: "SecurePassword123!", confirmPassword: "SecurePassword123!", first_name: "John", last_name: "Doe", tenant_name: "Acme Corp", agree_terms_of_service: true, }); ``` ### 2. AuthManager (`src/services/Manager/AuthManager.js`) Manages authentication state, token storage, and session lifecycle. **Key Features:** - Token management (access & refresh tokens) - LocalStorage persistence - Token expiry checking - User and tenant data storage - Session initialization and cleanup **New Methods:** - `register(registrationData)` - Register and store auth data - `storeAuthData(authResponse)` - Store tokens and user data - `clearSession()` - Clear all auth data - `isTokenExpired(expiry)` - Check token expiry - `getTenant()` - Get current tenant information **Storage Keys:** ```javascript maplepress_access_token maplepress_refresh_token maplepress_access_expiry maplepress_refresh_expiry maplepress_user maplepress_tenant maplepress_session_id ``` ### 3. Register Page (`src/pages/Auth/Register.jsx`) Complete registration form with all required fields. **Form Sections:** 1. **Personal Information** - First Name (required) - Last Name (required) - Email Address (required) - Password (required, min 8 chars) - Confirm Password (required) 2. **Organization Information** - Organization Name (required, slug auto-generated by backend) 3. **Terms and Consent** - Terms of Service agreement (required) - Promotional emails (optional) **Features:** - Password match validation (backend-validated) - Terms of service requirement - Automatic timezone detection - Loading state during submission - RFC 9457 error message display with field-specific errors ## Data Flow ``` User fills form ↓ Register.jsx validates data ↓ AuthManager.register(data) ↓ RegisterService.register(data) ↓ HTTP POST to /api/v1/register ↓ Backend validates and creates user + tenant ↓ Backend returns tokens and user data ↓ RegisterService transforms response ↓ AuthManager stores tokens in localStorage ↓ User redirected to /dashboard ``` ## Validation Rules ### Frontend Validation 1. **Email**: Required, valid email format 2. **Password**: - Required - Minimum 8 characters 3. **Confirm Password**: - Required - Must match password (validated by backend) 4. **Name**: Required 5. **Tenant Name**: Required 6. **Tenant Slug**: - Required - Only lowercase letters, numbers, and hyphens - Validated by regex: `/^[a-z0-9-]+$/` 7. **Terms of Service**: Must be checked ### Backend Validation Backend performs additional validation: - Email normalization and format validation - Password strength requirements (uppercase, lowercase, number, special char) - Password confirmation matching - Tenant slug uniqueness - Email uniqueness - No HTML in text fields - Input sanitization ## Error Handling ### RFC 9457 (Problem Details for HTTP APIs) The backend returns validation errors in **RFC 9457** format, which provides a structured, machine-readable error response. **Error Response Structure**: ```json { "type": "about:blank", "title": "Validation Error", "status": 400, "detail": "One or more validation errors occurred", "errors": { "email": ["Invalid email format"], "password": ["Field is required", "Password must be at least 8 characters"], "confirm_password": ["Field is required", "Passwords do not match"], "first_name": ["Field is required"], "last_name": ["Field is required"], "tenant_name": ["Field is required"], "agree_terms_of_service": ["Must agree to terms of service"] } } ``` **Content-Type**: `application/problem+json` **Key Fields**: - `type`: URI reference identifying the problem type (uses `about:blank` for generic errors) - `title`: Short, human-readable summary of the error type - `status`: HTTP status code - `detail`: Human-readable explanation of the error - `errors`: Dictionary/map of field-specific validation errors (extension field) ### Common Validation Errors | Field | Error Message | |-------|--------------| | email | `email: invalid email format` | | email | `email: email is required` | | password | `password: password is required` | | password | `password: password must be at least 8 characters` | | password | `password: password must contain at least one uppercase letter (A-Z)` | | password | `password: password must contain at least one lowercase letter (a-z)` | | password | `password: password must contain at least one number (0-9)` | | password | `password: password must contain at least one special character` | | confirm_password | `confirm_password: field is required` | | confirm_password | `confirm_password: passwords do not match` | | first_name | `first_name: field is required` | | first_name | `first_name: first_name must be between 1 and 100 characters` | | last_name | `last_name: field is required` | | last_name | `last_name: last_name must be between 1 and 100 characters` | | tenant_name | `tenant_name: tenant_name is required` | | tenant_name | `tenant_name: tenant_name must be between 1 and 100 characters` | | agree_terms_of_service | `agree_terms_of_service: must agree to terms of service` | ### Frontend Error Parsing The Register page component (`src/pages/Auth/Register.jsx`) includes a `parseBackendError()` function that: 1. Checks if the error object contains RFC 9457 `validationErrors` structure 2. Iterates through the errors dictionary and maps each field to its error messages 3. Joins multiple error messages for the same field with semicolons 4. Displays field-specific errors with red borders and inline messages 5. Shows an error summary box at the top with all errors listed **Error Parsing Implementation**: ```javascript const parseBackendError = (error) => { const fieldErrors = {}; let generalError = null; // Check if error has RFC 9457 validation errors structure if (error.validationErrors && typeof error.validationErrors === 'object') { // Process each field's errors Object.entries(error.validationErrors).forEach(([fieldName, errorMessages]) => { if (Array.isArray(errorMessages) && errorMessages.length > 0) { // Join multiple error messages for the same field fieldErrors[fieldName] = errorMessages.join('; '); } }); // Use the detail as general error if available if (error.message) { generalError = error.message; } } else { // Fallback for non-RFC 9457 errors generalError = error.message || "An error occurred. Please try again."; } return { fieldErrors, generalError }; }; ``` **Example Error Display**: When submitting an empty form, the user sees: - **Error Summary Box**: Lists all validation errors at the top of the form with the general message "One or more validation errors occurred" - **Highlighted Fields**: Red border on email, password, first_name, last_name, tenant_name, etc. - **Inline Messages**: Error text displayed below each affected field (e.g., "Field is required") ### ApiClient Error Handling The `ApiClient` (`src/services/API/ApiClient.js`) automatically parses RFC 9457 error responses and attaches the validation errors to the error object: ```javascript // Create error with RFC 9457 data if available const error = new Error( errorData.detail || errorData.message || `HTTP ${response.status}: ${response.statusText}` ); // Attach RFC 9457 fields to error for parsing if (errorData.errors) { error.validationErrors = errorData.errors; // RFC 9457 validation errors } if (errorData.title) { error.title = errorData.title; } if (errorData.status) { error.status = errorData.status; } throw error; ``` **Note**: The frontend **does not perform field validation** - all validation, including password matching, is handled by the backend. The form submits whatever the user enters, and the backend returns comprehensive validation errors in RFC 9457 format. ## Security Features 1. **Token Storage**: Tokens stored in localStorage (client-side only) 2. **Token Expiry**: Automatic expiry checking on initialization 3. **Password Validation**: Client and server-side validation 4. **HTTPS Required**: Production should use HTTPS 5. **Terms Agreement**: Required before account creation 6. **Input Sanitization**: Backend sanitizes all inputs ## Testing the Registration Flow ### 1. Start Backend ```bash cd cloud/mapleopentech-backend task dev ``` ### 2. Start Frontend ```bash cd web/maplepress-frontend npm run dev ``` ### 3. Navigate to Registration Open browser to: `http://localhost:5173/register` ### 4. Fill Form - **First Name**: John (required) - **Last Name**: Doe (required) - **Email**: test@example.com - **Password**: SecurePass123! - **Confirm Password**: SecurePass123! - **Organization Name**: Test Corp (slug auto-generated by backend) - **Terms of Service**: ✓ (checked) ### 5. Submit Click "Create Account" button ### 6. Expected Result - Loading state appears - Request sent to backend - Tokens stored in localStorage - User redirected to `/dashboard` - Dashboard shows user information ### 7. Verify in Browser Console ```javascript // Check stored tokens localStorage.getItem('maplepress_access_token') localStorage.getItem('maplepress_user') localStorage.getItem('maplepress_tenant') // Check service instance window.maplePressServices.authManager.isAuthenticated() window.maplePressServices.authManager.getUser() window.maplePressServices.authManager.getTenant() ``` ## Configuration ### Environment Variables Create `.env` file: ```bash # Backend API URL VITE_API_BASE_URL=http://localhost:8000 ``` ### Production Configuration For production: ```bash VITE_API_BASE_URL=https://api.maplepress.io ``` ## Future Enhancements ### Planned Features - [ ] Email verification flow - [ ] Password strength indicator - [ ] Captcha integration - [ ] Social authentication (Google, GitHub) - [ ] Organization logo upload - [ ] Custom domain support - [ ] Invitation codes/referrals - [ ] Account recovery flow ### Security Improvements - [ ] CSRF token implementation - [ ] Rate limiting on frontend - [ ] Session fingerprinting - [ ] Two-factor authentication - [ ] Password breach checking - [ ] Secure token storage (HTTP-only cookies) ## File Reference ### Created Files ``` src/services/API/RegisterService.js ``` ### Modified Files ``` src/services/Manager/AuthManager.js src/pages/Auth/Register.jsx ``` ### Backend Reference Files ``` cloud/maplepress-backend/docs/API.md cloud/maplepress-backend/internal/interface/http/dto/gateway/register_dto.go cloud/maplepress-backend/internal/interface/http/handler/gateway/register_handler.go ``` ## API Client Configuration The `ApiClient` automatically handles: - JSON content-type headers - Request/response transformation - Error parsing - Authentication headers (for protected endpoints) ### Base Configuration ```javascript API_CONFIG = { baseURL: import.meta.env.VITE_API_BASE_URL || "http://localhost:8000", timeout: 30000, } ``` ## Support For issues or questions: 1. Check backend logs: `docker logs mapleopentech_backend` 2. Check frontend console for errors 3. Verify backend is running on port 8000 4. Verify frontend environment variables 5. Test backend endpoint directly with curl (see API.md) ## Related Documentation - [ARCHITECTURE.md](./ARCHITECTURE.md) - Frontend architecture overview - [README.md](./README.md) - Getting started guide - [Backend API Documentation](../../cloud/maplepress-backend/docs/API.md) - Complete API reference