diff --git a/.env.example b/.env.example deleted file mode 100644 index 7711e158..00000000 --- a/.env.example +++ /dev/null @@ -1,23 +0,0 @@ -SBL_DEV_PORT="8899" -SBL_OIDC_AUTHORITY="http://localhost:8880/realms/regtech" -SBL_OIDC_CLIENT_ID="regtech-client" -SBL_OIDC_REDIRECT_URI="http://localhost:${SBL_DEV_PORT}/filing" -SBL_REGTECH_BASE_URL="http://localhost:8881" -SBL_FILING_BASE_URL="http://localhost:8882" -SBL_MAIL_BASE_URL="http://localhost:8765" -SBL_LOGOUT_REDIRECT_URL="" -SBL_VALIDATION_TIMEOUT_SECONDS="1200" -SBL_LONGPOLLING_DELAY_SECONDS="backoff" -SBL_UPLOAD_FILE_SIZE_LIMIT_BYTES="50000000" -SBL_ENABLE_PLAYWRIGHT_TEST_SETTINGS="false" -SBL_PLAYWRIGHT_TEST_TARGET="http://localhost:8899" -SBL_PLAYWRIGHT_TEST_KC_TARGET="http://localhost:8880/" -SBL_PLAYWRIGHT_TEST_KC_REALM="regtech" -SBL_PLAYWRIGHT_TEST_KC_CLI_USERNAME="admin" -SBL_PLAYWRIGHT_TEST_KC_CLI_CLIENT_ID="admin-cli" -SBL_PLAYWRIGHT_TEST_KC_CLI_CLIENT_SECRET="local_test_only" -SBL_PLAYWRIGHT_TEST_KC_CLI_GRANT_TYPE="client_credentials" -SBL_PLAYWRIGHT_TEST_KC_ADMIN_USERNAME="admin1" -SBL_PLAYWRIGHT_TEST_KC_ADMIN_PASSWORD="admin" -SBL_PLAYWRIGHT_TEST_KC_ADMIN_CLIENT_ID="regtech-client" -SBL_PLAYWRIGHT_TEST_KC_ADMIN_GRANT_TYPE="password" \ No newline at end of file diff --git a/.env.example.private b/.env.example.private new file mode 100644 index 00000000..058c1440 --- /dev/null +++ b/.env.example.private @@ -0,0 +1,22 @@ +############################################################### +# ONLY ADD ENVIRONMENT VARIABLES THAT ARE NOT MEANT TO BE +# PACKAGED WITH AND VISIBLE TO THE CLIENT +############################################################### + +NODE_EXTRA_CA_CERTS="./e2e/certs/entrust_chain.crt.pem" + +SBL_PLAYWRIGHT_TEST_TARGET="http://localhost:8899" +SBL_PLAYWRIGHT_TEST_REGTECH_TARGET="http://localhost:8881" +SBL_PLAYWRIGHT_TEST_FILING_TARGET="http://localhost:8882" +SBL_PLAYWRIGHT_TEST_CLEANUP_TARGET="http://localhost:8883" +SBL_PLAYWRIGHT_TEST_MAIL_TARGET="http://localhost:8765" +SBL_PLAYWRIGHT_TEST_KC_TARGET="http://localhost:8880/" +SBL_PLAYWRIGHT_TEST_KC_REALM="regtech" +SBL_PLAYWRIGHT_TEST_KC_CLI_USERNAME="admin" +SBL_PLAYWRIGHT_TEST_KC_CLI_CLIENT_ID="admin-cli" +SBL_PLAYWRIGHT_TEST_KC_CLI_CLIENT_SECRET="local_test_only" +SBL_PLAYWRIGHT_TEST_KC_CLI_GRANT_TYPE="client_credentials" +SBL_PLAYWRIGHT_TEST_KC_ADMIN_USERNAME="admin1" +SBL_PLAYWRIGHT_TEST_KC_ADMIN_PASSWORD="admin" +SBL_PLAYWRIGHT_TEST_KC_ADMIN_CLIENT_ID="regtech-client" +SBL_PLAYWRIGHT_TEST_KC_ADMIN_GRANT_TYPE="password" diff --git a/.env.example.public b/.env.example.public new file mode 100644 index 00000000..c8bbde5c --- /dev/null +++ b/.env.example.public @@ -0,0 +1,19 @@ +############################################################### +# ONLY ADD ENVIRONMENT VARIABLES THAT ARE MEANT TO BE PACKAGED +# WITH AND VISIBLE TO THE CLIENT +############################################################### + +SBL_DEV_PORT="8899" +SBL_OIDC_AUTHORITY="http://localhost:8880/realms/regtech" +SBL_OIDC_CLIENT_ID="regtech-client" +SBL_OIDC_REDIRECT_URI="http://localhost:${SBL_DEV_PORT}/filing" +SBL_REGTECH_BASE_URL="http://localhost:8881" +SBL_FILING_BASE_URL="http://localhost:8882" +SBL_CLEANUP_BASE_URL="http://localhost:8883" +SBL_MAIL_BASE_URL="http://localhost:8765" +SBL_LOGOUT_REDIRECT_URL="" +SBL_VALIDATION_TIMEOUT_SECONDS="1200" +SBL_LONGPOLLING_DELAY_SECONDS="backoff" +SBL_UPLOAD_FILE_SIZE_LIMIT_BYTES="50000000" + +SBL_ENABLE_PLAYWRIGHT_TEST_SETTINGS=false diff --git a/.github/actions/setvars/action.yml b/.github/actions/setvars/action.yml index 4e1c17e1..7ed6d282 100644 --- a/.github/actions/setvars/action.yml +++ b/.github/actions/setvars/action.yml @@ -9,5 +9,5 @@ runs: using: "composite" steps: - run: | - sed "" ${{ inputs.varFilePath }} >> $GITHUB_ENV + sed -r "/^#/Id" ${{ inputs.varFilePath }} | sed -r "/^\s*$/Id" >> $GITHUB_ENV shell: bash \ No newline at end of file diff --git a/.github/variables/.env b/.github/variables/.env index cbb553cf..bc99864d 100644 --- a/.github/variables/.env +++ b/.github/variables/.env @@ -1,16 +1,34 @@ +############################################################### +# ONLY ADD ENVIRONMENT VARIABLES THAT ARE MEANT TO BE PACKAGED +# WITH AND VISIBLE TO THE CLIENT BELOW +############################################################### + SBL_DEV_PORT="8899" SBL_OIDC_AUTHORITY="http://localhost:8880/realms/regtech" SBL_OIDC_CLIENT_ID="regtech-client" SBL_OIDC_REDIRECT_URI="http://localhost:${SBL_DEV_PORT}/filing" SBL_REGTECH_BASE_URL="http://localhost:8881" -SBL_MAIL_BASE_URL="http://localhost:8765" SBL_FILING_BASE_URL="http://localhost:8882" +SBL_CLEANUP_BASE_URL="http://localhost:8883" +SBL_MAIL_BASE_URL="http://localhost:8765" SBL_LOGOUT_REDIRECT_URL="" SBL_VALIDATION_TIMEOUT_SECONDS="1200" SBL_LONGPOLLING_DELAY_SECONDS="backoff" SBL_UPLOAD_FILE_SIZE_LIMIT_BYTES="50000000" -SBL_ENABLE_PLAYWRIGHT_TEST_SETTINGS="false" -SBL_PLAYWRIGHT_TEST_TARGET="http://localhost:8899" + +SBL_ENABLE_PLAYWRIGHT_TEST_SETTINGS=false + +############################################################### +# ONLY ADD ENVIRONMENT VARIABLES THAT ARE NOT MEANT TO BE +# PACKAGED WITH AND VISIBLE TO THE CLIENT BELOW +############################################################### +NODE_EXTRA_CA_CERTS="./e2e/certs/entrust_chain.crt.pem" + +SBL_PLAYWRIGHT_TEST_TARGET="http://localhost:${SBL_DEV_PORT}" +SBL_PLAYWRIGHT_TEST_REGTECH_TARGET="${SBL_REGTECH_BASE_URL}" +SBL_PLAYWRIGHT_TEST_FILING_TARGET="${SBL_FILING_BASE_URL}" +SBL_PLAYWRIGHT_TEST_CLEANUP_TARGET="${SBL_CLEANUP_BASE_URL}" +SBL_PLAYWRIGHT_TEST_MAIL_TARGET="${SBL_MAIL_BASE_URL}" SBL_PLAYWRIGHT_TEST_KC_TARGET="http://localhost:8880/" SBL_PLAYWRIGHT_TEST_KC_REALM="regtech" SBL_PLAYWRIGHT_TEST_KC_CLI_USERNAME="admin" diff --git a/.gitignore b/.gitignore index 90a6337d..5f3ae5b1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .env* -!.env.example +!.env.example.public +!.env.example.private node_modules .DS_Store dist diff --git a/Dockerfile b/Dockerfile index 8246c12b..5fc407da 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,7 +28,7 @@ COPY --from=build-stage /usr/src/app/dist /usr/share/nginx/html COPY --from=build-stage \ /usr/src/app/import-meta-env-alpine \ /usr/src/app/nginx-entrypoint.sh \ - /usr/src/app/.env.example \ + /usr/src/app/.env.example.public \ /usr/share/nginx/html/ # copy nginx configuration into template folder for env var injection diff --git a/ENV-GUIDE.md b/ENV-GUIDE.md index 64fe0a81..6ce0474f 100644 --- a/ENV-GUIDE.md +++ b/ENV-GUIDE.md @@ -1,8 +1,9 @@ # To start -Make a copy of `.env.example`, rename to `.env`, and place it into the root of the project's folder. +Make a copy of `.env.example.public`, rename to `.env`, and place it into the root of the project's folder. +Copy the content of `.env.example.private` into the `.env` file that was just copied. -# Required Environment Variables +### Required Runtime Environment Variables ```env SBL_DEV_PORT="8899" @@ -11,13 +12,24 @@ SBL_OIDC_CLIENT_ID="regtech-client" SBL_OIDC_REDIRECT_URI="http://localhost:${SBL_DEV_PORT}/filing" SBL_REGTECH_BASE_URL="http://localhost:8881" SBL_FILING_BASE_URL="http://localhost:8882" +SBL_CLEANUP_BASE_URL="http://localhost:8883" SBL_MAIL_BASE_URL="http://localhost:8765" SBL_LOGOUT_REDIRECT_URL="" SBL_VALIDATION_TIMEOUT_SECONDS="1200" SBL_LONGPOLLING_DELAY_SECONDS="backoff" SBL_UPLOAD_FILE_SIZE_LIMIT_BYTES="50000000" -SBL_ENABLE_PLAYWRIGHT_TEST_SETTINGS="false" -SBL_PLAYWRIGHT_TEST_TARGET="http://localhost:8899" +SBL_ENABLE_PLAYWRIGHT_TEST_SETTINGS=false +``` + +### Required Test Environment Variables + +```env +NODE_EXTRA_CA_CERTS="./e2e/certs/entrust_chain.crt.pem" +SBL_PLAYWRIGHT_TEST_TARGET="http://localhost:${SBL_DEV_PORT}" +SBL_PLAYWRIGHT_TEST_REGTECH_TARGET="${SBL_REGTECH_BASE_URL}" +SBL_PLAYWRIGHT_TEST_FILING_TARGET="${SBL_FILING_BASE_URL}" +SBL_PLAYWRIGHT_TEST_CLEANUP_TARGET="${SBL_CLEANUP_BASE_URL}" +SBL_PLAYWRIGHT_TEST_MAIL_TARGET="${SBL_MAIL_BASE_URL}" SBL_PLAYWRIGHT_TEST_KC_TARGET="http://localhost:8880/" SBL_PLAYWRIGHT_TEST_KC_REALM="regtech" SBL_PLAYWRIGHT_TEST_KC_CLI_USERNAME="admin" @@ -30,19 +42,44 @@ SBL_PLAYWRIGHT_TEST_KC_ADMIN_CLIENT_ID="regtech-client" SBL_PLAYWRIGHT_TEST_KC_ADMIN_GRANT_TYPE="password" ``` -### To add a new environment variable +## How to add new environment variables + +Both private and public variables will need to be added to the places listed below and in accordance with their applicable instructions -When adding a new env variable that needs to be used on production, there are a few places that need to be updated: +### To add a new public environment variable -- "Required Environment Variables" section in this guide (`ENV-GUIDE.md`) -- `.env.example` in the root of this repo +This is where environment vairables that are meant to be visible to the client go + +When adding a new public env variable that needs to be used on production, there are a few places that need to be updated: + +- "Required Runtime Environment Variables" section in this guide (`ENV-GUIDE.md`) +- `.env.example.public` in the root of this repo - `.github/workflows/test.yml` in this repo in the `env` section - Run `yarn start` at least once to generate types for the new env variables - `sbl-project/dev_setup/frontend.local.env` file in the `sbl-project` repo - ask a devops/backend engineer to help you update the `values.yaml` overrides -### To use an environment variable +### To use a public environment variable ```js import.meta.env.SOME_KEY; ``` + +### To add a new private environment variable + +This is where environment vairables that are not meant to be visible to the client go + +When adding a new private env variable that needs to be used on production, there are a few places that need to be updated: + +- "Required Test Environment Variables" section in this guide (`ENV-GUIDE.md`) +- `.env.example.private` in the root of this repo +- `.github/workflows/test.yml` in this repo in the `env` section +- Run `yarn start` at least once to generate types for the new env variables +- `sbl-project/dev_setup/frontend.local.env` file in the `sbl-project` repo +- ask a devops/backend engineer to help you update the `values.yaml` overrides + +### To use a private environment variable + +```js +process.env.SOME_KEY; +``` diff --git a/e2e/certs/README.md b/e2e/certs/README.md new file mode 100644 index 00000000..c47874ac --- /dev/null +++ b/e2e/certs/README.md @@ -0,0 +1,7 @@ +# Purpose + +The purpose of this directory and the files held within is to hold certificates from the certificate chain of the cert that will be presented by the dev deployment. The purpose of each file can be found below: + +- entrust_g2_ca.crt.pem: Root certificate for the chain in PEM format +- entrust_l1k.crt.pem: Intermediary certificate for the chain in PEM format +- entrust_chain.crt.pem: Both the root and the intermediary certificates in the same file so that they can both easily be passed as Node Extra Certs diff --git a/e2e/certs/entrust_chain.crt.pem b/e2e/certs/entrust_chain.crt.pem new file mode 100644 index 00000000..98bb4282 --- /dev/null +++ b/e2e/certs/entrust_chain.crt.pem @@ -0,0 +1,55 @@ +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFDjCCA/agAwIBAgIMDulMwwAAAABR03eFMA0GCSqGSIb3DQEBCwUAMIG+MQsw +CQYDVQQGEwJVUzEWMBQGA1UEChMNRW50cnVzdCwgSW5jLjEoMCYGA1UECxMfU2Vl +IHd3dy5lbnRydXN0Lm5ldC9sZWdhbC10ZXJtczE5MDcGA1UECxMwKGMpIDIwMDkg +RW50cnVzdCwgSW5jLiAtIGZvciBhdXRob3JpemVkIHVzZSBvbmx5MTIwMAYDVQQD +EylFbnRydXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjAeFw0x +NTEwMDUxOTEzNTZaFw0zMDEyMDUxOTQzNTZaMIG6MQswCQYDVQQGEwJVUzEWMBQG +A1UEChMNRW50cnVzdCwgSW5jLjEoMCYGA1UECxMfU2VlIHd3dy5lbnRydXN0Lm5l +dC9sZWdhbC10ZXJtczE5MDcGA1UECxMwKGMpIDIwMTIgRW50cnVzdCwgSW5jLiAt +IGZvciBhdXRob3JpemVkIHVzZSBvbmx5MS4wLAYDVQQDEyVFbnRydXN0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5IC0gTDFLMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEA2j+W0E25L0Tn2zlem1DuXKVh2kFnUwmqAJqOV38pa9vH4SEkqjrQ +jUcj0u1yFvCRIdJdt7hLqIOPt5EyaM/OJZMssn2XyP7BtBe6CZ4DkJN7fEmDImiK +m95HwzGYei59QAvS7z7Tsoyqj0ip/wDoKVgG97aTWpRzJiatWA7lQrjV6nN5ZGhT +JbiEz5R6rgZFDKNrTdDGvuoYpDbwkrK6HIiPOlJ/915tgxyd8B/lw9bdpXiSPbBt +LOrJz5RBGXFEaLpHPATpXbo+8DX3Fbae8i4VHj9HyMg4p3NFXU2wO7GOFyk36t0F +ASK7lDYqjVs1/lMZLwhGwSqzGmIdTivZGwIDAQABo4IBDDCCAQgwDgYDVR0PAQH/ +BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwMwYIKwYBBQUHAQEEJzAlMCMGCCsG +AQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5ldDAwBgNVHR8EKTAnMCWgI6Ah +hh9odHRwOi8vY3JsLmVudHJ1c3QubmV0L2cyY2EuY3JsMDsGA1UdIAQ0MDIwMAYE +VR0gADAoMCYGCCsGAQUFBwIBFhpodHRwOi8vd3d3LmVudHJ1c3QubmV0L3JwYTAd +BgNVHQ4EFgQUgqJwdN28Uz/Pe9T3zX+nYMYKTL8wHwYDVR0jBBgwFoAUanImetAe +733nO2lR1GyNn5ASZqswDQYJKoZIhvcNAQELBQADggEBADnVjpiDYcgsY9NwHRkw +y/YJrMxp1cncN0HyMg/vdMNY9ngnCTQIlZIv19+4o/0OgemknNM/TWgrFTEKFcxS +BJPok1DD2bHi4Wi3Ogl08TRYCj93mEC45mj/XeTIRsXsgdfJghhcg85x2Ly/rJkC +k9uUmITSnKa1/ly78EqvIazCP0kkZ9Yujs+szGQVGHLlbHfTUqi53Y2sAEo1GdRv +c6N172tkw+CNgxKhiucOhk3YtCAbvmqljEtoZuMrx1gL+1YQ1JH7HdMxWBCMRON1 +exCdtTix9qrKgWRs6PLigVWXUX/hwidQosk8WwBD9lu51aX8/wdQQGcHsFXwt35u +Lcw= +-----END CERTIFICATE----- diff --git a/e2e/certs/entrust_g2_ca.crt.pem b/e2e/certs/entrust_g2_ca.crt.pem new file mode 100644 index 00000000..2e23a605 --- /dev/null +++ b/e2e/certs/entrust_g2_ca.crt.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- diff --git a/e2e/certs/entrust_l1k.crt.pem b/e2e/certs/entrust_l1k.crt.pem new file mode 100644 index 00000000..33437f4d --- /dev/null +++ b/e2e/certs/entrust_l1k.crt.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFDjCCA/agAwIBAgIMDulMwwAAAABR03eFMA0GCSqGSIb3DQEBCwUAMIG+MQsw +CQYDVQQGEwJVUzEWMBQGA1UEChMNRW50cnVzdCwgSW5jLjEoMCYGA1UECxMfU2Vl +IHd3dy5lbnRydXN0Lm5ldC9sZWdhbC10ZXJtczE5MDcGA1UECxMwKGMpIDIwMDkg +RW50cnVzdCwgSW5jLiAtIGZvciBhdXRob3JpemVkIHVzZSBvbmx5MTIwMAYDVQQD +EylFbnRydXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjAeFw0x +NTEwMDUxOTEzNTZaFw0zMDEyMDUxOTQzNTZaMIG6MQswCQYDVQQGEwJVUzEWMBQG +A1UEChMNRW50cnVzdCwgSW5jLjEoMCYGA1UECxMfU2VlIHd3dy5lbnRydXN0Lm5l +dC9sZWdhbC10ZXJtczE5MDcGA1UECxMwKGMpIDIwMTIgRW50cnVzdCwgSW5jLiAt +IGZvciBhdXRob3JpemVkIHVzZSBvbmx5MS4wLAYDVQQDEyVFbnRydXN0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5IC0gTDFLMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEA2j+W0E25L0Tn2zlem1DuXKVh2kFnUwmqAJqOV38pa9vH4SEkqjrQ +jUcj0u1yFvCRIdJdt7hLqIOPt5EyaM/OJZMssn2XyP7BtBe6CZ4DkJN7fEmDImiK +m95HwzGYei59QAvS7z7Tsoyqj0ip/wDoKVgG97aTWpRzJiatWA7lQrjV6nN5ZGhT +JbiEz5R6rgZFDKNrTdDGvuoYpDbwkrK6HIiPOlJ/915tgxyd8B/lw9bdpXiSPbBt +LOrJz5RBGXFEaLpHPATpXbo+8DX3Fbae8i4VHj9HyMg4p3NFXU2wO7GOFyk36t0F +ASK7lDYqjVs1/lMZLwhGwSqzGmIdTivZGwIDAQABo4IBDDCCAQgwDgYDVR0PAQH/ +BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwMwYIKwYBBQUHAQEEJzAlMCMGCCsG +AQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5ldDAwBgNVHR8EKTAnMCWgI6Ah +hh9odHRwOi8vY3JsLmVudHJ1c3QubmV0L2cyY2EuY3JsMDsGA1UdIAQ0MDIwMAYE +VR0gADAoMCYGCCsGAQUFBwIBFhpodHRwOi8vd3d3LmVudHJ1c3QubmV0L3JwYTAd +BgNVHQ4EFgQUgqJwdN28Uz/Pe9T3zX+nYMYKTL8wHwYDVR0jBBgwFoAUanImetAe +733nO2lR1GyNn5ASZqswDQYJKoZIhvcNAQELBQADggEBADnVjpiDYcgsY9NwHRkw +y/YJrMxp1cncN0HyMg/vdMNY9ngnCTQIlZIv19+4o/0OgemknNM/TWgrFTEKFcxS +BJPok1DD2bHi4Wi3Ogl08TRYCj93mEC45mj/XeTIRsXsgdfJghhcg85x2Ly/rJkC +k9uUmITSnKa1/ly78EqvIazCP0kkZ9Yujs+szGQVGHLlbHfTUqi53Y2sAEo1GdRv +c6N172tkw+CNgxKhiucOhk3YtCAbvmqljEtoZuMrx1gL+1YQ1JH7HdMxWBCMRON1 +exCdtTix9qrKgWRs6PLigVWXUX/hwidQosk8WwBD9lu51aX8/wdQQGcHsFXwt35u +Lcw= +-----END CERTIFICATE----- diff --git a/e2e/fixtures/testFixture.ts b/e2e/fixtures/testFixture.ts index 4df371d0..2d994c2a 100644 --- a/e2e/fixtures/testFixture.ts +++ b/e2e/fixtures/testFixture.ts @@ -11,6 +11,7 @@ import pointOfContactJson from '../test-data/point-of-contact/point-of-contact-d import createDomainAssociation from '../utils/createDomainAssociation'; import createInstitution from '../utils/createInstitution'; import createKeycloakUser from '../utils/createKeycloakUser'; +import deleteKeycloakUser from '../utils/deleteKeycloakUser'; import getAdminKeycloakToken from '../utils/getKeycloakToken'; import type { Account } from '../utils/testFixture.utils'; import { @@ -18,6 +19,7 @@ import { expectedWithAssociationsUrl, getTestDataObject, } from '../utils/testFixture.utils'; +import cleanup, { cleanupHealthcheck } from '../utils/testFixture.cleanup'; import { ResultUploadMessage, uploadFile } from '../utils/uploadFile'; import { clickContinue, clickContinueNext } from '../utils/navigation.utils'; @@ -78,8 +80,7 @@ export const test = baseTest.extend<{ testRssdId, } = account; // eslint-enable @typescript-eslint/no-magic-numbers - - await createKeycloakUser({ + const testUserId = await createKeycloakUser({ testUserEmail, testUsername, testFirstName, @@ -112,6 +113,17 @@ export const test = baseTest.extend<{ await page .getByRole('button', { name: 'Sign in with Login.gov' }) .click(); + + if ( + !(process.env.SBL_PLAYWRIGHT_TEST_TARGET ?? '').includes('localhost:') + ) { + await expect( + page.getByRole('link', { name: '‹ Back to Small business' }), + ).toBeVisible(); + await page + .getByRole('link', { name: '‹ Back to Small business' }) + .click(); + } await expect(page.locator('#kc-page-title')).toContainText( 'Sign in to your account', ); @@ -142,6 +154,12 @@ export const test = baseTest.extend<{ }); await use(); + + const healthy = await cleanupHealthcheck({ adminToken }); + if (healthy) { + await cleanup({ adminToken, testLei }); + } + await deleteKeycloakUser({ id: testUserId }); }, { auto: true }, ], diff --git a/e2e/utils/createDomainAssociation.ts b/e2e/utils/createDomainAssociation.ts index 7f616436..fc890886 100644 --- a/e2e/utils/createDomainAssociation.ts +++ b/e2e/utils/createDomainAssociation.ts @@ -13,7 +13,7 @@ export default async function createDomainAssociation({ }: CreateDomainAssociationProperties): Promise { const optionsForDomainAssociation = { method: 'POST', - url: `http://localhost:8881/v1/institutions/${testLei}/domains`, + url: `${process.env.SBL_PLAYWRIGHT_TEST_REGTECH_TARGET}/v1/institutions/${testLei}/domains`, headers: { Authorization: `Bearer ${adminToken}` }, data: [{ domain: testEmailDomain }], }; diff --git a/e2e/utils/createInstitution.ts b/e2e/utils/createInstitution.ts index 5608fc54..778b7a86 100644 --- a/e2e/utils/createInstitution.ts +++ b/e2e/utils/createInstitution.ts @@ -20,7 +20,7 @@ export default async function createInstitution({ // eslint-disable @typescript-eslint/no-magic-numbers unicorn/numeric-separators-style const options = { method: 'POST', - url: 'http://localhost:8881/v1/institutions', + url: `${process.env.SBL_PLAYWRIGHT_TEST_REGTECH_TARGET}/v1/institutions`, headers: { Authorization: `Bearer ${adminToken}` }, data: { name: testInstitutionName, diff --git a/e2e/utils/createKeycloakUser.ts b/e2e/utils/createKeycloakUser.ts index 1a2c4d24..3938d652 100644 --- a/e2e/utils/createKeycloakUser.ts +++ b/e2e/utils/createKeycloakUser.ts @@ -14,7 +14,7 @@ export class KeycloakService { } } -const kcAdminClient = new KeycloakAdminClient({ +export const kcAdminClient = new KeycloakAdminClient({ baseUrl: config.target, realmName: config.realm, }); @@ -34,7 +34,9 @@ export default async function createKeycloakUser({ testFirstName, testLastName, testUserPassword, -}: CreateKeycloakUserProperties): Promise { +}: CreateKeycloakUserProperties): Promise { + let result = ''; + // Authorize with username / password try { await kcAdminClient.auth({ @@ -45,12 +47,15 @@ export default async function createKeycloakUser({ }); } catch (error) { // eslint-disable-next-line no-console - console.error('error when attempting to auth into :>>', error); + console.error( + 'error when attempting to auth into keycloak admin :>>', + error, + ); throw error; } try { - await kcAdminClient.users.create({ + const response = await kcAdminClient.users.create({ email: testUserEmail, username: testUsername, firstName: testFirstName, @@ -63,9 +68,11 @@ export default async function createKeycloakUser({ }, ], }); + result = response?.id ?? ''; } catch (error) { // eslint-disable-next-line no-console console.log('error when trying to create a user in keycloak :>>', error); throw error; } + return result; } diff --git a/e2e/utils/deleteKeycloakUser.ts b/e2e/utils/deleteKeycloakUser.ts new file mode 100644 index 00000000..c0881fb1 --- /dev/null +++ b/e2e/utils/deleteKeycloakUser.ts @@ -0,0 +1,37 @@ +import { config } from './authConstants'; +import { kcAdminClient } from './createKeycloakUser'; + +interface DeleteKeycloakUserProperties { + id: string; +} + +export default async function deleteKeycloakUser({ + id, +}: DeleteKeycloakUserProperties): Promise { + // Authorize with username / password + try { + await kcAdminClient.auth({ + username: config.cli.username, + clientId: config.cli.clientId, + clientSecret: config.cli.clientSecret, + grantType: config.cli.grantType, + }); + } catch (error) { + // eslint-disable-next-line no-console + console.error( + 'error when attempting to auth into keycloak admin :>>', + error, + ); + throw error; + } + + try { + await kcAdminClient.users.del({ + id: id, + }); + } catch (error) { + // eslint-disable-next-line no-console + console.log('error when trying to delete a user in keycloak :>>', error); + throw error; + } +} diff --git a/e2e/utils/testFixture.cleanup.ts b/e2e/utils/testFixture.cleanup.ts new file mode 100644 index 00000000..a3ae3780 --- /dev/null +++ b/e2e/utils/testFixture.cleanup.ts @@ -0,0 +1,53 @@ +import axios from 'axios'; + +interface CleanupHealthcheckProperties { + adminToken: string; +} + +export async function cleanupHealthcheck({ + adminToken, +}: CleanupHealthcheckProperties): Promise { + const options = { + method: 'GET', + url: `${process.env.SBL_PLAYWRIGHT_TEST_CLEANUP_TARGET}/v1/cleanup/healthcheck`, + headers: { Authorization: `Bearer ${adminToken}` }, + }; + + let result = false; + + try { + const response = await axios.request(options); + if (response?.data === 'Service is up.') { + result = true; + } + } catch (error) { + // eslint-disable-next-line no-console + console.error('error when calling cleanup api healthcheck :>>', error); + } + + return result; +} + +interface CleanupProperties { + adminToken: string; + testLei: string; +} + +export default async function cleanup({ + adminToken, + testLei, +}: CleanupProperties): Promise { + const options = { + method: 'DELETE', + url: `${process.env.SBL_PLAYWRIGHT_TEST_CLEANUP_TARGET}/v1/cleanup/${testLei}`, + headers: { Authorization: `Bearer ${adminToken}` }, + }; + + try { + await axios.request(options); + } catch (error) { + // eslint-disable-next-line no-console + console.error('error when calling cleanup api :>>', error); + throw error; + } +} diff --git a/e2e/utils/testFixture.utils.ts b/e2e/utils/testFixture.utils.ts index 92cea34b..cef68342 100644 --- a/e2e/utils/testFixture.utils.ts +++ b/e2e/utils/testFixture.utils.ts @@ -35,7 +35,7 @@ export const getTestDataObject = (): Account => { const testUserEmail = `playwright-test-user-${seed}@${testEmailDomain}`; const testUserPassword = `playwright-test-user-${seed}-password`; const testInstitutionName = `RegTech Regional Reserve - ${seed}`; - const testLei = `${seed.slice(-9)}TESTACCT053`; + const testLei = `${seed.slice(-6)}E2ETESTACCT053`; const testTaxId = `${seed.slice(4, 6)}-${seed.slice(-7)}`; const testRssdId = seed.slice(-7); // eslint-enable @typescript-eslint/no-magic-numbers diff --git a/nginx-entrypoint.sh b/nginx-entrypoint.sh index f7a7ae61..1908bc0d 100644 --- a/nginx-entrypoint.sh +++ b/nginx-entrypoint.sh @@ -6,7 +6,7 @@ cd /usr/share/nginx/html # inject non-secret, public env variables into index.html -./import-meta-env-alpine -x .env.example -p index.html --disposable || exit 1 +./import-meta-env-alpine -x .env.example.public -p index.html --disposable || exit 1 # # create nginx.conf with env vars from template # # must specify variables to be substituted to avoid replacing base nginx vars diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index 0f42ab88..fded1dd6 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -12,23 +12,13 @@ interface ImportMetaEnv { readonly SBL_OIDC_REDIRECT_URI: string; readonly SBL_REGTECH_BASE_URL: string; readonly SBL_FILING_BASE_URL: string; + readonly SBL_CLEANUP_BASE_URL: string; readonly SBL_MAIL_BASE_URL: string; readonly SBL_LOGOUT_REDIRECT_URL: string; readonly SBL_VALIDATION_TIMEOUT_SECONDS: string; readonly SBL_LONGPOLLING_DELAY_SECONDS: string; readonly SBL_UPLOAD_FILE_SIZE_LIMIT_BYTES: string; readonly SBL_ENABLE_PLAYWRIGHT_TEST_SETTINGS: string; - readonly SBL_PLAYWRIGHT_TEST_TARGET: string; - readonly SBL_PLAYWRIGHT_TEST_KC_TARGET: string; - readonly SBL_PLAYWRIGHT_TEST_KC_REALM: string; - readonly SBL_PLAYWRIGHT_TEST_KC_CLI_USERNAME: string; - readonly SBL_PLAYWRIGHT_TEST_KC_CLI_CLIENT_ID: string; - readonly SBL_PLAYWRIGHT_TEST_KC_CLI_CLIENT_SECRET: string; - readonly SBL_PLAYWRIGHT_TEST_KC_CLI_GRANT_TYPE: string; - readonly SBL_PLAYWRIGHT_TEST_KC_ADMIN_USERNAME: string; - readonly SBL_PLAYWRIGHT_TEST_KC_ADMIN_PASSWORD: string; - readonly SBL_PLAYWRIGHT_TEST_KC_ADMIN_CLIENT_ID: string; - readonly SBL_PLAYWRIGHT_TEST_KC_ADMIN_GRANT_TYPE: string; } interface ImportMeta { diff --git a/start.sh b/start.sh index bce57d74..f254a11a 100644 --- a/start.sh +++ b/start.sh @@ -120,7 +120,7 @@ else fi # generate types for new env vars if added to env.example (even if not changed in this commit) -npx @import-meta-env/typescript -x .env.example +npx @import-meta-env/typescript -x .env.example.public if [ $? -eq 0 ]; then # add linting comments and docs reference to top of types file (mac, linux, windows compatible) echo "\ diff --git a/vite.config.ts b/vite.config.ts index 941b556c..caa2e052 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -58,7 +58,7 @@ export default async ({ mode }) => { svgr(), tsconfigPaths(), react(), - importMetaEnv.vite({ example: '.env.example' }), + importMetaEnv.vite({ example: '.env.example.public' }), ...(mode === 'test' ? [] : [