Skip to content

Commit 2893e93

Browse files
committed
Feat: create a render deployment copy add test scripts
1 parent 6e72e84 commit 2893e93

315 files changed

Lines changed: 106414 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tourai_platform_deploy/README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# TourAI Platform
2+
3+
This folder contains the fullstack codebase for the TourGuideAI project, organized for easy deployment on Render using infrastructure-as-code.
4+
5+
## Folder Structure
6+
7+
- **backend/**: Node.js/Express backend API server
8+
- **frontend/**: React frontend application
9+
- **models/**: (Optional) ML models, data, or related code (not deployed to Render)
10+
- **render.yaml**: Render blueprint for automated deployment of backend and frontend as separate services
11+
12+
---
13+
14+
## Deployment on Render
15+
16+
You can deploy both the backend and frontend as separate services on Render using the provided `render.yaml` blueprint.
17+
18+
### 1. Prerequisites
19+
- Push this folder (with all contents) to your GitHub repository.
20+
- Make sure your backend `.env` file is set up (see `backend/.env`).
21+
22+
### 2. Deploy with Render Blueprints
23+
1. Go to [Render Dashboard](https://dashboard.render.com/).
24+
2. Click **New Blueprint** and connect your GitHub repo.
25+
3. Render will auto-detect `render.yaml` and set up two services:
26+
- **tourguideai-backend** (Node.js web service)
27+
- **tourguideai-frontend** (Static site)
28+
4. Fill in required environment variables for the backend (see `backend/.env`).
29+
5. Click **Apply** to deploy both services.
30+
31+
### 3. Service Details
32+
- **Backend**
33+
- Root: `backend/`
34+
- Build Command: `npm install`
35+
- Start Command: `npm start`
36+
- Set environment variables as needed (see `.env`)
37+
- **Frontend**
38+
- Root: `frontend/`
39+
- Build Command: `npm install && npm run build`
40+
- Publish Directory: `build`
41+
- (Optional) Set `REACT_APP_API_URL` to your backend's Render URL if needed
42+
43+
### 4. Connecting Frontend to Backend
44+
- Update your frontend code to use the backend's Render URL for API requests (e.g., via `REACT_APP_API_URL`).
45+
- Set this variable in the frontend service's environment settings on Render if needed.
46+
47+
---
48+
49+
## Notes
50+
- The `models/` folder is not deployed to Render, but can be used for local development or future ML service integration.
51+
- For advanced configuration, edit `render.yaml` as needed.
52+
53+
---
54+
55+
For any issues, consult the main project documentation or Render's deployment docs.
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
# TourGuideAI Server
2+
3+
Backend server for the TourGuideAI application, handling secure token management, proxy services, and authentication.
4+
5+
## Structure
6+
7+
- **routes**: API endpoint route handlers
8+
- **middleware**: Express middleware functions
9+
- **utils**: Utility functions and helpers
10+
- **logs**: Server log files
11+
- **config**: Configuration files for different environments
12+
- **vault**: Secure token storage directory (created at runtime)
13+
- **scripts**: Administrative and utility scripts
14+
15+
## Features
16+
17+
- **Secure Token Management**: Centralized vault for all API keys, tokens, and secrets
18+
- **Token Rotation**: Automatic tracking of token age and rotation requirements
19+
- **Multiple Backend Support**: Local, AWS Secrets Manager, or HashiCorp Vault support
20+
- **Proxy Services**: Route client requests to external APIs (OpenAI, Google Maps)
21+
- **Rate Limiting**: Prevent API abuse and manage quotas
22+
- **Caching**: Reduce duplicate API calls and improve performance
23+
- **Authentication**: User authorization and access control
24+
- **Logging**: Comprehensive logging for debugging and monitoring
25+
26+
## Getting Started
27+
28+
1. Install dependencies:
29+
30+
```bash
31+
npm install
32+
```
33+
34+
2. Set up environment variables:
35+
36+
```bash
37+
cp .env.example .env
38+
```
39+
40+
Edit the `.env` file with your vault configuration and API keys.
41+
42+
3. Start the development server:
43+
44+
```bash
45+
npm run dev
46+
```
47+
48+
## Token Management and Rotation
49+
50+
TourGuideAI includes a comprehensive token management system to securely handle API keys, secrets, and credentials:
51+
52+
### Automatic Rotation Detection
53+
54+
The system automatically detects tokens that need rotation based on their age:
55+
56+
| Token Type | Default Rotation Period |
57+
|------------|-------------------------|
58+
| API Keys | 90 days |
59+
| JWT Secrets| 180 days |
60+
| Encryption Keys | 365 days |
61+
| OAuth Tokens | 30 days |
62+
63+
### Token Rotation Tool
64+
65+
A dedicated command-line tool is included for securely rotating tokens:
66+
67+
```bash
68+
npm run rotate-tokens
69+
```
70+
71+
This interactive tool provides options to:
72+
- List tokens that need rotation
73+
- Rotate tokens securely
74+
- Add new tokens to the vault
75+
- List all tokens in the vault
76+
77+
### Security Features
78+
79+
- AES-256-GCM encryption for all stored tokens
80+
- Secure key derivation with salting
81+
- Token caching with short TTL to minimize vault access
82+
- Automatic clearing of tokens from memory
83+
- Support for hardware security modules (via AWS KMS)
84+
85+
### Production Recommendations
86+
87+
For production environments:
88+
1. Use a remote vault backend (AWS Secrets Manager or HashiCorp Vault)
89+
2. Set VAULT_BACKEND to 'aws' or 'hashicorp' in your environment
90+
3. Configure a secure rotation schedule with alerting
91+
4. Use the token rotation script in a secure environment only
92+
5. Consider using an HSM or KMS for the vault encryption key
93+
94+
## Token Vault System
95+
96+
TourGuideAI uses a secure token vault system to protect sensitive credentials:
97+
98+
- **Centralized Management**: All tokens, API keys, and secrets are managed in one place
99+
- **Encryption**: AES-256-GCM encryption for all stored credentials
100+
- **Rotation Policy**: Configurable rotation periods based on token type
101+
- **Multiple Backends**: Support for local file-based vault, AWS Secrets Manager, or HashiCorp Vault
102+
- **Seamless Integration**: Legacy environment variables still work during transition
103+
104+
### Vault Configuration
105+
106+
Configure the vault in your `.env` file:
107+
108+
```
109+
# Token Vault Configuration
110+
VAULT_BACKEND=local # Options: local, aws, hashicorp, in-memory
111+
VAULT_ENCRYPTION_KEY=your_vault_encryption_key_here
112+
VAULT_SALT=your_vault_salt_here
113+
VAULT_PATH=./vault/vault.enc # For local backend
114+
IMPORT_ENV_SECRETS=true # Import from environment variables on startup
115+
```
116+
117+
### Token Types and Rotation Periods
118+
119+
The vault supports different token types with appropriate rotation periods:
120+
121+
| Token Type | Usage | Default Rotation Period |
122+
|------------|-------|-------------------------|
123+
| API Key | External service API keys | 90 days |
124+
| JWT Secret | Authentication tokens | 180 days |
125+
| Encryption Key | Data encryption | 365 days |
126+
| OAuth Token | OAuth authentication | 30 days |
127+
| Database | Database credentials | 180 days |
128+
129+
## API Endpoints
130+
131+
| Endpoint | Method | Description |
132+
|----------|--------|-------------|
133+
| `/api/openai/chat` | POST | Proxy to OpenAI Chat API |
134+
| `/api/maps/geocode` | GET | Proxy to Google Maps Geocoding API |
135+
| `/api/maps/directions` | GET | Proxy to Google Maps Directions API |
136+
| `/api/maps/places` | GET | Proxy to Google Maps Places API |
137+
| `/api/auth/login` | POST | User authentication |
138+
| `/api/auth/logout` | POST | User logout |
139+
| `/api/health` | GET | Server health check |
140+
| `/api/admin/tokens/rotation` | GET | List tokens needing rotation (admin only) |
141+
142+
## Environment Configuration
143+
144+
The server uses the following environment variables:
145+
146+
- `NODE_ENV`: Application environment (development, production)
147+
- `PORT`: Server port (default: 3001)
148+
- `VAULT_BACKEND`: Token vault backend type (local, aws, hashicorp, in-memory)
149+
- `VAULT_ENCRYPTION_KEY`: Encryption key for the vault
150+
- `VAULT_SALT`: Salt for key derivation
151+
- `JWT_EXPIRY`: JWT token expiry time
152+
- `RATE_LIMIT_WINDOW_MS`: Rate limiting window in milliseconds
153+
- `RATE_LIMIT_MAX_REQUESTS`: Maximum requests per window
154+
155+
For backward compatibility, the following legacy variables are still supported:
156+
157+
- `OPENAI_API_KEY`: OpenAI API key
158+
- `GOOGLE_MAPS_API_KEY`: Google Maps API key
159+
- `JWT_SECRET`: Secret for signing JWT tokens
160+
- `ENCRYPTION_KEY`: Key for data encryption
161+
- `SENDGRID_API_KEY`: SendGrid API key
162+
163+
## Folder Structure
164+
165+
```
166+
server/
167+
├── logs/ # Log files (created at runtime)
168+
├── vault/ # Secure token storage (created at runtime)
169+
├── middleware/ # Express middleware
170+
│ ├── apiKeyValidation.js
171+
│ ├── authMiddleware.js
172+
│ ├── caching.js
173+
│ └── rateLimit.js
174+
├── routes/ # API route handlers
175+
│ ├── googlemaps.js
176+
│ ├── openai.js
177+
│ └── auth.js
178+
├── scripts/ # Utility and admin scripts
179+
│ └── rotateToken.js # Token rotation tool
180+
├── utils/ # Utility functions
181+
│ ├── vaultService.js
182+
│ ├── tokenProvider.js
183+
│ ├── jwtAuth.js
184+
│ └── logger.js
185+
├── .env # Environment variables (create from .env.example)
186+
├── .env.example # Example environment file
187+
├── package.json # Project dependencies
188+
├── server.js # Main server file
189+
└── test-server.js # Test script
190+
```
191+
192+
## Production Deployment
193+
194+
When deploying to production, ensure:
195+
196+
1. Set `NODE_ENV=production` in your environment
197+
2. Use a secure backend for the token vault (aws or hashicorp recommended)
198+
3. Configure proper `ALLOWED_ORIGIN` for CORS
199+
4. Set up a process manager like PM2 or run in Docker
200+
5. Use HTTPS with valid SSL certificates
201+
6. Set up proper monitoring and logging
202+
203+
## Security Considerations
204+
205+
- The vault encryption key and salt should be stored securely outside version control
206+
- In production, consider using a KMS (Key Management Service) for the vault encryption key
207+
- For highly secure environments, use a dedicated secrets manager like HashiCorp Vault
208+
- Enable automatic token rotation monitoring and notifications
209+
- Use environment-specific secrets with different rotation schedules
210+
- Implement the principle of least privilege for all service accounts
211+
- Never expose token rotation APIs to public networks
212+
213+
## License
214+
215+
MIT
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* Client for interacting with Google Maps API
3+
*/
4+
class GoogleMapsClient {
5+
constructor() {
6+
this.apiKey = process.env.GOOGLE_MAPS_API_KEY;
7+
}
8+
9+
/**
10+
* Validates if a location exists
11+
* @param {string} locationName - Name of the location to validate
12+
* @returns {Promise<Object>} - Validation result with location details
13+
*/
14+
async validateLocation(locationName) {
15+
try {
16+
// Mock implementation for testing
17+
return {
18+
valid: true,
19+
location: {
20+
lat: 48.8566,
21+
lng: 2.3522,
22+
address: 'Paris, France'
23+
}
24+
};
25+
} catch (error) {
26+
throw new Error(`Failed to validate location: ${error.message}`);
27+
}
28+
}
29+
30+
/**
31+
* Gets attractions for a location
32+
* @param {Object} location - Location coordinates and details
33+
* @returns {Promise<Array>} - List of attractions
34+
*/
35+
async getAttractions(location) {
36+
try {
37+
// Mock implementation for testing
38+
return [
39+
{ name: 'Eiffel Tower', rating: 4.5, description: 'Famous tower' },
40+
{ name: 'Louvre Museum', rating: 4.8, description: 'World-class art museum' }
41+
];
42+
} catch (error) {
43+
throw new Error(`Failed to get attractions: ${error.message}`);
44+
}
45+
}
46+
47+
/**
48+
* Gets accommodation options for a location
49+
* @param {Object} location - Location coordinates and details
50+
* @returns {Promise<Array>} - List of accommodations
51+
*/
52+
async getAccommodations(location) {
53+
try {
54+
// Mock implementation for testing
55+
return [
56+
{ name: 'Family Hotel Paris', rating: 4.2, price_range: '€€' },
57+
{ name: 'Paris Apartment', rating: 4.5, price_range: '€€€' }
58+
];
59+
} catch (error) {
60+
throw new Error(`Failed to get accommodations: ${error.message}`);
61+
}
62+
}
63+
64+
/**
65+
* Gets available transportation options for a location
66+
* @param {Object} location - Location coordinates and details
67+
* @returns {Promise<Array>} - List of transportation options
68+
*/
69+
async getTransportOptions(location) {
70+
try {
71+
// Mock implementation for testing
72+
return ['Metro', 'Bus', 'Taxi'];
73+
} catch (error) {
74+
throw new Error(`Failed to get transport options: ${error.message}`);
75+
}
76+
}
77+
}
78+
79+
module.exports = new GoogleMapsClient();

0 commit comments

Comments
 (0)