diff --git a/.env.development b/.env.development new file mode 100644 index 00000000..e69de29b diff --git a/.env.sample b/.env.sample index b0634f19..55f92736 100644 --- a/.env.sample +++ b/.env.sample @@ -1,26 +1,11 @@ -# running on port 3000 -PORT=3000 -MONCOMPTEPRO_HOST=http://localhost:3000 -# database configuration -DATABASE_URL=postgres://username:password@localhost:5432/dbname -REDIS_URL=redis://:@127.0.0.1:6379 -# email configuration -DO_NOT_SEND_MAIL=True -BREVO_API_KEY=____________________________ -DEBOUNCE_API_KEY=_____________ -ZAMMAD_URL=https://support.etalab.gouv.fr -ZAMMAD_TOKEN=___________________________________________________________ -# disable features -DO_NOT_CHECK_EMAIL_DELIVERABILITY=True -CONSIDER_ALL_EMAIL_DOMAINS_AS_NON_FREE=True -DO_NOT_USE_ANNUAIRE_EMAILS=True -DO_NOT_AUTHENTICATE_BROWSER=True -DISABLE_SECURITY_RESPONSE_HEADERS=True -SECURE_COOKIES=False -SESSION_COOKIE_SECRET=moncompteprosecret -SYMMETRIC_ENCRYPTION_KEY=aTrueRandom32BytesLongBase64EncodedStringAA= -# A default JWKS is necessary for interacting with a client with signed payloads enabled -JWKS: '{"keys":[{"crv":"P-256","x":"UtmbpHb1aHibmvEQJ2KlIzNro4tGfyMiBIVmO92YX7Q","y":"YsRG_NMtLOqvA6S9zq5r7M9Y-Cgo4YwKvH3xXyvFE2E","d":"taURynSwshCfxEWs6z2_Xz-ocheg-6ePaU87cjy572Y","kty":"EC","kid":"GCirOyeBc0rlWhcbMnwe9FUadPk6ToJlOq3yvxvkKlE","use":"enc"},{"crv":"P-256","x":"2SSoeci15SnMM6wwxvNwzp_xjVTwgEALOY1NvTBbdqs","y":"Gplus4XyX4dQ6Z0Pwb0UhsmJfx7S5_DCFxpK6yt396Q","d":"TLeCkidQUJG9s6hvHx8QSHNKfqyhcbIXCN7rJ67AjH4","kty":"EC","kid":"TeXJ6Hx4sG9A13LCFlU46-PYGopwwFOsmCTEJcwZvZ8","use":"sig"},{"crv":"Ed25519","x":"NQNM3isoJAeK6HWKEgHifRqFrC-R6ufusnv47BnlWn4","d":"WxFz4Ulx6rLBO5HHHhg86BMc_CtRoCmFn8Gwy-kbaL4","kty":"OKP","kid":"onHSTAw1rfQOz_qWnPTh2SZzrseoqbOOrD1tcxFOaIU","use":"sig"},{"e":"AQAB","n":"5yuakCQKnkzP4tNXYI6qRYX-0pyeuGKS8VKl7S1QNj7bAMjeV2o3xjDgg4qtrUrFrqxSFOfBX5kJR3NEBoYiQpUwl9zPmKNLR0zX0w6VpwDREDS8bpBL_naeiGRdLX_AYxR7jCsDETEXqFm0S1CmfLjgAoazLPDxzGvFaezLEo0rafcLR3MpKIa-INqwCoTiLWUAtXKv-ZcmO7QuzRcVJecFs7WaMQZNMrfSAdj-agdnVOkP2cXnd6xpT2Pcph7I6z2slRkEZ_Oz1BkG-FV_21IlY1U4tE3GigKdSNRSJmuyvdgI4wDb2noZdEStFr8nsOsG63kIYM_Gve-HWiTxmQ","d":"qClmBFjTiJgj2cMXmtvtLSnuVtMr-sFqVzZiEYiXAv7yXT3B0CEqdXf0unvVH2x3JTuhcies2Zf_0gQdhglpPro8YRx1v3l6N2HE1nmTj6reakWSlXNOdMthQ6KOzZxTHUA3J53aW1U0-nhW2TrQAYaTHgNSr-yOWMBFGWrxxomc8h_1OnnXS9wRxoicPshjx7S8huy3YLbWzQphBqzBx5vsPOClfbs0dtxhAY63vXbNDS_sAIVfn1U__f6ilFmzE9odgOydsSwBUtRm2Ir4wY5HhqYGRPOKAUNHLqEsDqwmp_o3RtBQwg937ymbOJvgoa6qkqg_uxtaVSP7RX4EKQ","p":"-X7pv_NpfJvqTTlQwQnaz6eiA_I7v7Jj0l1KtmBRBZz6q6R9qq1BVlP8XeOBO5TX9vQKIooY8fL3QsWf73ZqQmmy9W3C4dAhwbwalvBzZHZT2Wznrurp_bML_8Xx1XhNxTawAb263O3AUz7Rw3g5lI2cafTe4x1dSO8_CHL3eMs","q":"7TJj6aNzkVjyPeCZVHwBXGDWDIT2DxqWRjKrKgqlpWdzEftNce855Wg3Ve4JnNtFkg7Qow4imZVkbK69ChIStv9s1KDX_sGRCyfN17d0jlkyGUnFB2RSBB42t7SmcC4ZhHjxdAdopOG_o1r5vEwDo-0hKWikP9uyYmWyhfY3hqs","dp":"g0dYT3wQ4VRY8NFbwHci_2jBQzpOXgvLooEcMuJzP3TeITqoNQp8-qOuguiWs3caPAMk4g-wGH8zw5qhEStJtjBPzfw3MwKFAJ-tjgZvcUkhzaIUNmG9RZTUl3zcRurKYR7pdcETdfRT4nmHfkbgZV4uE0KZlP96ekoI7LUxqgk","dq":"1Gpl81t_KVDgTu2OIoySo2nNBpUjzc7feKnzgsjaItALyrSkXD4COSElPPzY-vGa0fwWd483CRcyQeoSPKyGuf7wNVJ9XBV4kObqfh46cSgLp33axo3erPVpxwYubxO5olq00FW6Lr5D4kSclTX1pJ29LtoZDV7v1xJ_11vxydU","qi":"4RyTKy-QINtOUezaLEymzNBIG3uZv_IKvGPhEYi4wRNP_XxIK9NwfgUFRAhxhpxSpEjco_eNuN3I6XBF7bXb4-Bnnye1mBm3sBTXx2_09r8zt9Uvg3cdh0pYem3hU1ANMRmr3rfjtain4DTskIJ2CxjvGIMyh3VXLyRyfzIGJig","kty":"RSA","kid":"kddKa_IDmU8a5RhJaIzwzpJcFe4qT-GtNFcG2AWclZ4","use":"enc"},{"e":"AQAB","n":"6btLS-c06m18O5BlLvJA4HJNVI7WauBg5JVoy1cHTdfjTJ-oSts5uetXKF_NlNcLuq-zIKZuu9wea5m2E3lJ-vtCSAtRaJgZY41KAOjIsrHQstVuc9di4zjgcA6zwEXhqwu48gklGKpWNk7wnfMCO6mNoRs_-8-CnK6lTFeJFzfoCDmS6dYbefmPeFW4qziEZzEv5DPGAcUsXXZhbOku_E8gILRVMkBwHpvY_G3jngE1EWXctiM9tYqhgvxyJC9QyPCVpgfAvDlslMpuQTxBviC9PsrcBaQ5PyAP_xNN3X8LB-STpz7jNpNquKL5Ls0Hv9R3fDCeHvcYoVsgDirwfQ","d":"L0a7DDdP9LsAjeu_C6fkh4GXMqtRo3yPHK077SVFTPGGAFGq8Lk3C-wWTQxTwO9eZ_xx9wCzFTyIyqrksTuvQxzfY0MmzEk3mXNSrKxpK_vbgtC47qV6UwuGGiRfJ1z7MGXGmu5OmpaZqZJ-CPTGVtsM0rF4V665dIe-15o9GHzLX80mhw8ySd0qqBIbdIWlK2zaSRPGL08mP02t_XnHdCCaWfRE_erO6zsEhR8ePvbmQqI7GRBull59seXefo1VDP30lEwHwH05Ju24_ZddhfuP2Y9jkZnNKqpSHF3EZzT6Vh3ggAaLjQzRWJvd1_0Zit7CD06o6L1aLV7nDnTYAQ","p":"_u6v29kLICnGvbF44-sF5cFisrIPyXcj8laaNx6uP5ax9ZOPD_THdxTFU3YWLUErzi4MQJQPLoJacphQJKnG78b0PX_733--r-vpqUqfbzAlIssS8N4CFj6_YEMFR8W70laXJYJdx7IsnGOAlxAUZur5ugaaR0zDzlMTQVuR30E","q":"6rXguomnHNGFslAeHWPxPDaHxihx3eRJ-8t1KyvvwT43YfdPn2xxdq5-TyO0MMKznvDIHk9HDMBMr8JH32Q9qx75Ec81NOLGkBWqO9x-8dBlKn95jr8-qkD3iXHmJiHHNWNurHJM4G4lo73IL_0jgo0CCpcZWP7iH5y-b_mXPj0","dp":"Cyf-4iwZZIrve5WsqKy8UVWpMBDCyBpCpHRNw2PAVGAP4aNXe2dG41sxV3mvdsOHWzqApsLT90EVHDa2KySS5CNcxOQ47Yr1mVVFoHb3izIcLe2dIpVUmgyc62WDcaShl47ahnWyDO8rLJzeH75AZlCaJR3s2nnth7Xy_cU4GQE","dq":"SvJe21HfQe2JsqGwrBPg0ShcfKMnkQI3uaaDOJDkEyHJz4eILlETfiFEBgNRo4xYjPU4Aa2w81poYms4RhYdNwpB4DT5OXT8kL_KRykmhBLWaxafezyIRxdNs97h7eU1Vk_05C3vbG7fqASO6vv7HdHnB_ityGRDUnLbwKfDasU","qi":"QomRmnqrW3k8cV8MIefgmKZMGDGHRC44bFk9B20YR15_XHcMimi7o9rjUE7BY-RO30RsPUiQqB_vkpKvQZILOuPmIQhElcgmguKqPNwprVMgx-krUQ1Khuh3tgzxhBgazXzPcKmx8JBbCopP_UwNiCpPcdm74VFcZ-OswmqQU08","kty":"RSA","kid":"lFWqEBQbScnjO5OzUbvkPp0rmjGy17bmzZOqUbWkQMo","use":"sig"}]}' -# INSEE credentials needed to fetch organization info -INSEE_CONSUMER_KEY=____________________________ -INSEE_CONSUMER_SECRET=____________________________ +# Section 1: These variables are required for the full connection process +DATABASE_URL=postgres://moncomptepro:moncomptepro@127.0.0.1:5432/moncomptepro +#INSEE_CONSUMER_KEY= +#INSEE_CONSUMER_SECRET= + +# Section 2: These variables are required for end-to-end testing +#BREVO_API_KEY= +#CYPRESS_MAILSLURP_API_KEY= +#DEBOUNCE_API_KEY= +#DO_NOT_SEND_MAIL=False +#ZAMMAD_TOKEN= diff --git a/.env.test b/.env.test index 9fa0dda0..e529dfb9 100644 --- a/.env.test +++ b/.env.test @@ -1,20 +1,3 @@ -BREVO_API_KEY=____________________________ CONSIDER_ALL_EMAIL_DOMAINS_AS_NON_FREE=False -DATABASE_URL=postgres://username:password@localhost:5432/dbname -DEBOUNCE_API_KEY=_____________ -DISABLE_SECURITY_RESPONSE_HEADERS=True -DO_NOT_AUTHENTICATE_BROWSER=True -DO_NOT_CHECK_EMAIL_DELIVERABILITY=False -DO_NOT_SEND_MAIL=True DO_NOT_USE_ANNUAIRE_EMAILS=False -INSEE_CONSUMER_KEY=____________________________ -INSEE_CONSUMER_SECRET=____________________________ -JWKS: '{"keys":[{"crv":"P-256","x":"UtmbpHb1aHibmvEQJ2KlIzNro4tGfyMiBIVmO92YX7Q","y":"YsRG_NMtLOqvA6S9zq5r7M9Y-Cgo4YwKvH3xXyvFE2E","d":"taURynSwshCfxEWs6z2_Xz-ocheg-6ePaU87cjy572Y","kty":"EC","kid":"GCirOyeBc0rlWhcbMnwe9FUadPk6ToJlOq3yvxvkKlE","use":"enc"},{"crv":"P-256","x":"2SSoeci15SnMM6wwxvNwzp_xjVTwgEALOY1NvTBbdqs","y":"Gplus4XyX4dQ6Z0Pwb0UhsmJfx7S5_DCFxpK6yt396Q","d":"TLeCkidQUJG9s6hvHx8QSHNKfqyhcbIXCN7rJ67AjH4","kty":"EC","kid":"TeXJ6Hx4sG9A13LCFlU46-PYGopwwFOsmCTEJcwZvZ8","use":"sig"},{"crv":"Ed25519","x":"NQNM3isoJAeK6HWKEgHifRqFrC-R6ufusnv47BnlWn4","d":"WxFz4Ulx6rLBO5HHHhg86BMc_CtRoCmFn8Gwy-kbaL4","kty":"OKP","kid":"onHSTAw1rfQOz_qWnPTh2SZzrseoqbOOrD1tcxFOaIU","use":"sig"},{"e":"AQAB","n":"5yuakCQKnkzP4tNXYI6qRYX-0pyeuGKS8VKl7S1QNj7bAMjeV2o3xjDgg4qtrUrFrqxSFOfBX5kJR3NEBoYiQpUwl9zPmKNLR0zX0w6VpwDREDS8bpBL_naeiGRdLX_AYxR7jCsDETEXqFm0S1CmfLjgAoazLPDxzGvFaezLEo0rafcLR3MpKIa-INqwCoTiLWUAtXKv-ZcmO7QuzRcVJecFs7WaMQZNMrfSAdj-agdnVOkP2cXnd6xpT2Pcph7I6z2slRkEZ_Oz1BkG-FV_21IlY1U4tE3GigKdSNRSJmuyvdgI4wDb2noZdEStFr8nsOsG63kIYM_Gve-HWiTxmQ","d":"qClmBFjTiJgj2cMXmtvtLSnuVtMr-sFqVzZiEYiXAv7yXT3B0CEqdXf0unvVH2x3JTuhcies2Zf_0gQdhglpPro8YRx1v3l6N2HE1nmTj6reakWSlXNOdMthQ6KOzZxTHUA3J53aW1U0-nhW2TrQAYaTHgNSr-yOWMBFGWrxxomc8h_1OnnXS9wRxoicPshjx7S8huy3YLbWzQphBqzBx5vsPOClfbs0dtxhAY63vXbNDS_sAIVfn1U__f6ilFmzE9odgOydsSwBUtRm2Ir4wY5HhqYGRPOKAUNHLqEsDqwmp_o3RtBQwg937ymbOJvgoa6qkqg_uxtaVSP7RX4EKQ","p":"-X7pv_NpfJvqTTlQwQnaz6eiA_I7v7Jj0l1KtmBRBZz6q6R9qq1BVlP8XeOBO5TX9vQKIooY8fL3QsWf73ZqQmmy9W3C4dAhwbwalvBzZHZT2Wznrurp_bML_8Xx1XhNxTawAb263O3AUz7Rw3g5lI2cafTe4x1dSO8_CHL3eMs","q":"7TJj6aNzkVjyPeCZVHwBXGDWDIT2DxqWRjKrKgqlpWdzEftNce855Wg3Ve4JnNtFkg7Qow4imZVkbK69ChIStv9s1KDX_sGRCyfN17d0jlkyGUnFB2RSBB42t7SmcC4ZhHjxdAdopOG_o1r5vEwDo-0hKWikP9uyYmWyhfY3hqs","dp":"g0dYT3wQ4VRY8NFbwHci_2jBQzpOXgvLooEcMuJzP3TeITqoNQp8-qOuguiWs3caPAMk4g-wGH8zw5qhEStJtjBPzfw3MwKFAJ-tjgZvcUkhzaIUNmG9RZTUl3zcRurKYR7pdcETdfRT4nmHfkbgZV4uE0KZlP96ekoI7LUxqgk","dq":"1Gpl81t_KVDgTu2OIoySo2nNBpUjzc7feKnzgsjaItALyrSkXD4COSElPPzY-vGa0fwWd483CRcyQeoSPKyGuf7wNVJ9XBV4kObqfh46cSgLp33axo3erPVpxwYubxO5olq00FW6Lr5D4kSclTX1pJ29LtoZDV7v1xJ_11vxydU","qi":"4RyTKy-QINtOUezaLEymzNBIG3uZv_IKvGPhEYi4wRNP_XxIK9NwfgUFRAhxhpxSpEjco_eNuN3I6XBF7bXb4-Bnnye1mBm3sBTXx2_09r8zt9Uvg3cdh0pYem3hU1ANMRmr3rfjtain4DTskIJ2CxjvGIMyh3VXLyRyfzIGJig","kty":"RSA","kid":"kddKa_IDmU8a5RhJaIzwzpJcFe4qT-GtNFcG2AWclZ4","use":"enc"},{"e":"AQAB","n":"6btLS-c06m18O5BlLvJA4HJNVI7WauBg5JVoy1cHTdfjTJ-oSts5uetXKF_NlNcLuq-zIKZuu9wea5m2E3lJ-vtCSAtRaJgZY41KAOjIsrHQstVuc9di4zjgcA6zwEXhqwu48gklGKpWNk7wnfMCO6mNoRs_-8-CnK6lTFeJFzfoCDmS6dYbefmPeFW4qziEZzEv5DPGAcUsXXZhbOku_E8gILRVMkBwHpvY_G3jngE1EWXctiM9tYqhgvxyJC9QyPCVpgfAvDlslMpuQTxBviC9PsrcBaQ5PyAP_xNN3X8LB-STpz7jNpNquKL5Ls0Hv9R3fDCeHvcYoVsgDirwfQ","d":"L0a7DDdP9LsAjeu_C6fkh4GXMqtRo3yPHK077SVFTPGGAFGq8Lk3C-wWTQxTwO9eZ_xx9wCzFTyIyqrksTuvQxzfY0MmzEk3mXNSrKxpK_vbgtC47qV6UwuGGiRfJ1z7MGXGmu5OmpaZqZJ-CPTGVtsM0rF4V665dIe-15o9GHzLX80mhw8ySd0qqBIbdIWlK2zaSRPGL08mP02t_XnHdCCaWfRE_erO6zsEhR8ePvbmQqI7GRBull59seXefo1VDP30lEwHwH05Ju24_ZddhfuP2Y9jkZnNKqpSHF3EZzT6Vh3ggAaLjQzRWJvd1_0Zit7CD06o6L1aLV7nDnTYAQ","p":"_u6v29kLICnGvbF44-sF5cFisrIPyXcj8laaNx6uP5ax9ZOPD_THdxTFU3YWLUErzi4MQJQPLoJacphQJKnG78b0PX_733--r-vpqUqfbzAlIssS8N4CFj6_YEMFR8W70laXJYJdx7IsnGOAlxAUZur5ugaaR0zDzlMTQVuR30E","q":"6rXguomnHNGFslAeHWPxPDaHxihx3eRJ-8t1KyvvwT43YfdPn2xxdq5-TyO0MMKznvDIHk9HDMBMr8JH32Q9qx75Ec81NOLGkBWqO9x-8dBlKn95jr8-qkD3iXHmJiHHNWNurHJM4G4lo73IL_0jgo0CCpcZWP7iH5y-b_mXPj0","dp":"Cyf-4iwZZIrve5WsqKy8UVWpMBDCyBpCpHRNw2PAVGAP4aNXe2dG41sxV3mvdsOHWzqApsLT90EVHDa2KySS5CNcxOQ47Yr1mVVFoHb3izIcLe2dIpVUmgyc62WDcaShl47ahnWyDO8rLJzeH75AZlCaJR3s2nnth7Xy_cU4GQE","dq":"SvJe21HfQe2JsqGwrBPg0ShcfKMnkQI3uaaDOJDkEyHJz4eILlETfiFEBgNRo4xYjPU4Aa2w81poYms4RhYdNwpB4DT5OXT8kL_KRykmhBLWaxafezyIRxdNs97h7eU1Vk_05C3vbG7fqASO6vv7HdHnB_ityGRDUnLbwKfDasU","qi":"QomRmnqrW3k8cV8MIefgmKZMGDGHRC44bFk9B20YR15_XHcMimi7o9rjUE7BY-RO30RsPUiQqB_vkpKvQZILOuPmIQhElcgmguKqPNwprVMgx-krUQ1Khuh3tgzxhBgazXzPcKmx8JBbCopP_UwNiCpPcdm74VFcZ-OswmqQU08","kty":"RSA","kid":"lFWqEBQbScnjO5OzUbvkPp0rmjGy17bmzZOqUbWkQMo","use":"sig"}]}' -MONCOMPTEPRO_HOST=http://localhost:3000 -PORT=3000 -REDIS_URL=redis://:@127.0.0.1:6379 -SECURE_COOKIES=False -SESSION_COOKIE_SECRET=moncompteprosecret -SYMMETRIC_ENCRYPTION_KEY=aTrueRandom32BytesLongBase64EncodedStringAA= -ZAMMAD_TOKEN=___________________________________________________________ -ZAMMAD_URL=https://support.etalab.gouv.fr +DO_NOT_CHECK_EMAIL_DELIVERABILITY=False diff --git a/.github/workflows/end-to-end.yml b/.github/workflows/end-to-end.yml index b7f54042..cc47a1dd 100644 --- a/.github/workflows/end-to-end.yml +++ b/.github/workflows/end-to-end.yml @@ -7,34 +7,21 @@ on: - "!master" env: - ACCESS_LOG_PATH: PGUSER: moncomptepro PGPASSWORD: moncomptepro PGDATABASE: moncomptepro PGHOST: 127.0.0.1 PGPORT: 5432 - DATABASE_URL: postgres://moncomptepro:moncomptepro@127.0.0.1:5432/moncomptepro BREVO_API_KEY: ${{ secrets.BREVO_API_KEY }} - MONCOMPTEPRO_HOST: http://172.18.0.1:3000 CYPRESS_BASE_URL: http://172.18.0.1:3000 - DO_NOT_SEND_MAIL: "False" - DO_NOT_CHECK_EMAIL_DELIVERABILITY: "True" - CONSIDER_ALL_EMAIL_DOMAINS_AS_NON_FREE: "True" - DO_NOT_RATE_LIMIT: "True" - DO_NOT_USE_ANNUAIRE_EMAILS: "True" - DO_NOT_AUTHENTICATE_BROWSER: "True" - SESSION_COOKIE_SECRET: secret + CYPRESS_MAILSLURP_API_KEY: ${{ secrets.MAILSLURP_API_KEY }} + DATABASE_URL: postgres://moncomptepro:moncomptepro@127.0.0.1:5432/moncomptepro DEBOUNCE_API_KEY: ${{ secrets.DEBOUNCE_API_KEY }} - SENTRY_DSN: + DO_NOT_SEND_MAIL: "False" INSEE_CONSUMER_KEY: ${{ secrets.INSEE_CONSUMER_KEY }} INSEE_CONSUMER_SECRET: ${{ secrets.INSEE_CONSUMER_SECRET }} - CYPRESS_MAILSLURP_API_KEY: ${{ secrets.MAILSLURP_API_KEY }} - SECURE_COOKIES: "False" - ZAMMAD_URL: ${{ secrets.ZAMMAD_URL }} + MONCOMPTEPRO_HOST: http://172.18.0.1:3000 ZAMMAD_TOKEN: ${{ secrets.ZAMMAD_TOKEN }} - MODERATION_TAG: "github-action-e2e-test" - SYMMETRIC_ENCRYPTION_KEY: aTrueRandom32BytesLongBase64EncodedStringAA= - JWKS: '{"keys":[{"crv":"P-256","x":"UtmbpHb1aHibmvEQJ2KlIzNro4tGfyMiBIVmO92YX7Q","y":"YsRG_NMtLOqvA6S9zq5r7M9Y-Cgo4YwKvH3xXyvFE2E","d":"taURynSwshCfxEWs6z2_Xz-ocheg-6ePaU87cjy572Y","kty":"EC","kid":"GCirOyeBc0rlWhcbMnwe9FUadPk6ToJlOq3yvxvkKlE","use":"enc"},{"crv":"P-256","x":"2SSoeci15SnMM6wwxvNwzp_xjVTwgEALOY1NvTBbdqs","y":"Gplus4XyX4dQ6Z0Pwb0UhsmJfx7S5_DCFxpK6yt396Q","d":"TLeCkidQUJG9s6hvHx8QSHNKfqyhcbIXCN7rJ67AjH4","kty":"EC","kid":"TeXJ6Hx4sG9A13LCFlU46-PYGopwwFOsmCTEJcwZvZ8","use":"sig"},{"crv":"Ed25519","x":"NQNM3isoJAeK6HWKEgHifRqFrC-R6ufusnv47BnlWn4","d":"WxFz4Ulx6rLBO5HHHhg86BMc_CtRoCmFn8Gwy-kbaL4","kty":"OKP","kid":"onHSTAw1rfQOz_qWnPTh2SZzrseoqbOOrD1tcxFOaIU","use":"sig"},{"e":"AQAB","n":"5yuakCQKnkzP4tNXYI6qRYX-0pyeuGKS8VKl7S1QNj7bAMjeV2o3xjDgg4qtrUrFrqxSFOfBX5kJR3NEBoYiQpUwl9zPmKNLR0zX0w6VpwDREDS8bpBL_naeiGRdLX_AYxR7jCsDETEXqFm0S1CmfLjgAoazLPDxzGvFaezLEo0rafcLR3MpKIa-INqwCoTiLWUAtXKv-ZcmO7QuzRcVJecFs7WaMQZNMrfSAdj-agdnVOkP2cXnd6xpT2Pcph7I6z2slRkEZ_Oz1BkG-FV_21IlY1U4tE3GigKdSNRSJmuyvdgI4wDb2noZdEStFr8nsOsG63kIYM_Gve-HWiTxmQ","d":"qClmBFjTiJgj2cMXmtvtLSnuVtMr-sFqVzZiEYiXAv7yXT3B0CEqdXf0unvVH2x3JTuhcies2Zf_0gQdhglpPro8YRx1v3l6N2HE1nmTj6reakWSlXNOdMthQ6KOzZxTHUA3J53aW1U0-nhW2TrQAYaTHgNSr-yOWMBFGWrxxomc8h_1OnnXS9wRxoicPshjx7S8huy3YLbWzQphBqzBx5vsPOClfbs0dtxhAY63vXbNDS_sAIVfn1U__f6ilFmzE9odgOydsSwBUtRm2Ir4wY5HhqYGRPOKAUNHLqEsDqwmp_o3RtBQwg937ymbOJvgoa6qkqg_uxtaVSP7RX4EKQ","p":"-X7pv_NpfJvqTTlQwQnaz6eiA_I7v7Jj0l1KtmBRBZz6q6R9qq1BVlP8XeOBO5TX9vQKIooY8fL3QsWf73ZqQmmy9W3C4dAhwbwalvBzZHZT2Wznrurp_bML_8Xx1XhNxTawAb263O3AUz7Rw3g5lI2cafTe4x1dSO8_CHL3eMs","q":"7TJj6aNzkVjyPeCZVHwBXGDWDIT2DxqWRjKrKgqlpWdzEftNce855Wg3Ve4JnNtFkg7Qow4imZVkbK69ChIStv9s1KDX_sGRCyfN17d0jlkyGUnFB2RSBB42t7SmcC4ZhHjxdAdopOG_o1r5vEwDo-0hKWikP9uyYmWyhfY3hqs","dp":"g0dYT3wQ4VRY8NFbwHci_2jBQzpOXgvLooEcMuJzP3TeITqoNQp8-qOuguiWs3caPAMk4g-wGH8zw5qhEStJtjBPzfw3MwKFAJ-tjgZvcUkhzaIUNmG9RZTUl3zcRurKYR7pdcETdfRT4nmHfkbgZV4uE0KZlP96ekoI7LUxqgk","dq":"1Gpl81t_KVDgTu2OIoySo2nNBpUjzc7feKnzgsjaItALyrSkXD4COSElPPzY-vGa0fwWd483CRcyQeoSPKyGuf7wNVJ9XBV4kObqfh46cSgLp33axo3erPVpxwYubxO5olq00FW6Lr5D4kSclTX1pJ29LtoZDV7v1xJ_11vxydU","qi":"4RyTKy-QINtOUezaLEymzNBIG3uZv_IKvGPhEYi4wRNP_XxIK9NwfgUFRAhxhpxSpEjco_eNuN3I6XBF7bXb4-Bnnye1mBm3sBTXx2_09r8zt9Uvg3cdh0pYem3hU1ANMRmr3rfjtain4DTskIJ2CxjvGIMyh3VXLyRyfzIGJig","kty":"RSA","kid":"kddKa_IDmU8a5RhJaIzwzpJcFe4qT-GtNFcG2AWclZ4","use":"enc"},{"e":"AQAB","n":"6btLS-c06m18O5BlLvJA4HJNVI7WauBg5JVoy1cHTdfjTJ-oSts5uetXKF_NlNcLuq-zIKZuu9wea5m2E3lJ-vtCSAtRaJgZY41KAOjIsrHQstVuc9di4zjgcA6zwEXhqwu48gklGKpWNk7wnfMCO6mNoRs_-8-CnK6lTFeJFzfoCDmS6dYbefmPeFW4qziEZzEv5DPGAcUsXXZhbOku_E8gILRVMkBwHpvY_G3jngE1EWXctiM9tYqhgvxyJC9QyPCVpgfAvDlslMpuQTxBviC9PsrcBaQ5PyAP_xNN3X8LB-STpz7jNpNquKL5Ls0Hv9R3fDCeHvcYoVsgDirwfQ","d":"L0a7DDdP9LsAjeu_C6fkh4GXMqtRo3yPHK077SVFTPGGAFGq8Lk3C-wWTQxTwO9eZ_xx9wCzFTyIyqrksTuvQxzfY0MmzEk3mXNSrKxpK_vbgtC47qV6UwuGGiRfJ1z7MGXGmu5OmpaZqZJ-CPTGVtsM0rF4V665dIe-15o9GHzLX80mhw8ySd0qqBIbdIWlK2zaSRPGL08mP02t_XnHdCCaWfRE_erO6zsEhR8ePvbmQqI7GRBull59seXefo1VDP30lEwHwH05Ju24_ZddhfuP2Y9jkZnNKqpSHF3EZzT6Vh3ggAaLjQzRWJvd1_0Zit7CD06o6L1aLV7nDnTYAQ","p":"_u6v29kLICnGvbF44-sF5cFisrIPyXcj8laaNx6uP5ax9ZOPD_THdxTFU3YWLUErzi4MQJQPLoJacphQJKnG78b0PX_733--r-vpqUqfbzAlIssS8N4CFj6_YEMFR8W70laXJYJdx7IsnGOAlxAUZur5ugaaR0zDzlMTQVuR30E","q":"6rXguomnHNGFslAeHWPxPDaHxihx3eRJ-8t1KyvvwT43YfdPn2xxdq5-TyO0MMKznvDIHk9HDMBMr8JH32Q9qx75Ec81NOLGkBWqO9x-8dBlKn95jr8-qkD3iXHmJiHHNWNurHJM4G4lo73IL_0jgo0CCpcZWP7iH5y-b_mXPj0","dp":"Cyf-4iwZZIrve5WsqKy8UVWpMBDCyBpCpHRNw2PAVGAP4aNXe2dG41sxV3mvdsOHWzqApsLT90EVHDa2KySS5CNcxOQ47Yr1mVVFoHb3izIcLe2dIpVUmgyc62WDcaShl47ahnWyDO8rLJzeH75AZlCaJR3s2nnth7Xy_cU4GQE","dq":"SvJe21HfQe2JsqGwrBPg0ShcfKMnkQI3uaaDOJDkEyHJz4eILlETfiFEBgNRo4xYjPU4Aa2w81poYms4RhYdNwpB4DT5OXT8kL_KRykmhBLWaxafezyIRxdNs97h7eU1Vk_05C3vbG7fqASO6vv7HdHnB_ityGRDUnLbwKfDasU","qi":"QomRmnqrW3k8cV8MIefgmKZMGDGHRC44bFk9B20YR15_XHcMimi7o9rjUE7BY-RO30RsPUiQqB_vkpKvQZILOuPmIQhElcgmguKqPNwprVMgx-krUQ1Khuh3tgzxhBgazXzPcKmx8JBbCopP_UwNiCpPcdm74VFcZ-OswmqQU08","kty":"RSA","kid":"lFWqEBQbScnjO5OzUbvkPp0rmjGy17bmzZOqUbWkQMo","use":"sig"}]}' jobs: test: strategy: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a169a8c4..6f1ee492 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,6 +6,11 @@ on: - "**" - "!master" +env: + DATABASE_URL: postgres://moncomptepro:moncomptepro@127.0.0.1:5432/moncomptepro + INSEE_CONSUMER_KEY: ${{ secrets.INSEE_CONSUMER_KEY }} + INSEE_CONSUMER_SECRET: ${{ secrets.INSEE_CONSUMER_SECRET }} + jobs: test: runs-on: ubuntu-22.04 diff --git a/cypress/README.md b/cypress/README.md index 9aae03ba..8b08af6c 100644 --- a/cypress/README.md +++ b/cypress/README.md @@ -4,15 +4,14 @@ ### Setup env vars -You will need to set `BREVO_API_KEY`, `DEBOUNCE_API_KEY`, `ZAMMAD_URL`, `ZAMMAD_TOKEN` and `CYPRESS_MAILSLURP_API_KEY`. +You will need to set `BREVO_API_KEY`, `CYPRESS_MAILSLURP_API_KEY`, `DEBOUNCE_API_KEY`, and `ZAMMAD_TOKEN`. Ask a teammate for them and put the values in your `.env`. -Also in your .env put the following values : +Also in your `.env` put the following values : ```dotenv DO_NOT_SEND_MAIL=False -DO_NOT_RATE_LIMIT=True ``` ### Load test fixtures in the database diff --git a/docker-compose.yml b/docker-compose.yml index c86d80dc..6bc57a38 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,9 +4,9 @@ services: ports: - "5432:5432" environment: - POSTGRES_USER: username - POSTGRES_PASSWORD: password - POSTGRES_DB: dbname + POSTGRES_USER: moncomptepro + POSTGRES_PASSWORD: moncomptepro + POSTGRES_DB: moncomptepro volumes: - db-data:/var/lib/postgresql/data diff --git a/installation.md b/installation.md index be1bac96..6b051ee4 100644 --- a/installation.md +++ b/installation.md @@ -22,8 +22,6 @@ This guide provides steps to run the MonComptePro Node.js application locally wh 1. **Install Node.js Dependencies**: - > If you don’t want to run end-to-end tests locally, you can prevent the installation script to download the (somewhat big) cypress binary by running `CYPRESS_INSTALL_BINARY=0 npm install` instead of the following command. - Inside the project’s root directory, run: ```bash @@ -38,14 +36,11 @@ This guide provides steps to run the MonComptePro Node.js application locally wh This will create a local copy of the `.env` file containing the environnement variables to run MonComptePro. - We set the defaults in `.env` (all environments) and, following the `NODE_ENV` environment variable, the `.env.development` (development environment), `.env.production` (production environment) or `.env.test` (test environment). - We recommend to use the `.env*.local` to override the defaults variables. `.env..local` will take precedence over `.env.local` and `.env.`. - 3. **Get your own INSEE api credential**: or use the one of your teammates. Fetch them at https://api.gouv.fr/les-api/sirene_v3. - Then fill your local .env file with them. + Then fill your `.env` file with them. 4. **Database Initialization**: The database will be automatically initialized with data from `scripts/fixtures.sql`. @@ -97,3 +92,19 @@ To connect to these databases, use the following commands: docker compose exec db psql postgres://username:password@db:5432/dbname docker compose exec redis redis-cli -h redis -p 6379 ``` + +## Configuring different environment variables + +The default environment variables are defined in the `.env` file, which applies to all environments. Based on the `NODE_ENV` variable, the corresponding file is selected: `.env.development` for the development environment, `.env.production` for production, or `.env.test` for testing. + +To customize or override these defaults, we recommend using the `.env*.local` files. The file `.env..local` will have higher priority over both `.env.local` and `.env.`. + +## Skipping Cypress Binary Installation for Local Setup + +If you prefer not to run end-to-end tests locally and want to avoid downloading the large Cypress binary, you can prevent it during the installation process. To do this, run the following command: + +```bash +CYPRESS_INSTALL_BINARY=0 npm install +``` + +This command ensures that the Cypress binary is not downloaded, saving time and disk space during the installation process. diff --git a/src/config/default-jwks.ts b/src/config/default-jwks.ts new file mode 100644 index 00000000..f2f75a50 --- /dev/null +++ b/src/config/default-jwks.ts @@ -0,0 +1,56 @@ +export const defaultJWKS = { + keys: [ + { + crv: "P-256", + d: "taURynSwshCfxEWs6z2_Xz-ocheg-6ePaU87cjy572Y", + kid: "GCirOyeBc0rlWhcbMnwe9FUadPk6ToJlOq3yvxvkKlE", + kty: "EC", + use: "enc", + x: "UtmbpHb1aHibmvEQJ2KlIzNro4tGfyMiBIVmO92YX7Q", + y: "YsRG_NMtLOqvA6S9zq5r7M9Y-Cgo4YwKvH3xXyvFE2E", + }, + { + crv: "P-256", + d: "TLeCkidQUJG9s6hvHx8QSHNKfqyhcbIXCN7rJ67AjH4", + kid: "TeXJ6Hx4sG9A13LCFlU46-PYGopwwFOsmCTEJcwZvZ8", + kty: "EC", + use: "sig", + x: "2SSoeci15SnMM6wwxvNwzp_xjVTwgEALOY1NvTBbdqs", + y: "Gplus4XyX4dQ6Z0Pwb0UhsmJfx7S5_DCFxpK6yt396Q", + }, + { + crv: "Ed25519", + d: "WxFz4Ulx6rLBO5HHHhg86BMc_CtRoCmFn8Gwy-kbaL4", + kid: "onHSTAw1rfQOz_qWnPTh2SZzrseoqbOOrD1tcxFOaIU", + kty: "OKP", + use: "sig", + x: "NQNM3isoJAeK6HWKEgHifRqFrC-R6ufusnv47BnlWn4", + }, + { + d: "qClmBFjTiJgj2cMXmtvtLSnuVtMr-sFqVzZiEYiXAv7yXT3B0CEqdXf0unvVH2x3JTuhcies2Zf_0gQdhglpPro8YRx1v3l6N2HE1nmTj6reakWSlXNOdMthQ6KOzZxTHUA3J53aW1U0-nhW2TrQAYaTHgNSr-yOWMBFGWrxxomc8h_1OnnXS9wRxoicPshjx7S8huy3YLbWzQphBqzBx5vsPOClfbs0dtxhAY63vXbNDS_sAIVfn1U__f6ilFmzE9odgOydsSwBUtRm2Ir4wY5HhqYGRPOKAUNHLqEsDqwmp_o3RtBQwg937ymbOJvgoa6qkqg_uxtaVSP7RX4EKQ", + dp: "g0dYT3wQ4VRY8NFbwHci_2jBQzpOXgvLooEcMuJzP3TeITqoNQp8-qOuguiWs3caPAMk4g-wGH8zw5qhEStJtjBPzfw3MwKFAJ-tjgZvcUkhzaIUNmG9RZTUl3zcRurKYR7pdcETdfRT4nmHfkbgZV4uE0KZlP96ekoI7LUxqgk", + dq: "1Gpl81t_KVDgTu2OIoySo2nNBpUjzc7feKnzgsjaItALyrSkXD4COSElPPzY-vGa0fwWd483CRcyQeoSPKyGuf7wNVJ9XBV4kObqfh46cSgLp33axo3erPVpxwYubxO5olq00FW6Lr5D4kSclTX1pJ29LtoZDV7v1xJ_11vxydU", + e: "AQAB", + kid: "kddKa_IDmU8a5RhJaIzwzpJcFe4qT-GtNFcG2AWclZ4", + kty: "RSA", + n: "5yuakCQKnkzP4tNXYI6qRYX-0pyeuGKS8VKl7S1QNj7bAMjeV2o3xjDgg4qtrUrFrqxSFOfBX5kJR3NEBoYiQpUwl9zPmKNLR0zX0w6VpwDREDS8bpBL_naeiGRdLX_AYxR7jCsDETEXqFm0S1CmfLjgAoazLPDxzGvFaezLEo0rafcLR3MpKIa-INqwCoTiLWUAtXKv-ZcmO7QuzRcVJecFs7WaMQZNMrfSAdj-agdnVOkP2cXnd6xpT2Pcph7I6z2slRkEZ_Oz1BkG-FV_21IlY1U4tE3GigKdSNRSJmuyvdgI4wDb2noZdEStFr8nsOsG63kIYM_Gve-HWiTxmQ", + p: "-X7pv_NpfJvqTTlQwQnaz6eiA_I7v7Jj0l1KtmBRBZz6q6R9qq1BVlP8XeOBO5TX9vQKIooY8fL3QsWf73ZqQmmy9W3C4dAhwbwalvBzZHZT2Wznrurp_bML_8Xx1XhNxTawAb263O3AUz7Rw3g5lI2cafTe4x1dSO8_CHL3eMs", + q: "7TJj6aNzkVjyPeCZVHwBXGDWDIT2DxqWRjKrKgqlpWdzEftNce855Wg3Ve4JnNtFkg7Qow4imZVkbK69ChIStv9s1KDX_sGRCyfN17d0jlkyGUnFB2RSBB42t7SmcC4ZhHjxdAdopOG_o1r5vEwDo-0hKWikP9uyYmWyhfY3hqs", + qi: "4RyTKy-QINtOUezaLEymzNBIG3uZv_IKvGPhEYi4wRNP_XxIK9NwfgUFRAhxhpxSpEjco_eNuN3I6XBF7bXb4-Bnnye1mBm3sBTXx2_09r8zt9Uvg3cdh0pYem3hU1ANMRmr3rfjtain4DTskIJ2CxjvGIMyh3VXLyRyfzIGJig", + use: "enc", + }, + { + d: "L0a7DDdP9LsAjeu_C6fkh4GXMqtRo3yPHK077SVFTPGGAFGq8Lk3C-wWTQxTwO9eZ_xx9wCzFTyIyqrksTuvQxzfY0MmzEk3mXNSrKxpK_vbgtC47qV6UwuGGiRfJ1z7MGXGmu5OmpaZqZJ-CPTGVtsM0rF4V665dIe-15o9GHzLX80mhw8ySd0qqBIbdIWlK2zaSRPGL08mP02t_XnHdCCaWfRE_erO6zsEhR8ePvbmQqI7GRBull59seXefo1VDP30lEwHwH05Ju24_ZddhfuP2Y9jkZnNKqpSHF3EZzT6Vh3ggAaLjQzRWJvd1_0Zit7CD06o6L1aLV7nDnTYAQ", + dp: "Cyf-4iwZZIrve5WsqKy8UVWpMBDCyBpCpHRNw2PAVGAP4aNXe2dG41sxV3mvdsOHWzqApsLT90EVHDa2KySS5CNcxOQ47Yr1mVVFoHb3izIcLe2dIpVUmgyc62WDcaShl47ahnWyDO8rLJzeH75AZlCaJR3s2nnth7Xy_cU4GQE", + dq: "SvJe21HfQe2JsqGwrBPg0ShcfKMnkQI3uaaDOJDkEyHJz4eILlETfiFEBgNRo4xYjPU4Aa2w81poYms4RhYdNwpB4DT5OXT8kL_KRykmhBLWaxafezyIRxdNs97h7eU1Vk_05C3vbG7fqASO6vv7HdHnB_ityGRDUnLbwKfDasU", + e: "AQAB", + kid: "lFWqEBQbScnjO5OzUbvkPp0rmjGy17bmzZOqUbWkQMo", + kty: "RSA", + n: "6btLS-c06m18O5BlLvJA4HJNVI7WauBg5JVoy1cHTdfjTJ-oSts5uetXKF_NlNcLuq-zIKZuu9wea5m2E3lJ-vtCSAtRaJgZY41KAOjIsrHQstVuc9di4zjgcA6zwEXhqwu48gklGKpWNk7wnfMCO6mNoRs_-8-CnK6lTFeJFzfoCDmS6dYbefmPeFW4qziEZzEv5DPGAcUsXXZhbOku_E8gILRVMkBwHpvY_G3jngE1EWXctiM9tYqhgvxyJC9QyPCVpgfAvDlslMpuQTxBviC9PsrcBaQ5PyAP_xNN3X8LB-STpz7jNpNquKL5Ls0Hv9R3fDCeHvcYoVsgDirwfQ", + p: "_u6v29kLICnGvbF44-sF5cFisrIPyXcj8laaNx6uP5ax9ZOPD_THdxTFU3YWLUErzi4MQJQPLoJacphQJKnG78b0PX_733--r-vpqUqfbzAlIssS8N4CFj6_YEMFR8W70laXJYJdx7IsnGOAlxAUZur5ugaaR0zDzlMTQVuR30E", + q: "6rXguomnHNGFslAeHWPxPDaHxihx3eRJ-8t1KyvvwT43YfdPn2xxdq5-TyO0MMKznvDIHk9HDMBMr8JH32Q9qx75Ec81NOLGkBWqO9x-8dBlKn95jr8-qkD3iXHmJiHHNWNurHJM4G4lo73IL_0jgo0CCpcZWP7iH5y-b_mXPj0", + qi: "QomRmnqrW3k8cV8MIefgmKZMGDGHRC44bFk9B20YR15_XHcMimi7o9rjUE7BY-RO30RsPUiQqB_vkpKvQZILOuPmIQhElcgmguKqPNwprVMgx-krUQ1Khuh3tgzxhBgazXzPcKmx8JBbCopP_UwNiCpPcdm74VFcZ-OswmqQU08", + use: "sig", + }, + ], +}; diff --git a/src/config/env.ts b/src/config/env.ts index a1f2f6d6..20dadf78 100644 --- a/src/config/env.ts +++ b/src/config/env.ts @@ -25,6 +25,7 @@ const parsedEnv = envSchema.safeParse(process.env, { if (!parsedEnv.success) throw fromZodError(parsedEnv.error, {}); export const { + ACCESS_LOG_PATH, API_AUTH_PASSWORD, API_AUTH_USERNAME, BREVO_API_KEY, @@ -37,6 +38,7 @@ export const { CRISP_RESOLVE_DELAY, CRISP_USER_NICKNAME, CRISP_WEBSITE_ID, + DATABASE_URL, DEBOUNCE_API_KEY, DEPLOY_ENV, DISABLE_SECURITY_RESPONSE_HEADERS, @@ -49,12 +51,15 @@ export const { EMAIL_DELIVERABILITY_WHITELIST, ENABLE_FIXED_ACR, HTTP_CLIENT_TIMEOUT, + INSEE_CONSUMER_KEY, + INSEE_CONSUMER_SECRET, JWKS, LOG_LEVEL, MAGIC_LINK_TOKEN_EXPIRATION_DURATION_IN_MINUTES, MAX_DURATION_BETWEEN_TWO_EMAIL_ADDRESS_VERIFICATION_IN_MINUTES, MAX_SUGGESTED_ORGANIZATIONS, MODERATION_TAG, + MONCOMPTEPRO_HOST, MONCOMPTEPRO_LABEL, NODE_ENV, PORT, @@ -73,12 +78,4 @@ export const { ZAMMAD_URL, } = parsedEnv.data; -export const { - MONCOMPTEPRO_HOST = `http://localhost:${PORT}`, - ACCESS_LOG_PATH, - DATABASE_URL, - INSEE_CONSUMER_KEY, - INSEE_CONSUMER_SECRET, -} = process.env; - export const MONCOMPTEPRO_IDENTIFIER = new URL(MONCOMPTEPRO_HOST).hostname; diff --git a/src/config/env.zod.ts b/src/config/env.zod.ts index 335ba646..535baa6a 100644 --- a/src/config/env.zod.ts +++ b/src/config/env.zod.ts @@ -1,13 +1,16 @@ import { z, type ZodTypeAny } from "zod"; +import { defaultJWKS } from "./default-jwks"; -// +export const emailEnvSchema = z.object({ + BREVO_API_KEY: z.string().optional(), + DO_NOT_SEND_MAIL: zodTrueFalseBoolean().default("True"), + ZAMMAD_TOKEN: z.string().optional(), + ZAMMAD_URL: z.string().url().default("https://support.etalab.gouv.fr"), +}); -export const apiEnvSchema = z.object({ +export const connectorEnvSchema = z.object({ API_AUTH_PASSWORD: z.string().default("admin"), API_AUTH_USERNAME: z.string().default("admin"), -}); - -export const crispEnvSchema = z.object({ CRISP_BASE_URL: z.string().url().default("https://api.crisp.chat"), CRISP_IDENTIFIER: z.string().default(""), CRISP_KEY: z.string().default(""), @@ -15,109 +18,113 @@ export const crispEnvSchema = z.object({ CRISP_RESOLVE_DELAY: z.coerce.number().int().nonnegative().default(1_000), // 1 second CRISP_USER_NICKNAME: z.string().default("MonComptePro"), CRISP_WEBSITE_ID: z.string().default(""), + DATABASE_URL: z.string().url(), + DEBOUNCE_API_KEY: z.string().optional(), + INSEE_CONSUMER_KEY: z.string(), + INSEE_CONSUMER_SECRET: z.string(), + REDIS_URL: z.string().url().default("redis://:@127.0.0.1:6379"), + SENTRY_DSN: z.string().default(""), }); -// +export const featureTogglesEnvSchema = z.object({ + CONSIDER_ALL_EMAIL_DOMAINS_AS_FREE: zodTrueFalseBoolean().default("False"), + CONSIDER_ALL_EMAIL_DOMAINS_AS_NON_FREE: zodTrueFalseBoolean().default("True"), + DISABLE_SECURITY_RESPONSE_HEADERS: zodTrueFalseBoolean().default("True"), + DISPLAY_TEST_ENV_WARNING: zodTrueFalseBoolean().default("False"), + DO_NOT_AUTHENTICATE_BROWSER: zodTrueFalseBoolean().default("True"), + DO_NOT_CHECK_EMAIL_DELIVERABILITY: zodTrueFalseBoolean().default("True"), + DO_NOT_RATE_LIMIT: zodTrueFalseBoolean().default("True"), + DO_NOT_USE_ANNUAIRE_EMAILS: zodTrueFalseBoolean().default("True"), + SECURE_COOKIES: zodTrueFalseBoolean().default("False"), + ENABLE_FIXED_ACR: zodTrueFalseBoolean().default("False"), +}); -export const envSchema = z - .object({ - ACCESS_LOG_PATH: z.string().optional(), - BREVO_API_KEY: z.string().default(""), - CONSIDER_ALL_EMAIL_DOMAINS_AS_FREE: zodTrueFalseBoolean().default("False"), - CONSIDER_ALL_EMAIL_DOMAINS_AS_NON_FREE: - zodTrueFalseBoolean().default("False"), - DATABASE_URL: z.string().url(), - DEBOUNCE_API_KEY: z.string().optional(), - DEPLOY_ENV: z.enum(["preview", "production", "sandbox"]).default("preview"), - DISABLE_SECURITY_RESPONSE_HEADERS: zodTrueFalseBoolean().default("False"), - DISPLAY_TEST_ENV_WARNING: zodTrueFalseBoolean().default("False"), - DO_NOT_AUTHENTICATE_BROWSER: zodTrueFalseBoolean().default("False"), - DO_NOT_CHECK_EMAIL_DELIVERABILITY: zodTrueFalseBoolean().default("False"), - DO_NOT_RATE_LIMIT: zodTrueFalseBoolean().default("False"), - DO_NOT_SEND_MAIL: zodTrueFalseBoolean().default("False"), - DO_NOT_USE_ANNUAIRE_EMAILS: zodTrueFalseBoolean().default("False"), - EMAIL_DELIVERABILITY_WHITELIST: zCoerceArray(z.string()).default(""), - ENABLE_FIXED_ACR: zodTrueFalseBoolean().default("False"), - HTTP_CLIENT_TIMEOUT: z.coerce - .number() - .int() - .nonnegative() - .default(55 * 1_000), // 55 seconds in milliseconds; - INSEE_CONSUMER_KEY: z.string(), - INSEE_CONSUMER_SECRET: z.string(), - JWKS: zCoerceJson().pipe(z.object({ keys: z.array(z.any()) })), - LOG_LEVEL: z - .enum(["trace", "debug", "info", "warn", "error", "fatal"]) - .default("info"), - MAGIC_LINK_TOKEN_EXPIRATION_DURATION_IN_MINUTES: z.coerce - .number() - .int() - .nonnegative() - .default(60), // 1 hour in minutes - MAX_DURATION_BETWEEN_TWO_EMAIL_ADDRESS_VERIFICATION_IN_MINUTES: z.coerce - .number() - .int() - .nonnegative() - .default(3 * 30 * 24 * 60), // 3 months in minutes - MAX_SUGGESTED_ORGANIZATIONS: z.coerce - .number() - .int() - .nonnegative() - .default(3), - MODERATION_TAG: z.string().default("moderation"), - MONCOMPTEPRO_HOST: z.string().url().default("http://localhost:3000"), - MONCOMPTEPRO_LABEL: z.string().default("MonComptePro"), - NODE_ENV: z - .enum(["production", "development", "test"]) - .default("development"), - PORT: z.coerce.number().int().nonnegative().default(3000), - RECENT_LOGIN_INTERVAL_IN_SECONDS: z.coerce - .number() - .int() - .nonnegative() - .default(15 * 60), // 15 minutes - REDIS_URL: z.string().url().default("redis://:@127.0.0.1:6379"), - RESET_PASSWORD_TOKEN_EXPIRATION_DURATION_IN_MINUTES: z.coerce - .number() - .int() - .nonnegative() - .default(60), // 1 hour in minutes - SECURE_COOKIES: zodTrueFalseBoolean().default("True"), - SENTRY_DSN: z.string().default(""), - SESSION_COOKIE_SECRET: zCoerceArray(z.string()).default(""), - SESSION_MAX_AGE_IN_SECONDS: z.coerce - .number() - .int() - .nonnegative() - .default(1 * 24 * 60 * 60), // 1 day in seconds - SYMMETRIC_ENCRYPTION_KEY: z.string().base64({ +export const secretEnvSchema = z.object({ + SYMMETRIC_ENCRYPTION_KEY: z + .string() + .base64({ message: "The SYMMETRIC_ENCRYPTION_KEY environment variable should be 32 bytes long! Use crypto.randomBytes(32).toString('base64') to generate one.", - }), - TEST_CONTACT_EMAIL: z.string().default("mairie@yopmail.com"), - TRUSTED_BROWSER_COOKIE_MAX_AGE_IN_SECONDS: z.coerce - .number() - .int() - .nonnegative() - .default(3 * 30 * 24 * 60 * 60), // 3 months in seconds - VERIFY_EMAIL_TOKEN_EXPIRATION_DURATION_IN_MINUTES: z.coerce - .number() - .int() - .nonnegative() - .default(60), // 1 hour in minutes - ZAMMAD_TOKEN: z.string(), - ZAMMAD_URL: z.string().url(), - }) - .merge(apiEnvSchema) - .merge(crispEnvSchema); + }) + .default("aTrueRandom32BytesLongBase64EncodedStringAA="), + SESSION_COOKIE_SECRET: zCoerceArray(z.string()).default("moncompteprosecret"), + JWKS: zCoerceJson() + .default(JSON.stringify(defaultJWKS)) + .pipe(z.object({ keys: z.array(z.any()) })), +}); + +export const paramsEnvSchema = z.object({ + ACCESS_LOG_PATH: z.string().optional(), + DEPLOY_ENV: z.enum(["preview", "production", "sandbox"]).default("preview"), + EMAIL_DELIVERABILITY_WHITELIST: zCoerceArray(z.string()).default(""), + HTTP_CLIENT_TIMEOUT: z.coerce + .number() + .int() + .nonnegative() + .default(55 * 1_000), // 55 seconds in milliseconds; + LOG_LEVEL: z + .enum(["trace", "debug", "info", "warn", "error", "fatal"]) + .default("info"), + MAGIC_LINK_TOKEN_EXPIRATION_DURATION_IN_MINUTES: z.coerce + .number() + .int() + .nonnegative() + .default(60), // 1 hour in minutes + MAX_DURATION_BETWEEN_TWO_EMAIL_ADDRESS_VERIFICATION_IN_MINUTES: z.coerce + .number() + .int() + .nonnegative() + .default(3 * 30 * 24 * 60), // 3 months in minutes + MAX_SUGGESTED_ORGANIZATIONS: z.coerce.number().int().nonnegative().default(3), + MODERATION_TAG: z.string().default("github-action-e2e-test"), + MONCOMPTEPRO_HOST: z.string().url().default("http://localhost:3000"), + MONCOMPTEPRO_LABEL: z.string().default("MonComptePro"), + NODE_ENV: z + .enum(["production", "development", "test"]) + .default("development"), + PORT: z.coerce.number().int().nonnegative().default(3000), + RECENT_LOGIN_INTERVAL_IN_SECONDS: z.coerce + .number() + .int() + .nonnegative() + .default(15 * 60), // 15 minutes + RESET_PASSWORD_TOKEN_EXPIRATION_DURATION_IN_MINUTES: z.coerce + .number() + .int() + .nonnegative() + .default(60), // 1 hour in minutes + SESSION_MAX_AGE_IN_SECONDS: z.coerce + .number() + .int() + .nonnegative() + .default(1 * 24 * 60 * 60), // 1 day in seconds + TEST_CONTACT_EMAIL: z.string().default("mairie@yopmail.com"), + TRUSTED_BROWSER_COOKIE_MAX_AGE_IN_SECONDS: z.coerce + .number() + .int() + .nonnegative() + .default(3 * 30 * 24 * 60 * 60), // 3 months in seconds + VERIFY_EMAIL_TOKEN_EXPIRATION_DURATION_IN_MINUTES: z.coerce + .number() + .int() + .nonnegative() + .default(60), // 1 hour in minutes +}); + +export const envSchema = z + .object({}) + .merge(emailEnvSchema) + .merge(connectorEnvSchema) + .merge(featureTogglesEnvSchema) + .merge(secretEnvSchema) + .merge(paramsEnvSchema); // + export function zodTrueFalseBoolean() { return z.enum(["True", "False"]).transform((v: string) => v === "True"); } -// - export function zCoerceArray(schema: T) { return z .string() diff --git a/test/env.zod.test.ts b/test/env.zod.test.ts index c2e22761..3c7b9b6f 100644 --- a/test/env.zod.test.ts +++ b/test/env.zod.test.ts @@ -1,22 +1,25 @@ // import { expect } from "chai"; -import { config } from "dotenv"; import { test } from "mocha"; +import { defaultJWKS } from "../src/config/default-jwks"; import { envSchema } from "../src/config/env.zod"; // -test("default sample env", () => { - const sample_env = {}; - config({ path: ".env.sample", processEnv: sample_env }); +test("default sample env with configured INSEE secrets", () => { + const sample_env = { + DATABASE_URL: + "postgres://moncomptepro:moncomptepro@127.0.0.1:5432/moncomptepro", + INSEE_CONSUMER_KEY: "fakesecret", + INSEE_CONSUMER_SECRET: "fakesecret", + }; const env = envSchema.parse(sample_env); expect(env).to.deep.equal({ API_AUTH_PASSWORD: "admin", API_AUTH_USERNAME: "admin", - BREVO_API_KEY: "____________________________", CONSIDER_ALL_EMAIL_DOMAINS_AS_FREE: false, CONSIDER_ALL_EMAIL_DOMAINS_AS_NON_FREE: true, CRISP_BASE_URL: "https://api.crisp.chat", @@ -26,27 +29,27 @@ test("default sample env", () => { CRISP_RESOLVE_DELAY: 1000, CRISP_USER_NICKNAME: "MonComptePro", CRISP_WEBSITE_ID: "", - DATABASE_URL: "postgres://username:password@localhost:5432/dbname", - DEBOUNCE_API_KEY: "_____________", + DATABASE_URL: + "postgres://moncomptepro:moncomptepro@127.0.0.1:5432/moncomptepro", DEPLOY_ENV: "preview", DISABLE_SECURITY_RESPONSE_HEADERS: true, DISPLAY_TEST_ENV_WARNING: false, DO_NOT_AUTHENTICATE_BROWSER: true, DO_NOT_CHECK_EMAIL_DELIVERABILITY: true, - DO_NOT_RATE_LIMIT: false, + DO_NOT_RATE_LIMIT: true, DO_NOT_SEND_MAIL: true, DO_NOT_USE_ANNUAIRE_EMAILS: true, EMAIL_DELIVERABILITY_WHITELIST: [], ENABLE_FIXED_ACR: false, HTTP_CLIENT_TIMEOUT: 55000, - INSEE_CONSUMER_KEY: "____________________________", - INSEE_CONSUMER_SECRET: "____________________________", - JWKS, + INSEE_CONSUMER_KEY: "fakesecret", + INSEE_CONSUMER_SECRET: "fakesecret", + JWKS: defaultJWKS, LOG_LEVEL: "info", MAGIC_LINK_TOKEN_EXPIRATION_DURATION_IN_MINUTES: 60, MAX_DURATION_BETWEEN_TWO_EMAIL_ADDRESS_VERIFICATION_IN_MINUTES: 129600, MAX_SUGGESTED_ORGANIZATIONS: 3, - MODERATION_TAG: "moderation", + MODERATION_TAG: "github-action-e2e-test", MONCOMPTEPRO_HOST: "http://localhost:3000", MONCOMPTEPRO_LABEL: "MonComptePro", NODE_ENV: "development", @@ -62,66 +65,6 @@ test("default sample env", () => { TEST_CONTACT_EMAIL: "mairie@yopmail.com", TRUSTED_BROWSER_COOKIE_MAX_AGE_IN_SECONDS: 7776000, VERIFY_EMAIL_TOKEN_EXPIRATION_DURATION_IN_MINUTES: 60, - ZAMMAD_TOKEN: "___________________________________________________________", ZAMMAD_URL: "https://support.etalab.gouv.fr", }); }); - -// - -const JWKS = { - keys: [ - { - crv: "P-256", - d: "taURynSwshCfxEWs6z2_Xz-ocheg-6ePaU87cjy572Y", - kid: "GCirOyeBc0rlWhcbMnwe9FUadPk6ToJlOq3yvxvkKlE", - kty: "EC", - use: "enc", - x: "UtmbpHb1aHibmvEQJ2KlIzNro4tGfyMiBIVmO92YX7Q", - y: "YsRG_NMtLOqvA6S9zq5r7M9Y-Cgo4YwKvH3xXyvFE2E", - }, - { - crv: "P-256", - d: "TLeCkidQUJG9s6hvHx8QSHNKfqyhcbIXCN7rJ67AjH4", - kid: "TeXJ6Hx4sG9A13LCFlU46-PYGopwwFOsmCTEJcwZvZ8", - kty: "EC", - use: "sig", - x: "2SSoeci15SnMM6wwxvNwzp_xjVTwgEALOY1NvTBbdqs", - y: "Gplus4XyX4dQ6Z0Pwb0UhsmJfx7S5_DCFxpK6yt396Q", - }, - { - crv: "Ed25519", - d: "WxFz4Ulx6rLBO5HHHhg86BMc_CtRoCmFn8Gwy-kbaL4", - kid: "onHSTAw1rfQOz_qWnPTh2SZzrseoqbOOrD1tcxFOaIU", - kty: "OKP", - use: "sig", - x: "NQNM3isoJAeK6HWKEgHifRqFrC-R6ufusnv47BnlWn4", - }, - { - d: "qClmBFjTiJgj2cMXmtvtLSnuVtMr-sFqVzZiEYiXAv7yXT3B0CEqdXf0unvVH2x3JTuhcies2Zf_0gQdhglpPro8YRx1v3l6N2HE1nmTj6reakWSlXNOdMthQ6KOzZxTHUA3J53aW1U0-nhW2TrQAYaTHgNSr-yOWMBFGWrxxomc8h_1OnnXS9wRxoicPshjx7S8huy3YLbWzQphBqzBx5vsPOClfbs0dtxhAY63vXbNDS_sAIVfn1U__f6ilFmzE9odgOydsSwBUtRm2Ir4wY5HhqYGRPOKAUNHLqEsDqwmp_o3RtBQwg937ymbOJvgoa6qkqg_uxtaVSP7RX4EKQ", - dp: "g0dYT3wQ4VRY8NFbwHci_2jBQzpOXgvLooEcMuJzP3TeITqoNQp8-qOuguiWs3caPAMk4g-wGH8zw5qhEStJtjBPzfw3MwKFAJ-tjgZvcUkhzaIUNmG9RZTUl3zcRurKYR7pdcETdfRT4nmHfkbgZV4uE0KZlP96ekoI7LUxqgk", - dq: "1Gpl81t_KVDgTu2OIoySo2nNBpUjzc7feKnzgsjaItALyrSkXD4COSElPPzY-vGa0fwWd483CRcyQeoSPKyGuf7wNVJ9XBV4kObqfh46cSgLp33axo3erPVpxwYubxO5olq00FW6Lr5D4kSclTX1pJ29LtoZDV7v1xJ_11vxydU", - e: "AQAB", - kid: "kddKa_IDmU8a5RhJaIzwzpJcFe4qT-GtNFcG2AWclZ4", - kty: "RSA", - n: "5yuakCQKnkzP4tNXYI6qRYX-0pyeuGKS8VKl7S1QNj7bAMjeV2o3xjDgg4qtrUrFrqxSFOfBX5kJR3NEBoYiQpUwl9zPmKNLR0zX0w6VpwDREDS8bpBL_naeiGRdLX_AYxR7jCsDETEXqFm0S1CmfLjgAoazLPDxzGvFaezLEo0rafcLR3MpKIa-INqwCoTiLWUAtXKv-ZcmO7QuzRcVJecFs7WaMQZNMrfSAdj-agdnVOkP2cXnd6xpT2Pcph7I6z2slRkEZ_Oz1BkG-FV_21IlY1U4tE3GigKdSNRSJmuyvdgI4wDb2noZdEStFr8nsOsG63kIYM_Gve-HWiTxmQ", - p: "-X7pv_NpfJvqTTlQwQnaz6eiA_I7v7Jj0l1KtmBRBZz6q6R9qq1BVlP8XeOBO5TX9vQKIooY8fL3QsWf73ZqQmmy9W3C4dAhwbwalvBzZHZT2Wznrurp_bML_8Xx1XhNxTawAb263O3AUz7Rw3g5lI2cafTe4x1dSO8_CHL3eMs", - q: "7TJj6aNzkVjyPeCZVHwBXGDWDIT2DxqWRjKrKgqlpWdzEftNce855Wg3Ve4JnNtFkg7Qow4imZVkbK69ChIStv9s1KDX_sGRCyfN17d0jlkyGUnFB2RSBB42t7SmcC4ZhHjxdAdopOG_o1r5vEwDo-0hKWikP9uyYmWyhfY3hqs", - qi: "4RyTKy-QINtOUezaLEymzNBIG3uZv_IKvGPhEYi4wRNP_XxIK9NwfgUFRAhxhpxSpEjco_eNuN3I6XBF7bXb4-Bnnye1mBm3sBTXx2_09r8zt9Uvg3cdh0pYem3hU1ANMRmr3rfjtain4DTskIJ2CxjvGIMyh3VXLyRyfzIGJig", - use: "enc", - }, - { - d: "L0a7DDdP9LsAjeu_C6fkh4GXMqtRo3yPHK077SVFTPGGAFGq8Lk3C-wWTQxTwO9eZ_xx9wCzFTyIyqrksTuvQxzfY0MmzEk3mXNSrKxpK_vbgtC47qV6UwuGGiRfJ1z7MGXGmu5OmpaZqZJ-CPTGVtsM0rF4V665dIe-15o9GHzLX80mhw8ySd0qqBIbdIWlK2zaSRPGL08mP02t_XnHdCCaWfRE_erO6zsEhR8ePvbmQqI7GRBull59seXefo1VDP30lEwHwH05Ju24_ZddhfuP2Y9jkZnNKqpSHF3EZzT6Vh3ggAaLjQzRWJvd1_0Zit7CD06o6L1aLV7nDnTYAQ", - dp: "Cyf-4iwZZIrve5WsqKy8UVWpMBDCyBpCpHRNw2PAVGAP4aNXe2dG41sxV3mvdsOHWzqApsLT90EVHDa2KySS5CNcxOQ47Yr1mVVFoHb3izIcLe2dIpVUmgyc62WDcaShl47ahnWyDO8rLJzeH75AZlCaJR3s2nnth7Xy_cU4GQE", - dq: "SvJe21HfQe2JsqGwrBPg0ShcfKMnkQI3uaaDOJDkEyHJz4eILlETfiFEBgNRo4xYjPU4Aa2w81poYms4RhYdNwpB4DT5OXT8kL_KRykmhBLWaxafezyIRxdNs97h7eU1Vk_05C3vbG7fqASO6vv7HdHnB_ityGRDUnLbwKfDasU", - e: "AQAB", - kid: "lFWqEBQbScnjO5OzUbvkPp0rmjGy17bmzZOqUbWkQMo", - kty: "RSA", - n: "6btLS-c06m18O5BlLvJA4HJNVI7WauBg5JVoy1cHTdfjTJ-oSts5uetXKF_NlNcLuq-zIKZuu9wea5m2E3lJ-vtCSAtRaJgZY41KAOjIsrHQstVuc9di4zjgcA6zwEXhqwu48gklGKpWNk7wnfMCO6mNoRs_-8-CnK6lTFeJFzfoCDmS6dYbefmPeFW4qziEZzEv5DPGAcUsXXZhbOku_E8gILRVMkBwHpvY_G3jngE1EWXctiM9tYqhgvxyJC9QyPCVpgfAvDlslMpuQTxBviC9PsrcBaQ5PyAP_xNN3X8LB-STpz7jNpNquKL5Ls0Hv9R3fDCeHvcYoVsgDirwfQ", - p: "_u6v29kLICnGvbF44-sF5cFisrIPyXcj8laaNx6uP5ax9ZOPD_THdxTFU3YWLUErzi4MQJQPLoJacphQJKnG78b0PX_733--r-vpqUqfbzAlIssS8N4CFj6_YEMFR8W70laXJYJdx7IsnGOAlxAUZur5ugaaR0zDzlMTQVuR30E", - q: "6rXguomnHNGFslAeHWPxPDaHxihx3eRJ-8t1KyvvwT43YfdPn2xxdq5-TyO0MMKznvDIHk9HDMBMr8JH32Q9qx75Ec81NOLGkBWqO9x-8dBlKn95jr8-qkD3iXHmJiHHNWNurHJM4G4lo73IL_0jgo0CCpcZWP7iH5y-b_mXPj0", - qi: "QomRmnqrW3k8cV8MIefgmKZMGDGHRC44bFk9B20YR15_XHcMimi7o9rjUE7BY-RO30RsPUiQqB_vkpKvQZILOuPmIQhElcgmguKqPNwprVMgx-krUQ1Khuh3tgzxhBgazXzPcKmx8JBbCopP_UwNiCpPcdm74VFcZ-OswmqQU08", - use: "sig", - }, - ], -};