mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-26 17:24:23 -04:00
Merge branch 'main' into 1256-bug-tour-steps-needs-to-be-adjusted-for-the-new-preview-page
This commit is contained in:
@@ -169,7 +169,7 @@
|
|||||||
"filename": "app/config.py",
|
"filename": "app/config.py",
|
||||||
"hashed_secret": "577a4c667e4af8682ca431857214b3a920883efc",
|
"hashed_secret": "577a4c667e4af8682ca431857214b3a920883efc",
|
||||||
"is_verified": false,
|
"is_verified": false,
|
||||||
"line_number": 111,
|
"line_number": 117,
|
||||||
"is_secret": false
|
"is_secret": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
77
.github/pull_request_template.md
vendored
77
.github/pull_request_template.md
vendored
@@ -1,79 +1,22 @@
|
|||||||
<!--
|
<!--
|
||||||
Please follow the instructions found in this pull request template so that we
|
Not sure what you should include or write in a pull request? Please read the
|
||||||
have all of the relevant details needed for our work.
|
[pull request documentation in our docs!](https://github.com/GSA/notifications-api/blob/main/docs/all.md#pull-requests)
|
||||||
|
|
||||||
At the minimum, please be sure to fill in all sections found below and also do
|
|
||||||
the following:
|
|
||||||
|
|
||||||
- Provide an appropriate and descriptive title for the pull request
|
|
||||||
- Link the pull request to its corresponding issue (must be done after creating
|
|
||||||
the pull request itself)
|
|
||||||
- Assign yourself as the author
|
|
||||||
- Attach the appropriate labels to it
|
|
||||||
- Set it to be on the Notify.gov project board
|
|
||||||
- Select one or more reviewers from the team or mark the pull request as a draft
|
|
||||||
depending on its current state
|
|
||||||
- If the pull request is a draft, please be sure to add reviewers once it is
|
|
||||||
ready for review and mark it ready for review
|
|
||||||
|
|
||||||
For each section, please delete the instructions/sample text (that includes this
|
|
||||||
text, though it is wrapped in an HTML comment just in case) and put in your own
|
|
||||||
information. Thank you!
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
*A note to PR reviewers: it may be helpful to review our
|
*A note to PR reviewers: it may be helpful to review our [code review documentation](https://github.com/GSA/notifications-api/blob/main/docs/all.md#code-reviews) to know what to keep in mind while reviewing pull requests.*
|
||||||
[code review documentation](https://github.com/GSA/notifications-api/blob/main/docs/all.md#code-reviews)
|
|
||||||
to know what to keep in mind while reviewing pull requests.*
|
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
Please enter a clear description about your proposed changes and what the
|
Please enter a detailed description here.
|
||||||
expected outcome(s) is/are from there. If there are complex implementation
|
|
||||||
details within the changes, this is a great place to explain those details using
|
|
||||||
plain language.
|
|
||||||
|
|
||||||
This should include:
|
|
||||||
|
|
||||||
- Links to issues that this PR addresses
|
|
||||||
- Screenshots or screen captures of any visible changes, especially for UI work
|
|
||||||
- Dependency changes
|
|
||||||
|
|
||||||
If there are any caveats, known issues, follow-up items, etc., make a quick note
|
|
||||||
of them here as well, though more details are probably warranted in the issue
|
|
||||||
itself in this case.
|
|
||||||
|
|
||||||
## TODO (optional)
|
## TODO (optional)
|
||||||
|
|
||||||
If you're opening a draft PR, it might be helpful to list any outstanding work,
|
* [ ] TODO item 1
|
||||||
especially if you're asking folks to take a look before it's ready for full
|
* [ ] TODO item 2
|
||||||
review. In this case, create a small checklist with the outstanding items:
|
* [ ] TODO item ...
|
||||||
|
|
||||||
- [ ] TODO item 1
|
|
||||||
- [ ] TODO item 2
|
|
||||||
- [ ] TODO item ...
|
|
||||||
|
|
||||||
## Security Considerations
|
## Security Considerations
|
||||||
|
|
||||||
Please think about the security compliance aspect of your changes and what the
|
* Consideration 1
|
||||||
potential impacts might be.
|
* Consideration 2
|
||||||
|
* Consideration ...
|
||||||
**NOTE: Please be mindful of sharing sensitive information here! If you're not
|
|
||||||
sure of what to write, please ask the team first before writing anything here.**
|
|
||||||
|
|
||||||
Relevant details could include (and are not limited to) the following:
|
|
||||||
|
|
||||||
- Handling secrets/credential management (or specifically calling out that there
|
|
||||||
is nothing to handle)
|
|
||||||
- Any adjustments to the flow of data in and out the system, or even within it
|
|
||||||
- Connecting or disconnecting any external services to the application
|
|
||||||
- Handling of any sensitive information, such as PII
|
|
||||||
- Handling of information within log statements or other application monitoring
|
|
||||||
services/hooks
|
|
||||||
- The inclusion of a new external dependency or the removal of an existing one
|
|
||||||
- ... (anything else relevant from a security compliance perspective)
|
|
||||||
|
|
||||||
There are some cases where there are no security considerations to be had, e.g.,
|
|
||||||
updating our documentation with publicly available information. In those cases
|
|
||||||
it is fine to simply put something like this:
|
|
||||||
|
|
||||||
- None; this is a documentation update with publicly available information.
|
|
||||||
|
|||||||
8
.github/workflows/deploy-demo.yml
vendored
8
.github/workflows/deploy-demo.yml
vendored
@@ -18,11 +18,11 @@ jobs:
|
|||||||
|
|
||||||
- name: Check for changes to Terraform
|
- name: Check for changes to Terraform
|
||||||
id: changed-terraform-files
|
id: changed-terraform-files
|
||||||
uses: tj-actions/changed-files@v41.0.0
|
uses: tj-actions/changed-files@v44
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
terraform/demo
|
terraform/demo/**
|
||||||
terraform/shared
|
terraform/shared/**
|
||||||
.github/workflows/deploy-demo.yml
|
.github/workflows/deploy-demo.yml
|
||||||
- name: Terraform init
|
- name: Terraform init
|
||||||
if: steps.changed-terraform-files.outputs.any_changed == 'true'
|
if: steps.changed-terraform-files.outputs.any_changed == 'true'
|
||||||
@@ -88,7 +88,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Check for changes to egress config
|
- name: Check for changes to egress config
|
||||||
id: changed-egress-config
|
id: changed-egress-config
|
||||||
uses: tj-actions/changed-files@v41.0.0
|
uses: tj-actions/changed-files@v44
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
deploy-config/egress_proxy/notify-admin-demo.*.acl
|
deploy-config/egress_proxy/notify-admin-demo.*.acl
|
||||||
|
|||||||
8
.github/workflows/deploy-prod.yml
vendored
8
.github/workflows/deploy-prod.yml
vendored
@@ -18,11 +18,11 @@ jobs:
|
|||||||
|
|
||||||
- name: Check for changes to Terraform
|
- name: Check for changes to Terraform
|
||||||
id: changed-terraform-files
|
id: changed-terraform-files
|
||||||
uses: tj-actions/changed-files@v41.0.0
|
uses: tj-actions/changed-files@v44
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
terraform/production
|
terraform/production/**
|
||||||
terraform/shared
|
terraform/shared/**
|
||||||
.github/workflows/deploy-prod.yml
|
.github/workflows/deploy-prod.yml
|
||||||
- name: Terraform init
|
- name: Terraform init
|
||||||
if: steps.changed-terraform-files.outputs.any_changed == 'true'
|
if: steps.changed-terraform-files.outputs.any_changed == 'true'
|
||||||
@@ -88,7 +88,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Check for changes to egress config
|
- name: Check for changes to egress config
|
||||||
id: changed-egress-config
|
id: changed-egress-config
|
||||||
uses: tj-actions/changed-files@v41.0.0
|
uses: tj-actions/changed-files@v44
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
deploy-config/egress_proxy/notify-admin-production.*.acl
|
deploy-config/egress_proxy/notify-admin-production.*.acl
|
||||||
|
|||||||
166
.github/workflows/deploy.yml
vendored
166
.github/workflows/deploy.yml
vendored
@@ -17,96 +17,96 @@ jobs:
|
|||||||
|
|
||||||
environment: staging
|
environment: staging
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 2
|
fetch-depth: 2
|
||||||
|
|
||||||
- name: Check for changes to Terraform
|
- name: Check for changes to Terraform
|
||||||
id: changed-terraform-files
|
id: changed-terraform-files
|
||||||
uses: tj-actions/changed-files@v41.0.0
|
uses: tj-actions/changed-files@v44
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
terraform/staging
|
terraform/staging/**
|
||||||
terraform/shared
|
terraform/shared/**
|
||||||
.github/workflows/deploy.yml
|
.github/workflows/deploy.yml
|
||||||
- name: Terraform init
|
- name: Terraform init
|
||||||
if: steps.changed-terraform-files.outputs.any_changed == 'true'
|
if: steps.changed-terraform-files.outputs.any_changed == 'true'
|
||||||
working-directory: terraform/staging
|
working-directory: terraform/staging
|
||||||
env:
|
env:
|
||||||
AWS_ACCESS_KEY_ID: ${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
|
AWS_ACCESS_KEY_ID: ${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
|
||||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
|
||||||
run: terraform init
|
run: terraform init
|
||||||
- name: Terraform apply
|
- name: Terraform apply
|
||||||
if: steps.changed-terraform-files.outputs.any_changed == 'true'
|
if: steps.changed-terraform-files.outputs.any_changed == 'true'
|
||||||
working-directory: terraform/staging
|
working-directory: terraform/staging
|
||||||
env:
|
env:
|
||||||
AWS_ACCESS_KEY_ID: ${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
|
AWS_ACCESS_KEY_ID: ${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
|
||||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
|
||||||
TF_VAR_cf_user: ${{ secrets.CLOUDGOV_USERNAME }}
|
TF_VAR_cf_user: ${{ secrets.CLOUDGOV_USERNAME }}
|
||||||
TF_VAR_cf_password: ${{ secrets.CLOUDGOV_PASSWORD }}
|
TF_VAR_cf_password: ${{ secrets.CLOUDGOV_PASSWORD }}
|
||||||
run: terraform apply -auto-approve -input=false
|
run: terraform apply -auto-approve -input=false
|
||||||
|
|
||||||
- uses: ./.github/actions/setup-project
|
- uses: ./.github/actions/setup-project
|
||||||
|
|
||||||
- name: Create requirements.txt
|
- name: Create requirements.txt
|
||||||
run: poetry export --without-hashes --format=requirements.txt > requirements.txt
|
run: poetry export --without-hashes --format=requirements.txt > requirements.txt
|
||||||
|
|
||||||
|
|
||||||
- name: Deploy to cloud.gov
|
- name: Deploy to cloud.gov
|
||||||
uses: 18f/cg-deploy-action@main
|
uses: 18f/cg-deploy-action@main
|
||||||
env:
|
env:
|
||||||
DANGEROUS_SALT: ${{ secrets.DANGEROUS_SALT }}
|
DANGEROUS_SALT: ${{ secrets.DANGEROUS_SALT }}
|
||||||
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
||||||
ADMIN_CLIENT_SECRET: ${{ secrets.ADMIN_CLIENT_SECRET }}
|
ADMIN_CLIENT_SECRET: ${{ secrets.ADMIN_CLIENT_SECRET }}
|
||||||
NEW_RELIC_LICENSE_KEY: ${{ secrets.NEW_RELIC_LICENSE_KEY }}
|
NEW_RELIC_LICENSE_KEY: ${{ secrets.NEW_RELIC_LICENSE_KEY }}
|
||||||
NR_BROWSER_KEY: ${{ secrets.NR_BROWSER_KEY }}
|
NR_BROWSER_KEY: ${{ secrets.NR_BROWSER_KEY }}
|
||||||
COMMIT_HASH: ${{ github.sha }}
|
COMMIT_HASH: ${{ github.sha }}
|
||||||
LOGIN_PEM: ${{ secrets.LOGIN_PEM }}
|
LOGIN_PEM: ${{ secrets.LOGIN_PEM }}
|
||||||
LOGIN_DOT_GOV_CLIENT_ID: "urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov"
|
LOGIN_DOT_GOV_CLIENT_ID: "urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov"
|
||||||
LOGIN_DOT_GOV_USER_INFO_URL: "https://secure.login.gov/api/openid_connect/userinfo"
|
LOGIN_DOT_GOV_USER_INFO_URL: "https://secure.login.gov/api/openid_connect/userinfo"
|
||||||
LOGIN_DOT_GOV_ACCESS_TOKEN_URL: "https://secure.login.gov/api/openid_connect/token"
|
LOGIN_DOT_GOV_ACCESS_TOKEN_URL: "https://secure.login.gov/api/openid_connect/token"
|
||||||
LOGIN_DOT_GOV_LOGOUT_URL: "https://secure.login.gov/openid_connect/logout?client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&post_logout_redirect_uri=https://notify-staging.app.cloud.gov/sign-out"
|
LOGIN_DOT_GOV_LOGOUT_URL: "https://secure.login.gov/openid_connect/logout?client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&post_logout_redirect_uri=https://notify-staging.app.cloud.gov/sign-out"
|
||||||
LOGIN_DOT_GOV_BASE_LOGOUT_URL: "https://secure.login.gov/openid_connect/logout?"
|
LOGIN_DOT_GOV_BASE_LOGOUT_URL: "https://secure.login.gov/openid_connect/logout?"
|
||||||
LOGIN_DOT_GOV_SIGNOUT_REDIRECT: "https://notify-staging.app.cloud.gov/sign-out"
|
LOGIN_DOT_GOV_SIGNOUT_REDIRECT: "https://notify-staging.app.cloud.gov/sign-out"
|
||||||
LOGIN_DOT_GOV_INITIAL_SIGNIN_URL: "https://secure.login.gov/openid_connect/authorize?acr_values=http%3A%2F%2Fidmanagement.gov%2Fns%2Fassurance%2Fial%2F1&client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&nonce=NONCE&prompt=select_account&redirect_uri=https://notify-staging.app.cloud.gov/sign-in&response_type=code&scope=openid+email&state=STATEE"
|
LOGIN_DOT_GOV_INITIAL_SIGNIN_URL: "https://secure.login.gov/openid_connect/authorize?acr_values=http%3A%2F%2Fidmanagement.gov%2Fns%2Fassurance%2Fial%2F1&client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&nonce=NONCE&prompt=select_account&redirect_uri=https://notify-staging.app.cloud.gov/sign-in&response_type=code&scope=openid+email&state=STATEE"
|
||||||
with:
|
with:
|
||||||
cf_username: ${{ secrets.CLOUDGOV_USERNAME }}
|
cf_username: ${{ secrets.CLOUDGOV_USERNAME }}
|
||||||
cf_password: ${{ secrets.CLOUDGOV_PASSWORD }}
|
cf_password: ${{ secrets.CLOUDGOV_PASSWORD }}
|
||||||
cf_org: gsa-tts-benefits-studio
|
cf_org: gsa-tts-benefits-studio
|
||||||
cf_space: notify-staging
|
cf_space: notify-staging
|
||||||
push_arguments: >-
|
push_arguments: >-
|
||||||
--vars-file deploy-config/staging.yml
|
--vars-file deploy-config/staging.yml
|
||||||
--var DANGEROUS_SALT="$DANGEROUS_SALT"
|
--var DANGEROUS_SALT="$DANGEROUS_SALT"
|
||||||
--var SECRET_KEY="$SECRET_KEY"
|
--var SECRET_KEY="$SECRET_KEY"
|
||||||
--var ADMIN_CLIENT_USERNAME="notify-admin"
|
--var ADMIN_CLIENT_USERNAME="notify-admin"
|
||||||
--var ADMIN_CLIENT_SECRET="$ADMIN_CLIENT_SECRET"
|
--var ADMIN_CLIENT_SECRET="$ADMIN_CLIENT_SECRET"
|
||||||
--var NEW_RELIC_LICENSE_KEY="$NEW_RELIC_LICENSE_KEY"
|
--var NEW_RELIC_LICENSE_KEY="$NEW_RELIC_LICENSE_KEY"
|
||||||
--var NR_BROWSER_KEY="$NR_BROWSER_KEY"
|
--var NR_BROWSER_KEY="$NR_BROWSER_KEY"
|
||||||
--var COMMIT_HASH="$COMMIT_HASH"
|
--var COMMIT_HASH="$COMMIT_HASH"
|
||||||
--var LOGIN_PEM="$LOGIN_PEM"
|
--var LOGIN_PEM="$LOGIN_PEM"
|
||||||
--var LOGIN_DOT_GOV_CLIENT_ID="$LOGIN_DOT_GOV_CLIENT_ID"
|
--var LOGIN_DOT_GOV_CLIENT_ID="$LOGIN_DOT_GOV_CLIENT_ID"
|
||||||
--var LOGIN_DOT_GOV_USER_INFO_URL="$LOGIN_DOT_GOV_USER_INFO_URL"
|
--var LOGIN_DOT_GOV_USER_INFO_URL="$LOGIN_DOT_GOV_USER_INFO_URL"
|
||||||
--var LOGIN_DOT_GOV_ACCESS_TOKEN_URL="$LOGIN_DOT_GOV_ACCESS_TOKEN_URL"
|
--var LOGIN_DOT_GOV_ACCESS_TOKEN_URL="$LOGIN_DOT_GOV_ACCESS_TOKEN_URL"
|
||||||
--var LOGIN_DOT_GOV_LOGOUT_URL="$LOGIN_DOT_GOV_LOGOUT_URL"
|
--var LOGIN_DOT_GOV_LOGOUT_URL="$LOGIN_DOT_GOV_LOGOUT_URL"
|
||||||
--var LOGIN_DOT_GOV_BASE_LOGOUT_URL="$LOGIN_DOT_GOV_BASE_LOGOUT_URL"
|
--var LOGIN_DOT_GOV_BASE_LOGOUT_URL="$LOGIN_DOT_GOV_BASE_LOGOUT_URL"
|
||||||
--var LOGIN_DOT_GOV_SIGNOUT_REDIRECT="$LOGIN_DOT_GOV_SIGNOUT_REDIRECT"
|
--var LOGIN_DOT_GOV_SIGNOUT_REDIRECT="$LOGIN_DOT_GOV_SIGNOUT_REDIRECT"
|
||||||
--var LOGIN_DOT_GOV_INITIAL_SIGNIN_URL="$LOGIN_DOT_GOV_INITIAL_SIGNIN_URL"
|
--var LOGIN_DOT_GOV_INITIAL_SIGNIN_URL="$LOGIN_DOT_GOV_INITIAL_SIGNIN_URL"
|
||||||
|
|
||||||
|
|
||||||
- name: Check for changes to egress config
|
- name: Check for changes to egress config
|
||||||
id: changed-egress-config
|
id: changed-egress-config
|
||||||
uses: tj-actions/changed-files@v41.0.0
|
uses: tj-actions/changed-files@v44
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
deploy-config/egress_proxy/notify-admin-staging.*.acl
|
deploy-config/egress_proxy/notify-admin-staging.*.acl
|
||||||
.github/actions/deploy-proxy/action.yml
|
.github/actions/deploy-proxy/action.yml
|
||||||
.github/workflows/deploy.yml
|
.github/workflows/deploy.yml
|
||||||
- name: Deploy egress proxy
|
- name: Deploy egress proxy
|
||||||
if: steps.changed-egress-config.outputs.any_changed == 'true'
|
if: steps.changed-egress-config.outputs.any_changed == 'true'
|
||||||
uses: ./.github/actions/deploy-proxy
|
uses: ./.github/actions/deploy-proxy
|
||||||
with:
|
with:
|
||||||
cf_space: notify-staging
|
cf_space: notify-staging
|
||||||
app: notify-admin-staging
|
app: notify-admin-staging
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
30
README.md
30
README.md
@@ -40,7 +40,7 @@ You will need the following items:
|
|||||||
[Follow the instructions here to set up the Notify.gov API.](https://github.com/GSA/notifications-api#before-you-start)
|
[Follow the instructions here to set up the Notify.gov API.](https://github.com/GSA/notifications-api#before-you-start)
|
||||||
|
|
||||||
The Notify.gov API is required in order for the Notify.gov Admin UI to run, and
|
The Notify.gov API is required in order for the Notify.gov Admin UI to run, and
|
||||||
it will also take care of many of the steps that are listed here. The sections
|
it will also take care of many of the steps that are listed here. The sections
|
||||||
that are a repeat from the API setup are flagged with an **[API Step]** label
|
that are a repeat from the API setup are flagged with an **[API Step]** label
|
||||||
in front of them.
|
in front of them.
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ in front of them.
|
|||||||
|
|
||||||
This project is set up to work with
|
This project is set up to work with
|
||||||
[nvm (Node Version Manager)](https://github.com/nvm-sh/nvm#installing-and-updating)
|
[nvm (Node Version Manager)](https://github.com/nvm-sh/nvm#installing-and-updating)
|
||||||
for managing and using Node.js (version 16.15.1) and the `npm` package manager.
|
for managing and using Node.js (version 22.3.0) and the `npm` package manager.
|
||||||
|
|
||||||
These instructions will walk you through how to set your machine up with all of
|
These instructions will walk you through how to set your machine up with all of
|
||||||
the required tools for this project.
|
the required tools for this project.
|
||||||
@@ -83,11 +83,13 @@ Your system `$PATH` environment variable is likely set in one of these
|
|||||||
locations:
|
locations:
|
||||||
|
|
||||||
For BASH shells:
|
For BASH shells:
|
||||||
|
|
||||||
- `~/.bashrc`
|
- `~/.bashrc`
|
||||||
- `~/.bash_profile`
|
- `~/.bash_profile`
|
||||||
- `~/.profile`
|
- `~/.profile`
|
||||||
|
|
||||||
For ZSH shells:
|
For ZSH shells:
|
||||||
|
|
||||||
- `~/.zshrc`
|
- `~/.zshrc`
|
||||||
- `~/.zprofile`
|
- `~/.zprofile`
|
||||||
|
|
||||||
@@ -97,7 +99,7 @@ environments.
|
|||||||
Which file you need to modify depends on whether or not you are running an
|
Which file you need to modify depends on whether or not you are running an
|
||||||
interactive shell or a login shell
|
interactive shell or a login shell
|
||||||
(see [this Stack Overflow post](https://stackoverflow.com/questions/18186929/what-are-the-differences-between-a-login-shell-and-interactive-shell)
|
(see [this Stack Overflow post](https://stackoverflow.com/questions/18186929/what-are-the-differences-between-a-login-shell-and-interactive-shell)
|
||||||
for an explanation of the differences). If you're still not sure, please ask
|
for an explanation of the differences). If you're still not sure, please ask
|
||||||
the team for help!
|
the team for help!
|
||||||
|
|
||||||
Once you determine which file you'll need to modify, add these lines before any
|
Once you determine which file you'll need to modify, add these lines before any
|
||||||
@@ -158,7 +160,7 @@ _NOTE: This project currently uses the latest `1.4.x release of Terraform._
|
|||||||
#### [API Step] Python Installation
|
#### [API Step] Python Installation
|
||||||
|
|
||||||
Now we're going to install a tool to help us manage Python versions and
|
Now we're going to install a tool to help us manage Python versions and
|
||||||
virtual environments on our system. First, we'll install
|
virtual environments on our system. First, we'll install
|
||||||
[pyenv](https://github.com/pyenv/pyenv) and one of its plugins,
|
[pyenv](https://github.com/pyenv/pyenv) and one of its plugins,
|
||||||
[pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv), with Homebrew:
|
[pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv), with Homebrew:
|
||||||
|
|
||||||
@@ -285,7 +287,7 @@ we'll use `3.12` in our example here since we recently upgraded to this version:
|
|||||||
pyenv install 3.12
|
pyenv install 3.12
|
||||||
```
|
```
|
||||||
|
|
||||||
Next, delete the virtual environment you previously had set up. If you followed
|
Next, delete the virtual environment you previously had set up. If you followed
|
||||||
the instructions above with the first-time set up, you can do this with `pyenv`:
|
the instructions above with the first-time set up, you can do this with `pyenv`:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -306,6 +308,20 @@ you'll be set with an upgraded version of Python.
|
|||||||
|
|
||||||
_If you're not sure about the details of your current virtual environment, you can run `poetry env info` to get more information. If you've been using `pyenv` for everything, you can also see all available virtual environments with `pyenv virtualenvs`._
|
_If you're not sure about the details of your current virtual environment, you can run `poetry env info` to get more information. If you've been using `pyenv` for everything, you can also see all available virtual environments with `pyenv virtualenvs`._
|
||||||
|
|
||||||
|
#### Updating the .env file for Login.gov
|
||||||
|
|
||||||
|
To configure the application for Login.gov, you will need to update the following environment variables in the .env file:
|
||||||
|
|
||||||
|
```
|
||||||
|
COMMIT_HASH=”--------”
|
||||||
|
```
|
||||||
|
|
||||||
|
Reach out to someone on the team to get the most recent Login.gov key.
|
||||||
|
|
||||||
|
```
|
||||||
|
LOGIN_PEM="INSERT_LOGIN_GOV_KEY_HERE"
|
||||||
|
```
|
||||||
|
|
||||||
#### Updating the .env file for E2E tests
|
#### Updating the .env file for E2E tests
|
||||||
|
|
||||||
With the newly created `.env` file in place, you'll need to make one more
|
With the newly created `.env` file in place, you'll need to make one more
|
||||||
@@ -353,7 +369,7 @@ API is running as well!
|
|||||||
## Creating a 'First User' in the database
|
## Creating a 'First User' in the database
|
||||||
|
|
||||||
After you have completed all setup steps, you will be unable to log in, because there
|
After you have completed all setup steps, you will be unable to log in, because there
|
||||||
will not be a user in the database to link to the login.gov account you are using. So
|
will not be a user in the database to link to the login.gov account you are using. So
|
||||||
you will need to create that user in your database using the 'create-test-user' command.
|
you will need to create that user in your database using the 'create-test-user' command.
|
||||||
|
|
||||||
Open two terminals pointing to the api project and then run these commands in the
|
Open two terminals pointing to the api project and then run these commands in the
|
||||||
@@ -372,8 +388,6 @@ is the same one you are using in login.gov and make sure your phone number is in
|
|||||||
If for any reason in the course of development it is necessary for your to delete your db
|
If for any reason in the course of development it is necessary for your to delete your db
|
||||||
via the `dropdb` command, you will need to repeat these steps when you recreate your db.
|
via the `dropdb` command, you will need to repeat these steps when you recreate your db.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Git Hooks
|
## Git Hooks
|
||||||
|
|
||||||
We're using [`pre-commit`](https://pre-commit.com/) to manage hooks in order to
|
We're using [`pre-commit`](https://pre-commit.com/) to manage hooks in order to
|
||||||
|
|||||||
@@ -53,7 +53,13 @@ class Config(object):
|
|||||||
PERMANENT_SESSION_LIFETIME = 1800 # 30 Minutes
|
PERMANENT_SESSION_LIFETIME = 1800 # 30 Minutes
|
||||||
SEND_FILE_MAX_AGE_DEFAULT = 365 * 24 * 60 * 60 # 1 year
|
SEND_FILE_MAX_AGE_DEFAULT = 365 * 24 * 60 * 60 # 1 year
|
||||||
REPLY_TO_EMAIL_ADDRESS_VALIDATION_TIMEOUT = 45
|
REPLY_TO_EMAIL_ADDRESS_VALIDATION_TIMEOUT = 45
|
||||||
ACTIVITY_STATS_LIMIT_DAYS = 7
|
ACTIVITY_STATS_LIMIT_DAYS = {
|
||||||
|
"today": 0,
|
||||||
|
"one_day": 1,
|
||||||
|
"three_day": 3,
|
||||||
|
"five_day": 5,
|
||||||
|
"seven_day": 7,
|
||||||
|
}
|
||||||
SESSION_COOKIE_HTTPONLY = True
|
SESSION_COOKIE_HTTPONLY = True
|
||||||
SESSION_COOKIE_NAME = "notify_admin_session"
|
SESSION_COOKIE_NAME = "notify_admin_session"
|
||||||
SESSION_COOKIE_SECURE = True
|
SESSION_COOKIE_SECURE = True
|
||||||
|
|||||||
@@ -143,11 +143,40 @@ def view_notifications(service_id, message_type=None):
|
|||||||
True: ["reference"],
|
True: ["reference"],
|
||||||
False: [],
|
False: [],
|
||||||
}.get(bool(current_service.api_keys)),
|
}.get(bool(current_service.api_keys)),
|
||||||
download_link=url_for(
|
download_link_one_day=url_for(
|
||||||
".download_notifications_csv",
|
".download_notifications_csv",
|
||||||
service_id=current_service.id,
|
service_id=current_service.id,
|
||||||
message_type=message_type,
|
message_type=message_type,
|
||||||
status=request.args.get("status"),
|
status=request.args.get("status"),
|
||||||
|
number_of_days="one_day",
|
||||||
|
),
|
||||||
|
download_link_today=url_for(
|
||||||
|
".download_notifications_csv",
|
||||||
|
service_id=current_service.id,
|
||||||
|
message_type=message_type,
|
||||||
|
status=request.args.get("status"),
|
||||||
|
number_of_days="today",
|
||||||
|
),
|
||||||
|
download_link_three_day=url_for(
|
||||||
|
".download_notifications_csv",
|
||||||
|
service_id=current_service.id,
|
||||||
|
message_type=message_type,
|
||||||
|
status=request.args.get("status"),
|
||||||
|
number_of_days="three_day",
|
||||||
|
),
|
||||||
|
download_link_five_day=url_for(
|
||||||
|
".download_notifications_csv",
|
||||||
|
service_id=current_service.id,
|
||||||
|
message_type=message_type,
|
||||||
|
status=request.args.get("status"),
|
||||||
|
number_of_days="five_day",
|
||||||
|
),
|
||||||
|
download_link_seven_day=url_for(
|
||||||
|
".download_notifications_csv",
|
||||||
|
service_id=current_service.id,
|
||||||
|
message_type=message_type,
|
||||||
|
status=request.args.get("status"),
|
||||||
|
number_of_days="seven_day",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -183,10 +212,9 @@ def get_notifications(service_id, message_type, status_override=None): # noqa
|
|||||||
filter_args["status"] = set_status_filters(filter_args)
|
filter_args["status"] = set_status_filters(filter_args)
|
||||||
service_data_retention_days = None
|
service_data_retention_days = None
|
||||||
search_term = request.form.get("to", "")
|
search_term = request.form.get("to", "")
|
||||||
|
|
||||||
if message_type is not None:
|
if message_type is not None:
|
||||||
service_data_retention_days = current_service.get_days_of_retention(
|
service_data_retention_days = current_service.get_days_of_retention(
|
||||||
message_type
|
message_type, number_of_days="seven_day"
|
||||||
)
|
)
|
||||||
|
|
||||||
if request.path.endswith("csv") and current_user.has_permissions("view_activity"):
|
if request.path.endswith("csv") and current_user.has_permissions("view_activity"):
|
||||||
@@ -212,7 +240,6 @@ def get_notifications(service_id, message_type, status_override=None): # noqa
|
|||||||
)
|
)
|
||||||
url_args = {"message_type": message_type, "status": request.args.get("status")}
|
url_args = {"message_type": message_type, "status": request.args.get("status")}
|
||||||
prev_page = None
|
prev_page = None
|
||||||
|
|
||||||
if "links" in notifications and notifications["links"].get("prev", None):
|
if "links" in notifications and notifications["links"].get("prev", None):
|
||||||
prev_page = generate_previous_dict(
|
prev_page = generate_previous_dict(
|
||||||
"main.view_notifications", service_id, page, url_args=url_args
|
"main.view_notifications", service_id, page, url_args=url_args
|
||||||
@@ -233,7 +260,6 @@ def get_notifications(service_id, message_type, status_override=None): # noqa
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
download_link = None
|
download_link = None
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"service_data_retention_days": service_data_retention_days,
|
"service_data_retention_days": service_data_retention_days,
|
||||||
"counts": render_template(
|
"counts": render_template(
|
||||||
@@ -362,6 +388,7 @@ def get_job_partials(job):
|
|||||||
filter_args = parse_filter_args(request.args)
|
filter_args = parse_filter_args(request.args)
|
||||||
filter_args["status"] = set_status_filters(filter_args)
|
filter_args["status"] = set_status_filters(filter_args)
|
||||||
notifications = job.get_notifications(status=filter_args["status"])
|
notifications = job.get_notifications(status=filter_args["status"])
|
||||||
|
number_of_days = "seven_day"
|
||||||
counts = render_template(
|
counts = render_template(
|
||||||
"partials/count.html",
|
"partials/count.html",
|
||||||
counts=_get_job_counts(job),
|
counts=_get_job_counts(job),
|
||||||
@@ -371,7 +398,7 @@ def get_job_partials(job):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
service_data_retention_days = current_service.get_days_of_retention(
|
service_data_retention_days = current_service.get_days_of_retention(
|
||||||
job.template_type
|
job.template_type, number_of_days
|
||||||
)
|
)
|
||||||
|
|
||||||
if request.referrer is not None:
|
if request.referrer is not None:
|
||||||
|
|||||||
@@ -137,9 +137,9 @@ def get_all_personalisation_from_notification(notification):
|
|||||||
def download_notifications_csv(service_id):
|
def download_notifications_csv(service_id):
|
||||||
filter_args = parse_filter_args(request.args)
|
filter_args = parse_filter_args(request.args)
|
||||||
filter_args["status"] = set_status_filters(filter_args)
|
filter_args["status"] = set_status_filters(filter_args)
|
||||||
|
number_of_days = request.args["number_of_days"]
|
||||||
service_data_retention_days = current_service.get_days_of_retention(
|
service_data_retention_days = current_service.get_days_of_retention(
|
||||||
filter_args.get("message_type")[0]
|
filter_args.get("message_type")[0], number_of_days
|
||||||
)
|
)
|
||||||
file_time = datetime.now().strftime("%Y-%m-%d %I:%M:%S %p")
|
file_time = datetime.now().strftime("%Y-%m-%d %I:%M:%S %p")
|
||||||
file_time = f"{file_time} {get_user_preferred_timezone()}"
|
file_time = f"{file_time} {get_user_preferred_timezone()}"
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ from app.utils.templates import get_template
|
|||||||
from app.utils.user import user_has_permissions
|
from app.utils.user import user_has_permissions
|
||||||
from notifications_utils import SMS_CHAR_COUNT_LIMIT
|
from notifications_utils import SMS_CHAR_COUNT_LIMIT
|
||||||
from notifications_utils.insensitive_dict import InsensitiveDict
|
from notifications_utils.insensitive_dict import InsensitiveDict
|
||||||
from notifications_utils.logging import scrub
|
|
||||||
from notifications_utils.recipients import RecipientCSV, first_column_headings
|
from notifications_utils.recipients import RecipientCSV, first_column_headings
|
||||||
from notifications_utils.sanitise_text import SanitiseASCII
|
from notifications_utils.sanitise_text import SanitiseASCII
|
||||||
|
|
||||||
@@ -953,9 +952,6 @@ def send_notification(service_id, template_id):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
current_app.logger.info(
|
|
||||||
hilite(scrub(f"Recipient for the one-off will be {recipient}"))
|
|
||||||
)
|
|
||||||
keys = []
|
keys = []
|
||||||
values = []
|
values = []
|
||||||
for k, v in session["placeholders"].items():
|
for k, v in session["placeholders"].items():
|
||||||
@@ -971,6 +967,17 @@ def send_notification(service_id, template_id):
|
|||||||
)
|
)
|
||||||
my_data = {"filename": filename, "template_id": template_id, "data": data}
|
my_data = {"filename": filename, "template_id": template_id, "data": data}
|
||||||
upload_id = s3upload(service_id, my_data)
|
upload_id = s3upload(service_id, my_data)
|
||||||
|
|
||||||
|
# To debug messages that the user reports have not been sent, we log
|
||||||
|
# the csv filename and the job id. The user will give us the file name,
|
||||||
|
# so we can search on that to obtain the job id, which we can use elsewhere
|
||||||
|
# on the API side to find out what happens to the message.
|
||||||
|
current_app.logger.info(
|
||||||
|
hilite(
|
||||||
|
f"One-off file: {filename} job_id: {upload_id} s3 location: service-{service_id}-notify/{upload_id}.csv"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
form = CsvUploadForm()
|
form = CsvUploadForm()
|
||||||
form.file.data = my_data
|
form.file.data = my_data
|
||||||
form.file.name = filename
|
form.file.name = filename
|
||||||
@@ -989,19 +996,6 @@ def send_notification(service_id, template_id):
|
|||||||
valid="True",
|
valid="True",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Here we are attempting to cleverly link the job id to the one-off recipient
|
|
||||||
# If we know the partial phone number of the recipient, we can search
|
|
||||||
# on that initially and find this, which will give us the job_id
|
|
||||||
# And once we know the job_id, we can search on that and it might tell us something
|
|
||||||
# about report generation.
|
|
||||||
current_app.logger.info(
|
|
||||||
hilite(
|
|
||||||
scrub(
|
|
||||||
f"Created job to send one-off, recipient is {recipient}, job_id is {upload_id}"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
session.pop("recipient")
|
session.pop("recipient")
|
||||||
session.pop("placeholders")
|
session.pop("placeholders")
|
||||||
|
|
||||||
@@ -1033,7 +1027,12 @@ def send_notification(service_id, template_id):
|
|||||||
job_id=upload_id,
|
job_id=upload_id,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
total = notifications["total"]
|
||||||
|
current_app.logger.info(
|
||||||
|
hilite(
|
||||||
|
f"job_id: {upload_id} has notifications: {total} and attempts: {attempts}"
|
||||||
|
)
|
||||||
|
)
|
||||||
return redirect(
|
return redirect(
|
||||||
url_for(
|
url_for(
|
||||||
".view_job",
|
".view_job",
|
||||||
|
|||||||
@@ -390,7 +390,7 @@ class Service(JSONModel, SortByNameMixin):
|
|||||||
def get_data_retention_item(self, id):
|
def get_data_retention_item(self, id):
|
||||||
return next((dr for dr in self.data_retention if dr["id"] == id), None)
|
return next((dr for dr in self.data_retention if dr["id"] == id), None)
|
||||||
|
|
||||||
def get_days_of_retention(self, notification_type):
|
def get_days_of_retention(self, notification_type, number_of_days):
|
||||||
return next(
|
return next(
|
||||||
(
|
(
|
||||||
dr
|
dr
|
||||||
@@ -398,7 +398,10 @@ class Service(JSONModel, SortByNameMixin):
|
|||||||
if dr["notification_type"] == notification_type
|
if dr["notification_type"] == notification_type
|
||||||
),
|
),
|
||||||
{},
|
{},
|
||||||
).get("days_of_retention", current_app.config["ACTIVITY_STATS_LIMIT_DAYS"])
|
).get(
|
||||||
|
"days_of_retention",
|
||||||
|
current_app.config["ACTIVITY_STATS_LIMIT_DAYS"].get(number_of_days),
|
||||||
|
)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def organization(self):
|
def organization(self):
|
||||||
|
|||||||
@@ -64,10 +64,22 @@
|
|||||||
|
|
||||||
{% if current_user.has_permissions('view_activity') %}
|
{% if current_user.has_permissions('view_activity') %}
|
||||||
<p class="font-body-sm">
|
<p class="font-body-sm">
|
||||||
<a href="{{ download_link }}" download="download" class="usa-link">Download this report (<abbr title="Comma separated values">CSV</abbr>)</a>
|
<a href="{{ download_link_seven_day }}" download="download" class="usa-link">Download all data last 7 days (<abbr title="Comma separated values">CSV</abbr>)</a>
|
||||||
 
|
 
|
||||||
Data available for {{ partials.service_data_retention_days }} days
|
Data available for {{ partials.service_data_retention_days }} days
|
||||||
</p>
|
</p>
|
||||||
|
<p class="font-body-sm">
|
||||||
|
<a href="{{ download_link_five_day }}" download="download" class="usa-link">Download all data last 5 days (<abbr title="Comma separated values">CSV</abbr>)</a>
|
||||||
|
 
|
||||||
|
</p>
|
||||||
|
<p class="font-body-sm">
|
||||||
|
<a href="{{ download_link_three_day }}" download="download" class="usa-link">Download all data last 3 days (<abbr title="Comma separated values">CSV</abbr>)</a>
|
||||||
|
 
|
||||||
|
</p>
|
||||||
|
<p class="font-body-sm">
|
||||||
|
<a href="{{ download_link_today }}" download="download" class="usa-link">Download all data today (<abbr title="Comma separated values">CSV</abbr>)</a>
|
||||||
|
 
|
||||||
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{{ ajax_block(
|
{{ ajax_block(
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ from flask_login import current_user
|
|||||||
from app.models.spreadsheet import Spreadsheet
|
from app.models.spreadsheet import Spreadsheet
|
||||||
from app.utils import hilite
|
from app.utils import hilite
|
||||||
from app.utils.templates import get_sample_template
|
from app.utils.templates import get_sample_template
|
||||||
from notifications_utils.logging import scrub
|
|
||||||
from notifications_utils.recipients import RecipientCSV
|
from notifications_utils.recipients import RecipientCSV
|
||||||
|
|
||||||
|
|
||||||
@@ -74,12 +73,11 @@ def generate_notifications_csv(**kwargs):
|
|||||||
|
|
||||||
# This generates the "batch" csv report
|
# This generates the "batch" csv report
|
||||||
if kwargs.get("job_id"):
|
if kwargs.get("job_id"):
|
||||||
# The kwargs contain the job id, which is linked to the recipient's partial phone number in other debug
|
|
||||||
# Some unit tests are mocking the kwargs and turning them into a function instead of dict,
|
# Some unit tests are mocking the kwargs and turning them into a function instead of dict,
|
||||||
# hence the try/except.
|
# hence the try/except.
|
||||||
try:
|
try:
|
||||||
current_app.logger.info(
|
current_app.logger.info(
|
||||||
hilite(f"Setting up report with kwargs {scrub(json.dumps(kwargs))}")
|
hilite(f"Setting up report with kwargs {json.dumps(kwargs)}")
|
||||||
)
|
)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
@@ -89,7 +87,7 @@ def generate_notifications_csv(**kwargs):
|
|||||||
# we display to 999 characters, because we don't want to show the contents for reports with thousands of rows.
|
# we display to 999 characters, because we don't want to show the contents for reports with thousands of rows.
|
||||||
current_app.logger.info(
|
current_app.logger.info(
|
||||||
hilite(
|
hilite(
|
||||||
f"Original csv for job_id {kwargs['job_id']}: {scrub(original_file_contents[0:999])}"
|
f"Original csv for job_id {kwargs['job_id']}: {original_file_contents[0:999]}"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
original_upload = RecipientCSV(
|
original_upload = RecipientCSV(
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ plugins.addSrc = require('gulp-add-src');
|
|||||||
plugins.babel = require('gulp-babel');
|
plugins.babel = require('gulp-babel');
|
||||||
plugins.cleanCSS = require('gulp-clean-css');
|
plugins.cleanCSS = require('gulp-clean-css');
|
||||||
plugins.concat = require('gulp-concat');
|
plugins.concat = require('gulp-concat');
|
||||||
plugins.cssUrlAdjuster = require('gulp-css-url-adjuster');
|
|
||||||
plugins.jshint = require('gulp-jshint');
|
plugins.jshint = require('gulp-jshint');
|
||||||
plugins.prettyerror = require('gulp-prettyerror');
|
plugins.prettyerror = require('gulp-prettyerror');
|
||||||
plugins.rollup = require('gulp-better-rollup')
|
plugins.rollup = require('gulp-better-rollup')
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ applications:
|
|||||||
- route: ((cloud_dot_gov_route))
|
- route: ((cloud_dot_gov_route))
|
||||||
|
|
||||||
services:
|
services:
|
||||||
- notify-admin-redis-((env))
|
- notify-admin-redis-v70-((env))
|
||||||
- notify-api-csv-upload-bucket-((env))
|
- notify-api-csv-upload-bucket-((env))
|
||||||
- notify-admin-logo-upload-bucket-((env))
|
- notify-admin-logo-upload-bucket-((env))
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ def configure_handler(handler, app, formatter):
|
|||||||
handler.addFilter(AppNameFilter(app.config["NOTIFY_APP_NAME"]))
|
handler.addFilter(AppNameFilter(app.config["NOTIFY_APP_NAME"]))
|
||||||
handler.addFilter(RequestIdFilter())
|
handler.addFilter(RequestIdFilter())
|
||||||
handler.addFilter(ServiceIdFilter())
|
handler.addFilter(ServiceIdFilter())
|
||||||
|
handler.addFilter(PIIFilter())
|
||||||
|
|
||||||
return handler
|
return handler
|
||||||
|
|
||||||
@@ -134,13 +135,30 @@ class JSONFormatter(BaseJSONFormatter):
|
|||||||
return log_record
|
return log_record
|
||||||
|
|
||||||
|
|
||||||
def scrub(msg):
|
class PIIFilter(logging.Filter):
|
||||||
# Eventually we want to scrub all messages in all logs for phone numbers
|
def scrub(self, msg):
|
||||||
# and email addresses, masking them. Ultimately this will probably get
|
# Eventually we want to scrub all messages in all logs for phone numbers
|
||||||
# refactored into a 'SafeLogger' subclass or something, but let's start here
|
# and email addresses, masking them. Ultimately this will probably get
|
||||||
# with phones.
|
# refactored into a 'SafeLogger' subclass or something, but let's start here
|
||||||
phones = re.findall("(?:\\+ *)?\\d[\\d\\- ]{7,}\\d", msg)
|
# with phones.
|
||||||
phones = [phone.replace("-", "").replace(" ", "") for phone in phones]
|
|
||||||
for phone in phones:
|
# Sometimes just an exception object is passed in for the message, skip those.
|
||||||
msg = msg.replace(phone, f"1XXXXX{phone[-5:]}")
|
if not isinstance(msg, str):
|
||||||
return msg
|
return msg
|
||||||
|
phones = re.findall("(?:\\+ *)?\\d[\\d\\- ]{7,}\\d", msg)
|
||||||
|
phones = [phone.replace("-", "").replace(" ", "") for phone in phones]
|
||||||
|
for phone in phones:
|
||||||
|
msg = msg.replace(phone, "1XXXXXXXXXX")
|
||||||
|
|
||||||
|
emails = re.findall(
|
||||||
|
r"[\w\.-]+@[\w\.-]+", msg
|
||||||
|
) # ['alice@google.com', 'bob@abc.com']
|
||||||
|
for email in emails:
|
||||||
|
# do something with each found email string
|
||||||
|
masked_email = "XXXXX@XXXXXXX"
|
||||||
|
msg = msg.replace(email, masked_email)
|
||||||
|
return msg
|
||||||
|
|
||||||
|
def filter(self, record):
|
||||||
|
record.msg = self.scrub(record.msg)
|
||||||
|
return record
|
||||||
|
|||||||
3426
package-lock.json
generated
3426
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
17
package.json
17
package.json
@@ -25,24 +25,24 @@
|
|||||||
"graceful-fs": "^4.2.11"
|
"graceful-fs": "^4.2.11"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@uswds/uswds": "^3.4.1",
|
"@uswds/uswds": "^3.8.1",
|
||||||
"cbor-js": "0.1.0",
|
"cbor-js": "0.1.0",
|
||||||
"chart.js": "^4.4.2",
|
"chart.js": "^4.4.3",
|
||||||
"govuk_frontend_toolkit": "8.1.0",
|
"govuk_frontend_toolkit": "8.1.0",
|
||||||
"govuk-frontend": "2.13.0",
|
"govuk-frontend": "2.13.0",
|
||||||
"hogan": "1.0.2",
|
"hogan": "1.0.2",
|
||||||
"jquery": "3.7.1",
|
"jquery": "3.7.1",
|
||||||
"morphdom": "2.6.1",
|
"morphdom": "2.7.2",
|
||||||
"python": "^0.0.4",
|
"python": "^0.0.4",
|
||||||
"query-command-supported": "1.0.0",
|
"query-command-supported": "1.0.0",
|
||||||
"sass-embedded": "^1.69.5",
|
"sass-embedded": "^1.77.5",
|
||||||
"socket.io-client": "^4.2.0",
|
"socket.io-client": "^4.2.0",
|
||||||
"textarea-caret": "3.1.0",
|
"textarea-caret": "3.1.0",
|
||||||
"timeago": "1.6.7"
|
"timeago": "1.6.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.19.6",
|
"@babel/core": "7.24.7",
|
||||||
"@babel/preset-env": "7.19.4",
|
"@babel/preset-env": "7.24.7",
|
||||||
"@uswds/compile": "^1.1.0",
|
"@uswds/compile": "^1.1.0",
|
||||||
"better-npm-audit": "^3.7.3",
|
"better-npm-audit": "^3.7.3",
|
||||||
"gulp": "^4.0.2",
|
"gulp": "^4.0.2",
|
||||||
@@ -51,15 +51,14 @@
|
|||||||
"gulp-better-rollup": "4.0.1",
|
"gulp-better-rollup": "4.0.1",
|
||||||
"gulp-clean-css": "4.3.0",
|
"gulp-clean-css": "4.3.0",
|
||||||
"gulp-concat": "2.6.1",
|
"gulp-concat": "2.6.1",
|
||||||
"gulp-css-url-adjuster": "0.2.3",
|
|
||||||
"gulp-include": "2.4.1",
|
"gulp-include": "2.4.1",
|
||||||
"gulp-jshint": "2.1.0",
|
"gulp-jshint": "2.1.0",
|
||||||
"gulp-prettyerror": "2.0.0",
|
"gulp-prettyerror": "2.0.0",
|
||||||
"gulp-uglify": "3.0.2",
|
"gulp-uglify": "3.0.2",
|
||||||
"jest": "29.2.2",
|
"jest": "29.7.0",
|
||||||
"jest-each": "^29.2.1",
|
"jest-each": "^29.2.1",
|
||||||
"jest-environment-jsdom": "^29.2.2",
|
"jest-environment-jsdom": "^29.2.2",
|
||||||
"jshint": "2.13.5",
|
"jshint": "2.13.6",
|
||||||
"jshint-stylish": "2.2.1",
|
"jshint-stylish": "2.2.1",
|
||||||
"rollup": "1.32.1",
|
"rollup": "1.32.1",
|
||||||
"rollup-plugin-commonjs": "10.1.0",
|
"rollup-plugin-commonjs": "10.1.0",
|
||||||
|
|||||||
183
poetry.lock
generated
183
poetry.lock
generated
@@ -182,17 +182,17 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "boto3"
|
name = "boto3"
|
||||||
version = "1.34.128"
|
version = "1.34.135"
|
||||||
description = "The AWS SDK for Python"
|
description = "The AWS SDK for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "boto3-1.34.128-py3-none-any.whl", hash = "sha256:a048ff980a81cd652724a73bc496c519b336fabe19cc8bfc6c53b2ff6eb22c7b"},
|
{file = "boto3-1.34.135-py3-none-any.whl", hash = "sha256:6f5d7a20afbe45e3f7c6b5e96071752d36c3942535b1f7924964f1fdf25376a7"},
|
||||||
{file = "boto3-1.34.128.tar.gz", hash = "sha256:43a6e99f53a8d34b3b4dbe424dbcc6b894350dc41a85b0af7c7bc24a7ec2cead"},
|
{file = "boto3-1.34.135.tar.gz", hash = "sha256:344f635233c85dbb509b87638232ff9132739f90bb5e6bf01fa0e0a521a9107e"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
botocore = ">=1.34.128,<1.35.0"
|
botocore = ">=1.34.135,<1.35.0"
|
||||||
jmespath = ">=0.7.1,<2.0.0"
|
jmespath = ">=0.7.1,<2.0.0"
|
||||||
s3transfer = ">=0.10.0,<0.11.0"
|
s3transfer = ">=0.10.0,<0.11.0"
|
||||||
|
|
||||||
@@ -201,13 +201,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "botocore"
|
name = "botocore"
|
||||||
version = "1.34.128"
|
version = "1.34.135"
|
||||||
description = "Low-level, data-driven core of boto 3."
|
description = "Low-level, data-driven core of boto 3."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "botocore-1.34.128-py3-none-any.whl", hash = "sha256:db67fda136c372ab3fa432580c819c89ba18d28a6152a4d2a7ea40d44082892e"},
|
{file = "botocore-1.34.135-py3-none-any.whl", hash = "sha256:3aa9e85e7c479babefb5a590e844435449df418085f3c74d604277bc52dc3109"},
|
||||||
{file = "botocore-1.34.128.tar.gz", hash = "sha256:8d8e03f7c8c080ecafda72036eb3b482d649f8417c90b5dca33b7c2c47adb0c9"},
|
{file = "botocore-1.34.135.tar.gz", hash = "sha256:2e72f37072f75cb1391fca9d7a4c32cecb52a3557d62431d0f59d5311dc7d0cf"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -473,63 +473,63 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "coverage"
|
name = "coverage"
|
||||||
version = "7.5.3"
|
version = "7.5.4"
|
||||||
description = "Code coverage measurement for Python"
|
description = "Code coverage measurement for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "coverage-7.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a6519d917abb15e12380406d721e37613e2a67d166f9fb7e5a8ce0375744cd45"},
|
{file = "coverage-7.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99"},
|
||||||
{file = "coverage-7.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aea7da970f1feccf48be7335f8b2ca64baf9b589d79e05b9397a06696ce1a1ec"},
|
{file = "coverage-7.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47"},
|
||||||
{file = "coverage-7.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:923b7b1c717bd0f0f92d862d1ff51d9b2b55dbbd133e05680204465f454bb286"},
|
{file = "coverage-7.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e"},
|
||||||
{file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62bda40da1e68898186f274f832ef3e759ce929da9a9fd9fcf265956de269dbc"},
|
{file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d"},
|
||||||
{file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8b7339180d00de83e930358223c617cc343dd08e1aa5ec7b06c3a121aec4e1d"},
|
{file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3"},
|
||||||
{file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:25a5caf742c6195e08002d3b6c2dd6947e50efc5fc2c2205f61ecb47592d2d83"},
|
{file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016"},
|
||||||
{file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:05ac5f60faa0c704c0f7e6a5cbfd6f02101ed05e0aee4d2822637a9e672c998d"},
|
{file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136"},
|
||||||
{file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:239a4e75e09c2b12ea478d28815acf83334d32e722e7433471fbf641c606344c"},
|
{file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9"},
|
||||||
{file = "coverage-7.5.3-cp310-cp310-win32.whl", hash = "sha256:a5812840d1d00eafae6585aba38021f90a705a25b8216ec7f66aebe5b619fb84"},
|
{file = "coverage-7.5.4-cp310-cp310-win32.whl", hash = "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8"},
|
||||||
{file = "coverage-7.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:33ca90a0eb29225f195e30684ba4a6db05dbef03c2ccd50b9077714c48153cac"},
|
{file = "coverage-7.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f"},
|
||||||
{file = "coverage-7.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f81bc26d609bf0fbc622c7122ba6307993c83c795d2d6f6f6fd8c000a770d974"},
|
{file = "coverage-7.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5"},
|
||||||
{file = "coverage-7.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7cec2af81f9e7569280822be68bd57e51b86d42e59ea30d10ebdbb22d2cb7232"},
|
{file = "coverage-7.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba"},
|
||||||
{file = "coverage-7.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55f689f846661e3f26efa535071775d0483388a1ccfab899df72924805e9e7cd"},
|
{file = "coverage-7.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b"},
|
||||||
{file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50084d3516aa263791198913a17354bd1dc627d3c1639209640b9cac3fef5807"},
|
{file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080"},
|
||||||
{file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:341dd8f61c26337c37988345ca5c8ccabeff33093a26953a1ac72e7d0103c4fb"},
|
{file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"},
|
||||||
{file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ab0b028165eea880af12f66086694768f2c3139b2c31ad5e032c8edbafca6ffc"},
|
{file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da"},
|
||||||
{file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5bc5a8c87714b0c67cfeb4c7caa82b2d71e8864d1a46aa990b5588fa953673b8"},
|
{file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0"},
|
||||||
{file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:38a3b98dae8a7c9057bd91fbf3415c05e700a5114c5f1b5b0ea5f8f429ba6614"},
|
{file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078"},
|
||||||
{file = "coverage-7.5.3-cp311-cp311-win32.whl", hash = "sha256:fcf7d1d6f5da887ca04302db8e0e0cf56ce9a5e05f202720e49b3e8157ddb9a9"},
|
{file = "coverage-7.5.4-cp311-cp311-win32.whl", hash = "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806"},
|
||||||
{file = "coverage-7.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:8c836309931839cca658a78a888dab9676b5c988d0dd34ca247f5f3e679f4e7a"},
|
{file = "coverage-7.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d"},
|
||||||
{file = "coverage-7.5.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:296a7d9bbc598e8744c00f7a6cecf1da9b30ae9ad51c566291ff1314e6cbbed8"},
|
{file = "coverage-7.5.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233"},
|
||||||
{file = "coverage-7.5.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:34d6d21d8795a97b14d503dcaf74226ae51eb1f2bd41015d3ef332a24d0a17b3"},
|
{file = "coverage-7.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747"},
|
||||||
{file = "coverage-7.5.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e317953bb4c074c06c798a11dbdd2cf9979dbcaa8ccc0fa4701d80042d4ebf1"},
|
{file = "coverage-7.5.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638"},
|
||||||
{file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:705f3d7c2b098c40f5b81790a5fedb274113373d4d1a69e65f8b68b0cc26f6db"},
|
{file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e"},
|
||||||
{file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1196e13c45e327d6cd0b6e471530a1882f1017eb83c6229fc613cd1a11b53cd"},
|
{file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555"},
|
||||||
{file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:015eddc5ccd5364dcb902eaecf9515636806fa1e0d5bef5769d06d0f31b54523"},
|
{file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f"},
|
||||||
{file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fd27d8b49e574e50caa65196d908f80e4dff64d7e592d0c59788b45aad7e8b35"},
|
{file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c"},
|
||||||
{file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:33fc65740267222fc02975c061eb7167185fef4cc8f2770267ee8bf7d6a42f84"},
|
{file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805"},
|
||||||
{file = "coverage-7.5.3-cp312-cp312-win32.whl", hash = "sha256:7b2a19e13dfb5c8e145c7a6ea959485ee8e2204699903c88c7d25283584bfc08"},
|
{file = "coverage-7.5.4-cp312-cp312-win32.whl", hash = "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b"},
|
||||||
{file = "coverage-7.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:0bbddc54bbacfc09b3edaec644d4ac90c08ee8ed4844b0f86227dcda2d428fcb"},
|
{file = "coverage-7.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7"},
|
||||||
{file = "coverage-7.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f78300789a708ac1f17e134593f577407d52d0417305435b134805c4fb135adb"},
|
{file = "coverage-7.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882"},
|
||||||
{file = "coverage-7.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b368e1aee1b9b75757942d44d7598dcd22a9dbb126affcbba82d15917f0cc155"},
|
{file = "coverage-7.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d"},
|
||||||
{file = "coverage-7.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f836c174c3a7f639bded48ec913f348c4761cbf49de4a20a956d3431a7c9cb24"},
|
{file = "coverage-7.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53"},
|
||||||
{file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:244f509f126dc71369393ce5fea17c0592c40ee44e607b6d855e9c4ac57aac98"},
|
{file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4"},
|
||||||
{file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4c2872b3c91f9baa836147ca33650dc5c172e9273c808c3c3199c75490e709d"},
|
{file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4"},
|
||||||
{file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dd4b3355b01273a56b20c219e74e7549e14370b31a4ffe42706a8cda91f19f6d"},
|
{file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9"},
|
||||||
{file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f542287b1489c7a860d43a7d8883e27ca62ab84ca53c965d11dac1d3a1fab7ce"},
|
{file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f"},
|
||||||
{file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:75e3f4e86804023e991096b29e147e635f5e2568f77883a1e6eed74512659ab0"},
|
{file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f"},
|
||||||
{file = "coverage-7.5.3-cp38-cp38-win32.whl", hash = "sha256:c59d2ad092dc0551d9f79d9d44d005c945ba95832a6798f98f9216ede3d5f485"},
|
{file = "coverage-7.5.4-cp38-cp38-win32.whl", hash = "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f"},
|
||||||
{file = "coverage-7.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:fa21a04112c59ad54f69d80e376f7f9d0f5f9123ab87ecd18fbb9ec3a2beed56"},
|
{file = "coverage-7.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633"},
|
||||||
{file = "coverage-7.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5102a92855d518b0996eb197772f5ac2a527c0ec617124ad5242a3af5e25f85"},
|
{file = "coverage-7.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088"},
|
||||||
{file = "coverage-7.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d1da0a2e3b37b745a2b2a678a4c796462cf753aebf94edcc87dcc6b8641eae31"},
|
{file = "coverage-7.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4"},
|
||||||
{file = "coverage-7.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8383a6c8cefba1b7cecc0149415046b6fc38836295bc4c84e820872eb5478b3d"},
|
{file = "coverage-7.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7"},
|
||||||
{file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9aad68c3f2566dfae84bf46295a79e79d904e1c21ccfc66de88cd446f8686341"},
|
{file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8"},
|
||||||
{file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e079c9ec772fedbade9d7ebc36202a1d9ef7291bc9b3a024ca395c4d52853d7"},
|
{file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d"},
|
||||||
{file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bde997cac85fcac227b27d4fb2c7608a2c5f6558469b0eb704c5726ae49e1c52"},
|
{file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029"},
|
||||||
{file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:990fb20b32990b2ce2c5f974c3e738c9358b2735bc05075d50a6f36721b8f303"},
|
{file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c"},
|
||||||
{file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3d5a67f0da401e105753d474369ab034c7bae51a4c31c77d94030d59e41df5bd"},
|
{file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7"},
|
||||||
{file = "coverage-7.5.3-cp39-cp39-win32.whl", hash = "sha256:e08c470c2eb01977d221fd87495b44867a56d4d594f43739a8028f8646a51e0d"},
|
{file = "coverage-7.5.4-cp39-cp39-win32.whl", hash = "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace"},
|
||||||
{file = "coverage-7.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:1d2a830ade66d3563bb61d1e3c77c8def97b30ed91e166c67d0632c018f380f0"},
|
{file = "coverage-7.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d"},
|
||||||
{file = "coverage-7.5.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:3538d8fb1ee9bdd2e2692b3b18c22bb1c19ffbefd06880f5ac496e42d7bb3884"},
|
{file = "coverage-7.5.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5"},
|
||||||
{file = "coverage-7.5.3.tar.gz", hash = "sha256:04aefca5190d1dc7a53a4c1a5a7f8568811306d7a8ee231c42fb69215571944f"},
|
{file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
@@ -741,34 +741,34 @@ testing = ["hatch", "pre-commit", "pytest", "tox"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filelock"
|
name = "filelock"
|
||||||
version = "3.15.1"
|
version = "3.15.4"
|
||||||
description = "A platform independent file lock."
|
description = "A platform independent file lock."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "filelock-3.15.1-py3-none-any.whl", hash = "sha256:71b3102950e91dfc1bb4209b64be4dc8854f40e5f534428d8684f953ac847fac"},
|
{file = "filelock-3.15.4-py3-none-any.whl", hash = "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7"},
|
||||||
{file = "filelock-3.15.1.tar.gz", hash = "sha256:58a2549afdf9e02e10720eaa4d4470f56386d7a6f72edd7d0596337af8ed7ad8"},
|
{file = "filelock-3.15.4.tar.gz", hash = "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"]
|
docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"]
|
||||||
testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-asyncio (>=0.21)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"]
|
testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-asyncio (>=0.21)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)", "virtualenv (>=20.26.2)"]
|
||||||
typing = ["typing-extensions (>=4.8)"]
|
typing = ["typing-extensions (>=4.8)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flake8"
|
name = "flake8"
|
||||||
version = "7.0.0"
|
version = "7.1.0"
|
||||||
description = "the modular source code checker: pep8 pyflakes and co"
|
description = "the modular source code checker: pep8 pyflakes and co"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8.1"
|
python-versions = ">=3.8.1"
|
||||||
files = [
|
files = [
|
||||||
{file = "flake8-7.0.0-py2.py3-none-any.whl", hash = "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3"},
|
{file = "flake8-7.1.0-py2.py3-none-any.whl", hash = "sha256:2e416edcc62471a64cea09353f4e7bdba32aeb079b6e360554c659a122b1bc6a"},
|
||||||
{file = "flake8-7.0.0.tar.gz", hash = "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132"},
|
{file = "flake8-7.1.0.tar.gz", hash = "sha256:48a07b626b55236e0fb4784ee69a465fbf59d79eec1f5b4785c3d3bc57d17aa5"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
mccabe = ">=0.7.0,<0.8.0"
|
mccabe = ">=0.7.0,<0.8.0"
|
||||||
pycodestyle = ">=2.11.0,<2.12.0"
|
pycodestyle = ">=2.12.0,<2.13.0"
|
||||||
pyflakes = ">=3.2.0,<3.3.0"
|
pyflakes = ">=3.2.0,<3.3.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1344,9 +1344,13 @@ files = [
|
|||||||
{file = "lxml-5.2.2-cp36-cp36m-win_amd64.whl", hash = "sha256:edcfa83e03370032a489430215c1e7783128808fd3e2e0a3225deee278585196"},
|
{file = "lxml-5.2.2-cp36-cp36m-win_amd64.whl", hash = "sha256:edcfa83e03370032a489430215c1e7783128808fd3e2e0a3225deee278585196"},
|
||||||
{file = "lxml-5.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:28bf95177400066596cdbcfc933312493799382879da504633d16cf60bba735b"},
|
{file = "lxml-5.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:28bf95177400066596cdbcfc933312493799382879da504633d16cf60bba735b"},
|
||||||
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a745cc98d504d5bd2c19b10c79c61c7c3df9222629f1b6210c0368177589fb8"},
|
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a745cc98d504d5bd2c19b10c79c61c7c3df9222629f1b6210c0368177589fb8"},
|
||||||
|
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b590b39ef90c6b22ec0be925b211298e810b4856909c8ca60d27ffbca6c12e6"},
|
||||||
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b336b0416828022bfd5a2e3083e7f5ba54b96242159f83c7e3eebaec752f1716"},
|
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b336b0416828022bfd5a2e3083e7f5ba54b96242159f83c7e3eebaec752f1716"},
|
||||||
|
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:c2faf60c583af0d135e853c86ac2735ce178f0e338a3c7f9ae8f622fd2eb788c"},
|
||||||
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:4bc6cb140a7a0ad1f7bc37e018d0ed690b7b6520ade518285dc3171f7a117905"},
|
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:4bc6cb140a7a0ad1f7bc37e018d0ed690b7b6520ade518285dc3171f7a117905"},
|
||||||
|
{file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7ff762670cada8e05b32bf1e4dc50b140790909caa8303cfddc4d702b71ea184"},
|
||||||
{file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:57f0a0bbc9868e10ebe874e9f129d2917750adf008fe7b9c1598c0fbbfdde6a6"},
|
{file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:57f0a0bbc9868e10ebe874e9f129d2917750adf008fe7b9c1598c0fbbfdde6a6"},
|
||||||
|
{file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:a6d2092797b388342c1bc932077ad232f914351932353e2e8706851c870bca1f"},
|
||||||
{file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:60499fe961b21264e17a471ec296dcbf4365fbea611bf9e303ab69db7159ce61"},
|
{file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:60499fe961b21264e17a471ec296dcbf4365fbea611bf9e303ab69db7159ce61"},
|
||||||
{file = "lxml-5.2.2-cp37-cp37m-win32.whl", hash = "sha256:d9b342c76003c6b9336a80efcc766748a333573abf9350f4094ee46b006ec18f"},
|
{file = "lxml-5.2.2-cp37-cp37m-win32.whl", hash = "sha256:d9b342c76003c6b9336a80efcc766748a333573abf9350f4094ee46b006ec18f"},
|
||||||
{file = "lxml-5.2.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b16db2770517b8799c79aa80f4053cd6f8b716f21f8aca962725a9565ce3ee40"},
|
{file = "lxml-5.2.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b16db2770517b8799c79aa80f4053cd6f8b716f21f8aca962725a9565ce3ee40"},
|
||||||
@@ -1899,13 +1903,13 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pip"
|
name = "pip"
|
||||||
version = "24.0"
|
version = "24.1.1"
|
||||||
description = "The PyPA recommended tool for installing Python packages."
|
description = "The PyPA recommended tool for installing Python packages."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "pip-24.0-py3-none-any.whl", hash = "sha256:ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc"},
|
{file = "pip-24.1.1-py3-none-any.whl", hash = "sha256:efca15145a95e95c00608afeab66311d40bfb73bb2266a855befd705e6bb15a0"},
|
||||||
{file = "pip-24.0.tar.gz", hash = "sha256:ea9bd1a847e8c5774a5777bb398c19e80bcd4e2aa16a4b301b718fe6f593aba2"},
|
{file = "pip-24.1.1.tar.gz", hash = "sha256:5aa64f65e1952733ee0a9a9b1f52496ebdb3f3077cc46f80a16d983b58d1180a"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2054,13 +2058,13 @@ defusedxml = ">=0.7.1,<0.8.0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pycodestyle"
|
name = "pycodestyle"
|
||||||
version = "2.11.1"
|
version = "2.12.0"
|
||||||
description = "Python style guide checker"
|
description = "Python style guide checker"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"},
|
{file = "pycodestyle-2.12.0-py2.py3-none-any.whl", hash = "sha256:949a39f6b86c3e1515ba1787c2022131d165a8ad271b11370a8819aa070269e4"},
|
||||||
{file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"},
|
{file = "pycodestyle-2.12.0.tar.gz", hash = "sha256:442f950141b4f43df752dd303511ffded3a04c2b6fb7f65980574f0c31e6e79c"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2474,13 +2478,13 @@ unidecode = ["Unidecode (>=1.1.1)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "python-socketio"
|
name = "python-socketio"
|
||||||
version = "5.11.2"
|
version = "5.11.3"
|
||||||
description = "Socket.IO server and client for Python"
|
description = "Socket.IO server and client for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "python-socketio-5.11.2.tar.gz", hash = "sha256:ae6a1de5c5209ca859dc574dccc8931c4be17ee003e74ce3b8d1306162bb4a37"},
|
{file = "python_socketio-5.11.3-py3-none-any.whl", hash = "sha256:2a923a831ff70664b7c502df093c423eb6aa93c1ce68b8319e840227a26d8b69"},
|
||||||
{file = "python_socketio-5.11.2-py3-none-any.whl", hash = "sha256:b9f22a8ff762d7a6e123d16a43ddb1a27d50f07c3c88ea999334f2f89b0ad52b"},
|
{file = "python_socketio-5.11.3.tar.gz", hash = "sha256:194af8cdbb7b0768c2e807ba76c7abc288eb5bb85559b7cddee51a6bc7a65737"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -2528,6 +2532,7 @@ files = [
|
|||||||
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
|
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
|
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
|
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
|
||||||
|
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
|
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
|
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
|
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
|
||||||
@@ -2582,13 +2587,13 @@ toml = ["tomli (>=2.0.1)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redis"
|
name = "redis"
|
||||||
version = "5.0.6"
|
version = "5.0.7"
|
||||||
description = "Python client for Redis database and key-value store"
|
description = "Python client for Redis database and key-value store"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "redis-5.0.6-py3-none-any.whl", hash = "sha256:c0d6d990850c627bbf7be01c5c4cbaadf67b48593e913bb71c9819c30df37eee"},
|
{file = "redis-5.0.7-py3-none-any.whl", hash = "sha256:0e479e24da960c690be5d9b96d21f7b918a98c0cf49af3b6fafaa0753f93a0db"},
|
||||||
{file = "redis-5.0.6.tar.gz", hash = "sha256:38473cd7c6389ad3e44a91f4c3eaf6bcb8a9f746007f29bf4fb20824ff0b2197"},
|
{file = "redis-5.0.7.tar.gz", hash = "sha256:8f611490b93c8109b50adc317b31bfd84fff31def3475b92e7e80bf39f48175b"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
@@ -2774,13 +2779,13 @@ diagram = ["matplotlib (>=3.0.0)", "pydot (>=1.3.0)", "tqdm (>=v4.31.0)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "s3transfer"
|
name = "s3transfer"
|
||||||
version = "0.10.1"
|
version = "0.10.2"
|
||||||
description = "An Amazon S3 Transfer Manager"
|
description = "An Amazon S3 Transfer Manager"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">= 3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "s3transfer-0.10.1-py3-none-any.whl", hash = "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d"},
|
{file = "s3transfer-0.10.2-py3-none-any.whl", hash = "sha256:eca1c20de70a39daee580aef4986996620f365c4e0fda6a86100231d62f1bf69"},
|
||||||
{file = "s3transfer-0.10.1.tar.gz", hash = "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19"},
|
{file = "s3transfer-0.10.2.tar.gz", hash = "sha256:0711534e9356d3cc692fdde846b4a1e4b0cb6519971860796e6bc4c7aea00ef6"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -2983,13 +2988,13 @@ zstd = ["zstandard (>=0.18.0)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "virtualenv"
|
name = "virtualenv"
|
||||||
version = "20.26.2"
|
version = "20.26.3"
|
||||||
description = "Virtual Python Environment builder"
|
description = "Virtual Python Environment builder"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "virtualenv-20.26.2-py3-none-any.whl", hash = "sha256:a624db5e94f01ad993d476b9ee5346fdf7b9de43ccaee0e0197012dc838a0e9b"},
|
{file = "virtualenv-20.26.3-py3-none-any.whl", hash = "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589"},
|
||||||
{file = "virtualenv-20.26.2.tar.gz", hash = "sha256:82bf0f4eebbb78d36ddaee0283d43fe5736b53880b8a8cdcd37390a07ac3741c"},
|
{file = "virtualenv-20.26.3.tar.gz", hash = "sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -3112,4 +3117,4 @@ files = [
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.12.2"
|
python-versions = "^3.12.2"
|
||||||
content-hash = "b45f2c38493f81bd7fc9d4bfd294b001d71e4082380eb0851d4f3ea8dcdb949c"
|
content-hash = "cc90483c3fdf6d2900f9ec64345b6cb8c2f0f83040a57a0051d500e23f997963"
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ wtforms = "~=3.1"
|
|||||||
markdown = "^3.5.2"
|
markdown = "^3.5.2"
|
||||||
async-timeout = "^4.0.3"
|
async-timeout = "^4.0.3"
|
||||||
bleach = "^6.1.0"
|
bleach = "^6.1.0"
|
||||||
boto3 = "^1.34.128"
|
boto3 = "^1.34.135"
|
||||||
botocore = "^1.34.128"
|
botocore = "^1.34.135"
|
||||||
cachetools = "^5.3.3"
|
cachetools = "^5.3.3"
|
||||||
cffi = "^1.16.0"
|
cffi = "^1.16.0"
|
||||||
cryptography = "^42.0.8"
|
cryptography = "^42.0.8"
|
||||||
@@ -53,9 +53,9 @@ ordered-set = "^4.1.0"
|
|||||||
phonenumbers = "^8.13.39"
|
phonenumbers = "^8.13.39"
|
||||||
pycparser = "^2.22"
|
pycparser = "^2.22"
|
||||||
python-json-logger = "^2.0.7"
|
python-json-logger = "^2.0.7"
|
||||||
redis = "^5.0.6"
|
redis = "^5.0.7"
|
||||||
regex = "^2024.5.15"
|
regex = "^2024.5.15"
|
||||||
s3transfer = "^0.10.1"
|
s3transfer = "^0.10.2"
|
||||||
shapely = "^2.0.4"
|
shapely = "^2.0.4"
|
||||||
smartypants = "^2.0.1"
|
smartypants = "^2.0.1"
|
||||||
certifi = "^2024.2.2"
|
certifi = "^2024.2.2"
|
||||||
@@ -77,7 +77,7 @@ bandit = "*"
|
|||||||
black = "^24.2.0"
|
black = "^24.2.0"
|
||||||
coverage = "*"
|
coverage = "*"
|
||||||
freezegun = "^1.5.1"
|
freezegun = "^1.5.1"
|
||||||
flake8 = "^7.0.0"
|
flake8 = "^7.1.0"
|
||||||
flake8-bugbear = "^24.1.17"
|
flake8-bugbear = "^24.1.17"
|
||||||
flake8-print = "^5.0.0"
|
flake8-print = "^5.0.0"
|
||||||
flake8-pytest-style = "^1.7.2"
|
flake8-pytest-style = "^1.7.2"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ FLASK_APP=application.py
|
|||||||
FLASK_DEBUG=true
|
FLASK_DEBUG=true
|
||||||
WERKZEUG_DEBUG_PIN=off
|
WERKZEUG_DEBUG_PIN=off
|
||||||
|
|
||||||
NODE_VERSION=16.15.1
|
NODE_VERSION=22.3.0
|
||||||
NODE_EXTRA_CA_CERTS="path to Homebrew CA certificate"
|
NODE_EXTRA_CA_CERTS="path to Homebrew CA certificate"
|
||||||
|
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
terraform {
|
terraform {
|
||||||
required_version = "~> 1.0"
|
required_version = "~> 1.7"
|
||||||
required_providers {
|
required_providers {
|
||||||
cloudfoundry = {
|
cloudfoundry = {
|
||||||
source = "cloudfoundry-community/cloudfoundry"
|
source = "cloudfoundry-community/cloudfoundry"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,18 @@ locals {
|
|||||||
recursive_delete = false
|
recursive_delete = false
|
||||||
}
|
}
|
||||||
|
|
||||||
module "redis" {
|
module "redis-v70" {
|
||||||
source = "github.com/18f/terraform-cloudgov//redis?ref=v0.7.1"
|
source = "github.com/GSA-TTS/terraform-cloudgov//redis?ref=v1.0.0"
|
||||||
|
|
||||||
cf_org_name = local.cf_org_name
|
cf_org_name = local.cf_org_name
|
||||||
cf_space_name = local.cf_space_name
|
cf_space_name = local.cf_space_name
|
||||||
name = "${local.app_name}-redis-${local.env}"
|
name = "${local.app_name}-redis-v70-${local.env}"
|
||||||
recursive_delete = local.recursive_delete
|
redis_plan_name = "redis-dev"
|
||||||
redis_plan_name = "redis-dev"
|
json_params = jsonencode(
|
||||||
|
{
|
||||||
|
"engineVersion" : "7.0",
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
module "logo_upload_bucket" {
|
module "logo_upload_bucket" {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
terraform {
|
terraform {
|
||||||
required_version = "~> 1.0"
|
required_version = "~> 1.7"
|
||||||
required_providers {
|
required_providers {
|
||||||
cloudfoundry = {
|
cloudfoundry = {
|
||||||
source = "cloudfoundry-community/cloudfoundry"
|
source = "cloudfoundry-community/cloudfoundry"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
terraform {
|
terraform {
|
||||||
required_version = "~> 1.0"
|
required_version = "~> 1.7"
|
||||||
required_providers {
|
required_providers {
|
||||||
cloudfoundry = {
|
cloudfoundry = {
|
||||||
source = "cloudfoundry-community/cloudfoundry"
|
source = "cloudfoundry-community/cloudfoundry"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,18 @@ locals {
|
|||||||
recursive_delete = false
|
recursive_delete = false
|
||||||
}
|
}
|
||||||
|
|
||||||
module "redis" {
|
module "redis-v70" {
|
||||||
source = "github.com/18f/terraform-cloudgov//redis?ref=v0.7.1"
|
source = "github.com/GSA-TTS/terraform-cloudgov//redis?ref=v1.0.0"
|
||||||
|
|
||||||
cf_org_name = local.cf_org_name
|
cf_org_name = local.cf_org_name
|
||||||
cf_space_name = local.cf_space_name
|
cf_space_name = local.cf_space_name
|
||||||
name = "${local.app_name}-redis-${local.env}"
|
name = "${local.app_name}-redis-v70-${local.env}"
|
||||||
recursive_delete = local.recursive_delete
|
redis_plan_name = "redis-3node-large"
|
||||||
redis_plan_name = "redis-3node-large"
|
json_params = jsonencode(
|
||||||
|
{
|
||||||
|
"engineVersion" : "7.0",
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
module "logo_upload_bucket" {
|
module "logo_upload_bucket" {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
terraform {
|
terraform {
|
||||||
required_version = "~> 1.0"
|
required_version = "~> 1.7"
|
||||||
required_providers {
|
required_providers {
|
||||||
cloudfoundry = {
|
cloudfoundry = {
|
||||||
source = "cloudfoundry-community/cloudfoundry"
|
source = "cloudfoundry-community/cloudfoundry"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ locals {
|
|||||||
recursive_delete = true
|
recursive_delete = true
|
||||||
}
|
}
|
||||||
|
|
||||||
module "redis" {
|
module "redis" { # default v6.2; delete after v7.0 resource is bound
|
||||||
source = "github.com/18f/terraform-cloudgov//redis?ref=v0.7.1"
|
source = "github.com/18f/terraform-cloudgov//redis?ref=v0.7.1"
|
||||||
|
|
||||||
cf_org_name = local.cf_org_name
|
cf_org_name = local.cf_org_name
|
||||||
@@ -16,6 +16,20 @@ module "redis" {
|
|||||||
redis_plan_name = "redis-dev"
|
redis_plan_name = "redis-dev"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module "redis-v70" {
|
||||||
|
source = "github.com/GSA-TTS/terraform-cloudgov//redis?ref=v1.0.0"
|
||||||
|
|
||||||
|
cf_org_name = local.cf_org_name
|
||||||
|
cf_space_name = local.cf_space_name
|
||||||
|
name = "${local.app_name}-redis-v70-${local.env}"
|
||||||
|
redis_plan_name = "redis-dev"
|
||||||
|
json_params = jsonencode(
|
||||||
|
{
|
||||||
|
"engineVersion" : "7.0",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
module "logo_upload_bucket" {
|
module "logo_upload_bucket" {
|
||||||
source = "github.com/18f/terraform-cloudgov//s3?ref=v0.7.1"
|
source = "github.com/18f/terraform-cloudgov//s3?ref=v0.7.1"
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
terraform {
|
terraform {
|
||||||
required_version = "~> 1.0"
|
required_version = "~> 1.7"
|
||||||
required_providers {
|
required_providers {
|
||||||
cloudfoundry = {
|
cloudfoundry = {
|
||||||
source = "cloudfoundry-community/cloudfoundry"
|
source = "cloudfoundry-community/cloudfoundry"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
terraform {
|
terraform {
|
||||||
required_version = "~> 1.0"
|
required_version = "~> 1.7"
|
||||||
required_providers {
|
required_providers {
|
||||||
cloudfoundry = {
|
cloudfoundry = {
|
||||||
source = "cloudfoundry-community/cloudfoundry"
|
source = "cloudfoundry-community/cloudfoundry"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,26 @@ locals {
|
|||||||
recursive_delete = true
|
recursive_delete = true
|
||||||
}
|
}
|
||||||
|
|
||||||
module "redis" {
|
resource "null_resource" "prevent_destroy" {
|
||||||
source = "github.com/18f/terraform-cloudgov//redis?ref=v0.7.1"
|
|
||||||
|
|
||||||
cf_org_name = local.cf_org_name
|
lifecycle {
|
||||||
cf_space_name = local.cf_space_name
|
prevent_destroy = false # destroying staging is allowed
|
||||||
name = "${local.app_name}-redis-${local.env}"
|
}
|
||||||
recursive_delete = local.recursive_delete
|
}
|
||||||
redis_plan_name = "redis-dev"
|
|
||||||
|
|
||||||
|
module "redis-v70" {
|
||||||
|
source = "github.com/GSA-TTS/terraform-cloudgov//redis?ref=v1.0.0"
|
||||||
|
|
||||||
|
cf_org_name = local.cf_org_name
|
||||||
|
cf_space_name = local.cf_space_name
|
||||||
|
name = "${local.app_name}-redis-v70-${local.env}"
|
||||||
|
redis_plan_name = "redis-dev"
|
||||||
|
json_params = jsonencode(
|
||||||
|
{
|
||||||
|
"engineVersion" : "7.0",
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
module "logo_upload_bucket" {
|
module "logo_upload_bucket" {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
terraform {
|
terraform {
|
||||||
required_version = "~> 1.0"
|
required_version = "~> 1.7"
|
||||||
required_providers {
|
required_providers {
|
||||||
cloudfoundry = {
|
cloudfoundry = {
|
||||||
source = "cloudfoundry-community/cloudfoundry"
|
source = "cloudfoundry-community/cloudfoundry"
|
||||||
version = "0.53.0"
|
version = "0.53.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -228,12 +228,18 @@ def test_can_show_notifications_if_data_retention_not_available(
|
|||||||
url_for,
|
url_for,
|
||||||
".download_notifications_csv",
|
".download_notifications_csv",
|
||||||
message_type=None,
|
message_type=None,
|
||||||
|
number_of_days="seven_day",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
create_active_user_with_permissions(),
|
create_active_user_with_permissions(),
|
||||||
{"status": "failed"},
|
{"status": "failed"},
|
||||||
partial(url_for, ".download_notifications_csv", status="failed"),
|
partial(
|
||||||
|
url_for,
|
||||||
|
".download_notifications_csv",
|
||||||
|
status="failed",
|
||||||
|
number_of_days="seven_day",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
create_active_user_with_permissions(),
|
create_active_user_with_permissions(),
|
||||||
@@ -242,15 +248,13 @@ def test_can_show_notifications_if_data_retention_not_available(
|
|||||||
url_for,
|
url_for,
|
||||||
".download_notifications_csv",
|
".download_notifications_csv",
|
||||||
message_type="sms",
|
message_type="sms",
|
||||||
|
number_of_days="seven_day",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
create_active_user_view_permissions(),
|
create_active_user_view_permissions(),
|
||||||
{},
|
{},
|
||||||
partial(
|
partial(url_for, ".download_notifications_csv", number_of_days="seven_day"),
|
||||||
url_for,
|
|
||||||
".download_notifications_csv",
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
create_active_caseworking_user(),
|
create_active_caseworking_user(),
|
||||||
|
|||||||
@@ -51,11 +51,16 @@ def test_base_json_formatter_contains_service_id():
|
|||||||
assert service_id_filter.filter(record).service_id == "no-service-id"
|
assert service_id_filter.filter(record).service_id == "no-service-id"
|
||||||
|
|
||||||
|
|
||||||
def test_scrub():
|
def test_pii_filter():
|
||||||
result = logging.scrub(
|
record = builtin_logging.LogRecord(
|
||||||
"This is a message with 17775554324, and also 18884449323 and also 17775554324"
|
name="log thing",
|
||||||
)
|
level="info",
|
||||||
assert (
|
pathname="path",
|
||||||
result
|
lineno=123,
|
||||||
== "This is a message with 1XXXXX54324, and also 1XXXXX49323 and also 1XXXXX54324"
|
msg="phone1: 1555555555, phone2: 1555555554, email1: fake@fake.gov, email2: fake@fake2.fake.gov",
|
||||||
|
exc_info=None,
|
||||||
|
args=None,
|
||||||
)
|
)
|
||||||
|
pii_filter = logging.PIIFilter()
|
||||||
|
clean_msg = "phone1: 1XXXXXXXXXX, phone2: 1XXXXXXXXXX, email1: XXXXX@XXXXXXX, email2: XXXXX@XXXXXXX"
|
||||||
|
assert pii_filter.filter(record).msg == clean_msg
|
||||||
|
|||||||
Reference in New Issue
Block a user