Removing csp console error (#2963)

* Removing csp console error

* Fixed activity page console error as well
This commit is contained in:
Alex Janousek
2025-10-01 19:50:35 -04:00
committed by GitHub
parent ce6eddd4e3
commit a4e1cc0d38
7 changed files with 78 additions and 39 deletions

View File

@@ -161,7 +161,7 @@
"filename": "app/config.py",
"hashed_secret": "577a4c667e4af8682ca431857214b3a920883efc",
"is_verified": false,
"line_number": 120,
"line_number": 121,
"is_secret": false
}
],
@@ -634,5 +634,5 @@
}
]
},
"generated_at": "2025-10-01T14:58:39Z"
"generated_at": "2025-10-01T20:50:24Z"
}

View File

@@ -198,17 +198,17 @@ def create_app(application):
# @application.context_processor
# def inject_feature_flags():
# this is where feature flags can be easily added as a dictionary within context
# feature_socket_enabled = application.config.get("FEATURE_SOCKET_ENABLED", True)
# this is where feature flags can be easily added as a dictionary within context
# feature_socket_enabled = application.config.get("FEATURE_SOCKET_ENABLED", True)
# current_app.logger.info(
# f"FEATURE_SOCKET_ENABLED value in __init__.py coming \
# from config is {application.config.get('FEATURE_SOCKET_ENABLED')} and \
# the ending value is {feature_socket_enabled}"
# )
# return dict(
# FEATURE_SOCKET_ENABLED=feature_socket_enabled,
# )
# current_app.logger.info(
# f"FEATURE_SOCKET_ENABLED value in __init__.py coming \
# from config is {application.config.get('FEATURE_SOCKET_ENABLED')} and \
# the ending value is {feature_socket_enabled}"
# )
# return dict(
# FEATURE_SOCKET_ENABLED=feature_socket_enabled,
# )
@application.context_processor
def inject_initial_signin_url():

View File

@@ -130,7 +130,9 @@
}
loadNotificationsTable() {
const url = `${window.location.href.split('?')[0]}?_=${Date.now()}`;
const url = `/services/${this.serviceId}/jobs/${this.jobId}/notifications-table`;
console.debug('Loading notifications table from:', url);
fetch(url, {
headers: {
@@ -138,20 +140,28 @@
'Pragma': 'no-cache'
}
})
.then(response => response.text())
.then(response => {
console.debug('Notifications table response status:', response.status);
if (response.status === 204) {
// No content yet, job still processing
console.debug('Job still processing, no notifications yet');
return null;
}
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.text();
})
.then(html => {
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const notificationsTable = doc.querySelector('.job-status-table');
if (!html) return;
if (notificationsTable) {
const insertPoint = document.querySelector('.notification-status');
if (insertPoint) {
insertPoint.insertAdjacentElement('afterend', notificationsTable);
} else {
window.location.reload();
}
console.debug('Received HTML length:', html.length);
const insertPoint = document.querySelector('[data-key="notifications"]');
if (insertPoint) {
console.debug('Inserting notifications table');
insertPoint.innerHTML = html;
} else {
console.error('Could not find [data-key="notifications"], reloading page');
window.location.reload();
}
})

View File

@@ -66,6 +66,7 @@ class Config(object):
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_NAME = "notify_admin_session"
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = "Lax"
# don't send back the cookie if it hasn't been modified by the request. this means that the expiry time won't be
# updated unless the session is changed - but it's generally refreshed by `save_service_or_org_after_request`
# every time anyway, except for specific endpoints (png/pdfs generally) where we've disabled that handler.

View File

@@ -23,7 +23,7 @@ from app import (
service_api_client,
)
from app.enums import NotificationStatus, ServicePermission
from app.formatters import message_count_noun
from app.formatters import get_time_left, message_count_noun
from app.main import main
from app.main.forms import SearchNotificationsForm
from app.models.job import Job
@@ -136,7 +136,9 @@ def view_job_status_poll(service_id, job_id):
try:
api_response = job_api_client.get_job_status(service_id, job_id)
except HTTPError as e:
current_app.logger.error(f"API error fetching job status: {e.status_code} - {e.message}")
current_app.logger.error(
f"API error fetching job status: {e.status_code} - {e.message}"
)
if e.status_code == 404:
abort(404)
elif e.status_code >= 500:
@@ -155,6 +157,44 @@ def view_job_status_poll(service_id, job_id):
return jsonify(response_data)
@main.route("/services/<uuid:service_id>/jobs/<uuid:job_id>/notifications-table")
@user_has_permissions()
def view_job_notifications_table(service_id, job_id):
"""Endpoint that returns only the notifications table HTML fragment."""
job = Job.from_id(job_id, service_id=current_service.id)
if job.cancelled or not job.finished_processing:
return "", 204
filter_args = parse_filter_args(request.args)
filter_args["status"] = set_status_filters(filter_args)
notifications_data = job.get_notifications(status=filter_args["status"])
notifications = list(
add_preview_of_content_to_notifications(
notifications_data.get("notifications", [])
)
)
more_than_one_page = bool(notifications_data.get("links", {}).get("next"))
return render_template(
"partials/jobs/notifications.html",
job=job,
notifications=notifications,
more_than_one_page=more_than_one_page,
uploaded_file_name=job.original_file_name,
time_left=get_time_left(job.created_at),
service_data_retention_days=current_service.get_days_of_retention(
job.template_type, number_of_days="seven_day"
),
download_link=url_for(
".view_job_csv",
service_id=current_service.id,
job_id=job.id,
),
)
@main.route("/services/<uuid:service_id>/notifications", methods=["GET", "POST"])
@main.route(
"/services/<uuid:service_id>/notifications/<template_type:message_type>",

View File

@@ -59,19 +59,6 @@
{% endif %}
{% endset %}
{% block maincolumn_content %}
<style>
.download-reports-container .usa-button {
padding: 0.75rem 1rem;
min-height: 48px;
justify-content: flex-start;
}
.download-reports-container .usa-icon {
width: 1.25rem;
height: 1.25rem;
flex-shrink: 0;
}
</style>
<div class="margin-bottom-8">
<h1 class="usa-sr-only">All activity</h1>
<h2 class="font-body-2xl line-height-sans-2 margin-0">All activity</h2>

View File

@@ -241,6 +241,7 @@ EXCLUDED_ENDPOINTS = tuple(
"verify_email",
"view_job",
"view_job_csv",
"view_job_notifications_table",
"view_job_status_poll",
"view_jobs",
"view_notification",