diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..4105fb9 --- /dev/null +++ b/.env.example @@ -0,0 +1,47 @@ +# ======================================== +# FIREBASE ENVIRONMENT VARIABLES TEMPLATE +# ======================================== +# +# ARCHITECTURE: +# - These variables are stored in .env (server-side) +# - Server endpoint /api/config serves them to client +# - Client loads via scripts/env.js before Firebase initialization +# - Never expose .env to public repository +# +# SETUP INSTRUCTIONS: +# 1. Copy this file: cp .env.example .env +# 2. Get your Firebase project config from Firebase Console +# 3. Fill in your actual values below +# 4. NEVER push .env file to GitHub (it's in .gitignore) +# 5. Each developer/environment needs their own .env file +# 6. Server must be running for client to fetch config via /api/config +# +# ======================================== + +# API Key - Allows app to connect to your Firebase project +# Get from: Firebase Console > Project Settings > Web App Config +VITE_FIREBASE_API_KEY=your_firebase_api_key_here + +# Auth Domain - Used for user login/signup +# Format: your-project-name.firebaseapp.com +VITE_FIREBASE_AUTH_DOMAIN=your_project_id.firebaseapp.com + +# Project ID - Unique identifier for your Firebase project +# Get from: Firebase Console > Project Settings +VITE_FIREBASE_PROJECT_ID=your_project_id + +# Storage Bucket - Where user files are stored +# Format: your-project-name.firebasestorage.app +VITE_FIREBASE_STORAGE_BUCKET=your_project_id.firebasestorage.app + +# Messaging Sender ID - For push notifications (if used) +# Get from: Firebase Console > Project Settings +VITE_FIREBASE_MESSAGING_SENDER_ID=your_messaging_sender_id + +# App ID - Identifies this web app in Firebase +# Format: 1:number:web:random-id +VITE_FIREBASE_APP_ID=1:your_app_id:web:your_web_app_id + +# Measurement ID - For Google Analytics (optional) +# Get from: Firebase Console > Google Analytics settings +VITE_FIREBASE_MEASUREMENT_ID=G-your_measurement_id diff --git a/.gitignore b/.gitignore index e50905a..773b7b4 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,6 @@ yarn-error.log .env .env.local .env.*.local -env.js # IDE .vscode/ diff --git a/contact.html b/contact.html index 953dd58..29af812 100644 --- a/contact.html +++ b/contact.html @@ -344,6 +344,38 @@ .contact-form button:hover { background: #764ba2; } + .contact-form .form-group { + display: flex; + flex-direction: column; + gap: 0.3rem; + position: relative; + } + .contact-form .form-help, + .contact-form .error-message { + font-size: 0.85rem; + margin-top: 0.2rem; + } + .contact-form .form-help { + color: #aab4e8; + } + .contact-form .error-message { + color: #ff6b6b; + display: none; + } + .contact-form .form-group.has-error .error-message { + display: block; + } + .contact-form .form-group.has-error input, + .contact-form .form-group.has-error textarea { + border-color: #ff6b6b; + box-shadow: 0 0 0 3px rgba(255, 107, 107, 0.1); + } + .contact-form .message-counter { + font-size: 0.85rem; + color: #aab4e8; + text-align: right; + margin-top: 0.2rem; + } .contact-details { margin-top: 2.5rem; color: #e4e8f7; @@ -500,11 +532,24 @@

Contact Us

We'd love to hear from you! Fill out the form below and our team will get back to you soon.

-
- - - - + +
+ + Full name (2-50 characters) + +
+
+ + Valid email address + +
+
+ + Your message (10-1000 characters) + +
0/1000
+
+

Email: support@venturalink.com

@@ -549,34 +594,146 @@

+ \ No newline at end of file diff --git a/forgot-password.html b/forgot-password.html index d368a97..17b4155 100644 --- a/forgot-password.html +++ b/forgot-password.html @@ -138,6 +138,7 @@

Forgot Password

+ diff --git a/package-lock.json b/package-lock.json index ec479e7..ff95151 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,10 @@ "@google/generative-ai": "^0.21.0", "cors": "^2.8.5", "dotenv": "^16.4.5", - "express": "^5.1.0" + "express": "^5.1.0", + "express-rate-limit": "^7.4.1", + "express-validator": "^7.2.0", + "helmet": "^8.0.0" } }, "node_modules/@google/generative-ai": { @@ -301,6 +304,34 @@ "url": "https://opencollective.com/express" } }, + "node_modules/express-rate-limit": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", + "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/express-validator": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.3.1.tgz", + "integrity": "sha512-IGenaSf+DnWc69lKuqlRE9/i/2t5/16VpH5bXoqdxWz1aCpRvEdrBuu1y95i/iL5QP8ZYVATiwLFhwk3EDl5vg==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21", + "validator": "~13.15.23" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/finalhandler": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", @@ -418,6 +449,15 @@ "node": ">= 0.4" } }, + "node_modules/helmet": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-8.1.0.tgz", + "integrity": "sha512-jOiHyAZsmnr8LqoPGmCjYAaiuWwjAPLgY8ZX2XrmHawt99/u1y6RgrZMTeoPfpUbV96HOalYgz1qzkRbw54Pmg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -476,6 +516,12 @@ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", "license": "MIT" }, + "node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "license": "MIT" + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -869,6 +915,15 @@ "node": ">= 0.8" } }, + "node_modules/validator": { + "version": "13.15.26", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.26.tgz", + "integrity": "sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/profile.html b/profile.html index 7d6a132..ba88c1a 100644 --- a/profile.html +++ b/profile.html @@ -129,16 +129,18 @@

Edit Your Profile

- +
+ Maximum 500 characters
- +
+ Enter a valid phone number with country code (e.g., +1-555-123-4567)