From 6fd476717e8e7939295b55767fcf7bdc5e4b979a Mon Sep 17 00:00:00 2001 From: Xavier De Koninck Date: Wed, 18 Dec 2024 17:45:57 +0100 Subject: [PATCH] feat(proxy): add testing proxy setup for strapi testing environment --- README.md | 6 + nginx-strapi-testing-proxy/Dockerfile | 12 ++ nginx-strapi-testing-proxy/README.md | 43 +++++++ .../launch-testing-proxy.sh | 114 ++++++++++++++++++ nginx-strapi-testing-proxy/nginx.conf | 17 +++ .../transfer-from-testing.sh | 28 +++++ package.json | 6 +- .../src/lib/analytics/analyticsProvider.ts | 2 +- 8 files changed, 226 insertions(+), 2 deletions(-) create mode 100644 nginx-strapi-testing-proxy/Dockerfile create mode 100644 nginx-strapi-testing-proxy/README.md create mode 100755 nginx-strapi-testing-proxy/launch-testing-proxy.sh create mode 100644 nginx-strapi-testing-proxy/nginx.conf create mode 100755 nginx-strapi-testing-proxy/transfer-from-testing.sh diff --git a/README.md b/README.md index 3bad48d0..6eb41e4a 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,10 @@ The project includes several scripts to simplify development and setup: - `yarn test:deadcode:update`: Update the public_website and content_management_system dead code snapshots. - `yarn test:lint`: Test both public_website and content_management_system linting. - `yarn test:types`: Test both public_website and content_management_system typing. +- `yarn proxy:testing`: Launches the testing proxy server. This script navigates to the nginx-strapi-testing-proxy directory and runs the [launch-testing-proxy.sh](./nginx-strapi-testing-proxy/launch-testing-proxy.sh) script. +- `yarn proxy:testing:infinite`: Launches the testing proxy server in infinite mode. This script runs [launch-testing-proxy.sh](./nginx-strapi-testing-proxy/launch-testing-proxy-sh) with the -l true option to continuously monitor and regenerate tokens. +- `yarn proxy:testing:stop`: Stops the currently running testing proxy server by stopping the nginx-strapi-testing-proxy Docker container. +- `yarn proxy:transfer`: Executes the transfer script to sync data from the testing proxy. This script navigates to the nginx-strapi-testing-proxy directory and runs [transfer-from-testing.sh](./nginx-strapi-testing-proxy/transfer-from-testing.sh). ## Testing @@ -101,6 +105,7 @@ The commits of the PR won't be on `main`, but are still useful for PR readiness Here is a recap: ``` + [optional scope]: │ │ │ │ │ └─⫸ PR Description: A short and concise summary of the changes. Present tense. @@ -110,6 +115,7 @@ Here is a recap: | │ └─⫸ PR Type: build:, chore:, ci:, docs:, feat:, fix:, perf:, refactor:, revert:, style:, test: + ``` Here is a more detailed explanation for different types: diff --git a/nginx-strapi-testing-proxy/Dockerfile b/nginx-strapi-testing-proxy/Dockerfile new file mode 100644 index 00000000..db2be7ba --- /dev/null +++ b/nginx-strapi-testing-proxy/Dockerfile @@ -0,0 +1,12 @@ +FROM nginx:1.27.3 + +RUN apt-get update && \ + apt-get install -y gettext-base && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +COPY nginx.conf /etc/nginx/nginx.conf.template + +CMD ["sh", "-c", "envsubst '$IAP_ID_TOKEN' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf && exec nginx -g 'daemon off;'"] + + +EXPOSE 8080 diff --git a/nginx-strapi-testing-proxy/README.md b/nginx-strapi-testing-proxy/README.md new file mode 100644 index 00000000..52e9af15 --- /dev/null +++ b/nginx-strapi-testing-proxy/README.md @@ -0,0 +1,43 @@ +# Strapi Testing Environment + +To connect the project to the Strapi testing environment, ensure the testing proxy is correctly set up and running. You can use the following commands: + +- Start the testing proxy server: + +```bash +yarn proxy:testing +``` + +This launches the testing proxy server to connect to Strapi. + +- Run the proxy server in infinite mode: + +```bash +yarn proxy:testing:infinite +``` + +This mode ensures the proxy regenerates the JWT token automatically every hour to avoid token expiration issues. + +- Stop the testing proxy server: + +```bash +yarn proxy:testing:stop +``` + +This stops the currently running proxy server. + +### Common Issues and Considerations + +- **Token Expiration**: JWT tokens for the Strapi testing environment expire after 1 hour. If you encounter access issues due to expired tokens, use the infinite mode to regenerate tokens automatically. + +- **Data Consistency**: The testing environment may contain test-specific data that differs from the local database. Always validate the data before running tests or debugging features. + +- **Data Transfer**: You can transfer data from the testing environment to your local setup (excluding files) using: + +```bash +yarn proxy:transfer +``` + +This ensures your local instance is synced with the testing environment. + +By following these steps, you can easily point to the Strapi testing server, manage JWT token lifecycles, and handle potential data inconsistencies during development and testing. diff --git a/nginx-strapi-testing-proxy/launch-testing-proxy.sh b/nginx-strapi-testing-proxy/launch-testing-proxy.sh new file mode 100755 index 00000000..1008fa3c --- /dev/null +++ b/nginx-strapi-testing-proxy/launch-testing-proxy.sh @@ -0,0 +1,114 @@ +#!/bin/bash + +# Script usage function +usage() { + echo "⭐ Usage: $0 [-d AUTH_DIR] [-l true|false]" + echo "⭐ -d AUTH_DIR Directory containing the get-iap-tokens.py script (default: ../../iap-local-authentication)" + echo "⭐ Repository: https://github.com/pass-culture/iap-local-authentication" + echo "⭐ -l LOOP_MODE Enable infinite loop to refresh JWT (true/false, default: false)" + exit 1 +} + +# Default values +DEFAULT_AUTH_DIR="../../iap-local-authentication" +CLOUDSDK_PYTHON="/usr/bin/python3" +IMAGE_NAME="nginx-strapi-testing-proxy" +CONTAINER_NAME="nginx-strapi-testing-proxy" +VENV_DIR="venv" +JWT_EXPIRATION_TIME=3600 # JWT valid for 1 hour (3600 seconds) +LOOP_MODE=false + +# Parse command-line arguments +while getopts "d:l:" opt; do + case $opt in + d) AUTH_DIR="$OPTARG" ;; + l) LOOP_MODE="$OPTARG" ;; + *) usage ;; + esac +done + +# Use the default AUTH_DIR if none is provided +AUTH_DIR=${AUTH_DIR:-$DEFAULT_AUTH_DIR} + +# Step 1: Create virtual environment and install dependencies +echo "✨ Setting up the virtual environment and installing dependencies..." +cd "$AUTH_DIR" || { echo "⚠️ Error: Cannot access $AUTH_DIR"; exit 1; } + +if [ ! -d "$VENV_DIR" ]; then + python3 -m venv "$VENV_DIR" + echo "⭐ Virtual environment created in $AUTH_DIR/$VENV_DIR." +fi + +# Activate the virtual environment and install dependencies +# shellcheck disable=SC1091 +source "$VENV_DIR/bin/activate" +if [ -f "requirements.txt" ]; then + echo "🛠️ Installing dependencies from requirements.txt..." + pip install --upgrade pip + pip install -r requirements.txt || { echo "⚠️ Error: Failed to install dependencies."; exit 1; } +else + echo "⚠️ Error: requirements.txt not found in $AUTH_DIR." + exit 1 +fi + +# Step 2: Google Cloud authentication +echo "💳 Authenticating with Google Cloud..." +export CLOUDSDK_PYTHON="$CLOUDSDK_PYTHON" + +gcloud auth application-default login || { echo "⚠️ Error: Google Cloud authentication failed"; exit 1; } + +# Step 3: Generate the IAP token +generate_jwt() { + echo "✨ Generating the IAP token..." + python3 get-iap-tokens.py || { echo "⚠️ Error: Failed to generate IAP token."; exit 1; } + + # Load environment variables containing the token + echo "📂 Loading IAP credentials..." + # shellcheck disable=SC1090 + source ~/.iap-credentials || { echo "⚠️ Error: Unable to load ~/.iap-credentials"; exit 1; } + + # Verify that the IAP_ID_TOKEN is set + if [ -z "$IAP_ID_TOKEN" ]; then + echo "⚠️ Error: IAP_ID_TOKEN is empty. Check the get-iap-tokens.py script." + exit 1 + fi +} + +generate_jwt + +# Return to the Docker directory +echo "👉 Returning to the Docker directory..." +deactivate +cd - >/dev/null || exit 1 + +# Step 4: Build the Docker image +echo "🔧 Building the Docker image..." +docker build -t "$IMAGE_NAME" . || { echo "⚠️ Error: Docker build failed"; exit 1; } + +# Step 5: Run the Docker container +start_container() { + echo "🚀 Running the Docker container..." + docker stop "$CONTAINER_NAME" >/dev/null 2>&1 || true + docker run -d --rm -p 8080:8080 -e IAP_ID_TOKEN="$IAP_ID_TOKEN" --name "$CONTAINER_NAME" "$IMAGE_NAME" || { + echo "⚠️ Error: Docker container failed to start"; exit 1; + } + echo "🎉 Container $CONTAINER_NAME is now running on port 8080. (http://localhost:8080/)" +} + +start_container + +# Step 6: Infinite loop for JWT refresh if enabled +if [ "$LOOP_MODE" = "true" ]; then + echo "🔄 Infinite loop mode enabled. Monitoring JWT expiration..." + while true; do + sleep $((JWT_EXPIRATION_TIME - 60)) # Refresh 1 minute before expiration + + echo "⏳ JWT about to expire. Regenerating..." + generate_jwt + + echo "⟳ Restarting container with new JWT..." + start_container + done +else + echo "✅ Infinite loop mode disabled. Script execution complete." +fi diff --git a/nginx-strapi-testing-proxy/nginx.conf b/nginx-strapi-testing-proxy/nginx.conf new file mode 100644 index 00000000..257fc121 --- /dev/null +++ b/nginx-strapi-testing-proxy/nginx.conf @@ -0,0 +1,17 @@ +events {} + +http { + server { + listen 8080; + + location / { + proxy_pass https://siteinstit-cms.testing.passculture.team/; + + proxy_set_header Proxy-Authorization "Bearer $IAP_ID_TOKEN"; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_pass_request_headers on; + } + } +} \ No newline at end of file diff --git a/nginx-strapi-testing-proxy/transfer-from-testing.sh b/nginx-strapi-testing-proxy/transfer-from-testing.sh new file mode 100755 index 00000000..d9c7d680 --- /dev/null +++ b/nginx-strapi-testing-proxy/transfer-from-testing.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Configuration +CONTAINER_NAME="nginx-strapi-testing-proxy" +PROXY_URL="http://localhost:8080/admin" +TRANSFER_COMMAND="yarn strapi transfer --from $PROXY_URL --exclude files" + +# Step 1: Check if the Docker container is running +echo "Checking if the Docker proxy container '$CONTAINER_NAME' is running..." + +if docker ps --filter "name=$CONTAINER_NAME" --format "{{.Names}}" | grep -q "$CONTAINER_NAME"; then + echo "✅ Docker proxy container '$CONTAINER_NAME' is running." +else + echo "❌ Error: Docker proxy container '$CONTAINER_NAME' is not running." + echo "Please start the proxy container before running this command." + echo "=> yarn proxy:testing" + exit 1 +fi + +# Step 2: Execute the transfer command +cd ../content_management_system >/dev/null || exit 1 +echo "Executing the Strapi transfer command..." +if $TRANSFER_COMMAND; then + echo "✅ Strapi transfer completed successfully." +else + echo "❌ Error: Strapi transfer failed. Please check the logs for details." + exit 1 +fi diff --git a/package.json b/package.json index b504ed82..74542ca2 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,11 @@ "test:deadcode:update": "yarn --silent test:deadcode > scripts/dead_code_snapshot.txt", "test:lint": "concurrently \"cd public_website && yarn test:lint\" \"cd content_management_system && yarn test:lint\"", "test:types": "concurrently \"cd public_website && yarn test:types\" \"cd content_management_system && yarn test:types\"", - "copytypes": "node copyTypes.js" + "copytypes": "node copyTypes.js", + "proxy:testing": "cd nginx-strapi-testing-proxy && bash launch-testing-proxy.sh", + "proxy:testing:infinite": "cd nginx-strapi-testing-proxy && bash launch-testing-proxy.sh -l true", + "proxy:testing:stop": "docker stop nginx-strapi-testing-proxy", + "proxy:transfer": "cd nginx-strapi-testing-proxy && bash transfer-from-testing.sh" }, "devDependencies": { "concurrently": "^9.0.0" diff --git a/public_website/src/lib/analytics/analyticsProvider.ts b/public_website/src/lib/analytics/analyticsProvider.ts index a4da717b..b4263aa5 100644 --- a/public_website/src/lib/analytics/analyticsProvider.ts +++ b/public_website/src/lib/analytics/analyticsProvider.ts @@ -29,7 +29,7 @@ export type EventMap = { pageView: { origin: string } } -export const eventMapKeys: { [K in keyof EventMap]: true } = { +export const eventMapKeys = { testEvent: true, goToSignUpNative: true, goToSignUpPro: true,