From ae19ec9c3d0ef1f527036718da0214205667ba3d Mon Sep 17 00:00:00 2001 From: alphaeusmote <41258468-alphaeusmote@users.noreply.replit.com> Date: Sat, 24 May 2025 02:16:17 +0000 Subject: [PATCH] Document project architecture, setup, usage, and API endpoints Adds comprehensive documentation including architecture, API reference, deployment, development, and user guides with README.md. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 9111ef36-26c8-4085-84ca-a35dc1fec1b5 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7083d608-d6d3-4a6a-9a27-6286c5109627/910f6160-6716-488e-83e6-61256595c269.jpg --- README.md | 129 +++++++++ docs/api-reference.md | 586 ++++++++++++++++++++++++++++++++++++++ docs/architecture.md | 118 ++++++++ docs/deployment-guide.md | 380 ++++++++++++++++++++++++ docs/development-guide.md | 505 ++++++++++++++++++++++++++++++++ docs/user-guide.md | 237 +++++++++++++++ 6 files changed, 1955 insertions(+) create mode 100644 README.md create mode 100644 docs/api-reference.md create mode 100644 docs/architecture.md create mode 100644 docs/deployment-guide.md create mode 100644 docs/development-guide.md create mode 100644 docs/user-guide.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..6978e1b --- /dev/null +++ b/README.md @@ -0,0 +1,129 @@ +# DynamoDNS + +A comprehensive web-based dynamic DNS management platform offering advanced infrastructure control, monitoring, and multi-provider integration with a focus on user experience and security. + +![DynamoDNS Dashboard](docs/images/dashboard-preview.png) + +## Features + +- **Multi-Provider DNS Management**: Support for Cloudflare, AWS Route53, GoDaddy, and custom providers +- **Dynamic DNS Updates**: Automatic IP detection and DNS record updates +- **Role-Based Access Control**: Granular permissions with customizable roles +- **Customer Management**: Support for multiple organizations with isolated access +- **Historical Tracking**: Complete audit trail of DNS changes +- **Performance Metrics**: Visualize DNS performance and activity +- **API Integration**: RESTful API with token-based authentication +- **Webhook Notifications**: Real-time notifications for DNS events +- **Multi-Factor Authentication**: Enhanced security for user accounts +- **Customizable Dashboards**: Personalized monitoring views + +## Technology Stack + +- **Backend**: + - Express.js for API server + - PostgreSQL for robust data storage + - Drizzle ORM for database interactions + - Passport.js for multi-method authentication + - WebSockets for real-time updates + +- **Frontend**: + - React for user interface + - TanStack Query for data fetching and caching + - Shadcn UI components for consistent design + - Tailwind CSS for styling + - Recharts for data visualization + +## Getting Started + +### Prerequisites + +- Node.js (v18 or later) +- PostgreSQL (v14 or later) +- Modern web browser + +### Installation + +1. Clone the repository: + ```bash + git clone https://github.com/yourusername/dynamodns.git + cd dynamodns + ``` + +2. Install dependencies: + ```bash + npm install + ``` + +3. Configure environment variables by creating a `.env` file: + ``` + DATABASE_URL=postgresql://username:password@localhost:5432/dynamodns + PORT=5000 + SESSION_SECRET=your_secure_secret + ENABLE_REGISTRATION=false + ``` + +4. Run database migrations: + ```bash + npm run db:push + ``` + +5. Start the application: + ```bash + npm run dev + ``` + +6. Access the application at http://localhost:5000 + +### Default Admin Account + +On first launch, a default admin account is created: +- Username: `admin` +- Password: `admin` + +**Important**: Change the default password immediately after first login. + +## Documentation + +Comprehensive documentation is available in the `/docs` directory: + +- [User Guide](docs/user-guide.md) - For end users managing DNS records +- [API Reference](docs/api-reference.md) - For developers integrating with the API +- [Deployment Guide](docs/deployment-guide.md) - For system administrators +- [Development Guide](docs/development-guide.md) - For contributors +- [Architecture](docs/architecture.md) - System design and architecture overview + +## Deployment + +DynamoDNS can be deployed in various environments: + +- **Standalone Server**: Direct installation on Linux/Windows servers +- **Docker**: Container-based deployment with Docker Compose +- **Cloud Platforms**: Deploy to AWS, Azure, Google Cloud, or other providers + +See the [Deployment Guide](docs/deployment-guide.md) for detailed instructions. + +## Contributing + +We welcome contributions from the community! Please see our [Development Guide](docs/development-guide.md) for information on getting started with development. + +To contribute: + +1. Fork the repository +2. Create a feature branch (`git checkout -b feature/amazing-feature`) +3. Commit your changes (`git commit -m 'Add some amazing feature'`) +4. Push to the branch (`git push origin feature/amazing-feature`) +5. Open a Pull Request + +## License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. + +## Support + +For support or questions, please [open an issue](https://github.com/yourusername/dynamodns/issues) on GitHub, or contact the maintainers directly. + +## Acknowledgements + +- The open source community for the amazing tools that make this project possible +- Contributors who have helped improve and maintain this project +- Users who have provided feedback and feature suggestions \ No newline at end of file diff --git a/docs/api-reference.md b/docs/api-reference.md new file mode 100644 index 0000000..28b5492 --- /dev/null +++ b/docs/api-reference.md @@ -0,0 +1,586 @@ +# DynamoDNS API Reference + +This document provides detailed information about the DynamoDNS REST API endpoints, request/response formats, and authentication mechanisms. + +## Authentication + +The API supports two authentication methods: + +### Session Authentication (Web UI) + +Used for browser-based interactions. Authenticate via: +- POST `/api/login` +- GET `/api/user` (verify current session) +- POST `/api/logout` + +### API Token Authentication + +Required for programmatic access: +- Include the token in the `Authorization` header: `Authorization: Bearer YOUR_API_TOKEN` +- API tokens can be created and managed through the web interface or via API + +## API Endpoints + +### Authentication + +#### `POST /api/login` + +Authenticates a user and creates a session. + +**Request:** +```json +{ + "username": "string", + "password": "string" +} +``` + +**Response:** +```json +{ + "id": "string", + "username": "string", + "email": "string", + "fullName": "string", + "role": "string" +} +``` + +#### `POST /api/register` + +Registers a new user (if enabled). + +**Request:** +```json +{ + "username": "string", + "email": "string", + "password": "string", + "fullName": "string" +} +``` + +**Response:** +```json +{ + "id": "string", + "username": "string", + "email": "string", + "fullName": "string", + "role": "string" +} +``` + +#### `POST /api/logout` + +Ends the current user session. + +**Response:** +HTTP 200 OK + +#### `GET /api/user` + +Retrieves the current authenticated user's information. + +**Response:** +```json +{ + "id": "string", + "username": "string", + "email": "string", + "fullName": "string", + "role": "string" +} +``` + +#### `GET /api/auth/config` + +Retrieves the authentication configuration. + +**Response:** +```json +{ + "localAuthEnabled": true, + "registrationEnabled": false, + "ldapEnabled": false, + "oidcEnabled": false +} +``` + +### Customers + +#### `GET /api/customers` + +Returns all customers the authenticated user has access to. + +**Response:** +```json +[ + { + "id": "string", + "name": "string", + "description": "string", + "email": "string", + "phone": "string", + "address": "string", + "city": "string", + "state": "string", + "zipCode": "string", + "country": "string", + "website": "string", + "industry": "string", + "notes": "string", + "accountManager": "string", + "billingEmail": "string", + "billingAddress": "string", + "isActive": true, + "createdAt": "string" + } +] +``` + +#### `GET /api/customers/:id` + +Returns a specific customer by ID. + +**Response:** Customer object + +#### `POST /api/customers` + +Creates a new customer. + +**Request:** Customer object without id and createdAt +**Response:** Created customer object + +#### `PUT /api/customers/:id` + +Updates an existing customer. + +**Request:** Partial customer object +**Response:** Updated customer object + +#### `DELETE /api/customers/:id` + +Deletes a customer. + +**Response:** HTTP 200 OK + +### Domains + +#### `GET /api/domains` + +Returns all domains the user has access to. + +**Query Parameters:** +- `customerId` (optional): Filter by customer ID + +**Response:** +```json +[ + { + "id": "string", + "name": "string", + "customerId": "string", + "providerId": "string", + "isActive": true, + "createdAt": "string", + "lastUpdated": "string" + } +] +``` + +#### `GET /api/domains/:id` + +Returns a specific domain by ID. + +**Response:** Domain object + +#### `POST /api/domains` + +Creates a new domain. + +**Request:** +```json +{ + "name": "string", + "customerId": "string", + "providerId": "string", + "isActive": true +} +``` + +**Response:** Created domain object + +#### `PUT /api/domains/:id` + +Updates an existing domain. + +**Request:** Partial domain object +**Response:** Updated domain object + +#### `DELETE /api/domains/:id` + +Deletes a domain. + +**Response:** HTTP 200 OK + +### DNS Records + +#### `GET /api/dns-records` + +Returns DNS records the user has access to. + +**Query Parameters:** +- `domainId` (optional): Filter by domain ID + +**Response:** +```json +[ + { + "id": "string", + "name": "string", + "type": "A | AAAA | CNAME | MX | TXT | SRV | NS | CAA | PTR", + "content": "string", + "domainId": "string", + "priority": 0, + "ttl": 3600, + "proxied": false, + "isAutoIP": false, + "isActive": true, + "notes": "string", + "providerRecordId": "string", + "createdAt": "string", + "updatedAt": "string", + "currentIp": "string" // Only present when isAutoIP is true + } +] +``` + +#### `GET /api/dns-records/:id` + +Returns a specific DNS record by ID. + +**Response:** DNS record object + +#### `POST /api/dns-records` + +Creates a new DNS record. + +**Request:** DNS record object without id, createdAt, updatedAt +**Response:** Created DNS record object + +#### `PUT /api/dns-records/:id` + +Updates an existing DNS record. + +**Request:** Partial DNS record object +**Response:** Updated DNS record object + +#### `DELETE /api/dns-records/:id` + +Deletes a DNS record. + +**Response:** HTTP 200 OK + +#### `POST /api/dns-records/:id/toggle` + +Toggles a DNS record's active status. + +**Response:** Updated DNS record object + +### Providers + +#### `GET /api/providers` + +Returns all DNS providers. + +**Response:** +```json +[ + { + "id": "string", + "name": "string", + "type": "cloudflare | route53 | godaddy | other", + "isActive": true, + "credentials": { + // Provider-specific credentials (redacted in response) + }, + "createdAt": "string" + } +] +``` + +#### `GET /api/providers/:id` + +Returns a specific provider by ID. + +**Response:** Provider object (credentials redacted) + +#### `POST /api/providers` + +Creates a new provider. + +**Request:** Provider object with credentials +**Response:** Created provider object (credentials redacted) + +#### `PUT /api/providers/:id` + +Updates an existing provider. + +**Request:** Partial provider object +**Response:** Updated provider object (credentials redacted) + +#### `DELETE /api/providers/:id` + +Deletes a provider. + +**Response:** HTTP 200 OK + +### DNS History + +#### `GET /api/dns-history` + +Returns DNS history records. + +**Query Parameters:** +- `recordId` (optional): Filter by DNS record ID +- `domainId` (optional): Filter by domain ID +- `startDate` (optional): Filter by start date +- `endDate` (optional): Filter by end date + +**Response:** +```json +[ + { + "id": "string", + "recordId": "string", + "domainId": "string", + "previousValue": "string", + "newValue": "string", + "changedBy": "string", + "createdAt": "string" + } +] +``` + +### Metrics + +#### `GET /api/dns-metrics` + +Returns DNS metrics. + +**Query Parameters:** +- `recordId` (optional): Filter by DNS record ID +- `domainId` (optional): Filter by domain ID +- `type` (optional): Filter by metric type +- `startDate` (optional): Filter by start date +- `endDate` (optional): Filter by end date + +**Response:** +```json +[ + { + "id": "string", + "recordId": "string", + "domainId": "string", + "type": "string", + "value": 0, + "timestamp": "string" + } +] +``` + +### API Tokens + +#### `GET /api/api-tokens` + +Returns all API tokens for the authenticated user. + +**Response:** +```json +[ + { + "id": "string", + "name": "string", + "token": "string", // Only the first few and last few characters + "createdBy": "string", + "expiresAt": "string", + "isActive": true, + "role": "string", + "createdAt": "string", + "customerAccess": [ + { + "customerId": "string", + "customerName": "string" // Populated for convenience + } + ] + } +] +``` + +#### `POST /api/api-tokens` + +Creates a new API token. + +**Request:** +```json +{ + "name": "string", + "expiresAt": "string", // optional + "role": "string", + "customerIds": ["string"] // optional, if empty, grants access to all customers +} +``` + +**Response:** Created API token object with the full token value (only returned once) + +#### `PUT /api/api-tokens/:id` + +Updates an existing API token. + +**Request:** +```json +{ + "name": "string", + "expiresAt": "string", + "isActive": true, + "customerIds": ["string"] +} +``` + +**Response:** Updated API token object + +#### `DELETE /api/api-tokens/:id` + +Revokes an API token. + +**Response:** HTTP 200 OK + +### Webhooks + +#### `GET /api/webhooks` + +Returns all webhooks for the authenticated user's customers. + +**Response:** +```json +[ + { + "id": "string", + "customerId": "string", + "name": "string", + "url": "string", + "secret": "string", // Redacted + "events": ["string"], + "isActive": true, + "createdAt": "string", + "lastTriggered": "string" + } +] +``` + +#### `POST /api/webhooks` + +Creates a new webhook. + +**Request:** +```json +{ + "customerId": "string", + "name": "string", + "url": "string", + "secret": "string", + "events": ["string"], + "isActive": true +} +``` + +**Response:** Created webhook object (secret redacted) + +#### `GET /api/webhook-logs` + +Returns webhook delivery logs. + +**Query Parameters:** +- `webhookId` (required): Filter by webhook ID + +**Response:** +```json +[ + { + "id": "string", + "webhookId": "string", + "event": "string", + "payload": "object", + "response": "string", + "statusCode": 0, + "success": true, + "createdAt": "string" + } +] +``` + +### Utility Endpoints + +#### `GET /api/public-ip` + +Returns the public IP addresses of the client. + +**Response:** +```json +{ + "ipv4": "string", + "ipv6": "string" +} +``` + +## Error Responses + +All API endpoints return standard HTTP status codes: + +- **400 Bad Request**: Invalid input +- **401 Unauthorized**: Missing or invalid authentication +- **403 Forbidden**: Insufficient permissions +- **404 Not Found**: Resource not found +- **500 Internal Server Error**: Server-side error + +Error responses include a JSON body with error details: + +```json +{ + "message": "Error description", + "code": "ERROR_CODE", + "details": {} // Additional error details when available +} +``` + +## Rate Limiting + +API requests are rate-limited to prevent abuse. Rate limit headers are included in all responses: + +- `X-RateLimit-Limit`: Number of requests allowed in the current time window +- `X-RateLimit-Remaining`: Number of requests remaining in the current time window +- `X-RateLimit-Reset`: Time when the rate limit window resets (Unix timestamp) + +When rate limits are exceeded, a 429 Too Many Requests response is returned. + +## Pagination + +List endpoints support pagination using the following query parameters: + +- `page`: Page number (default: 1) +- `limit`: Items per page (default: 20, max: 100) + +Paginated responses include metadata: + +```json +{ + "data": [], + "pagination": { + "total": 0, + "pages": 0, + "page": 1, + "limit": 20 + } +} +``` \ No newline at end of file diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..0bd261a --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,118 @@ +# DynamoDNS Architecture + +## Overview + +DynamoDNS is a comprehensive web-based dynamic DNS management platform that offers advanced infrastructure control, monitoring, and multi-provider integration. The application focuses on user experience and security while providing a robust solution for maintaining DNS records across multiple providers. + +## System Architecture + +The system is built on a modern web stack with the following components: + +### Backend +- **Express.js Server**: Handles API requests, authentication, and business logic +- **PostgreSQL Database**: Provides robust data storage using the Neon serverless Postgres service +- **Drizzle ORM**: Manages database interactions and schema definition +- **Authentication System**: Supports multiple authentication methods (local, LDAP, OIDC) +- **DNS Provider Modules**: Integrates with various DNS providers (Cloudflare, AWS Route53, GoDaddy, etc.) + +### Frontend +- **React**: Powers the user interface +- **TanStack Query**: Manages data fetching and caching +- **Shadcn UI**: Provides consistent, accessible UI components +- **Tailwind CSS**: Handles styling with utility-first approach +- **Wouter**: Manages client-side routing + +## Component Diagram + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Client Browser │ +└───────────────────────────┬─────────────────────────────────┘ + │ +┌───────────────────────────▼─────────────────────────────────┐ +│ Express Server │ +│ │ +│ ┌─────────────────┐ ┌──────────────┐ ┌────────────┐ │ +│ │ Authentication │ │ API Routes │ │ WebSockets │ │ +│ └─────────────────┘ └──────────────┘ └────────────┘ │ +│ │ +│ ┌─────────────────┐ ┌──────────────┐ ┌────────────┐ │ +│ │ Storage Layer │ │ DNS Provider │ │ Metrics │ │ +│ └────────┬────────┘ │ Modules │ │ Collection │ │ +│ │ └──────┬───────┘ └────────────┘ │ +└───────────┼──────────────────────────────────────────────────┘ + │ │ +┌───────────▼────────┐ ┌────────▼───────────────────────────┐ +│ PostgreSQL DB │ │ External DNS APIs │ +│ (via Drizzle ORM) │ │ (Cloudflare, Route53, GoDaddy) │ +└────────────────────┘ └────────────────────────────────────┘ +``` + +## Database Schema + +The database schema is defined using Drizzle ORM and includes the following main entities: + +- **Users**: Application users with authentication details +- **Customers**: Organizations/accounts using the system +- **Customer User Assignments**: Many-to-many relationship connecting users to customers +- **Providers**: DNS service providers integrated with the system +- **Domains**: DNS domains managed by the system +- **DNS Records**: Individual DNS records within domains +- **DNS History**: Historical record of DNS changes +- **Metrics**: Performance and usage metrics +- **API Tokens**: Tokens for API authentication +- **Webhooks**: Notification integration points + +## Authentication Flow + +The application supports multiple authentication methods: + +1. **Local Authentication**: Username/password stored in the database +2. **LDAP**: Integration with corporate directories +3. **OpenID Connect**: Single sign-on with identity providers + +Authentication is managed via Passport.js with session-based authentication for the web interface and token-based authentication for API access. + +## Authorization Model + +The system implements a role-based access control (RBAC) model with the following roles: + +- **Admin**: Full system access +- **Manager**: Can manage customers, domains, and DNS records +- **User**: Can manage assigned domains and DNS records +- **ReadOnly**: View-only access to assigned resources +- **Custom Roles**: User-defined roles with specific permissions + +## Data Flow + +### DNS Record Updates + +1. User initiates a DNS record update through the UI +2. Server validates the request and user permissions +3. Server dispatches the update to the appropriate DNS provider module +4. Provider module makes API calls to the external DNS service +5. Results are recorded in the database (success or failure) +6. Historical entry is created +7. Metrics are updated +8. Webhooks are triggered (if configured) +9. Client is notified of the outcome + +### Automatic IP Updates + +For dynamic DNS functionality: + +1. Client periodically checks for IP changes +2. When a change is detected, updates are sent to the server +3. Server processes updates for all DNS records configured for automatic IP updates +4. External DNS providers are updated +5. History and metrics are recorded + +## Security Considerations + +- **Authentication**: Multiple secure authentication methods +- **Authorization**: Granular role-based access control +- **API Tokens**: Scoped access with expiration +- **Audit Trail**: Comprehensive history logging +- **Credential Storage**: Secure storage of provider credentials +- **Input Validation**: Strict validation of all inputs +- **Rate Limiting**: Protection against abuse \ No newline at end of file diff --git a/docs/deployment-guide.md b/docs/deployment-guide.md new file mode 100644 index 0000000..9fa03b4 --- /dev/null +++ b/docs/deployment-guide.md @@ -0,0 +1,380 @@ +# DynamoDNS Deployment Guide + +This guide outlines the steps required to deploy and configure DynamoDNS in your environment. + +## System Requirements + +### Minimum Requirements + +- **Node.js**: v18.0.0 or higher +- **PostgreSQL**: v14.0 or higher (or Neon serverless database) +- **Operating System**: Any OS that supports Node.js (Linux recommended for production) +- **Memory**: 1GB RAM minimum (2GB+ recommended) +- **Storage**: 1GB for application, database size depends on usage + +### Recommended Production Setup + +- **Node.js**: Latest LTS version +- **PostgreSQL**: Latest stable version +- **Operating System**: Linux (Ubuntu 22.04 LTS or similar) +- **Memory**: 4GB RAM +- **Storage**: 10GB SSD +- **Web Server**: Nginx as a reverse proxy +- **SSL Certificate**: Let's Encrypt or similar + +## Installation + +### Option 1: Docker Deployment (Recommended) + +1. **Clone the repository**: + ```bash + git clone https://github.com/yourusername/dynamodns.git + cd dynamodns + ``` + +2. **Configure environment variables**: + Create a `.env` file based on the `.env.example` template: + ```bash + cp .env.example .env + nano .env # Edit with your configuration + ``` + +3. **Build and start the containers**: + ```bash + docker-compose up -d + ``` + +4. **Run database migrations**: + ```bash + docker-compose exec app npm run db:push + ``` + +5. **Create initial admin user** (if not using the automated setup): + ```bash + docker-compose exec app npm run create-admin + ``` + +### Option 2: Manual Deployment + +1. **Clone the repository**: + ```bash + git clone https://github.com/yourusername/dynamodns.git + cd dynamodns + ``` + +2. **Install dependencies**: + ```bash + npm install + ``` + +3. **Configure environment variables**: + Create a `.env` file with your configuration: + ``` + # Database configuration + DATABASE_URL=postgresql://user:password@localhost:5432/dynamodns + + # Server configuration + PORT=5000 + NODE_ENV=production + SESSION_SECRET=your_secure_session_secret + + # Authentication configuration + ENABLE_REGISTRATION=false + + # Optional: LDAP configuration + LDAP_ENABLED=false + LDAP_URL=ldap://ldap.example.com + LDAP_BIND_DN=cn=admin,dc=example,dc=com + LDAP_BIND_PASSWORD=password + LDAP_SEARCH_BASE=ou=users,dc=example,dc=com + LDAP_SEARCH_FILTER=(uid={{username}}) + + # Optional: OpenID Connect configuration + OIDC_ENABLED=false + OIDC_ISSUER=https://auth.example.com + OIDC_CLIENT_ID=your_client_id + OIDC_CLIENT_SECRET=your_client_secret + OIDC_CALLBACK_URL=https://dynamodns.example.com/api/auth/oidc/callback + ``` + +4. **Run database migrations**: + ```bash + npm run db:push + ``` + +5. **Build the application**: + ```bash + npm run build + ``` + +6. **Start the application**: + ```bash + npm start + ``` + +## Configuration Options + +### Database Configuration + +- **DATABASE_URL**: Connection string for PostgreSQL + +### Server Configuration + +- **PORT**: The port on which the server will listen (default: 5000) +- **NODE_ENV**: Environment (development/production) +- **HOST**: Host to bind to (default: 0.0.0.0) +- **SESSION_SECRET**: Secret for session encryption (generate a secure random string) + +### Authentication Configuration + +- **ENABLE_REGISTRATION**: Allow new user registration (true/false) +- **DEFAULT_ADMIN_USERNAME**: Username for the default admin (default: admin) +- **DEFAULT_ADMIN_PASSWORD**: Password for the default admin (set this for initial setup) +- **DEFAULT_ADMIN_EMAIL**: Email for the default admin (default: admin@example.com) + +### LDAP Configuration (Optional) + +- **LDAP_ENABLED**: Enable LDAP authentication (true/false) +- **LDAP_URL**: LDAP server URL +- **LDAP_BIND_DN**: DN for binding to LDAP +- **LDAP_BIND_PASSWORD**: Password for binding to LDAP +- **LDAP_SEARCH_BASE**: Base DN for user search +- **LDAP_SEARCH_FILTER**: Filter for finding users (use {{username}} as placeholder) +- **LDAP_USER_ATTR_USERNAME**: LDAP attribute for username (default: uid) +- **LDAP_USER_ATTR_EMAIL**: LDAP attribute for email (default: mail) +- **LDAP_USER_ATTR_DISPLAY_NAME**: LDAP attribute for display name (default: cn) + +### OpenID Connect Configuration (Optional) + +- **OIDC_ENABLED**: Enable OIDC authentication (true/false) +- **OIDC_ISSUER**: OIDC issuer URL +- **OIDC_CLIENT_ID**: Client ID for OIDC +- **OIDC_CLIENT_SECRET**: Client secret for OIDC +- **OIDC_CALLBACK_URL**: Callback URL for OIDC authentication +- **OIDC_SCOPE**: Scopes to request (default: "openid profile email") + +## DNS Provider Configuration + +DynamoDNS supports multiple DNS providers. Each requires specific configuration: + +### Cloudflare + +Required credentials: +- API Token or API Key + Email +- Zone IDs (optional, can be fetched automatically) + +### AWS Route53 + +Required credentials: +- Access Key ID +- Secret Access Key +- Region + +### GoDaddy + +Required credentials: +- API Key +- API Secret + +### Generic Provider + +For custom or unsupported providers: +- API URL +- Authentication method +- Request format + +## Setting Up Reverse Proxy + +For production deployments, it's recommended to use a reverse proxy like Nginx or Apache. + +### Nginx Configuration Example + +```nginx +server { + listen 80; + server_name dynamodns.example.com; + + # Redirect to HTTPS + location / { + return 301 https://$host$request_uri; + } +} + +server { + listen 443 ssl; + server_name dynamodns.example.com; + + ssl_certificate /path/to/cert.pem; + ssl_certificate_key /path/to/key.pem; + + # SSL configuration + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; + ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256'; + + # Proxy to Node.js application + location / { + proxy_pass http://localhost:5000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_cache_bypass $http_upgrade; + } +} +``` + +## Database Backup and Maintenance + +### Automated Backups + +For PostgreSQL: + +```bash +# Add to crontab for daily backups +0 2 * * * pg_dump -U username -d dynamodns > /path/to/backup/dynamodns_$(date +\%Y\%m\%d).sql +``` + +For Neon PostgreSQL: +- Enable automated backups through the Neon dashboard +- Set an appropriate backup schedule and retention policy + +### Database Maintenance + +Regular maintenance tasks: + +```bash +# Vacuum the database to optimize performance +psql -U username -d dynamodns -c "VACUUM ANALYZE;" + +# Check for slow queries +psql -U username -d dynamodns -c "SELECT * FROM pg_stat_activity WHERE state = 'active';" +``` + +## System Monitoring + +### Health Check Endpoint + +The application provides a health check endpoint at `/api/health` that returns: +- Application status +- Database connectivity +- DNS provider connectivity + +### Recommended Monitoring Tools + +- **Uptime Monitoring**: Pingdom, UptimeRobot, or similar +- **Application Monitoring**: New Relic, Datadog, or similar +- **Log Management**: ELK Stack, Graylog, or similar + +## Security Considerations + +### Securing Your Deployment + +1. **Use HTTPS**: Always use SSL/TLS in production +2. **Firewall Configuration**: Restrict access to the server +3. **Regular Updates**: Keep all dependencies up to date +4. **Secure Credentials**: Use environment variables, not hardcoded values +5. **Rate Limiting**: Configure rate limiting to prevent abuse + +### Data Protection + +1. **Encryption**: Sensitive data is encrypted in the database +2. **Backups**: Regular encrypted backups +3. **Access Control**: Implement least privilege principle +4. **Audit Logs**: Monitor and review access logs + +## Upgrading + +### Standard Upgrade Process + +1. **Backup your data**: + ```bash + pg_dump -U username -d dynamodns > /path/to/backup/dynamodns_before_upgrade.sql + ``` + +2. **Pull the latest changes**: + ```bash + git pull origin main + ``` + +3. **Install dependencies**: + ```bash + npm install + ``` + +4. **Run database migrations**: + ```bash + npm run db:push + ``` + +5. **Rebuild the application**: + ```bash + npm run build + ``` + +6. **Restart the service**: + ```bash + # If using systemd + sudo systemctl restart dynamodns + + # If using PM2 + pm2 restart dynamodns + ``` + +### Docker Upgrade Process + +1. **Pull the latest image**: + ```bash + docker-compose pull + ``` + +2. **Restart the containers**: + ```bash + docker-compose down + docker-compose up -d + ``` + +3. **Run migrations**: + ```bash + docker-compose exec app npm run db:push + ``` + +## Troubleshooting + +### Common Issues + +1. **Database Connection Errors**: + - Check DATABASE_URL environment variable + - Verify network connectivity and firewall rules + - Ensure PostgreSQL is running + +2. **Authentication Issues**: + - Verify SESSION_SECRET is set + - Check LDAP/OIDC configuration if using external authentication + +3. **DNS Provider Integration Errors**: + - Verify API credentials for the DNS provider + - Check for rate limiting or IP restrictions + +### Logs + +Access logs for troubleshooting: + +```bash +# Application logs +tail -f logs/app.log + +# In Docker +docker-compose logs -f app +``` + +### Getting Support + +If you encounter issues not covered in this documentation: + +1. Check the GitHub repository issues +2. Create a new issue with detailed information about your problem +3. Contact commercial support if you have a support agreement \ No newline at end of file diff --git a/docs/development-guide.md b/docs/development-guide.md new file mode 100644 index 0000000..b63bdf9 --- /dev/null +++ b/docs/development-guide.md @@ -0,0 +1,505 @@ +# DynamoDNS Development Guide + +This guide provides information for developers who want to contribute to the DynamoDNS project or extend its functionality. + +## Development Setup + +### Prerequisites + +- **Node.js**: v18.0.0 or higher +- **npm**: v8.0.0 or higher +- **PostgreSQL**: v14.0 or higher (or Neon serverless database) +- **Git**: Latest version + +### Getting Started + +1. **Clone the repository**: + ```bash + git clone https://github.com/yourusername/dynamodns.git + cd dynamodns + ``` + +2. **Install dependencies**: + ```bash + npm install + ``` + +3. **Set up environment variables**: + Create a `.env` file based on the `.env.example` template: + ``` + # Database - Use a local PostgreSQL instance for development + DATABASE_URL=postgresql://postgres:postgres@localhost:5432/dynamodns_dev + + # Server + PORT=5000 + NODE_ENV=development + SESSION_SECRET=dev_session_secret + + # Auth - Enable registration for easier testing + ENABLE_REGISTRATION=true + ``` + +4. **Set up the database**: + ```bash + # Create the database + createdb dynamodns_dev + + # Run migrations + npm run db:push + ``` + +5. **Start the development server**: + ```bash + npm run dev + ``` + +6. **Access the application**: + Open your browser and navigate to http://localhost:5000 + +## Project Structure + +``` +dynamodns/ +├── client/ # Frontend React application +│ ├── src/ # Source code +│ │ ├── components/ # Reusable UI components +│ │ ├── context/ # React context providers +│ │ ├── hooks/ # Custom React hooks +│ │ ├── lib/ # Utility functions +│ │ ├── pages/ # Page components +│ │ └── App.tsx # Main application component +├── docs/ # Documentation +├── migrations/ # Database migration files +├── server/ # Backend Express application +│ ├── providers/ # DNS provider integrations +│ ├── utils/ # Utility functions +│ ├── auth.ts # Authentication logic +│ ├── db.ts # Database connection +│ ├── index.ts # Application entry point +│ ├── routes.ts # API routes +│ ├── storage.ts # Storage interface +│ └── vite.ts # Vite integration +├── shared/ # Shared code between client and server +│ └── schema.ts # Database schema with Drizzle ORM +└── various config files # Configuration files for the project +``` + +## Technology Stack + +### Backend + +- **Express.js**: Web server framework +- **Drizzle ORM**: Database ORM for TypeScript +- **PostgreSQL**: Relational database +- **Passport.js**: Authentication middleware +- **WebSockets**: Real-time communication + +### Frontend + +- **React**: UI library +- **TanStack Query**: Data fetching and caching +- **Shadcn UI**: Component library built on Radix UI +- **Tailwind CSS**: Utility-first CSS framework +- **Wouter**: Lightweight routing +- **Zod**: Schema validation +- **React Hook Form**: Form handling + +## Architecture + +### Frontend Architecture + +The frontend follows a component-based architecture with React: + +- **Context Providers**: Manage global state (auth, customer, theme) +- **Hooks**: Custom hooks for data fetching and business logic +- **Pages**: Top-level components for different routes +- **Components**: Reusable UI building blocks + +Data flow utilizes TanStack Query for client-side data fetching and caching: + +```javascript +// Example query +const { data, isLoading, error } = useQuery({ + queryKey: ['/api/domains'], + enabled: !!user +}); + +// Example mutation +const mutation = useMutation({ + mutationFn: async (data) => { + const res = await apiRequest('POST', '/api/domains', data); + return await res.json(); + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['/api/domains'] }); + // Handle success + }, + onError: (error) => { + // Handle error + } +}); +``` + +### Backend Architecture + +The backend follows a layered architecture: + +1. **Routes Layer**: API endpoints and request handling +2. **Service Layer**: Business logic +3. **Data Access Layer**: Database interactions via Drizzle ORM +4. **Provider Layer**: Integrations with external DNS services + +The application uses a storage interface pattern to abstract database operations: + +```typescript +// Example storage interface method +async getUser(id: string): Promise { + const [user] = await db.select().from(users).where(eq(users.id, id)); + return user || undefined; +} +``` + +## Adding Features + +### Adding a New DNS Provider + +1. **Create a provider module**: + Create a new file in `server/providers/` directory (e.g., `cloudflare.ts`). + +2. **Implement the provider interface**: + ```typescript + import { DNSProvider, DNSRecord, DNSProviderError } from './types'; + + export class CloudflareProvider implements DNSProvider { + constructor(private credentials: any) { + // Initialize with provider credentials + } + + async createRecord(record: DNSRecord): Promise { + // Implementation + } + + async updateRecord(recordId: string, record: DNSRecord): Promise { + // Implementation + } + + async deleteRecord(recordId: string): Promise { + // Implementation + } + + async getRecord(recordId: string): Promise { + // Implementation + } + } + ``` + +3. **Register the provider**: + Add the provider to the provider factory in `server/providers/index.ts`. + +### Adding a New API Endpoint + +1. **Create the route handler**: + Add your endpoint to `server/routes.ts`: + + ```typescript + app.get('/api/your-endpoint', (req, res) => { + // Implementation + }); + ``` + +2. **Add validation**: + Use Zod to validate request inputs: + + ```typescript + const schema = z.object({ + name: z.string().min(1), + // Other fields + }); + + app.post('/api/your-endpoint', (req, res) => { + const result = schema.safeParse(req.body); + if (!result.success) { + return res.status(400).json({ errors: result.error.format() }); + } + + // Implementation with validated data + const data = result.data; + }); + ``` + +3. **Use the storage interface**: + Interact with the database using the storage interface: + + ```typescript + app.get('/api/your-endpoint/:id', async (req, res) => { + try { + const item = await storage.getItem(req.params.id); + if (!item) { + return res.status(404).json({ message: 'Not found' }); + } + res.json(item); + } catch (error) { + res.status(500).json({ message: 'Server error' }); + } + }); + ``` + +### Adding a New UI Component + +1. **Create the component**: + Create a new file in the appropriate directory under `client/src/components/`. + +2. **Implement the component**: + ```tsx + import React from 'react'; + import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; + + interface MyComponentProps { + title: string; + children: React.ReactNode; + } + + export function MyComponent({ title, children }: MyComponentProps) { + return ( + + + {title} + + + {children} + + + ); + } + ``` + +3. **Use the component**: + Import and use your component in a page or another component. + +## Database Schema Management + +The project uses Drizzle ORM with a schema defined in `shared/schema.ts`. + +### Adding a New Table + +1. **Define the table**: + ```typescript + export const myNewTable = pgTable('my_new_table', { + id: text('id').primaryKey().defaultRandom(), + name: text('name').notNull(), + createdAt: timestamp('created_at').defaultNow().notNull(), + customerId: text('customer_id').references(() => customers.id, { onDelete: 'cascade' }), + }); + ``` + +2. **Define relations**: + ```typescript + export const myNewTableRelations = relations(myNewTable, ({ one }) => ({ + customer: one(customers, { + fields: [myNewTable.customerId], + references: [customers.id], + }), + })); + ``` + +3. **Create insert schema and types**: + ```typescript + export const insertMyNewTableSchema = createInsertSchema(myNewTable).pick({ + name: true, + customerId: true, + }); + + export type InsertMyNewTable = z.infer; + export type MyNewTable = typeof myNewTable.$inferSelect; + ``` + +4. **Update the storage interface**: + Add methods to `server/storage.ts` for CRUD operations on your new table. + +5. **Push the schema changes**: + ```bash + npm run db:push + ``` + +## Testing + +### Unit Tests + +The project uses Jest for unit testing: + +```bash +# Run all tests +npm test + +# Run tests with coverage +npm test -- --coverage + +# Run specific test file +npm test -- src/path/to/test.test.ts +``` + +### Writing Tests + +Example test for a utility function: + +```typescript +// src/utils/formatDate.test.ts +import { formatDate } from './formatDate'; + +describe('formatDate', () => { + it('formats a date correctly', () => { + const date = new Date('2023-01-01T12:00:00Z'); + expect(formatDate(date)).toBe('Jan 1, 2023'); + }); + + it('handles null values', () => { + expect(formatDate(null)).toBe(''); + }); +}); +``` + +Example test for a React component using React Testing Library: + +```typescript +// src/components/Button.test.tsx +import { render, screen, fireEvent } from '@testing-library/react'; +import { Button } from './Button'; + +describe('Button', () => { + it('renders correctly', () => { + render(); + expect(screen.getByText('Click me')).toBeInTheDocument(); + }); + + it('calls onClick when clicked', () => { + const handleClick = jest.fn(); + render(); + fireEvent.click(screen.getByText('Click me')); + expect(handleClick).toHaveBeenCalledTimes(1); + }); +}); +``` + +### API Testing + +For API endpoints, use Supertest: + +```typescript +// src/routes/domains.test.ts +import request from 'supertest'; +import { app } from '../app'; +import { db } from '../db'; + +describe('Domains API', () => { + beforeEach(async () => { + // Set up test data + }); + + afterEach(async () => { + // Clean up test data + }); + + it('GET /api/domains returns domains', async () => { + const response = await request(app) + .get('/api/domains') + .set('Authorization', `Bearer ${testToken}`); + + expect(response.status).toBe(200); + expect(response.body).toHaveLength(2); + }); +}); +``` + +## Code Style and Linting + +The project uses ESLint and Prettier for code style and linting: + +```bash +# Run ESLint +npm run lint + +# Fix ESLint issues +npm run lint:fix + +# Format code with Prettier +npm run format +``` + +### Commit Guidelines + +We follow the Conventional Commits specification: + +- `feat`: A new feature +- `fix`: A bug fix +- `docs`: Documentation changes +- `style`: Changes that do not affect the meaning of the code +- `refactor`: Code changes that neither fix a bug nor add a feature +- `perf`: Performance improvements +- `test`: Adding or fixing tests +- `chore`: Changes to the build process or auxiliary tools + +Example: +``` +feat(dns-records): add support for SRV records +``` + +## Debugging + +### Server-side Debugging + +Add logging with debug statements: + +```typescript +import debug from 'debug'; + +const log = debug('dynamodns:server'); + +app.get('/api/domains', (req, res) => { + log('Fetching domains for user', req.user?.id); + // Implementation +}); +``` + +Run the application with debug enabled: + +```bash +DEBUG=dynamodns:* npm run dev +``` + +### Client-side Debugging + +Use React DevTools for component inspection and debugging. + +For network debugging, use the browser's developer tools and the Network tab. + +## Deployment + +See the [Deployment Guide](./deployment-guide.md) for information on deploying the application. + +## Contributing + +1. **Fork the repository** +2. **Create a feature branch**: + ```bash + git checkout -b feature/your-feature-name + ``` +3. **Make your changes** +4. **Run tests**: + ```bash + npm test + ``` +5. **Commit your changes** following the commit guidelines +6. **Push to your fork**: + ```bash + git push origin feature/your-feature-name + ``` +7. **Create a Pull Request** + +## Resources + +- **Drizzle ORM Documentation**: [https://orm.drizzle.team/docs/overview](https://orm.drizzle.team/docs/overview) +- **React Documentation**: [https://react.dev/](https://react.dev/) +- **TanStack Query Documentation**: [https://tanstack.com/query/latest](https://tanstack.com/query/latest) +- **Shadcn UI Documentation**: [https://ui.shadcn.com/](https://ui.shadcn.com/) +- **Tailwind CSS Documentation**: [https://tailwindcss.com/docs](https://tailwindcss.com/docs) +- **Express.js Documentation**: [https://expressjs.com/](https://expressjs.com/) \ No newline at end of file diff --git a/docs/user-guide.md b/docs/user-guide.md new file mode 100644 index 0000000..d435dac --- /dev/null +++ b/docs/user-guide.md @@ -0,0 +1,237 @@ +# DynamoDNS User Guide + +This guide provides detailed instructions for using the DynamoDNS platform to manage your DNS records across multiple providers. + +## Getting Started + +### Account Setup + +1. **Login**: Access the application using your provided credentials at the login page. +2. **First-time Setup**: If this is your first time, you'll be prompted to create a new customer account. +3. **Dashboard**: After login, you'll be directed to the main dashboard showing your DNS records and metrics. + +### Navigation + +The main navigation menu includes: + +- **Dashboard**: Overview of your DNS infrastructure +- **Domains**: Manage domain registrations +- **DNS Records**: Create and manage DNS records +- **History**: View historical changes to DNS records +- **Metrics**: Analyze performance and usage statistics +- **Webhooks**: Configure notification endpoints +- **API Tokens**: Manage access tokens for API usage +- **Settings**: Configure user and customer settings + +## Managing Customers + +Customers represent organizations that own domains in the system. Each customer can have multiple domains and users. + +### Creating a Customer + +1. Navigate to Settings → Customer tab +2. Click "Create New Customer" +3. Fill in the required information: + - Customer Name (required) + - Description (optional) + - Contact Information (email, phone) + - Address Information + - Website and Industry + - Notes and Account Manager +4. Click "Create Customer" + +### Editing Customer Details + +1. Navigate to Settings → Customer tab +2. Update the information as needed +3. Click "Save Changes" + +### Switching Between Customers + +Use the customer selector in the top navigation bar to switch between different customers you have access to. + +## Managing Domains + +Domains are the DNS zones that contain your DNS records. + +### Adding a Domain + +1. Navigate to the Domains page +2. Click "Add Domain" +3. Enter the domain name (e.g., example.com) +4. Select the DNS provider (Cloudflare, Route53, GoDaddy, etc.) +5. Enter necessary provider credentials (if not already configured) +6. Click "Add Domain" + +### Managing Domain Settings + +1. Navigate to the Domains page +2. Click on a domain to view its details +3. Use the "Edit" button to modify domain settings +4. Use the "Delete" button to remove the domain + +## Managing DNS Records + +DNS records define how domain names are mapped to resources on the internet. + +### Adding a DNS Record + +1. Navigate to the DNS Records page +2. Filter by domain if needed +3. Click "Add Record" +4. Select the record type (A, AAAA, CNAME, MX, TXT, etc.) +5. Enter the required fields: + - Name: The subdomain or @ for the root domain + - Content: The value for the record (IP address, hostname, text) + - TTL: Time To Live in seconds + - Priority: For MX and SRV records +6. Optional settings: + - Enable "Auto IP" for dynamic DNS functionality + - Enable "Proxied" for Cloudflare-specific features + - Add notes for documentation +7. Click "Create Record" + +### Editing DNS Records + +1. Navigate to the DNS Records page +2. Click the "Edit" button for the record you want to modify +3. Update the record information +4. Click "Save Changes" + +### Dynamic DNS Updates + +For records with "Auto IP" enabled: + +1. The system will automatically track your public IP address +2. When changes are detected, DNS records are updated automatically +3. The history of changes can be viewed on the History page + +## Viewing History + +The History page provides a complete audit trail of changes to your DNS records. + +1. Navigate to the History page +2. Filter by domain, record, or date range +3. View details of each change including: + - Previous value + - New value + - Timestamp + - User who made the change + +## Analyzing Metrics + +The Metrics page provides insights into DNS performance and usage. + +1. Navigate to the Metrics page +2. Select the time period for analysis +3. View metrics by: + - Domain + - Record type + - Update frequency + - Success/failure rates + +## Configuring Webhooks + +Webhooks allow external applications to receive notifications about DNS changes. + +### Creating a Webhook + +1. Navigate to the Webhooks page +2. Click "Add Webhook" +3. Configure the webhook: + - Name: For identification + - URL: The endpoint that will receive webhook data + - Secret: Used to verify webhook authenticity + - Events: Select which events trigger the webhook +4. Click "Create Webhook" + +### Testing Webhooks + +1. Navigate to the Webhooks page +2. Select a webhook +3. Click "Test Webhook" +4. View the delivery status and response + +## Managing API Tokens + +API tokens allow programmatic access to the DynamoDNS API. + +### Creating an API Token + +1. Navigate to the API Tokens page +2. Click "Create Token" +3. Configure the token: + - Name: For identification + - Expiration: When the token should expire + - Access level: Which customers the token can access + - Role: What permissions the token has +4. Click "Create Token" +5. Save the displayed token securely (it will only be shown once) + +### Revoking API Tokens + +1. Navigate to the API Tokens page +2. Click "Revoke" next to the token you want to disable +3. Confirm the action + +## User Management + +### Managing Your Account + +1. Navigate to Settings → Account tab +2. Update your profile information +3. Change your password +4. Configure two-factor authentication (if available) + +### Managing Users (Admin Only) + +1. Navigate to Users & Roles page +2. View all users in the system +3. Create new users by clicking "Add User" +4. Edit user details by clicking "Edit" +5. Disable users by toggling the "Active" status + +## Role Management + +Roles determine what actions users can perform in the system. + +### System Roles + +- **Admin**: Complete access to all features +- **Manager**: Can manage customers, domains, and DNS records +- **User**: Can manage assigned domains and DNS records +- **ReadOnly**: View-only access to assigned resources + +### Custom Roles (Admin Only) + +1. Navigate to Users & Roles page +2. Click on the "Roles" tab +3. Click "Create Custom Role" +4. Configure permissions for the role +5. Assign users to the custom role + +## Troubleshooting + +### Common Issues + +1. **DNS Propagation Delays**: DNS changes may take time to propagate (up to 48 hours, though typically much faster) +2. **Provider API Limitations**: Some DNS providers have rate limits or restrictions +3. **Authentication Errors**: Check your credentials for the DNS provider + +### Getting Support + +If you encounter issues: + +1. Check the detailed error message +2. Review the documentation +3. Contact system administrators for assistance + +## Best Practices + +- Regularly review and clean up unused DNS records +- Use descriptive names and notes for records +- Set appropriate TTL values based on your needs +- Use API tokens with the minimum necessary permissions +- Regularly rotate API tokens for security +- Configure webhooks for important events to maintain awareness +- Review the history log periodically to audit changes \ No newline at end of file