monorepo/web/maplepress-frontend/docs/API/REGISTRATION_API.md

480 lines
14 KiB
Markdown

# 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