diff --git a/.github/workflows/deploy-demo.yml b/.github/workflows/deploy-demo.yml
index 38947c4b3..65384ac81 100644
--- a/.github/workflows/deploy-demo.yml
+++ b/.github/workflows/deploy-demo.yml
@@ -57,12 +57,12 @@ jobs:
COMMIT_HASH: $(git rev-parse --short "$GITHUB_SHA")
LOGIN_PEM: ${{ secrets.LOGIN_PEM }}
LOGIN_DOT_GOV_CLIENT_ID: "urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov"
- LOGIN_DOT_GOV_USER_INFO_URL: "https://idp.int.identitysandbox.gov/api/openid_connect/userinfo"
- LOGIN_DOT_GOV_ACCESS_TOKEN_URL: "https://idp.int.identitysandbox.gov/api/openid_connect/token"
- LOGIN_DOT_GOV_LOGOUT_URL: "https://idp.int.identitysandbox.gov/openid_connect/logout?client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&post_logout_redirect_uri=https://notify-demo.app.cloud.gov/sign-out"
- LOGIN_DOT_GOV_BASE_LOGOUT_URL: "https://idp.int.identitysandbox.gov/openid_connect/logout?"
+ 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_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-demo.app.cloud.gov/sign-out"
+ LOGIN_DOT_GOV_BASE_LOGOUT_URL: "https://secure.login.gov/openid_connect/logout?"
LOGIN_DOT_GOV_SIGNOUT_REDIRECT: "https://notify-demo.app.cloud.gov/sign-out"
- LOGIN_DOT_GOV_INITIAL_SIGNIN_URL: "https://idp.int.identitysandbox.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=01234567890123456789012345&prompt=select_account&redirect_uri=https://notify-demo.app.cloud.gov/sign-in&response_type=code&scope=openid+email&state=abcdefghijklmnopabcdefghijklmnop"
+ 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=01234567890123456789012345&prompt=select_account&redirect_uri=https://notify-demo.app.cloud.gov/sign-in&response_type=code&scope=openid+email&state=abcdefghijklmnopabcdefghijklmnop"
with:
cf_username: ${{ secrets.CLOUDGOV_USERNAME }}
cf_password: ${{ secrets.CLOUDGOV_PASSWORD }}
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index ac6aac9d0..cbb7b9bb7 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -63,12 +63,12 @@ jobs:
COMMIT_HASH: $(git rev-parse --short "$GITHUB_SHA")
LOGIN_PEM: ${{ secrets.LOGIN_PEM }}
LOGIN_DOT_GOV_CLIENT_ID: "urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov"
- LOGIN_DOT_GOV_USER_INFO_URL: "https://idp.int.identitysandbox.gov/api/openid_connect/userinfo"
- LOGIN_DOT_GOV_ACCESS_TOKEN_URL: "https://idp.int.identitysandbox.gov/api/openid_connect/token"
- LOGIN_DOT_GOV_LOGOUT_URL: "https://idp.int.identitysandbox.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://idp.int.identitysandbox.gov/openid_connect/logout?"
+ 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_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_SIGNOUT_REDIRECT: "https://notify-staging.app.cloud.gov/sign-out"
- LOGIN_DOT_GOV_INITIAL_SIGNIN_URL: "https://idp.int.identitysandbox.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=01234567890123456789012345&prompt=select_account&redirect_uri=https://notify-staging.app.cloud.gov/sign-in&response_type=code&scope=openid+email&state=abcdefghijklmnopabcdefghijklmnop"
+ 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=01234567890123456789012345&prompt=select_account&redirect_uri=https://notify-staging.app.cloud.gov/sign-in&response_type=code&scope=openid+email&state=abcdefghijklmnopabcdefghijklmnop"
with:
cf_username: ${{ secrets.CLOUDGOV_USERNAME }}
cf_password: ${{ secrets.CLOUDGOV_PASSWORD }}
diff --git a/README.md b/README.md
index e98fe4535..0d080c9d8 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
+
+
# Notify.gov Admin UI
This is the Notify front-end for government users and admins. To see it in
diff --git a/app/assets/sass/uswds/_legacy-styles.scss b/app/assets/sass/uswds/_legacy-styles.scss
index 3b09e2218..b96a24844 100644
--- a/app/assets/sass/uswds/_legacy-styles.scss
+++ b/app/assets/sass/uswds/_legacy-styles.scss
@@ -48,13 +48,13 @@
}
}
-.sms-message-sender {
- margin: units(1) 0 0;
+.sms-message-sender, .sms-message-file-name, .sms-message-scheduler, .sms-message-template, .sms-message-sender {
+ margin:0.25rem 0 0;
}
.sms-message-recipient {
color: color('gray-cool-90');
- margin: 0 0 units(1);
+ margin: units(1) 0 units(1);
}
.sms-message-status {
@@ -131,7 +131,7 @@
&-label,
&-button-label {
font-weight: bold;
- font-size: 19px;
+ font-size: 19px;
display: block;
margin: 0 0 10px 0;
}
diff --git a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss
index addf9cc7a..55f17a795 100644
--- a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss
+++ b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss
@@ -26,7 +26,7 @@ i.e.
.usa-logo {
font-family: family("sans");
margin: units(4) 0;
- @include at-media-max('mobile-lg') {
+ @include at-media-max('desktop') {
margin: units(4) 0 units(4) units(2);
}
img {
@@ -43,6 +43,16 @@ i.e.
text-decoration: underline;
}
}
+ @include at-media-max('desktop') {
+ padding: 0 units(2);
+ ul li {
+ padding-bottom: units(1);
+ }
+ }
+ }
+ .usa-nav-container {
+ max-width: 100%;
+ padding: 0;
}
}
@@ -345,6 +355,9 @@ td.table-empty-message {
background-image: url(../img/material-icons/description.svg);
}
}
+ .table-wrapper {
+ overflow-x: scroll;
+ }
}
.dashboard-table {
@@ -403,8 +416,11 @@ td.table-empty-message {
width: 5%;
}
th {
- padding: 0.5rem 0.5rem;
+ padding: 0.5rem 1rem
}
+ td {
+ padding: 0.5rem 1rem
+ }
}
#template-list {
diff --git a/app/config.py b/app/config.py
index b1bdeafd8..4328f4a75 100644
--- a/app/config.py
+++ b/app/config.py
@@ -36,7 +36,7 @@ class Config(object):
NR_BROWSER_KEY = getenv("NR_BROWSER_KEY")
settings = newrelic.agent.global_settings()
NR_MONITOR_ON = settings and settings.monitor_mode
- COMMIT_HASH = getenv("COMMIT_HASH", "Unknown")
+ COMMIT_HASH = getenv("COMMIT_HASH", "-----")
TEMPLATE_PREVIEW_API_HOST = getenv(
"TEMPLATE_PREVIEW_API_HOST", "http://localhost:9999"
diff --git a/app/main/forms.py b/app/main/forms.py
index 2e6655cc5..70dbfa37f 100644
--- a/app/main/forms.py
+++ b/app/main/forms.py
@@ -1226,7 +1226,11 @@ class CsvUploadForm(StripWhitespaceForm):
validators=[
DataRequired(message="Please pick a file"),
CsvFileValidator(),
- FileSize(max_size=10e6, message="File must be smaller than 10Mb"), # 10Mb
+ FileSize(
+ max_size=10e6,
+ message="File must be smaller than 10Mb. If you are trying to upload an Excel file, \
+ please export the contents in the CSV format and then try again.",
+ ), # 10Mb
],
)
diff --git a/app/main/views/dashboard.py b/app/main/views/dashboard.py
index 24b3e0490..4d5aca14d 100644
--- a/app/main/views/dashboard.py
+++ b/app/main/views/dashboard.py
@@ -76,6 +76,7 @@ def service_dashboard(service_id):
"notifications": aggregate_notifications_by_job.get(job["id"], []),
}
for job in job_response
+ if aggregate_notifications_by_job.get(job["id"], [])
]
return render_template(
"views/dashboard/dashboard.html",
diff --git a/app/main/views/index.py b/app/main/views/index.py
index f4e3a67db..e6107ab10 100644
--- a/app/main/views/index.py
+++ b/app/main/views/index.py
@@ -102,15 +102,6 @@ def security():
return render_template("views/security.html", navigation_links=features_nav())
-@main.route("/features/terms", endpoint="terms")
-@user_is_logged_in
-def terms():
- return render_template(
- "views/terms-of-use.html",
- navigation_links=features_nav(),
- )
-
-
@main.route("/features/using_notify")
@user_is_logged_in
def using_notify():
@@ -214,7 +205,6 @@ def send_files_by_email():
@main.route("/roadmap", endpoint="old_roadmap")
-@main.route("/terms", endpoint="old_terms")
@main.route("/information-security", endpoint="information_security")
@main.route("/using_notify", endpoint="old_using_notify")
@main.route("/information-risk-management", endpoint="information_risk_management")
@@ -222,7 +212,6 @@ def send_files_by_email():
def old_page_redirects():
redirects = {
"main.old_roadmap": "main.roadmap",
- "main.old_terms": "main.terms",
"main.information_security": "main.using_notify",
"main.old_using_notify": "main.using_notify",
"main.information_risk_management": "main.security",
diff --git a/app/main/views/jobs.py b/app/main/views/jobs.py
index ed8f051a3..774f2a916 100644
--- a/app/main/views/jobs.py
+++ b/app/main/views/jobs.py
@@ -276,12 +276,16 @@ def get_status_filters(service, message_type, statistics):
}
else:
stats = statistics[message_type]
- stats["sending"] = stats["requested"] - stats["delivered"] - stats["failed"]
+
+ if stats.get("failure") is not None:
+ stats["failed"] = stats["failure"]
+
+ stats["pending"] = stats["requested"] - stats["delivered"] - stats["failed"]
filters = [
# key, label, option
("requested", "total", "sending,delivered,failed"),
- ("sending", "pending", "pending"),
+ ("pending", "pending", "pending"),
("delivered", "delivered", "delivered"),
("failed", "failed", "failed"),
]
@@ -296,7 +300,7 @@ def get_status_filters(service, message_type, statistics):
message_type=message_type,
status=option,
),
- stats[key],
+ stats.get(key),
)
for key, label, option in filters
]
diff --git a/app/main/views/send.py b/app/main/views/send.py
index 6c786e3ac..b1cea53a8 100644
--- a/app/main/views/send.py
+++ b/app/main/views/send.py
@@ -6,6 +6,7 @@ from zipfile import BadZipFile
from flask import abort, flash, redirect, render_template, request, session, url_for
from flask_login import current_user
+from markupsafe import Markup
from notifications_python_client.errors import HTTPError
from notifications_utils import SMS_CHAR_COUNT_LIMIT
from notifications_utils.insensitive_dict import InsensitiveDict
@@ -151,8 +152,11 @@ def send_messages(service_id, template_id):
# just show the first error, as we don't expect the form to have more
# than one, since it only has one field
first_field_errors = list(form.errors.values())[0]
- flash(first_field_errors[0])
-
+ error_message = ''
+ error_message = f"{error_message}{first_field_errors[0]}"
+ error_message = f"{error_message}"
+ error_message = Markup(error_message)
+ flash(error_message)
column_headings = get_spreadsheet_column_headings_from_template(template)
return render_template(
@@ -504,13 +508,18 @@ def _check_messages(service_id, template_id, upload_id, preview_row):
template = get_template(
db_template,
current_service,
- show_recipient=True,
+ show_recipient=False,
email_reply_to=email_reply_to,
sms_sender=sms_sender,
)
+ simplifed_template = get_template(
+ db_template,
+ current_service,
+ show_recipient=False,
+ )
recipients = RecipientCSV(
contents,
- template=template,
+ template=template or simplifed_template,
max_initial_rows_shown=50,
max_errors_shown=50,
guestlist=(
@@ -530,11 +539,20 @@ def _check_messages(service_id, template_id, upload_id, preview_row):
back_link = url_for(
"main.send_one_off", service_id=service_id, template_id=template.id
)
+ back_link_from_preview = url_for(
+ "main.send_one_off", service_id=service_id, template_id=template.id
+ )
choose_time_form = None
else:
back_link = url_for(
"main.send_messages", service_id=service_id, template_id=template.id
)
+ back_link_from_preview = url_for(
+ "main.check_messages",
+ service_id=service_id,
+ template_id=template.id,
+ upload_id=upload_id,
+ )
choose_time_form = ChooseTimeForm()
if preview_row < 2:
@@ -542,6 +560,7 @@ def _check_messages(service_id, template_id, upload_id, preview_row):
if preview_row < len(recipients) + 2:
template.values = recipients[preview_row - 2].recipient_and_personalisation
+ simplifed_template.values = recipients[preview_row - 2].recipient_and_personalisation
elif preview_row > 2:
abort(404)
@@ -562,11 +581,14 @@ def _check_messages(service_id, template_id, upload_id, preview_row):
remaining_messages=remaining_messages,
choose_time_form=choose_time_form,
back_link=back_link,
+ back_link_from_preview=back_link_from_preview,
first_recipient_column=recipients.recipient_column_headers[0],
preview_row=preview_row,
sent_previously=job_api_client.has_sent_previously(
service_id, template.id, db_template["version"], original_file_name
),
+ template_id=template_id,
+ simplifed_template=simplifed_template,
)
@@ -614,13 +636,34 @@ def check_messages(service_id, template_id, upload_id, row_index=2):
return render_template("views/check/ok.html", **data)
+@main.route(
+ "/services///check//preview",
+ methods=["POST"],
+)
+@main.route(
+ "/services///check//preview/row-",
+ methods=["POST"],
+)
+@user_has_permissions("send_messages", restrict_admin_usage=True)
+def preview_job(service_id, template_id, upload_id, row_index=2):
+ session["scheduled_for"] = request.form.get("scheduled_for", "")
+ data = _check_messages(service_id, template_id, upload_id, row_index)
+
+ return render_template(
+ "views/check/preview.html",
+ scheduled_for=session["scheduled_for"],
+ **data,
+ )
+
+
@main.route("/services//start-job/", methods=["POST"])
@user_has_permissions("send_messages", restrict_admin_usage=True)
def start_job(service_id, upload_id):
+ scheduled_for = session.pop("scheduled_for", None)
job_api_client.create_job(
upload_id,
service_id,
- scheduled_for=request.form.get("scheduled_for", ""),
+ scheduled_for=scheduled_for,
)
session.pop("sender_id", None)
@@ -679,7 +722,20 @@ def get_send_test_page_title(template_type, entering_recipient, name=None):
return "Personalize this message"
-def get_back_link(service_id, template, step_index, placeholders=None):
+def get_back_link(
+ service_id,
+ template,
+ step_index,
+ placeholders=None,
+ preview=False,
+):
+ if preview:
+ return url_for(
+ "main.check_notification",
+ service_id=service_id,
+ template_id=template.id,
+ )
+
if step_index == 0:
if should_skip_template_page(template._template):
return url_for(
@@ -779,11 +835,18 @@ def _check_notification(service_id, template_id, exception=None):
email_reply_to=email_reply_to,
sms_sender=sms_sender,
)
-
+ simplifed_template = get_template(
+ db_template,
+ current_service,
+ )
placeholders = fields_to_fill_in(template)
back_link = get_back_link(service_id, template, len(placeholders), placeholders)
+ back_link_from_preview = get_back_link(
+ service_id, template, len(placeholders), placeholders, preview=True
+ )
+
choose_time_form = ChooseTimeForm()
if (not session.get("recipient")) or not all_placeholders_in_session(
@@ -797,8 +860,10 @@ def _check_notification(service_id, template_id, exception=None):
return dict(
template=template,
back_link=back_link,
+ back_link_from_preview=back_link_from_preview,
choose_time_form=choose_time_form,
**(get_template_error_dict(exception) if exception else {}),
+ simplifed_template=simplifed_template
)
@@ -828,12 +893,39 @@ def get_template_error_dict(exception):
}
+@main.route(
+ "/services//template//notification/check/preview",
+ methods=["POST"],
+)
+@user_has_permissions("send_messages", restrict_admin_usage=True)
+def preview_notification(service_id, template_id):
+ recipient = get_recipient()
+ if not recipient:
+ return redirect(
+ url_for(
+ ".send_one_off",
+ service_id=service_id,
+ template_id=template_id,
+ )
+ )
+
+ session["scheduled_for"] = request.form.get("scheduled_for", "")
+
+ return render_template(
+ "views/notifications/preview.html",
+ **_check_notification(service_id, template_id),
+ scheduled_for=session["scheduled_for"],
+ recipient=recipient,
+ )
+
+
@main.route(
"/services//template//notification/check",
methods=["POST"],
)
@user_has_permissions("send_messages", restrict_admin_usage=True)
def send_notification(service_id, template_id):
+ scheduled_for = session.pop("scheduled_for", "")
recipient = get_recipient()
if not recipient:
return redirect(
@@ -868,7 +960,7 @@ def send_notification(service_id, template_id):
job_api_client.create_job(
upload_id,
service_id,
- scheduled_for=request.form.get("scheduled_for", ""),
+ scheduled_for=scheduled_for,
template_id=template_id,
original_file_name=filename,
notification_count=1,
diff --git a/app/main/views/sign_in.py b/app/main/views/sign_in.py
index be313c59b..d39cb89af 100644
--- a/app/main/views/sign_in.py
+++ b/app/main/views/sign_in.py
@@ -53,22 +53,19 @@ def _get_access_token(code, state):
# JWT expiration time (10 minute maximum)
"exp": int(time.time()) + (10 * 60),
}
- current_app.logger.warning(f"Here is the raw payload {payload}")
token = jwt.encode(payload, keystring, algorithm="RS256")
base_url = f"{access_token_url}?"
cli_assert = f"client_assertion={token}"
cli_assert_type = "client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer"
code_param = f"code={code}"
url = f"{base_url}{cli_assert}&{cli_assert_type}&{code_param}&grant_type=authorization_code"
- current_app.logger.info(f"This is the url we use to get the access token: {url}")
headers = {"Authorization": "Bearer %s" % token}
response = requests.post(url, headers=headers)
- current_app.logger.info(f"GOT A RESPONSE {response.json()}")
access_token = response.json()["access_token"]
return access_token
-def _get_user_email(access_token):
+def _get_user_email_and_uuid(access_token):
headers = {"Authorization": "Bearer %s" % access_token}
user_info_url = os.getenv("LOGIN_DOT_GOV_USER_INFO_URL")
user_attributes = requests.get(
@@ -76,7 +73,8 @@ def _get_user_email(access_token):
headers=headers,
)
user_email = user_attributes.json()["email"]
- return user_email
+ user_uuid = user_attributes.json()["sub"]
+ return user_email, user_uuid
@main.route("/sign-in", methods=(["GET", "POST"]))
@@ -88,11 +86,11 @@ def sign_in():
login_gov_error = request.args.get("error")
if code and state:
access_token = _get_access_token(code, state)
- user_email = _get_user_email(access_token)
+ user_email, user_uuid = _get_user_email_and_uuid(access_token)
redirect_url = request.args.get("next")
# activate the user
- user = user_api_client.get_user_by_email(user_email)
+ user = user_api_client.get_user_by_uuid_or_email(user_uuid, user_email)
activate_user(user["id"])
return redirect(url_for("main.show_accounts_or_dashboard", next=redirect_url))
@@ -198,7 +196,7 @@ def sign_in():
form=form,
again=bool(redirect_url),
other_device=other_device,
- login_gov_enabled=bool(notify_env in ["development", "staging"]),
+ login_gov_enabled=bool(notify_env in ["development", "staging", "demo"]),
password_reset_url=password_reset_url,
initial_signin_url=initial_signin_url,
)
diff --git a/app/main/views/sub_navigation_dictionaries.py b/app/main/views/sub_navigation_dictionaries.py
index f76d69c14..5e32bc003 100644
--- a/app/main/views/sub_navigation_dictionaries.py
+++ b/app/main/views/sub_navigation_dictionaries.py
@@ -18,10 +18,6 @@ def features_nav():
"name": "Security",
"link": "main.security",
},
- {
- "name": "Terms of use",
- "link": "main.terms",
- },
]
diff --git a/app/navigation.py b/app/navigation.py
index 94f970540..3c79598cc 100644
--- a/app/navigation.py
+++ b/app/navigation.py
@@ -45,7 +45,6 @@ class HeaderNavigation(Navigation):
"features_sms",
"roadmap",
"security",
- "terms",
},
"using_notify": {
"get_started",
diff --git a/app/notify_client/user_api_client.py b/app/notify_client/user_api_client.py
index bfe2f7182..a17059e52 100644
--- a/app/notify_client/user_api_client.py
+++ b/app/notify_client/user_api_client.py
@@ -44,6 +44,16 @@ class UserApiClient(NotifyAdminAPIClient):
user_data = self.post("/user/email", data={"email": email_address})
return user_data["data"]
+ def get_user_by_uuid_or_email(self, user_uuid, email_address):
+
+ user_data = self.post(
+ "/user/get-login-gov-user",
+ data={"login_uuid": user_uuid, "email": email_address},
+ )
+ if user_data is None:
+ raise Exception("User not found")
+ return user_data["data"]
+
def get_user_by_email_or_none(self, email_address):
try:
return self.get_user_by_email(email_address)
diff --git a/app/templates/admin_template.html b/app/templates/admin_template.html
index df70151ce..1c9fe195f 100644
--- a/app/templates/admin_template.html
+++ b/app/templates/admin_template.html
@@ -203,10 +203,6 @@
"href": url_for("main.security"),
"text": "Security"
},
- {
- "href": url_for("main.terms"),
- "text": "Terms of use"
- },
]
},
{
diff --git a/app/templates/components/components/header/template.njk b/app/templates/components/components/header/template.njk
index 6cc8cabd8..a4cd0d9e2 100644
--- a/app/templates/components/components/header/template.njk
+++ b/app/templates/components/components/header/template.njk
@@ -44,61 +44,63 @@