diff --git a/collabmate/.env.example b/collabmate/.env.example new file mode 100644 index 0000000..42afa64 --- /dev/null +++ b/collabmate/.env.example @@ -0,0 +1,8 @@ +FIREBASE_API_KEY=your_firebase_api_key_here +FIREBASE_AUTH_DOMAIN=your_firebase_auth_domain_here +FIREBASE_PROJECT_ID=your_firebase_project_id_here +FIREBASE_STORAGE_BUCKET=your_firebase_storage_bucket_here +FIREBASE_MESSAGING_ID=your_firebase_messaging_id_here +FIREBASE_APP_ID=your_firebase_app_id_here +FIREBASE_MEASUREMENT_ID=your_firebase_measurement_id_here +SERPAPI_API_KEY=your_serpapi_api_key_here \ No newline at end of file diff --git a/collabmate/.gitignore b/collabmate/.gitignore new file mode 100644 index 0000000..8d4b137 --- /dev/null +++ b/collabmate/.gitignore @@ -0,0 +1,25 @@ +.venv/ +venv/ +.env +__pycache__/ +*.pyc +*.pyo +*.pyd +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info +.installed.cfg +*.egg +MANIFEST +*.log \ No newline at end of file diff --git a/collabmate/app.py b/collabmate/app.py index b812f93..083e57a 100644 --- a/collabmate/app.py +++ b/collabmate/app.py @@ -1,8 +1,23 @@ +import os + from flask import Flask, render_template, request, jsonify from serpapi import GoogleSearch app = Flask(__name__) + +def get_firebase_web_config(): + config = { + "apiKey": os.getenv("FIREBASE_API_KEY", ""), + "authDomain": os.getenv("FIREBASE_AUTH_DOMAIN", ""), + "projectId": os.getenv("FIREBASE_PROJECT_ID", ""), + "storageBucket": os.getenv("FIREBASE_STORAGE_BUCKET", ""), + "messagingSenderId": os.getenv("FIREBASE_MESSAGING_SENDER_ID", ""), + "appId": os.getenv("FIREBASE_APP_ID", ""), + "measurementId": os.getenv("FIREBASE_MEASUREMENT_ID", ""), + } + return {key: value for key, value in config.items() if value} + # ---------------- ROUTES ---------------- # @app.route("/") @@ -30,6 +45,38 @@ def about(): return render_template("about.html") +@app.route("/api/firebase-config", methods=["GET"]) +def firebase_config(): + # Map client config keys to their corresponding environment variable names + required_env_vars = { + "apiKey": "FIREBASE_API_KEY", + "authDomain": "FIREBASE_AUTH_DOMAIN", + "projectId": "FIREBASE_PROJECT_ID", + "storageBucket": "FIREBASE_STORAGE_BUCKET", + "messagingSenderId": "FIREBASE_MESSAGING_SENDER_ID", + "appId": "FIREBASE_APP_ID", + # measurementId is often optional; leave it out of required set + } + + missing_keys = [ + client_key + for client_key, env_name in required_env_vars.items() + if not os.getenv(env_name, "") + ] + + if missing_keys: + return ( + jsonify( + { + "error": "Firebase configuration is incomplete", + "missingKeys": missing_keys, + } + ), + 500, + ) + return jsonify(get_firebase_web_config()) + + # ---------------- SEARCH API ---------------- # @app.route("/search", methods=["POST"]) @@ -40,10 +87,13 @@ def search(): params = { "engine": "google", "q": f"site:linkedin.com/in {skill} developer", - "api_key": "e982c35751fcf5b616da20a53c8b2e37888ee7df15e3a42f3730043767c02233", + "api_key": os.getenv("SERPAPI_API_KEY", ""), "num": 5 } + if not params["api_key"]: + return jsonify({"error": "SERPAPI_API_KEY is not configured"}), 500 + search = GoogleSearch(params) results = search.get_dict() diff --git a/collabmate/requirements.txt b/collabmate/requirements.txt index e45ffe3..38ee2d3 100644 Binary files a/collabmate/requirements.txt and b/collabmate/requirements.txt differ diff --git a/collabmate/static/firebase/firebase-config.js b/collabmate/static/firebase/firebase-config.js index fe15895..915d308 100644 --- a/collabmate/static/firebase/firebase-config.js +++ b/collabmate/static/firebase/firebase-config.js @@ -1,13 +1,34 @@ -// Firebase configuration -const firebaseConfig = { - apiKey: "AIzaSyBK-BHorRztdxUjKZWSdi9yKd3SQPvRlXE", - authDomain: "collabmate-ai-53941.firebaseapp.com", - projectId: "collabmate-ai-53941", - storageBucket: "collabmate-ai-53941.firebasestorage.app", - messagingSenderId: "789622234866", - appId: "1:789622234866:web:f1b8291921aea068eb7a6b", - measurementId: "G-W604B1RY8H" -}; - -// Initialize Firebase -firebase.initializeApp(firebaseConfig); \ No newline at end of file +function initFirebase() { + // Ensure Firebase initialization is only performed once and expose a global promise + if (!window.firebaseInitPromise) { + window.firebaseInitPromise = (async () => { + try { + const response = await fetch('/api/firebase-config', { + method: 'GET', + cache: 'no-store' + }); + + if (!response.ok) { + throw new Error('Failed to load Firebase config'); + } + + const firebaseConfig = await response.json(); + + if (!firebaseConfig.apiKey || !firebaseConfig.projectId || !firebaseConfig.appId) { + throw new Error('Firebase config is incomplete'); + } + + firebase.initializeApp(firebaseConfig); + } catch (error) { + console.error('Firebase initialization failed:', error); + // Re-throw so consumers of firebaseInitPromise can handle failures if needed + throw error; + } + })(); + } + + return window.firebaseInitPromise; +} + +// Kick off initialization immediately when this file loads +initFirebase(); \ No newline at end of file