From ba938be7ada4d7d584fa5e2180d9f374623989e6 Mon Sep 17 00:00:00 2001 From: bwnyasse <5323628+bwnyasse@users.noreply.github.com> Date: Sat, 10 Jan 2026 11:18:48 -0500 Subject: [PATCH] feat(Makefile): replace Cloud Run deployment with Firebase Hosting for launchpad feat(firebase.json): remove site property from api-harness hosting config feat(firebase): migrate launchpad to firebase hosting with auth This commit migrates the internal launchpad from Cloud Run with IAP to Firebase Hosting with Firebase Authentication. This change simplifies the deployment process and leverages Firebase's authentication capabilities for user access control. The following changes were made: - Updated the Makefile to remove Cloud Run deployment tasks and add Firebase Hosting deployment tasks. - Removed the Dockerfile and .gcloudignore files, as they are no longer needed for Firebase Hosting. - Updated the firebase.json file to configure Firebase Hosting for the launchpad. - Modified the launchpad's index.html to include Firebase Authentication logic. - Updated the iap-users.txt file to be used as a whitelist for Firebase Authentication. - Added a launchpad-dev target to run the launchpad locally using the Firebase Hosting emulator. - Removed the configure-iap-launchpad target, as IAP is no longer used. - Removed the site property from the api-harness hosting configuration in firebase.json, as it is not needed. The migration to Firebase Hosting provides the following benefits: - Simplified deployment process. - Firebase Authentication for user access control. - Improved scalability and reliability. - Reduced operational overhead. --- Makefile | 63 +--- firebase.json | 2 - firebase/internal-launchpad/.gcloudignore | 18 - firebase/internal-launchpad/Dockerfile | 28 -- firebase/internal-launchpad/iap-users.txt | 9 +- firebase/internal-launchpad/index.html | 393 +++++++++++----------- 6 files changed, 220 insertions(+), 293 deletions(-) delete mode 100644 firebase/internal-launchpad/.gcloudignore delete mode 100644 firebase/internal-launchpad/Dockerfile diff --git a/Makefile b/Makefile index 71c83e6a..2467ccfa 100644 --- a/Makefile +++ b/Makefile @@ -21,10 +21,6 @@ GCP_STAGING_PROJECT_ID := krow-workforce-staging IAP_SERVICE_ACCOUNT := service-933560802882@gcp-sa-iap.iam.gserviceaccount.com # --- Cloud Run Configuration --- -CR_LAUNCHPAD_SERVICE_NAME := internal-launchpad -CR_LAUNCHPAD_REGION := us-central1 -CR_LAUNCHPAD_IMAGE_URI := us-docker.pkg.dev/$(GCP_DEV_PROJECT_ID)/gcr-io/$(CR_LAUNCHPAD_SERVICE_NAME) - CR_ADMIN_SERVICE_NAME := admin-console CR_ADMIN_REGION := us-central1 CR_ADMIN_IMAGE_URI = us-docker.pkg.dev/$(GCP_PROJECT_ID)/gcr-io/$(CR_ADMIN_SERVICE_NAME) @@ -68,6 +64,7 @@ help: @echo " make install - Installs web frontend dependencies." @echo " make dev - Starts the local web frontend server." @echo " make build - Builds the web frontend for production." + @echo " make launchpad-dev - Starts the local launchpad server (Firebase Hosting emulator)." @echo "" @echo " --- MOBILE APP DEVELOPMENT ---" @echo " make mobile-client-install - Install dependencies for client app" @@ -79,7 +76,7 @@ help: @echo " make mobile-staff-build - Build staff app (requires ENV & PLATFORM, optional BUILD_TYPE=apk)" @echo "" @echo " --- DEPLOYMENT ---" - @echo " make deploy-launchpad-full - Deploys internal launchpad to Cloud Run (dev only) with IAP." + @echo " make deploy-launchpad-hosting - Deploys internal launchpad to Firebase Hosting (Auth via Firebase)." @echo " make deploy-admin-full [ENV=staging] - Deploys Admin Console to Cloud Run with IAP (default: dev)." @echo " make deploy-app [ENV=staging] - Builds and deploys the main web app via Firebase Hosting (default: dev)." @echo "" @@ -125,29 +122,17 @@ build: @echo "--> Building web frontend for production..." @cd frontend-web && VITE_APP_ENV=$(ENV) npm run build -# --- Deployment --- -deploy-launchpad: - @echo "--> Building and deploying Internal Launchpad to Cloud Run..." - @echo " - Step 1: Building container image..." - @cd firebase/internal-launchpad && gcloud builds submit \ - --tag $(CR_LAUNCHPAD_IMAGE_URI) \ - --project=$(GCP_DEV_PROJECT_ID) - @echo " - Step 2: Deploying to Cloud Run..." - @gcloud run deploy $(CR_LAUNCHPAD_SERVICE_NAME) \ - --image $(CR_LAUNCHPAD_IMAGE_URI) \ - --platform managed \ - --region $(CR_LAUNCHPAD_REGION) \ - --no-allow-unauthenticated \ - --project=$(GCP_DEV_PROJECT_ID) - @echo " - Step 3: Enabling IAP on the service..." - @gcloud beta run services update $(CR_LAUNCHPAD_SERVICE_NAME) \ - --region=$(CR_LAUNCHPAD_REGION) \ - --project=$(GCP_DEV_PROJECT_ID) \ - --iap - @echo "--> ✅ Deployment to Cloud Run successful." +launchpad-dev: + @echo "--> Starting local Launchpad server using Firebase Hosting emulator..." + @firebase serve --only hosting:launchpad --project=$(FIREBASE_ALIAS) -deploy-launchpad-full: deploy-launchpad configure-iap-launchpad - @echo "✅ Launchpad deployed and IAP configured successfully!" +# --- Deployment --- +deploy-launchpad-hosting: + @echo "--> Deploying Internal Launchpad to Firebase Hosting..." + @echo " - Target: hosting:launchpad" + @echo " - Project: $(FIREBASE_ALIAS)" + @firebase deploy --only hosting:launchpad --project=$(FIREBASE_ALIAS) + @echo "--> ✅ Deployment to Firebase Hosting successful." deploy-app: build @echo "--> Deploying Frontend Web App to [$(ENV)] environment..." @@ -214,30 +199,6 @@ free-dev: dataconnect-sync @cd frontend-web-free && npm run dev -- --port 5174 # --- Cloud IAP Configuration --- -configure-iap-launchpad: - @echo "--> Configuring IAP for Cloud Run service [$(CR_LAUNCHPAD_SERVICE_NAME)]..." - @echo " - Granting Cloud Run Invoker role to IAP Service Account..." - @gcloud run services add-iam-policy-binding $(CR_LAUNCHPAD_SERVICE_NAME) \ - --region=$(CR_LAUNCHPAD_REGION) \ - --project=$(GCP_DEV_PROJECT_ID) \ - --member=\"serviceAccount:$(IAP_SERVICE_ACCOUNT)\" \ - --role='roles/run.invoker' \ - --quiet - @echo " - Adding users from iap-users.txt..." - @cd firebase/internal-launchpad && \ - grep -v '^#' iap-users.txt | grep -v '^$$' | while read -r member; do \ - echo " Adding $$member as IAP-secured Web App User..."; \ - gcloud beta iap web add-iam-policy-binding \ - --project=$(GCP_DEV_PROJECT_ID) \ - --resource-type=cloud-run \ - --service=$(CR_LAUNCHPAD_SERVICE_NAME) \ - --region=$(CR_LAUNCHPAD_REGION) \ - --member=\"$$member\" \ - --role='roles/iap.httpsResourceAccessor' \ - --quiet; \ - done - @echo "✅ IAP configuration for Launchpad complete." - configure-iap-admin: @echo "--> Configuring IAP for Cloud Run service [$(CR_ADMIN_SERVICE_NAME)] in [$(ENV)]..." @echo " - Granting Cloud Run Invoker role to IAP Service Account..." diff --git a/firebase.json b/firebase.json index 8900d6b8..b08c11a0 100644 --- a/firebase.json +++ b/firebase.json @@ -48,7 +48,6 @@ { "target": "api-harness-dev", "public": "internal-api-harness/dist", - "site": "krow-api-harness-dev", "ignore": [ "firebase.json", "**/.*", @@ -64,7 +63,6 @@ { "target": "api-harness-staging", "public": "internal-api-harness/dist", - "site": "krow-api-harness-staging", "ignore": [ "firebase.json", "**/.*", diff --git a/firebase/internal-launchpad/.gcloudignore b/firebase/internal-launchpad/.gcloudignore deleted file mode 100644 index 28b93809..00000000 --- a/firebase/internal-launchpad/.gcloudignore +++ /dev/null @@ -1,18 +0,0 @@ -# This file specifies files that are *not* uploaded to Google Cloud -# using gcloud. It follows the same syntax as .gitignore, with the addition of -# "#!include" directives (which insert the entries of the given .gitignore-style -# file at that point). -# -# For more information, run: -# $ gcloud topic gcloudignore -# -.gcloudignore -# If you would like to upload your .git directory, .gitignore file or files -# from your .gitignore file, remove the corresponding line -# below: -.git -.gitignore - -# Node.js dependencies: -node_modules/ -*.log \ No newline at end of file diff --git a/firebase/internal-launchpad/Dockerfile b/firebase/internal-launchpad/Dockerfile deleted file mode 100644 index 84bf1d83..00000000 --- a/firebase/internal-launchpad/Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -# Utiliser nginx pour servir les fichiers statiques -FROM nginx:alpine - -# Copier les fichiers statiques -COPY index.html /usr/share/nginx/html/ -COPY assets /usr/share/nginx/html/assets/ -COPY favicon.svg /usr/share/nginx/html/ -COPY logo.svg /usr/share/nginx/html/ - -# Configuration nginx pour le routing SPA -RUN echo 'server { \ - listen 8080; \ - server_name _; \ - root /usr/share/nginx/html; \ - index index.html; \ - location / { \ - try_files $uri $uri/ /index.html; \ - } \ - # Headers de sécurité \ - add_header X-Frame-Options "SAMEORIGIN" always; \ - add_header X-Content-Type-Options "nosniff" always; \ - add_header X-XSS-Protection "1; mode=block" always; \ -}' > /etc/nginx/conf.d/default.conf - -# Nginx écoute sur le port 8080 (requis par Cloud Run) -EXPOSE 8080 - -CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/firebase/internal-launchpad/iap-users.txt b/firebase/internal-launchpad/iap-users.txt index 4b166559..c3133c2c 100644 --- a/firebase/internal-launchpad/iap-users.txt +++ b/firebase/internal-launchpad/iap-users.txt @@ -1,9 +1,8 @@ -# List of authorized users for the Internal Launchpad +# List of authorized users for the Krow DevOps Launchpad # Format: one email per line, lines starting with # are comments # -# IMPORTANT: These users must belong to the 'krowwithus.com' organization. -# This is a known limitation of enabling IAP directly on Cloud Run. -# See: https://docs.cloud.google.com/run/docs/securing/identity-aware-proxy-cloud-run#known_limitations +# Users must be listed here to access the Launchpad via Firebase Auth. +# Both internal (@krowwithus.com) and external emails are supported. user:admin@krowwithus.com -# user:boris@oloodi.com # External users are not supported with this IAP method +user:boris@oloodi.com diff --git a/firebase/internal-launchpad/index.html b/firebase/internal-launchpad/index.html index 5857dfd4..463cf70a 100644 --- a/firebase/internal-launchpad/index.html +++ b/firebase/internal-launchpad/index.html @@ -4,7 +4,7 @@ - KROW Launchpad + Krow DevOps Launchpad @@ -73,15 +73,8 @@ } @keyframes pulse { - - 0%, - 100% { - opacity: 1; - } - - 50% { - opacity: .7; - } + 0%, 100% { opacity: 1; } + 50% { opacity: .7; } } .scrollbar-hide::-webkit-scrollbar { @@ -106,18 +99,14 @@ padding: 0.75rem 1rem; font-size: 0.875rem; color: #4b5563; - /* text-gray-600 */ text-align: left; background-color: #f9fafb; - /* bg-gray-50 */ border-radius: 0.5rem; - /* rounded-lg */ transition: background-color 0.2s ease; } .accordion-button:hover { background-color: #f3f4f6; - /* bg-gray-100 */ } .accordion-button .chevron { @@ -134,182 +123,78 @@ max-height: 0; } - /* Modal styles */ - .modal-overlay { - backdrop-filter: blur(4px); - animation: fadeIn 0.2s ease-out; - } - - @keyframes fadeIn { - from { - opacity: 0; - } - - to { - opacity: 1; - } - } - - .modal-content { - animation: slideUp 0.3s ease-out; - } - - @keyframes slideUp { - from { - opacity: 0; - transform: translateY(20px); - } - - to { - opacity: 1; - transform: translateY(0); - } - } - /* Markdown styling */ - .markdown-content { - line-height: 1.7; - color: #374151; - } + .markdown-content { line-height: 1.7; color: #374151; } + .markdown-content h1 { font-size: 2em; font-weight: 700; margin-top: 1.5em; margin-bottom: 0.5em; padding-bottom: 0.3em; border-bottom: 2px solid #e5e7eb; color: #111827; } + .markdown-content h1:first-child { margin-top: 0; } + .markdown-content h2 { font-size: 1.5em; font-weight: 600; margin-top: 1.5em; margin-bottom: 0.5em; padding-bottom: 0.2em; border-bottom: 1px solid #e5e7eb; color: #111827; } + .markdown-content h3 { font-size: 1.25em; font-weight: 600; margin-top: 1.2em; margin-bottom: 0.5em; color: #111827; } + .markdown-content h4 { font-size: 1.1em; font-weight: 600; margin-top: 1em; margin-bottom: 0.5em; color: #111827; } + .markdown-content p { margin-bottom: 1em; } + .markdown-content ul, .markdown-content ol { margin-bottom: 1em; padding-left: 2em; } + .markdown-content ul { list-style-type: disc; } + .markdown-content ol { list-style-type: decimal; } + .markdown-content li { margin-bottom: 0.5em; } + .markdown-content code { background-color: #f3f4f6; padding: 0.2em 0.4em; border-radius: 0.25em; font-size: 0.9em; font-family: 'Courier New', monospace; color: #dc2626; } + .markdown-content pre { background-color: #1f2937; color: #f9fafb; padding: 1em; border-radius: 0.5em; overflow-x: auto; margin-bottom: 1em; } + .markdown-content pre code { background-color: transparent; padding: 0; color: inherit; } + .markdown-content blockquote { border-left: 4px solid #3b82f6; padding-left: 1em; margin: 1em 0; color: #6b7280; font-style: italic; } + .markdown-content a { color: #3b82f6; text-decoration: underline; } + .markdown-content a:hover { color: #2563eb; } + .markdown-content table { width: 100%; border-collapse: collapse; margin-bottom: 1em; } + .markdown-content th, .markdown-content td { border: 1px solid #e5e7eb; padding: 0.5em; text-align: left; } + .markdown-content th { background-color: #f9fafb; font-weight: 600; } + .markdown-content img { max-width: 100%; height: auto; border-radius: 0.5em; margin: 1em 0; } + .markdown-content hr { border: none; border-top: 2px solid #e5e7eb; margin: 2em 0; } - .markdown-content h1 { - font-size: 2em; - font-weight: 700; - margin-top: 1.5em; - margin-bottom: 0.5em; - padding-bottom: 0.3em; - border-bottom: 2px solid #e5e7eb; - color: #111827; + /* Loading Overlay */ + #auth-loading { + position: fixed; top: 0; left: 0; right: 0; bottom: 0; + background: white; z-index: 50; + display: flex; flex-direction: column; align-items: center; justify-content: center; } - - .markdown-content h1:first-child { - margin-top: 0; - } - - .markdown-content h2 { - font-size: 1.5em; - font-weight: 600; - margin-top: 1.5em; - margin-bottom: 0.5em; - padding-bottom: 0.2em; - border-bottom: 1px solid #e5e7eb; - color: #111827; - } - - .markdown-content h3 { - font-size: 1.25em; - font-weight: 600; - margin-top: 1.2em; - margin-bottom: 0.5em; - color: #111827; - } - - .markdown-content h4 { - font-size: 1.1em; - font-weight: 600; - margin-top: 1em; - margin-bottom: 0.5em; - color: #111827; - } - - .markdown-content p { - margin-bottom: 1em; - } - - .markdown-content ul, - .markdown-content ol { - margin-bottom: 1em; - padding-left: 2em; - } - - .markdown-content ul { - list-style-type: disc; - } - - .markdown-content ol { - list-style-type: decimal; - } - - .markdown-content li { - margin-bottom: 0.5em; - } - - .markdown-content code { - background-color: #f3f4f6; - padding: 0.2em 0.4em; - border-radius: 0.25em; - font-size: 0.9em; - font-family: 'Courier New', monospace; - color: #dc2626; - } - - .markdown-content pre { - background-color: #1f2937; - color: #f9fafb; - padding: 1em; - border-radius: 0.5em; - overflow-x: auto; - margin-bottom: 1em; - } - - .markdown-content pre code { - background-color: transparent; - padding: 0; - color: inherit; - } - - .markdown-content blockquote { - border-left: 4px solid #3b82f6; - padding-left: 1em; - margin: 1em 0; - color: #6b7280; - font-style: italic; - } - - .markdown-content a { - color: #3b82f6; - text-decoration: underline; - } - - .markdown-content a:hover { - color: #2563eb; - } - - .markdown-content table { - width: 100%; - border-collapse: collapse; - margin-bottom: 1em; - } - - .markdown-content th, - .markdown-content td { - border: 1px solid #e5e7eb; - padding: 0.5em; - text-align: left; - } - - .markdown-content th { - background-color: #f9fafb; - font-weight: 600; - } - - .markdown-content img { - max-width: 100%; - height: auto; - border-radius: 0.5em; - margin: 1em 0; - } - - .markdown-content hr { - border: none; - border-top: 2px solid #e5e7eb; - margin: 2em 0; + #login-screen { + display: none; + position: fixed; top: 0; left: 0; right: 0; bottom: 0; + background: linear-gradient(135deg, #f3f4f6 0%, #e5e7eb 100%); + z-index: 40; + align-items: center; justify-content: center; } -
+ + +
+
+

Verifying access...

+
+ + +
+
+
+ KROW Logo +
+

Internal DevOps Launchpad

+

Please sign in to access internal development resources.

+ + + +
+
+ + +
-

KROW

-

Launchpad

+

KROW DevOps

+

Launchpad Hub

@@ -347,9 +232,15 @@
-
-
- System Online +
+
+
+ System Online +
+
+ + +
@@ -361,8 +252,8 @@
-

Welcome to KROW Launchpad

-

Your central hub for workforce management infrastructure

+

Krow DevOps Launchpad

+

Central hub for KROW development and operations infrastructure