Skip to content

Commit

Permalink
Merge pull request #891 from GSA/main
Browse files Browse the repository at this point in the history
Production deploy 10/31/23
  • Loading branch information
stvnrlly authored Nov 1, 2023
2 parents 867c721 + 4a98080 commit cf2dbfc
Show file tree
Hide file tree
Showing 98 changed files with 2,004 additions and 2,118 deletions.
16 changes: 14 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ NVMSH := $(shell [ -f "$(HOME)/.nvm/nvm.sh" ] && echo "$(HOME)/.nvm/nvm.sh" || e

.PHONY: bootstrap
bootstrap: generate-version-file ## Set up everything to run the app
poetry install
poetry install --sync
poetry run playwright install --with-deps
source $(NVMSH) --no-use && nvm install && npm ci --no-audit
source $(NVMSH) && npm run build
Expand Down Expand Up @@ -92,6 +92,18 @@ js-test: ## Run javascript unit tests
fix-imports: ## Fix imports using isort
poetry run isort ./app ./tests

.PHONY: py-lock
py-lock: ## Syncs dependencies and updates lock file without performing recursive internal updates
poetry lock --no-update
poetry install --sync

.PHONY: update-utils
update-utils: ## Forces Poetry to pull the latest changes from the notifications-utils repo; requires that you commit the changes to poetry.lock!
poetry update notifications-utils
@echo
@echo !!! PLEASE MAKE SURE TO COMMIT AND PUSH THE UPDATED poetry.lock FILE !!!
@echo

.PHONY: freeze-requirements
freeze-requirements: ## create static requirements.txt
poetry export --without-hashes --format=requirements.txt > requirements.txt
Expand All @@ -101,7 +113,7 @@ pip-audit:
poetry requirements > requirements.txt
poetry requirements --dev > requirements_for_test.txt
poetry run pip-audit -r requirements.txt
-poetry run pip-audit -r requirements_for_test.txt
poetry run pip-audit -r requirements_for_test.txt

.PHONY: audit
audit: npm-audit pip-audit
Expand Down
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,52 @@ The [Notify API](https://github.com/GSA/notifications-api) provides the UI's bac

If you are using VS Code, there are also instructions for [running inside Docker](./docs/docker-remote-containers.md)

### Python dependency management

We're using [`Poetry`](https://python-poetry.org/) for managing our Python
dependencies and local virtual environments. When it comes to managing the
Python dependencies, there are a couple of things to bear in mind.

For situations where you manually manipulate the `pyproject.toml` file, you
should use the `make py-lock` command to sync the `poetry.lock` file. This will
ensure that you don't inadvertently bring in other transitive dependency updates
that have not been fully tested with the project yet.

If you're just trying to update a dependency to a newer (or the latest) version,
you should let Poetry take care of that for you by running the following:

```
poetry update <dependency> [<dependency>...]
```

You can specify more than one dependency together. With this command, Poetry
will do the following for you:

- Find the latest compatible version(s) of the specified dependency/dependencies
- Install the new versions
- Update and sync the `poetry.lock` file

In either situation, once you are finished and have verified the dependency
changes are working, please be sure to commit both the `pyproject.toml` and
`poetry.lock` files.

### Keeping the notification-utils dependency up-to-date

The `notifications-utils` dependency references the other repository we have at
https://github.com/GSA/notifications-utils - this dependency requires a bit of
extra legwork to ensure it stays up-to-date.

Whenever a PR is merged in the `notifications-utils` repository, we need to make
sure the changes are pulled in here and committed to this repository as well.
You can do this by going through these steps:

- Make sure your local `main` branch is up-to-date
- Create a new branch to work in
- Run `make update-utils`
- Commit the updated `poetry.lock` file and push the changes
- Make a new PR with the change
- Have the PR get reviewed and merged

## To test the application

From a terminal within the running devcontainer:
Expand Down
2 changes: 1 addition & 1 deletion app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ def make_session_permanent():
"""
Make sessions permanent. By permanent, we mean "admin app sets when it expires". Normally the cookie would expire
whenever you close the browser. With this, the session expiry is set in `config['PERMANENT_SESSION_LIFETIME']`
(20 hours) and is refreshed after every request. IE: you will be logged out after twenty hours of inactivity.
(30 min) and is refreshed after every request. IE: you will be logged out after thirty minutes of inactivity.
We don't _need_ to set this every request (it's saved within the cookie itself under the `_permanent` flag), only
when you first log in/sign up/get invited/etc, but we do it just to be safe. For more reading, check here:
Expand Down
1 change: 0 additions & 1 deletion app/assets/javascripts/errorBanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,5 @@
hideBanner: () => $('.banner-dangerous').addClass('display-none'),
showBanner: () => $('.banner-dangerous')
.removeClass('display-none')
.trigger('focus'),
};
})(window);
4 changes: 2 additions & 2 deletions app/assets/javascripts/fileUpload.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@

// The label gets styled like a button and is used to hide the native file upload control. This is so that
// users see a button that looks like the others on the site.
//
this.$form.find('label.file-upload-button').addClass('usa-button margin-bottom-1');

this.$form.find('label.file-upload-button').addClass('usa-button margin-bottom-1').attr( {role: 'button', tabindex: '0'} );

// Clear the form if the user navigates back to the page
$(window).on("pageshow", () => this.$form[0].reset());

Expand Down
2 changes: 0 additions & 2 deletions app/assets/javascripts/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ $(() => GOVUK.modules.start());

$(() => $('.error-message, .usa-error-message').eq(0).parent('label').next('input').trigger('focus'));

$(() => $('.banner-dangerous').eq(0).trigger('focus'));

$(() => $('.govuk-header__container').on('click', function() {
$(this).css('border-color', '#005ea5');
}));
Expand Down
65 changes: 65 additions & 0 deletions app/assets/javascripts/timeoutPopup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
window.GOVUK = window.GOVUK || {};
window.GOVUK.Modules = window.GOVUK.Modules || {};
window.GOVUK.Modules.TimeoutPopup = window.GOVUK.Modules.TimeoutPopup || {};

(function(global) {
"use strict";

const sessionTimer = document.getElementById("sessionTimer");
let intervalId = null;

function checkTimer(timeTillSessionEnd) {
var now = new Date().getTime();
var difference = timeTillSessionEnd - now;
var minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((difference % (1000 * 60)) / 1000);
document.getElementById("timeLeft").innerHTML = + minutes + "m " + seconds + "s";
showTimer();
document.getElementById("logOutTimer").addEventListener("click", signoutUser);
document.getElementById("extendSessionTimer").addEventListener("click", extendSession);
if (difference < 0) {
clearInterval(intervalId);
intervalId = null;
closeTimer();
expireUserSession();
}
}

function expireUserSession() {
var signOutLink = '/sign-out?next=' + window.location.pathname;
window.location.href = signOutLink;

}

function signoutUser() {
window.location.href = '/sign-out';
}

function extendSession() {
window.location.reload();
}

function showTimer() {
sessionTimer.showModal();
}

function closeTimer() {
sessionTimer.close();
}

function setSessionTimer() {
var timeTillSessionEnd = new Date().getTime() + (5 * 60 * 1000);
intervalId = setInterval(checkTimer, 1000, timeTillSessionEnd);
}

if (document.getElementById("timeLeft") !== null) {
setTimeout(setSessionTimer, 25 * 60 * 1000);
}

global.GOVUK.Modules.TimeoutPopup.checkTimer = checkTimer;
global.GOVUK.Modules.TimeoutPopup.expireUserSession = expireUserSession;
global.GOVUK.Modules.TimeoutPopup.signoutUser = signoutUser;
global.GOVUK.Modules.TimeoutPopup.extendSession = extendSession;
global.GOVUK.Modules.TimeoutPopup.showTimer = showTimer;
global.GOVUK.Modules.TimeoutPopup.closeTimer = closeTimer;
})(window);
1 change: 0 additions & 1 deletion app/assets/sass/uswds/_uswds-theme-custom-styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,6 @@ details form {
display: block;
box-sizing: border-box;
position: relative;
margin: 0;
padding: 4px;
overflow: hidden;
line-height: 1.6;
Expand Down
2 changes: 1 addition & 1 deletion app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Config(object):
EMAIL_EXPIRY_SECONDS = 3600 # 1 hour
INVITATION_EXPIRY_SECONDS = 3600 * 24 * 2 # 2 days - also set on api
EMAIL_2FA_EXPIRY_SECONDS = 1800 # 30 Minutes
PERMANENT_SESSION_LIFETIME = 20 * 60 * 60 # 20 hours
PERMANENT_SESSION_LIFETIME = 1800 # 30 Minutes
SEND_FILE_MAX_AGE_DEFAULT = 365 * 24 * 60 * 60 # 1 year
REPLY_TO_EMAIL_ADDRESS_VALIDATION_TIMEOUT = 45
ACTIVITY_STATS_LIMIT_DAYS = 7
Expand Down
43 changes: 41 additions & 2 deletions app/templates/admin_template.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<meta property="og:site_name" content="Notify.gov">
<meta property="og:image" content="{{ asset_url('images/usa-opengraph-image.png') }}">
{% endblock %}
<!-- <script type="text/javascript" src="{{ asset_url('js/gtm_head.js') }}"></script> -->
<script type="text/javascript" src="{{ asset_url('js/gtm_head.js') }}"></script>
{% endblock %}

{% block pageTitle %}
Expand Down Expand Up @@ -137,7 +137,6 @@
{% endblock %}

{% block footer %}


{% if current_service and current_service.research_mode %}
{% set meta_suffix = 'Built by the <a href="https://www.gsa.gov/about-us/organization/federal-acquisition-service/technology-transformation-services/tts-solutions" class="usa-link">Technology Transformation Services</a><span id="research-mode" class="research-mode">research mode</span>' %}
Expand Down Expand Up @@ -216,13 +215,53 @@
"html": meta_suffix
}
}) }}

{% if current_user.is_authenticated %}
{% block sessionUserWarning %}
<dialog class="usa-modal" id="sessionTimer" aria-labelledby="sessionTimerHeading" aria-describedby="timerWarning">
<div class="usa-modal__content">
<div class="usa-modal__main">
<h2 class="usa-modal__heading" id="sessionTimerHeading">
Your session will end soon.
<span class="usa-sr-only">Please choose to extend your session or sign out. Your session will expire in 5 minutes or less.</span>
</h2>
<div class="usa-prose">
<p>You have been inactive for too long.
Your session will expire in <span id="timeLeft" role="timer"></span>.
</p>
</div>
<div class="usa-modal__footer">
<ul class="usa-button-group">
<li class="usa-button-group__item">
<button type="button" class="usa-button" id="extendSessionTimer" data-close-modal>
Extend Session
</button>
</li>
<li class="usa-button-group__item">
<button type="button" class="usa-button usa-button--unstyled padding-105 text-center" id="logOutTimer"
data-close-modal>
Sign out
</button>
</li>
</ul>
</div>
</div>
</div>
</dialog>
{% endblock %}
{% endif %}

{% endblock %}


{% block bodyEnd %}
{% block extra_javascripts %}
{% endblock %}
<!--[if gt IE 8]><!-->
<script type="text/javascript" src="{{ asset_url('javascripts/all.js') }}"></script>
<script type="text/javascript" src="{{ asset_url('js/uswds.min.js') }}"></script>
<!--<![endif]-->

{% endblock %}


2 changes: 1 addition & 1 deletion app/templates/components/components/alert/template.njk
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<div class="usa-alert__body">
<h{{params.header_level}} class="usa-alert__heading">{{params.heading}}</h{{params.header_level}}>
<p class="usa-alert__text">
{{params.text}}
{{params.text | safe }}
</p>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div {%- if params.id %} id="{{ params.id }}"{% endif %} class="govuk-inset-text {%- if params.classes %} {{ params.classes }}{% endif %}"
<div {%- if params.id %} id="{{ params.id }}"{% endif %} class="bg-base-lightest padding-y-1 padding-x-2 {%- if params.classes %} {{ params.classes }}{% endif %}"
{%- for attribute, value in params.attributes %} {{attribute}}="{{value}}"{% endfor %}>
{{ params.html | safe if params.html else params.text }}
</div>
16 changes: 9 additions & 7 deletions app/templates/partials/check/message-too-long.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<h1 class='banner-title'>
Message too long
</h1>
<p class="usa-body">
Text messages cannot be longer than {{ SMS_CHAR_COUNT_LIMIT }} characters.
Your message is {{ template.content_count }} characters.
</p>
<div class="usa-alert usa-alert--error" role="alert">
<div class="usa-alert__body">
<h1 class="usa-alert__heading">Message too long</h1>
<p class="usa-alert__text">
Text messages cannot be longer than {{ SMS_CHAR_COUNT_LIMIT }} characters.
Your message is {{ template.content_count }} characters.
</p>
</div>
</div>
28 changes: 16 additions & 12 deletions app/templates/partials/check/not-allowed-to-send-to.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
<h1 class='banner-title' data-module="track-error" data-error-type="Trial mode: bad recipients" data-error-label="{{ upload_id }}">
You cannot send to
{{ 'this' if count_of_recipients == 1 else 'these' }}
{{ template_type_label }}
{%- if count_of_recipients != 1 -%}
{{ 'es' if 'email address' == template_type_label else 's' }}
{%- endif %}
</h1>
<p class="usa-body">
In <a class="usa-link" href="{{ url_for('.trial_mode_new') }}">trial mode</a> you can only
send to yourself and members of your team
</p>
<div class="usa-alert usa-alert--error" role="alert">
<div class="usa-alert__body">
<h1 class="usa-alert__heading">
You cannot send to
{{ 'this' if count_of_recipients == 1 else 'these' }}
{{ template_type_label }}
{%- if count_of_recipients != 1 -%}
{{ 'es' if 'email address' == template_type_label else 's' }}
{%- endif %}
</h1>
<p class="usa-alert__text">
In <a class="usa-link" href="{{ url_for('.trial_mode_new') }}">trial mode</a> you can only
send to yourself and members of your team
</p>
</div>
</div>
14 changes: 8 additions & 6 deletions app/templates/partials/check/sent-previously.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<h1 class='banner-title' data-module="track-error" data-error-type="File previously sent" data-error-label="{{ upload_id }}">
These messages have already been sent today
</h1>
<p class="usa-body">
If you need to resend them, rename the file and upload it again.
</p>
<div class="usa-alert usa-alert--error" role="alert">
<div class="usa-alert__body">
<h1 class="usa-alert__heading">These messages have already been sent today</h1>
<p class="usa-alert__text">
If you need to resend them, rename the file and upload it again.
</p>
</div>
</div>
Loading

0 comments on commit cf2dbfc

Please sign in to comment.