diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000..4f39080 --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,3 @@ +{ + "extends": ["config:base"] +} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..bb39073 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,127 @@ +name: Seattle Deploy +run-name: Seattle Deploy for ${{ github.event.inputs.environment || 'staging' }} + +on: + workflow_dispatch: + inputs: + environment: + type: environment + default: staging + required: true + + deploy_enabled: + type: boolean + description: 'Deploy when checked' + default: true + required: true + + probers_enabled: + type: boolean + description: 'Runs probers when checked' + default: false + required: true + + schedule: + - cron: '0 12 1/1 * *' + +permissions: + id-token: write + contents: read + +# Two probers running at once can break each other. +concurrency: + group: group-${{ github.event.inputs.environment || 'staging' }} + +jobs: + deploy: + runs-on: ubuntu-latest + environment: ${{ github.event.inputs.environment || 'staging' }} + + env: + SKIP_CONFIRMATIONS: true + SKIP_USER_INPUT: true + SLACK_CHANNEL: 'C03UXPUEXU4' + # When run by the schedule github.event.inputs are not set. It's easier to normalize these here into environment variables + # than to have the extra logic all over and duplicated. + # If environment is null default to the staging site + ENVIRONMENT: ${{ github.event.inputs.environment || 'staging' }} + # Consider deployment to be enabled if manually checked or if run from a schedule + DEPLOY_ENABLED: ${{ (github.event.inputs == null || github.event.inputs.deploy_enabled == 'true') }} + # Consider probers to be enabled if manually checked or if run from a schedule, but only run them on the staging site + # beause we don't want to wipe test site data. + # PROBERS_ENABLED: ${{ (github.event.inputs == null || github.event.inputs.probers_enabled == 'true') && ((github.event.inputs.environment || 'staging') == 'staging') }} + PROBERS_ENABLED: ${{ (github.event.inputs.probers_enabled == 'true') && ((github.event.inputs.environment || 'staging') == 'staging') }} + + steps: + - name: Notify Slack Start + uses: slackapi/slack-github-action@v2.0.0 + with: + method: chat.postMessage + token: ${{ secrets.SLACK_BOT_TOKEN }} + payload: | + channel: ${{ env.CHANNEL_ID }} + text: ":space-needle: Starting Seattle Deploy\nEnv: ${{ env.ENVIRONMENT }}\nDeploy: ${{ env.DEPLOY_ENABLED }}\nProbers: ${{ env.PROBERS_ENABLED }}" + env: + CHANNEL_ID: C03UXPUEXU4 + + - name: Checkout + uses: actions/checkout@v4 + + - name: Install terraform cli + uses: hashicorp/setup-terraform@v3 + with: + terraform_wrapper: false + + - name: Resolve Latest Snapshot Tag + run: source bin/resolve-latest-snapshot-tag + + - name: Configure AWS Credentials + id: credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-west-2 + role-to-assume: ${{ secrets.AWS_ROLE_IAM }} + output-credentials: true + + - name: Get caller identity + run: aws sts get-caller-identity + + - name: Run deployment with latest on ${{ env.ENVIRONMENT }} + if: (env.DEPLOY_ENABLED == 'true') + env: + AWS_ACCESS_KEY_ID: ${{ steps.credentials.outputs.aws-access-key-id }} + AWS_SECRET_ACCESS_KEY: ${{ steps.credentials.outputs.aws-secret-access-key }} + run: bin/deploy --config="civiform_config.${{ env.ENVIRONMENT }}.sh" + + - name: Run Prober tests + if: (env.PROBERS_ENABLED == 'true') + env: + TEST_USER_LOGIN: ${{ secrets.TEST_USER_LOGIN }} + TEST_USER_PASSWORD: ${{ secrets.TEST_USER_PASSWORD }} + TEST_USER_DISPLAY_NAME: 'TEST, UATAPP' + TEST_CIVIC_ENTITY_SHORT_NAME: '${{ vars.CIVIC_ENTITY_SHORT_NAME }}' + BASE_URL: 'https://${{ vars.SUBDOMAIN }}.seattle.gov' + run: bin/run-prober + + - name: Upload test videos and traces on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: tests videos and traces + retention-days: 3 + path: | + tmp/html-output/ + tmp/videos/ + + - name: Notify Slack Complete + if: always() + uses: slackapi/slack-github-action@v2.0.0 + with: + method: chat.postMessage + token: ${{ secrets.SLACK_BOT_TOKEN }} + payload: | + channel: ${{ env.SLACK_CHANNEL }} + text: ":space-needle: ${{ env.STATUS_ICON }} Completed Seattle Deploy <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|${{ job.status }}>\nVersion: ${{ env.LATEST_SNAPSHOT_TAG }}\nEnv: ${{ env.ENVIRONMENT }}\nDeploy: ${{ env.DEPLOY_ENABLED }}\nProbers: ${{ env.PROBERS_ENABLED }}" + env: + CHANNEL_ID: C03UXPUEXU4 + STATUS_ICON: ${{fromJSON('[":no_entry:", ":white_check_mark:"]')[job.status == 'success']}} diff --git a/.github/workflows/slack-notification-tester.yml b/.github/workflows/slack-notification-tester.yml new file mode 100644 index 0000000..4c44d3b --- /dev/null +++ b/.github/workflows/slack-notification-tester.yml @@ -0,0 +1,23 @@ +name: Slack Notification Tester + +on: + workflow_dispatch: {} + +permissions: read-all + +jobs: + run_prober: + runs-on: ubuntu-latest + steps: + - name: Notify Slack Complete + if: always() + uses: slackapi/slack-github-action@v2.0.0 + with: + method: chat.postMessage + token: ${{ secrets.SLACK_BOT_TOKEN }} + payload: | + channel: ${{ env.CHANNEL_ID }} + text: ":space-needle: Test Message from Seattle Staging Deploy: \n${{ job.status }} ${{ env.ICON }} <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|${{ job.status }} TEST>" + env: + CHANNEL_ID: C03UXPUEXU4 + ICON: ${{fromJSON('[":no_entry:", ":white_check_mark:"]')[job.status == 'success']}} diff --git a/.github/workflows/test_api.yml b/.github/workflows/test_api.yml new file mode 100644 index 0000000..dacac9b --- /dev/null +++ b/.github/workflows/test_api.yml @@ -0,0 +1,45 @@ +name: Test API +run-name: Test API + +on: + workflow_dispatch: + inputs: + environment: + type: environment + default: test + required: true + +permissions: {} + +jobs: + test-api: + runs-on: ubuntu-latest + environment: ${{ github.event.inputs.environment || 'staging' }} + + env: + ENVIRONMENT: ${{ github.event.inputs.environment || 'staging' }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup + run: cd qa && npm install + + - name: Run + env: + BASE_URL: 'https://${{ vars.SUBDOMAIN }}.seattle.gov' + API_TOKEN: ${{ secrets.API_TOKEN }} + PROGRAM_SLUGS: ${{ secrets.PROGRAM_SLUGS }} + run: cd qa && npx playwright test + + - name: On Failure + if: failure() + run: echo "FAILED" + + # - name: Send message to ms teams + # if: failure() + # uses: dhollerbach/actions.send-message-to-ms-teams@1.0.10 + # with: + # webhook: '${{ secrets.MICROSOFT_TEAMS_WEBHOOK_URI }}' + # message: 'Testing API failed. There *may* be issues with the API. ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}' diff --git a/.github/workflows/test_gis.yml b/.github/workflows/test_gis.yml new file mode 100644 index 0000000..78e1ff1 --- /dev/null +++ b/.github/workflows/test_gis.yml @@ -0,0 +1,43 @@ +name: Test GIS + +on: + workflow_dispatch: + inputs: + force_send_teams_message: + type: boolean + description: 'Message Teams anyway' + default: false + required: false + + schedule: + - cron: '0 * * * *' + +permissions: {} + +jobs: + test-gis: + runs-on: ubuntu-latest + + env: + FORCE_SEND_TEAMS_MESSAGE: ${{ (github.event.inputs != null && github.event.inputs.force_send_teams_message == 'true') }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Run gis testing script + run: bin/test_gis.sh + + - name: Send message to ms teams + if: failure() + uses: dhollerbach/actions.send-message-to-ms-teams@1.0.10 + with: + webhook: '${{ secrets.MICROSOFT_TEAMS_WEBHOOK_URI }}' + message: 'Testing GIS failed. There *may* be issues afoot. ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}' + + - name: Force send test message to ms teams + if: (env.FORCE_SEND_TEAMS_MESSAGE == 'true') + uses: dhollerbach/actions.send-message-to-ms-teams@1.0.10 + with: + webhook: '${{ secrets.MICROSOFT_TEAMS_WEBHOOK_URI }}' + message: 'Nothing is wrong. Just testing the teams connection.' diff --git a/.gitignore b/.gitignore index b384efb..5ab2b0f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ -civiform_config.sh .DS_Store .idea *.log +*.tar tmp/ nuke.yaml # this file is created by developers when working on the deployment system. see https://docs.civiform.us/contributor-guide/developer-guide/deploy-system/prerequisites#setup-aws-nuke checkout/ +node_modules/ diff --git a/CODEOWNERS b/CODEOWNERS deleted file mode 100644 index 29851f8..0000000 --- a/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -@civiform/developers diff --git a/SETUP.md b/SETUP.md new file mode 100644 index 0000000..c9140d4 --- /dev/null +++ b/SETUP.md @@ -0,0 +1,5 @@ +# Setup + +Environments are configured under the repository settings. + +To add a new deployment target create a new environment and a new deploy config file named civiform_config.ENV_NAME.sh diff --git a/bin/remove-pgadmin-temp-secrets.sh b/bin/remove-pgadmin-temp-secrets.sh new file mode 100755 index 0000000..9dd92d0 --- /dev/null +++ b/bin/remove-pgadmin-temp-secrets.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +pushd $(git rev-parse --show-toplevel) > /dev/null + +CONFIG="${1}" + +if [[ ! -f "${CONFIG}" ]]; then + echo "Add config file name" + exit 1 +fi + +source ${CONFIG} + +aws secretsmanager delete-secret --force-delete-without-recovery --secret-id "${APP_PREFIX}-cf-pgadmin-default-password" +aws secretsmanager delete-secret --force-delete-without-recovery --secret-id "${APP_PREFIX}-cf-pgadmin-default-username" diff --git a/bin/resolve-latest-snapshot-tag b/bin/resolve-latest-snapshot-tag new file mode 100755 index 0000000..247c916 --- /dev/null +++ b/bin/resolve-latest-snapshot-tag @@ -0,0 +1,23 @@ +#! /usr/bin/env bash + +set -e +set -o pipefail + +docker pull docker.io/civiform/civiform:latest + +snapshot_tag="$(docker inspect docker.io/civiform/civiform:latest \ + | jq '.[0].Config.Env' \ + | grep 'CIVIFORM_IMAGE_TAG' \ + | grep -oP 'SNAPSHOT-\w+-\d+')" + +if [[ -z "${snapshot_tag}" ]]; then + echo "Latest snapshot tag not found." 2>&1 + exit 1 +fi + +export LATEST_SNAPSHOT_TAG="${snapshot_tag}" + +if [[ -n "${GITHUB_ENV}" ]]; then + echo "LATEST_SNAPSHOT_TAG=${snapshot_tag}" >>"${GITHUB_ENV}" +fi + diff --git a/bin/run-prober b/bin/run-prober new file mode 100755 index 0000000..cc73046 --- /dev/null +++ b/bin/run-prober @@ -0,0 +1,19 @@ +#! /usr/bin/env bash + +# DOC: Run the browser test suite in Docker against the staging environment. + +docker pull civiform/civiform-browser-test:latest + +docker run \ + -v "$(pwd)/tmp:/usr/src/civiform-browser-tests/tmp" \ + -e BASE_URL="${BASE_URL}" \ + -e TEST_USER_AUTH_STRATEGY="seattle-staging" \ + -e TEST_USER_LOGIN="${TEST_USER_LOGIN}" \ + -e TEST_USER_PASSWORD="${TEST_USER_PASSWORD}" \ + -e TEST_USER_DISPLAY_NAME="TEST, UATAPP" \ + -e TEST_CIVIC_ENTITY_SHORT_NAME="Seattle [STAGING]" \ + -e DISABLE_BROWSER_ERROR_WATCHER=true \ + -e DISABLE_SCREENSHOTS=false \ + -e CI=true \ + civiform/civiform-browser-test:latest \ + -c "npm install && npm test -- --grep-invert @northstar $@" diff --git a/bin/test_gis.sh b/bin/test_gis.sh new file mode 100755 index 0000000..5be88d9 --- /dev/null +++ b/bin/test_gis.sh @@ -0,0 +1,54 @@ +#! /usr/bin/env bash + +# DOC: Test seattle gis servers + +pushd "$(git rev-parse --show-toplevel)" > /dev/null + +set -e +set +x + +function test_url { + local url="${1}" + local jq_array_path="${2}" + local expected_array_size="${3}" + local RED='\033[0;31m' + local GREEN='\033[0;32m' + local NC='\033[0m' + + response="$(curl \ + --silent \ + "${url}")" + + if ! jq --exit-status . >/dev/null 2>&1 <<<"${response}"; then + printf "${RED}Failed to parse response${NC}\n" + echo "--------------------------------------------------------------------" + echo "${response}" + exit 1 + else + printf "${GREEN}Valid JSON${NC}\n" + fi + + actual_array_size="$(jq "${jq_array_path} | length" <<<"${response}")" + + if [[ "${expected_array_size}" != "${actual_array_size:0:1}" ]]; then + printf "${RED}Did not get the expected result count. Expected |${expected_array_size}|. Actual |${actual_array_size}|${NC}\n" + echo "--------------------------------------------------------------------" + echo "${response}" | jq + exit 1 + else + printf "${GREEN}General array counts match${NC}\n" + fi +} + +echo "Test findAddressCandidates" +findAddressCandidatesUrl="https://gisdata.seattle.gov/cosgis/rest/services/locators/AddressPoints/GeocodeServer/findAddressCandidates?Address=700+5th+Ave&City=Seattle&Region=WA&Postal=98101&f=pjson" +test_url "${findAddressCandidatesUrl}" ".candidates" 3 + +echo "Test serviceArea" +serviceAreaUrl="https://gisdata.seattle.gov/server/rest/services/COS/Seattle_City_Limits/MapServer/1/query?geometryType=esriGeometryPoint&outFields=*&returnGeometry=false&f=json&inSR=2926&maxLocations=3&geometry={''x'':1271253,''y'':224277,''spatialReference'':2926}" +test_url "${serviceAreaUrl}" ".fields" 8 + +echo "Test ssl certficate" +echo | openssl s_client -servername gisdata.seattle.gov -connect gisdata.seattle.gov:443 + +echo "" diff --git a/civiform_config.prod.sh b/civiform_config.prod.sh new file mode 100644 index 0000000..24c0f91 --- /dev/null +++ b/civiform_config.prod.sh @@ -0,0 +1,256 @@ +#! /usr/bin/env bash + +# CiviForm deployment configuration file. +# +# Copy this file to civiform_config.sh in the same directory and edit the copy. +# +# cp civiform_config.example.sh civiform_config.sh +# +# Configuration variables must be specified in SCREAMING_SNAKE_CASE with the +# "export" keyword preceding them. All values must be quoted as strings. There +# should be no spaces before or after the equals sign. + +################################################# +# Global variables for all CiviForm deployments +################################################# + +# REQUIRED +# One of prod, staging, or dev. +export CIVIFORM_MODE="prod" + +# REQUIRED +# CiviForm server version to deploy. +# +# For dev and staging civiform modes, can be "latest". For prod, must be a version from +# https://github.com/civiform/civiform/releases, for example "v1.2.3". +export CIVIFORM_VERSION="v2.23.0" + +# REQUIRED +# Version of the infrastructure to use. +# Needs to be either: +# - Label from https://hub.docker.com/r/civiform/civiform-cloud-deployment if USE_DOCKER=true +# - Commit sha from https://github.com/civiform/cloud-deploy-infra if USE_DOCKER=false +# - "latest" to use latest version of either docker image or code from the repo, +# depending on USE_DOCKER flag. +# +# Using "latest" is recommended. +#export CIVIFORM_CLOUD_DEPLOYMENT_VERSION="latest" +export CIVIFORM_CLOUD_DEPLOYMENT_VERSION="${CIVIFORM_VERSION}" + +# Lock to this postgres version so it doesn't update unexpectedly +export POSTGRESQL_VERSION="16.3" + +# Terraform configuration +################################################# + +# REQUIRED +# A supported CiviForm cloud provider, lower case. +# "aws" or "azure" +export CIVIFORM_CLOUD_PROVIDER="aws" + +# REQUIRED +# The template directory for this deployment. +# For aws, use "cloud/aws/templates/aws_oidc" +# For azure, use "cloud/azure/templates/azure_saml_ses" +export TERRAFORM_TEMPLATE_DIR="cloud/aws/templates/aws_oidc" + +# REQUIRED +# The docker repository name for retrieving server images. +export DOCKER_REPOSITORY_NAME="civiform" + +# REQUIRED +# The docker user name for retrieving server images. +export DOCKER_USERNAME="civiform" + +# REQUIRED +# The authentication protocal used for applicant and trusted intermediary accounts. +export CIVIFORM_APPLICANT_AUTH_PROTOCOL="oidc" + +# Deployment-specific Civiform configuration +################################################# + +# REQUIRED +# A link to an image of the civic entity logo, to be used on the login page +export CIVIC_ENTITY_SMALL_LOGO_URL="https://raw.githubusercontent.com/seattle-civiform/civiform-deploy-tf/main/logos/civiform-small-logo.png" + +# OPTIONAL +# A link to an 16x16 of 32x32 pixel favicon of the civic entity, +# in format .ico, .png, or .gif. +export FAVICON_URL="https://seattle.gov/favicon.ico" + +# REQUIRED +# The email address to use for the "from" field in emails sent from CiviForm. +export SENDER_EMAIL_ADDRESS="civiform-notification@seattle.gov" + +# REQUIRED +# The email address that receives a notifications email each time an applicant +# submits an application to a program in the staging environments, instead of +# sending it to the program administrator's email, as would happen in prod. +export STAGING_PROGRAM_ADMIN_NOTIFICATION_MAILING_LIST="civiform.staging@seattle.gov" + +# REQUIRED +# The email address that receives a notifications email each time an applicant +# submits an application to a program in the staging environments, instead of +# sending it to the trusted intermediary's email, as would happen in prod. +export STAGING_TI_NOTIFICATION_MAILING_LIST="civiform.staging@seattle.gov" + +# REQUIRED +# The email address that receives a notifications email each time an applicant +# submits an application to a program in the staging environments, instead of +# sending it to the applicant's email, as would happen in prod. +export STAGING_APPLICANT_NOTIFICATION_MAILING_LIST="civiform.staging@seattle.gov" + +# OPTIONAL +# If this is a staging deployment and this variable is set to true, a robots +# noindex metadata tag is added to the CiviForm pages. This causes the staging +# site to not be listed on search engines. +export STAGING_ADD_NOINDEX_META_TAG=false + +# REQUIRED +# The domain name for this CiviForm deployment, including the protocol. +# E.g. "https://civiform.seattle.gov" +export BASE_URL="https://civiform.seattle.gov" +export STAGING_HOSTNAME="civiformstage.seattle.gov" + +# OPTIONAL +# The time zone to be used when rendering any times within the CiviForm +# UI. A list of valid time zone identifiers can be found at: +# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +export CIVIFORM_TIME_ZONE_ID="America/Los_Angeles" + +# OPTIONAL +# If enabled, allows exporting Prometheus server metrics over HTTP at "/metrics" +# Defaults to false. +export CIVIFORM_SERVER_METRICS_ENABLED=true + +# Don't deploy of Prometheus and Graphana +export MONITORING_STACK_ENABLED=true + +################################################# +# Template variables for: aws_oidc +################################################# + +# REQUIRED +export AWS_REGION="us-west-2" + +# OPTIONAL +# Database size +export POSTGRES_INSTANCE_CLASS="db.m5.large" + +# OPTIONAL +# Number of days to keep backups +export POSTGRES_BACKUP_RETENTION_DAYS=7 + +# REQUIRED +# The name to prefix all resources with. +export APP_PREFIX="cf-prod" # max 19 chars, only numbers, letters, dashes, and underscores + +export SSL_CERTIFICATE_ARN="arn:aws:acm:us-west-2:405662711265:certificate/c62046c2-ac1c-4131-8a1d-3c91d2b81a21" +export FARGATE_DESIRED_TASK_COUNT=2 +export ECS_SCALE_TARGET_MIN_CAPACITY=2 + +# REQUIRED +# Which auth provider to use for applicants to login. +# If set to a non-disabled value, you must configure the respective auth parameters +export CIVIFORM_APPLICANT_IDP="idcs" + +# generic-oidc Auth configuration +################################################# + +# REQUIRED if CIVIFORM_APPLICANT_IDP="generic-oidc" +# The name of the OIDC provider. Must be URL-safe. +# Gets appended to the auth callback URL. +export APPLICANT_OIDC_PROVIDER_NAME="OidcClient" + +# REQUIRED if CIVIFORM_APPLICANT_IDP="generic-oidc" +# The discovery metadata URI provideded by the OIDC provider. +# Usually ends in .well-known/openid-configuration +export APPLICANT_OIDC_DISCOVERY_URI="https://idcs-3359adb31e35415e8c1729c5c8098c6d.identity.oraclecloud.com/.well-known/openid-configuration" +export IDCS_DISCOVERY_URI="https://idcs-3359adb31e35415e8c1729c5c8098c6d.identity.oraclecloud.com/.well-known/openid-configuration" + +# OPTIONAL +# The type of OIDC flow to execute, and how the data is encoded. +# See https://auth0.com/docs/authenticate/protocols/oauth#authorization-endpoint +export APPLICANT_OIDC_RESPONSE_MODE="form_post" +export APPLICANT_OIDC_RESPONSE_TYPE="id_token token" + +# OPTIONAL +# Any additional claims to request, in addition to the default scopes "openid profile email" +export APPLICANT_OIDC_ADDITIONAL_SCOPES="" + +# OPTIONAL +# If your OIDC provider provides the user's language preference, +# provide the profile field it's returned in. +export APPLICANT_OIDC_LOCALE_ATTRIBUTE="" + +# OPTIONAL +# The name of the profile field where the user's name is stored. +# If there is only one name field(the display name) use APPLICANT_OIDC_FIRST_NAME_ATTRIBUTE. +# If the name is split into multiple fields, use the APPLICANT_OIDC_MIDDLE_NAME_ATTRIBUTE +# and APPLICANT_OIDC_LAST_NAME_ATTRIBUTE as necessary. +export APPLICANT_OIDC_FIRST_NAME_ATTRIBUTE="name" +export APPLICANT_OIDC_MIDDLE_NAME_ATTRIBUTE="" +export APPLICANT_OIDC_LAST_NAME_ATTRIBUTE="" + +# REQUIRED +export APPLICANT_REGISTER_URI="https://login.seattle.gov/#/registration?appName=CiviForm" +export APPLICANT_OIDC_OVERRIDE_LOGOUT_URL="https://login.seattle.gov/#/logout?appName=CIVIFORM" +export APPLICANT_OIDC_POST_LOGOUT_REDIRECT_PARAM="" +export APPLICANT_OIDC_PROVIDER_LOGOUT=true + +# ADFS and Azure AD configuration +# More information on https://docs.civiform.us/contributor-guide/developer-guide/authentication-providers +######################################################################################################### + +# REQUIRED +# The discovery metadata URI provideded by the ADFS provider. +# Usually ends in .well-known/openid-configuration +export ADFS_DISCOVERY_URI="https://login.microsoftonline.com/78e61e45-6beb-4009-8f99-359d8b54f41b/v2.0/.well-known/openid-configuration" + +# OPTIONAL +# Should be set to "allatclaims" for ADFS and empty value for Azure AD. +export ADFS_ADDITIONAL_SCOPES="" + +# OPTIONAL +# Should be set to "group" for ADFS and "groups" for Azure AD. +export AD_GROUPS_ATTRIBUTE_NAME="groups" + +# OPTIONAL +# The ADFS group name for specifying CiviForm admins. If using Azure AD this is +# the group's object ID +export ADFS_ADMIN_GROUP="f8c8e6c8-a5d7-4476-91bd-7f1691d16625" + +################################################# +# Additional settings +################################################# + +# Caching +export VERSION_CACHE_ENABLED=true +export PROGRAM_CACHE_ENABLED=true +export QUESTION_CACHE_ENABLED=true + +# Evolutions +export DATABASE_APPLY_DESTRUCTIVE_CHANGES=true + +# Analytics +export MEASUREMENT_ID="G-HXM0Y35TGE" + +# ESRI +export ESRI_FIND_ADDRESS_CANDIDATES_URLS="https://gisdata.seattle.gov/cosgis/rest/services/locators/AddressPoints/GeocodeServer/findAddressCandidates, https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates" +export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_URLS="https://gisdata.seattle.gov/server/rest/services/COS/Seattle_City_Limits/MapServer/1/query" +export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_LABELS="Seattle" +export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_IDS="Seattle" +export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_ATTRIBUTES="CITYNAME" +export ESRI_WELLKNOWN_ID_OVERRIDE="2926" + +# Additional Customization +export FILE_UPLOAD_ALLOWED_FILE_TYPE_SPECIFIERS="image/*,.pdf,.xlsx" + +# Language Settings +export CIVIFORM_SUPPORTED_LANGUAGES="en-US, am, zh-TW, ko, so, es-US, tl, vi" +export CIVIFORM_APPLICANT_ENABLED_LANGUAGES="en-US, am, zh-TW, ko, so, es-US, tl, vi" + +# Feature Flags +export ADMIN_OIDC_ENHANCED_LOGOUT_ENABLED=true +export APPLICANT_OIDC_ENHANCED_LOGOUT_ENABLED=true +export NEW_APPLICANT_URL_SCHEMA_ENABLED=true diff --git a/civiform_config.staging.sh b/civiform_config.staging.sh new file mode 100644 index 0000000..80f0640 --- /dev/null +++ b/civiform_config.staging.sh @@ -0,0 +1,284 @@ +#! /usr/bin/env bash + +# CiviForm deployment configuration file. +# +# Copy this file to civiform_config.sh in the same directory and edit the copy. +# +# cp civiform_config.example.sh civiform_config.sh +# +# Configuration variables must be specified in SCREAMING_SNAKE_CASE with the +# "export" keyword preceding them. All values must be quoted as strings. There +# should be no spaces before or after the equals sign. + +################################################# +# Global variables for all CiviForm deployments +################################################# + +# REQUIRED +# One of prod, staging, or dev. +export CIVIFORM_MODE="staging" + +# REQUIRED +# CiviForm server version to deploy. +# +# For dev and staging civiform modes, can be "latest". For prod, must be a version from +# https://github.com/civiform/civiform/releases, for example "v1.2.3". +export CIVIFORM_VERSION="latest" + +# REQUIRED +# Version of the infrastructure to use. +# Needs to be either: +# - Label from https://hub.docker.com/r/civiform/civiform-cloud-deployment if USE_DOCKER=true +# - Commit sha from https://github.com/civiform/cloud-deploy-infra if USE_DOCKER=false +# - "latest" to use latest version of either docker image or code from the repo, +# depending on USE_DOCKER flag. +# +# Using "latest" is recommended. +export CIVIFORM_CLOUD_DEPLOYMENT_VERSION="latest" + +# Terraform configuration +################################################# + +# REQUIRED +# A supported CiviForm cloud provider, lower case. +# "aws" or "azure" +export CIVIFORM_CLOUD_PROVIDER="aws" + +# REQUIRED +# The template directory for this deployment. +# For aws, use "cloud/aws/templates/aws_oidc" +# For azure, use "cloud/azure/templates/azure_saml_ses" +export TERRAFORM_TEMPLATE_DIR="cloud/aws/templates/aws_oidc" + +# REQUIRED +# The docker repository name for retrieving server images. +export DOCKER_REPOSITORY_NAME="civiform" + +# REQUIRED +# The docker user name for retrieving server images. +export DOCKER_USERNAME="civiform" + +# REQUIRED +# The authentication protocal used for applicant and trusted intermediary accounts. +export CIVIFORM_APPLICANT_AUTH_PROTOCOL="oidc" + +# Deployment-specific Civiform configuration +################################################# + +# REQUIRED +# The short name for the civic entity. Ex. "Rochester" +export WHITELABEL_CIVIC_ENTITY_SHORT_NAME="Seattle [STAGING]" + +# REQUIRED +# The full name for the civic entity. Ex. "City of Rochester" +export WHITELABEL_CIVIC_ENTITY_FULL_NAME="City of Seattle" + +# REQUIRED +# The email address to contact for support with using Civiform. Ex. "Civiform@CityOfRochester.gov +export SUPPORT_EMAIL_ADDRESS="civiform.staging@seattle.gov" + +# OPTIONAL +export CIVIC_ENTITY_PRODUCTION_URL="https://civiform.seattle.gov" + +# REQUIRED +# A link to an image of the civic entity logo, to be used on the login page +export CIVIC_ENTITY_SMALL_LOGO_URL="https://raw.githubusercontent.com/seattle-civiform/civiform-deploy-tf/main/logos/civiform-small-logo.png" + +# REQUIRED +export APPLICANT_PORTAL_NAME="Seattle" + +# OPTIONAL +# A link to an 16x16 of 32x32 pixel favicon of the civic entity, +# in format .ico, .png, or .gif. +export FAVICON_URL="https://seattle.gov/favicon.ico" + +# REQUIRED +# The email address to use for the "from" field in emails sent from CiviForm. +export SENDER_EMAIL_ADDRESS="civiform.staging@seattle.gov" + +# REQUIRED +# The email address that receives a notifications email each time an applicant +# submits an application to a program in the staging environments, instead of +# sending it to the program administrator's email, as would happen in prod. +export STAGING_PROGRAM_ADMIN_NOTIFICATION_MAILING_LIST="civiform.staging@seattle.gov" + +# REQUIRED +# The email address that receives a notifications email each time an applicant +# submits an application to a program in the staging environments, instead of +# sending it to the trusted intermediary's email, as would happen in prod. +export STAGING_TI_NOTIFICATION_MAILING_LIST="civiform.staging@seattle.gov" + +# REQUIRED +# The email address that receives a notifications email each time an applicant +# submits an application to a program in the staging environments, instead of +# sending it to the applicant's email, as would happen in prod. +export STAGING_APPLICANT_NOTIFICATION_MAILING_LIST="civiform.staging@seattle.gov" + +# OPTIONAL +# If this is a staging deployment and this variable is set to true, a robots +# noindex metadata tag is added to the CiviForm pages. This causes the staging +# site to not be listed on search engines. +export STAGING_ADD_NOINDEX_META_TAG=true + +# REQUIRED +# The domain name for this CiviForm deployment, including the protocol. +# E.g. "https://civiform.seattle.gov" +export BASE_URL="https://civiformstage.seattle.gov" +export STAGING_HOSTNAME="civiformstage.seattle.gov" + +# OPTIONAL +# The time zone to be used when rendering any times within the CiviForm +# UI. A list of valid time zone identifiers can be found at: +# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +export CIVIFORM_TIME_ZONE_ID="America/Los_Angeles" + +# OPTIONAL +# If enabled, allows exporting Prometheus server metrics over HTTP at "/metrics" +# Defaults to false. +export CIVIFORM_SERVER_METRICS_ENABLED=false + +# Don't deploy of Prometheus and Graphana +export MONITORING_STACK_ENABLED=false + +################################################# +# Template variables for: aws_oidc +################################################# + +# REQUIRED +export AWS_REGION="us-west-2" + +# OPTIONAL +# Database size +export POSTGRES_INSTANCE_CLASS="db.t3.micro" + +# OPTIONAL +# Number of days to keep backups +export POSTGRES_BACKUP_RETENTION_DAYS=3 + +# REQUIRED +# The name to prefix all resources with. +export APP_PREFIX="cf-staging" # max 19 chars, only numbers, letters, dashes, and underscores + +export SSL_CERTIFICATE_ARN="arn:aws:acm:us-west-2:405662711265:certificate/c62046c2-ac1c-4131-8a1d-3c91d2b81a21" +export FARGATE_DESIRED_TASK_COUNT=1 +export ECS_SCALE_TARGET_MIN_CAPACITY=1 + +# REQUIRED +# Which auth provider to use for applicants to login. +# If set to a non-disabled value, you must configure the respective auth parameters +export CIVIFORM_APPLICANT_IDP="idcs" + +# generic-oidc Auth configuration +################################################# + +# REQUIRED if CIVIFORM_APPLICANT_IDP="generic-oidc" +# The name of the OIDC provider. Must be URL-safe. +# Gets appended to the auth callback URL. +export APPLICANT_OIDC_PROVIDER_NAME="OidcClient" + +# REQUIRED if CIVIFORM_APPLICANT_IDP="generic-oidc" +# The discovery metadata URI provideded by the OIDC provider. +# Usually ends in .well-known/openid-configuration +export APPLICANT_OIDC_DISCOVERY_URI="https://idcs-f582fefb879b4db5a88a370e8f2f6013.identity.oraclecloud.com/.well-known/openid-configuration" + +# OPTIONAL +# The type of OIDC flow to execute, and how the data is encoded. +# See https://auth0.com/docs/authenticate/protocols/oauth#authorization-endpoint +export APPLICANT_OIDC_RESPONSE_MODE="form_post" +export APPLICANT_OIDC_RESPONSE_TYPE="id_token token" + +# OPTIONAL +# Any additional claims to request, in addition to the default scopes "openid profile email" +export APPLICANT_OIDC_ADDITIONAL_SCOPES="" + +# OPTIONAL +# If your OIDC provider provides the user's language preference, +# provide the profile field it's returned in. +export APPLICANT_OIDC_LOCALE_ATTRIBUTE="" + +# OPTIONAL +# The name of the profile field where the user's name is stored. +# If there is only one name field(the display name) use APPLICANT_OIDC_FIRST_NAME_ATTRIBUTE. +# If the name is split into multiple fields, use the APPLICANT_OIDC_MIDDLE_NAME_ATTRIBUTE +# and APPLICANT_OIDC_LAST_NAME_ATTRIBUTE as necessary. +export APPLICANT_OIDC_FIRST_NAME_ATTRIBUTE="name" +export APPLICANT_OIDC_MIDDLE_NAME_ATTRIBUTE="" +export APPLICANT_OIDC_LAST_NAME_ATTRIBUTE="" + +# REQUIRED +export APPLICANT_REGISTER_URI="https://qalogin.seattle.gov:12443/#/registration?appName=CIVIFORM_STAGE" +export APPLICANT_OIDC_OVERRIDE_LOGOUT_URL="https://qalogin.seattle.gov:12443/#/logout?appName=CIVIFORM_STAGE" +export APPLICANT_OIDC_POST_LOGOUT_REDIRECT_PARAM="" +export APPLICANT_OIDC_PROVIDER_LOGOUT=true + +# ADFS and Azure AD configuration +# More information on https://docs.civiform.us/contributor-guide/developer-guide/authentication-providers +######################################################################################################### + +# REQUIRED +# The discovery metadata URI provideded by the ADFS provider. +# Usually ends in .well-known/openid-configuration +export ADFS_DISCOVERY_URI="https://login.microsoftonline.com/78e61e45-6beb-4009-8f99-359d8b54f41b/v2.0/.well-known/openid-configuration" + +# OPTIONAL +# Should be set to "allatclaims" for ADFS and empty value for Azure AD. +export ADFS_ADDITIONAL_SCOPES="" + +# OPTIONAL +# Should be set to "group" for ADFS and "groups" for Azure AD. +export AD_GROUPS_ATTRIBUTE_NAME="groups" + +# OPTIONAL +# The ADFS group name for specifying CiviForm admins. If using Azure AD this is +# the group's object ID +export ADFS_ADMIN_GROUP="5909e7f3-3f4c-4ad1-93e8-17e6ba6ab8a3" + +################################################# +# Additional settings +################################################# + +# Caching +export VERSION_CACHE_ENABLED=true +export PROGRAM_CACHE_ENABLED=true +export QUESTION_CACHE_ENABLED=true + +# API +export CIVIFORM_API_KEYS_BAN_GLOBAL_SUBNET=false + +# Evolutions +export DATABASE_APPLY_DESTRUCTIVE_CHANGES=true + +# Analytics +export MEASUREMENT_ID="G-HXM0Y35TGE" + +# ESRI +export ESRI_ADDRESS_CORRECTION_ENABLED=true +export ESRI_FIND_ADDRESS_CANDIDATES_URLS="https://gisdata.seattle.gov/cosgis/rest/services/locators/AddressPoints/GeocodeServer/findAddressCandidates, https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates" +export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_ENABLED=true +export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_URLS="https://gisdata.seattle.gov/server/rest/services/COS/Seattle_City_Limits/MapServer/1/query, https://gisdata.kingcounty.gov/arcgis/rest/services/OpenDataPortal/property__parcel_address_area/MapServer/1722/query, https://gisdata.kingcounty.gov/arcgis/rest/services/OpenDataPortal/property__parcel_address_area/MapServer/1722/query" +export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_LABELS="Seattle, IsSmt_PropName, IsSmt_SiteId" +export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_IDS="Seattle, SEATTLE MUNICIPAL TOWER, {8761A355-5251-49DB-90D3-4B3A885FBF40}" +export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_ATTRIBUTES="CITYNAME, PROP_NAME, SITEID" +export ESRI_WELLKNOWN_ID_OVERRIDE="2926" + +# Common Intake +export COMMON_INTAKE_MORE_RESOURCES_LINK_TEXT="Affordable Seattle" +export COMMON_INTAKE_MORE_RESOURCES_LINK_HREF="https://www.affordableseattle.org" + +# Additional Customization +export FILE_UPLOAD_ALLOWED_FILE_TYPE_SPECIFIERS="image/*,.pdf,.xlsx" + +# Language Settings +export CIVIFORM_SUPPORTED_LANGUAGES="en-US, am, zh-TW, ko, so, es-US, tl, vi" +export CIVIFORM_APPLICANT_ENABLED_LANGUAGES="en-US, am, zh-TW, ko, so, es-US, tl, vi" + +# Feature Flags +export ALLOW_ADMIN_WRITEABLE=true +export ALLOW_CIVIFORM_ADMIN_ACCESS_PROGRAMS=true +export APPLICATION_EXPORTABLE=true +export API_GENERATED_DOCS_ENABLED=true +export ADMIN_OIDC_ENHANCED_LOGOUT_ENABLED=true +export APPLICANT_OIDC_ENHANCED_LOGOUT_ENABLED=true +export NEW_APPLICANT_URL_SCHEMA_ENABLED=true +export SHOW_NOT_PRODUCTION_BANNER_ENABLED=false +export BULK_STATUS_UPDATE_ENABLED=true diff --git a/civiform_config.test.sh b/civiform_config.test.sh new file mode 100644 index 0000000..f0c4f7b --- /dev/null +++ b/civiform_config.test.sh @@ -0,0 +1,253 @@ +#! /usr/bin/env bash + +# CiviForm deployment configuration file. +# +# Copy this file to civiform_config.sh in the same directory and edit the copy. +# +# cp civiform_config.example.sh civiform_config.sh +# +# Configuration variables must be specified in SCREAMING_SNAKE_CASE with the +# "export" keyword preceding them. All values must be quoted as strings. There +# should be no spaces before or after the equals sign. + +################################################# +# Global variables for all CiviForm deployments +################################################# + +# REQUIRED +# One of prod, staging, or dev. +export CIVIFORM_MODE="staging" + +# REQUIRED +# CiviForm server version to deploy. +# +# For dev and staging civiform modes, can be "latest". For prod, must be a version from +# https://github.com/civiform/civiform/releases, for example "v1.2.3". +export CIVIFORM_VERSION="v2.26.0" + +# REQUIRED +# Version of the infrastructure to use. +# Needs to be either: +# - Label from https://hub.docker.com/r/civiform/civiform-cloud-deployment if USE_DOCKER=true +# - Commit sha from https://github.com/civiform/cloud-deploy-infra if USE_DOCKER=false +# - "latest" to use latest version of either docker image or code from the repo, +# depending on USE_DOCKER flag. +# +# Using "latest" is recommended. +#export CIVIFORM_CLOUD_DEPLOYMENT_VERSION="latest" +export CIVIFORM_CLOUD_DEPLOYMENT_VERSION="${CIVIFORM_VERSION}" + +# Terraform configuration +################################################# + +# REQUIRED +# A supported CiviForm cloud provider, lower case. +# "aws" or "azure" +export CIVIFORM_CLOUD_PROVIDER="aws" + +# REQUIRED +# The template directory for this deployment. +# For aws, use "cloud/aws/templates/aws_oidc" +# For azure, use "cloud/azure/templates/azure_saml_ses" +export TERRAFORM_TEMPLATE_DIR="cloud/aws/templates/aws_oidc" + +# REQUIRED +# The docker repository name for retrieving server images. +export DOCKER_REPOSITORY_NAME="civiform" + +# REQUIRED +# The docker user name for retrieving server images. +export DOCKER_USERNAME="civiform" + +# REQUIRED +# The authentication protocal used for applicant and trusted intermediary accounts. +export CIVIFORM_APPLICANT_AUTH_PROTOCOL="oidc" + +# Deployment-specific Civiform configuration +################################################# + +# REQUIRED +# A link to an image of the civic entity logo, to be used on the login page +export CIVIC_ENTITY_SMALL_LOGO_URL="https://raw.githubusercontent.com/seattle-civiform/civiform-deploy-tf/main/logos/civiform-small-logo.png" + +# OPTIONAL +# A link to an 16x16 of 32x32 pixel favicon of the civic entity, +# in format .ico, .png, or .gif. +export FAVICON_URL="https://seattle.gov/favicon.ico" + +# REQUIRED +# The email address to use for the "from" field in emails sent from CiviForm. +export SENDER_EMAIL_ADDRESS="civiform.staging@seattle.gov" + +# REQUIRED +# The email address that receives a notifications email each time an applicant +# submits an application to a program in the staging environments, instead of +# sending it to the program administrator's email, as would happen in prod. +export STAGING_PROGRAM_ADMIN_NOTIFICATION_MAILING_LIST="civiform.staging@seattle.gov" + +# REQUIRED +# The email address that receives a notifications email each time an applicant +# submits an application to a program in the staging environments, instead of +# sending it to the trusted intermediary's email, as would happen in prod. +export STAGING_TI_NOTIFICATION_MAILING_LIST="civiform.staging@seattle.gov" + +# REQUIRED +# The email address that receives a notifications email each time an applicant +# submits an application to a program in the staging environments, instead of +# sending it to the applicant's email, as would happen in prod. +export STAGING_APPLICANT_NOTIFICATION_MAILING_LIST="civiform.staging@seattle.gov" + +# OPTIONAL +# If this is a staging deployment and this variable is set to true, a robots +# noindex metadata tag is added to the CiviForm pages. This causes the staging +# site to not be listed on search engines. +export STAGING_ADD_NOINDEX_META_TAG=true + +# REQUIRED +# The domain name for this CiviForm deployment, including the protocol. +# E.g. "https://civiform.seattle.gov" +export BASE_URL="https://civiformtest.seattle.gov" +export STAGING_HOSTNAME="civiformstage.seattle.gov" + +# OPTIONAL +# The time zone to be used when rendering any times within the CiviForm +# UI. A list of valid time zone identifiers can be found at: +# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +export CIVIFORM_TIME_ZONE_ID="America/Los_Angeles" + +# OPTIONAL +# If enabled, allows exporting Prometheus server metrics over HTTP at "/metrics" +# Defaults to false. +export CIVIFORM_SERVER_METRICS_ENABLED=false + +# Don't deploy of Prometheus and Graphana +export MONITORING_STACK_ENABLED=false + +################################################# +# Template variables for: aws_oidc +################################################# + +# REQUIRED +export AWS_REGION="us-west-2" + +# OPTIONAL +# Database size +export POSTGRES_INSTANCE_CLASS="db.t3.micro" + +# OPTIONAL +# Number of days to keep backups +export POSTGRES_BACKUP_RETENTION_DAYS=5 + +# REQUIRED +# The name to prefix all resources with. +export APP_PREFIX="cf-test" # max 19 chars, only numbers, letters, dashes, and underscores + +export SSL_CERTIFICATE_ARN="arn:aws:acm:us-west-2:405662711265:certificate/c62046c2-ac1c-4131-8a1d-3c91d2b81a21" +export FARGATE_DESIRED_TASK_COUNT=1 +export ECS_SCALE_TARGET_MIN_CAPACITY=1 + +# REQUIRED +# Which auth provider to use for applicants to login. +# If set to a non-disabled value, you must configure the respective auth parameters +export CIVIFORM_APPLICANT_IDP="idcs" + +# generic-oidc Auth configuration +################################################# + +# REQUIRED if CIVIFORM_APPLICANT_IDP="generic-oidc" +# The name of the OIDC provider. Must be URL-safe. +# Gets appended to the auth callback URL. +export APPLICANT_OIDC_PROVIDER_NAME="OidcClient" + +# REQUIRED if CIVIFORM_APPLICANT_IDP="generic-oidc" +# The discovery metadata URI provideded by the OIDC provider. +# Usually ends in .well-known/openid-configuration +export APPLICANT_OIDC_DISCOVERY_URI="https://idcs-f582fefb879b4db5a88a370e8f2f6013.identity.oraclecloud.com/.well-known/openid-configuration" +export IDCS_DISCOVERY_URI="https://idcs-f582fefb879b4db5a88a370e8f2f6013.identity.oraclecloud.com/.well-known/openid-configuration" + +# OPTIONAL +# The type of OIDC flow to execute, and how the data is encoded. +# See https://auth0.com/docs/authenticate/protocols/oauth#authorization-endpoint +export APPLICANT_OIDC_RESPONSE_MODE="form_post" +export APPLICANT_OIDC_RESPONSE_TYPE="id_token token" + +# OPTIONAL +# Any additional claims to request, in addition to the default scopes "openid profile email" +export APPLICANT_OIDC_ADDITIONAL_SCOPES="" + +# OPTIONAL +# If your OIDC provider provides the user's language preference, +# provide the profile field it's returned in. +export APPLICANT_OIDC_LOCALE_ATTRIBUTE="" + +# OPTIONAL +# The name of the profile field where the user's name is stored. +# If there is only one name field(the display name) use APPLICANT_OIDC_FIRST_NAME_ATTRIBUTE. +# If the name is split into multiple fields, use the APPLICANT_OIDC_MIDDLE_NAME_ATTRIBUTE +# and APPLICANT_OIDC_LAST_NAME_ATTRIBUTE as necessary. +export APPLICANT_OIDC_FIRST_NAME_ATTRIBUTE="name" +export APPLICANT_OIDC_MIDDLE_NAME_ATTRIBUTE="" +export APPLICANT_OIDC_LAST_NAME_ATTRIBUTE="" + +# REQUIRED +export APPLICANT_REGISTER_URI="https://qalogin.seattle.gov:12443/#/registration?appName=CIVIFORM_TEST" +export APPLICANT_OIDC_OVERRIDE_LOGOUT_URL="https://qalogin.seattle.gov:12443/#/logout?appName=CIVIFORM_TEST" +export APPLICANT_OIDC_POST_LOGOUT_REDIRECT_PARAM="" +export APPLICANT_OIDC_PROVIDER_LOGOUT=true + +# ADFS and Azure AD configuration +# More information on https://docs.civiform.us/contributor-guide/developer-guide/authentication-providers +######################################################################################################### + +# REQUIRED +# The discovery metadata URI provideded by the ADFS provider. +# Usually ends in .well-known/openid-configuration +export ADFS_DISCOVERY_URI="https://login.microsoftonline.com/78e61e45-6beb-4009-8f99-359d8b54f41b/v2.0/.well-known/openid-configuration" + +# OPTIONAL +# Should be set to "allatclaims" for ADFS and empty value for Azure AD. +export ADFS_ADDITIONAL_SCOPES="" + +# OPTIONAL +# Should be set to "group" for ADFS and "groups" for Azure AD. +export AD_GROUPS_ATTRIBUTE_NAME="groups" + +# OPTIONAL +# The ADFS group name for specifying CiviForm admins. If using Azure AD this is +# the group's object ID +export ADFS_ADMIN_GROUP="5909e7f3-3f4c-4ad1-93e8-17e6ba6ab8a3" + +################################################# +# Additional settings +################################################# + +# Caching +export VERSION_CACHE_ENABLED=true +export PROGRAM_CACHE_ENABLED=true +export QUESTION_CACHE_ENABLED=true + +# Evolutions +export DATABASE_APPLY_DESTRUCTIVE_CHANGES=true + +# Analytics +export MEASUREMENT_ID="G-HXM0Y35TGE" + +# ESRI +export ESRI_FIND_ADDRESS_CANDIDATES_URLS="https://gisdata.seattle.gov/cosgis/rest/services/locators/AddressPoints/GeocodeServer/findAddressCandidates, https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates" +export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_URLS="https://gisdata.seattle.gov/server/rest/services/COS/Seattle_City_Limits/MapServer/1/query" +export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_LABELS="Seattle" +export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_IDS="Seattle" +export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_ATTRIBUTES="CITYNAME" +export ESRI_WELLKNOWN_ID_OVERRIDE="2926" + +# Additional Customization +export FILE_UPLOAD_ALLOWED_FILE_TYPE_SPECIFIERS="image/*,.pdf,.xlsx" + +# Language Settings +export CIVIFORM_SUPPORTED_LANGUAGES="en-US, am, zh-TW, ko, so, es-US, tl, vi" +export CIVIFORM_APPLICANT_ENABLED_LANGUAGES="en-US, am, zh-TW, ko, so, es-US, tl, vi" + +# Feature Flags +export ADMIN_OIDC_ENHANCED_LOGOUT_ENABLED=true +export APPLICANT_OIDC_ENHANCED_LOGOUT_ENABLED=true +export NEW_APPLICANT_URL_SCHEMA_ENABLED=true diff --git a/logos/civiform-long-logo.png b/logos/civiform-long-logo.png new file mode 100644 index 0000000..c977439 Binary files /dev/null and b/logos/civiform-long-logo.png differ diff --git a/logos/civiform-small-logo.png b/logos/civiform-small-logo.png new file mode 100644 index 0000000..785a107 Binary files /dev/null and b/logos/civiform-small-logo.png differ diff --git a/qa/.gitignore b/qa/.gitignore new file mode 100644 index 0000000..51511d1 --- /dev/null +++ b/qa/.gitignore @@ -0,0 +1 @@ +test-results/ diff --git a/qa/package-lock.json b/qa/package-lock.json new file mode 100644 index 0000000..c87ce79 --- /dev/null +++ b/qa/package-lock.json @@ -0,0 +1,108 @@ +{ + "name": "seattle-civiform-smoke-tests", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "seattle-civiform-smoke-tests", + "devDependencies": { + "@playwright/test": "1.48.2", + "@types/node": "22.8.5", + "typescript": "5.6.3" + } + }, + "node_modules/@playwright/test": { + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.2.tgz", + "integrity": "sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.48.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@types/node": { + "version": "22.8.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.5.tgz", + "integrity": "sha512-5iYk6AMPtsMbkZqCO1UGF9W5L38twq11S2pYWkybGHH2ogPUvXWNlQqJBzuEZWKj/WRH+QTeiv6ySWqJtvIEgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.8" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/playwright": { + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.2.tgz", + "integrity": "sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.48.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.2.tgz", + "integrity": "sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/qa/package.json b/qa/package.json new file mode 100644 index 0000000..2af155c --- /dev/null +++ b/qa/package.json @@ -0,0 +1,8 @@ +{ + "name": "seattle-civiform-smoke-tests", + "devDependencies": { + "@playwright/test": "1.48.2", + "@types/node": "22.8.5", + "typescript": "5.6.3" + } +} diff --git a/qa/playwright.config.ts b/qa/playwright.config.ts new file mode 100644 index 0000000..d1674d2 --- /dev/null +++ b/qa/playwright.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from '@playwright/test' + +export default defineConfig({ + timeout: 5000, + use: { + baseURL: process.env.BASE_URL || 'http://localhost:9000', + extraHTTPHeaders: { + 'Authorization': `Basic ${process.env.API_TOKEN}` + } + }, + reporter: [ + ['list', { printSteps: true }] + ], +}) + diff --git a/qa/tests/api.spec.ts b/qa/tests/api.spec.ts new file mode 100644 index 0000000..cd4156e --- /dev/null +++ b/qa/tests/api.spec.ts @@ -0,0 +1,48 @@ +import { test, expect } from '@playwright/test' + + +test.describe('smoke tests for program applications list api endpoint', () => { + const programSlugs = (process.env.PROGRAM_SLUGS || '').split(',') + + for (const programSlug of programSlugs) { + test(`program slug: ${programSlug}`, async ({ request }) => { + const response = await request.get(`/api/v1/admin/programs/${programSlug}/applications`, { + params: { + 'pageSize': 1 + } + }) + + expect(response).toBeOK() + + const result: ApiResult = await response.json() + + expect(result).not.toBeNull() + expect(result.payload.length).toBeLessThanOrEqual(1) + + if (result.payload.length > 0) { + expect(result.payload[0].application).not.toBeNull() + } + }) + } +}) + +interface ApiResult { + nextPageToken: string | null + payload: Payload[] +} + +interface Payload { + applicant_id: number + application_id: number + create_time: string + language: string + program_name: string + program_version_id: number + revision_state: string + status: string | null + submit_time: string + submitter_type: string + ti_email: string | null + ti_organization: string | null + application: any +}