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
This commit is contained in:
alphaeusmote
2025-05-24 02:16:17 +00:00
6 changed files with 1955 additions and 0 deletions
+129
View File
@@ -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
+586
View File
@@ -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
}
}
```
+118
View File
@@ -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
+380
View File
@@ -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
+505
View File
@@ -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<User | undefined> {
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<string> {
// Implementation
}
async updateRecord(recordId: string, record: DNSRecord): Promise<void> {
// Implementation
}
async deleteRecord(recordId: string): Promise<void> {
// Implementation
}
async getRecord(recordId: string): Promise<DNSRecord> {
// 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 (
<Card>
<CardHeader>
<CardTitle>{title}</CardTitle>
</CardHeader>
<CardContent>
{children}
</CardContent>
</Card>
);
}
```
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<typeof insertMyNewTableSchema>;
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(<Button>Click me</Button>);
expect(screen.getByText('Click me')).toBeInTheDocument();
});
it('calls onClick when clicked', () => {
const handleClick = jest.fn();
render(<Button onClick={handleClick}>Click me</Button>);
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/)
+237
View File
@@ -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