diff --git a/app/commands/incident.py b/app/commands/incident.py index d463dbc9..d835eb66 100644 --- a/app/commands/incident.py +++ b/app/commands/incident.py @@ -312,7 +312,7 @@ def submit(ack, view, say, body, client, logger): say(text=text, channel=channel_id) # Reminder to brief up - text = ":alphabet-yellow-question: Is this a `cybersecurity incident` (secret/data leak, account compromise, attack)? Please initiate the briefing process for CCCS and TBS OCIO Cyber." + text = ":alphabet-yellow-question: Is this a `cybersecurity incident` (secret/data leak, account compromise, attack)? Please initiate the briefing process for CCCS and TBS OCIO Cyber. This just means we send a summary of the incident (or initial findings and updates if incident is ongoing) to cyberincident@cyber.gc.ca and CC zztbscybers@tbs-sct.gc.ca, and security@cds-snc.ca! CCCS will reach out with a case number, and any questions if they need more information." say(text=text, channel=channel_id) # Reminder to stop planned testing diff --git a/app/commands/locales/secret.en-US.yml b/app/commands/locales/secret.en-US.yml new file mode 100644 index 00000000..f93be625 --- /dev/null +++ b/app/commands/locales/secret.en-US.yml @@ -0,0 +1,18 @@ +en-US: + locale_button: "Français" + locale_value: "en-US" + locale_short: "en" + submit: "Submit" + close: "Close" + title: "Share a new secret" + label: "Secret" + placeholder: "Enter your secret here" + ttl: "Time to live" + days: "days" + day: "day" + hours: "hours" + hour: "hour" + minutes: "minutes" + minute: "minute" + error: "There was an error creating your secret" + link_available: "Your secret is available at the following link:" diff --git a/app/commands/locales/secret.fr-FR.yml b/app/commands/locales/secret.fr-FR.yml new file mode 100644 index 00000000..06663456 --- /dev/null +++ b/app/commands/locales/secret.fr-FR.yml @@ -0,0 +1,18 @@ +fr-FR: + locale_button: "English" + locale_value: "fr-FR" + locale_short: "fr" + submit: "Soumettre" + close: "Fermer" + title: "Partager secret" + label: "Secret" + placeholder: "Entrez votre secret ici" + ttl: "Durée de vie" + days: "jours" + day: "jour" + hours: "heures" + hour: "heure" + minutes: "minutes" + minute: "minute" + error: "Il y avait une erreur en créant votre secret" + link_available: "Votre secret est disponible au lien suivant:" diff --git a/app/commands/secret.py b/app/commands/secret.py new file mode 100644 index 00000000..1cf86c7d --- /dev/null +++ b/app/commands/secret.py @@ -0,0 +1,163 @@ +import i18n +import requests +import time +from commands.utils import get_user_locale + +i18n.load_path.append("./commands/locales/") + +i18n.set("locale", "en-US") +i18n.set("fallback", "en-US") + + +def secret_command(client, ack, command, body): + ack() + if "user" in body: + user_id = body["user"]["id"] + else: + user_id = body["user_id"] + locale = get_user_locale(user_id, client) + i18n.set("locale", locale) + view = generate_secret_command_modal_view(command, user_id, locale) + client.views_open(trigger_id=body["trigger_id"], view=view) + + +def secret_view_handler(ack, client, view, logger): + ack() + locale = view["blocks"][0]["elements"][0]["value"] + i18n.set("locale", locale) + secret = view["state"]["values"]["secret_input"]["secret_submission"]["value"] + ttl = view["state"]["values"]["product"]["secret_ttl"]["selected_option"]["value"] + + # Encrypted message API + endpoint = "https://encrypted-message.cdssandbox.xyz/encrypt" + json = {"body": secret, "ttl": int(ttl) + int(time.time())} + response = requests.post( + endpoint, json=json, timeout=10, headers={"Content-Type": "application/json"} + ) + + try: + id = response.json()["id"] + url = f"https://encrypted-message.cdssandbox.xyz/{i18n.t('secret.locale_short')}/view/{id}" + client.chat_postEphemeral( + channel=view["private_metadata"], + user=view["private_metadata"], + text=f"{i18n.t('secret.link_available')} {url}", + ) + except Exception as e: + logger.error(e) + client.chat_postEphemeral( + channel=view["private_metadata"], + user=view["private_metadata"], + text=i18n.t("secret.error"), + ) + return + + +def handle_change_locale_button(ack, client, body): + ack() + if "user" in body: + user_id = body["user"]["id"] + else: + user_id = body["user_id"] + locale = body["actions"][0]["value"] + if locale == "en-US": + locale = "fr-FR" + else: + locale = "en-US" + i18n.set("locale", locale) + command = { + "text": body["view"]["state"]["values"]["secret_input"]["secret_submission"][ + "value" + ] + } + if command["text"] is None: + command["text"] = "" + view = generate_secret_command_modal_view(command, user_id, locale) + client.views_update(view_id=body["view"]["id"], view=view) + + +def generate_secret_command_modal_view(command, user_id, locale="en-US"): + ttl_options = [ + {"name": "7 " + i18n.t("secret.days"), "value": "604800"}, + {"name": "3 " + i18n.t("secret.days"), "value": "259200"}, + {"name": "1 " + i18n.t("secret.day"), "value": "86400"}, + {"name": "12 " + i18n.t("secret.hours"), "value": "43200"}, + {"name": "4 " + i18n.t("secret.hours"), "value": "14400"}, + {"name": "1 " + i18n.t("secret.hour"), "value": "3600"}, + {"name": "30 " + i18n.t("secret.minutes"), "value": "1800"}, + {"name": "5 " + i18n.t("secret.minutes"), "value": "300"}, + ] + + options = [ + { + "text": {"type": "plain_text", "text": i["name"]}, + "value": i["value"], + } + for i in ttl_options + ] + return { + "type": "modal", + "private_metadata": user_id, + "callback_id": "secret_view", + "title": { + "type": "plain_text", + "text": i18n.t("secret.title"), + }, + "submit": { + "type": "plain_text", + "text": i18n.t("secret.submit"), + }, + "blocks": [ + { + "type": "actions", + "block_id": "locale", + "elements": [ + { + "type": "button", + "text": { + "type": "plain_text", + "text": i18n.t("secret.locale_button"), + "emoji": True, + }, + "value": locale, + "action_id": "secret_change_locale", + } + ], + }, + { + "type": "input", + "block_id": "secret_input", + "label": { + "type": "plain_text", + "text": i18n.t("secret.label"), + }, + "element": { + "type": "plain_text_input", + "action_id": "secret_submission", + "initial_value": command["text"], + "placeholder": { + "type": "plain_text", + "text": i18n.t("secret.placeholder"), + }, + }, + }, + { + "block_id": "product", + "type": "input", + "element": { + "type": "static_select", + "placeholder": { + "type": "plain_text", + "text": i18n.t("secret.ttl"), + }, + "options": options, + "action_id": "secret_ttl", + }, + "label": { + "type": "plain_text", + "text": i18n.t("secret.ttl"), + "emoji": True, + }, + }, + ], + } diff --git a/app/integrations/google_drive.py b/app/integrations/google_drive.py index b6b3fed8..53eb5089 100644 --- a/app/integrations/google_drive.py +++ b/app/integrations/google_drive.py @@ -497,3 +497,15 @@ def update_spreadsheet_close_incident(channel_name): ).execute() return True return False + + +def healthcheck(): + """Check if the bot can interact with Google Drive.""" + healthy = False + try: + metadata = list_metadata(INCIDENT_TEMPLATE) + healthy = "id" in metadata + logging.info(f"Google Drive healthcheck result: {metadata}") + except Exception as error: + logging.error(f"Google Drive healthcheck failed: {error}") + return healthy diff --git a/app/integrations/maxmind.py b/app/integrations/maxmind.py index de4d6b87..92540105 100644 --- a/app/integrations/maxmind.py +++ b/app/integrations/maxmind.py @@ -1,3 +1,4 @@ +import logging import geoip2.database from geoip2.errors import AddressNotFoundError @@ -16,3 +17,15 @@ def geolocate(ip): return "IP address not found" except ValueError: return "Invalid IP address" + + +def healthcheck(): + """Check if the bot can interact with Maxmind.""" + healthy = False + try: + result = geolocate("8.8.8.8") + healthy = isinstance(result, tuple) + logging.info(f"Maxmind healthcheck result: {result}") + except Exception as error: + logging.error(f"Maxmind healthcheck failed: {error}") + return healthy diff --git a/app/integrations/opsgenie.py b/app/integrations/opsgenie.py index 6d2f1340..2d5aaf66 100644 --- a/app/integrations/opsgenie.py +++ b/app/integrations/opsgenie.py @@ -41,6 +41,22 @@ def create_alert(description): return "Could not issue alert to Opsgenie!" +def healthcheck(): + """Check if the bot can interact with the Opsgenie API.""" + healthy = False + try: + content = api_get_request( + "https://api.opsgenie.com/v1/services", + {"name": "GenieKey", "token": OPSGENIE_KEY}, + ) + result = json.loads(content) + healthy = "data" in result + logging.info(f"OpsGenie healthcheck result: {result}") + except Exception as error: + logging.error(f"OpsGenie healthcheck failed: {error}") + return healthy + + def api_get_request(url, auth): req = Request(url) req.add_header("Authorization", f"{auth['name']} {auth['token']}") diff --git a/app/jobs/scheduled_tasks.py b/app/jobs/scheduled_tasks.py index 8f37e20a..74e662a3 100644 --- a/app/jobs/scheduled_tasks.py +++ b/app/jobs/scheduled_tasks.py @@ -5,6 +5,8 @@ import schedule import logging +from integrations import google_drive, maxmind, opsgenie + logging.basicConfig(level=logging.INFO) @@ -17,12 +19,27 @@ def init(bot): schedule.every(10).seconds.do(revoke_aws_sso_access, client=bot.client) schedule.every(5).minutes.do(scheduler_heartbeat) + schedule.every(5).minutes.do(integration_healthchecks) def scheduler_heartbeat(): logging.info("Scheduler is running at %s", time.ctime()) +def integration_healthchecks(): + logging.info("Running integration healthchecks ...") + healthchecks = { + "google_drive": google_drive.healthcheck, + "maxmind": maxmind.healthcheck, + "opsgenie": opsgenie.healthcheck, + } + for key, healthcheck in healthchecks.items(): + if not healthcheck(): + logging.error(f"Integration {key} is unhealthy 💀") + else: + logging.info(f"Integration {key} is healthy 🌈") + + def run_continuously(interval=1): """Continuously run, while executing pending jobs at each elapsed time interval. diff --git a/app/main.py b/app/main.py index 87babcf4..630f34ed 100644 --- a/app/main.py +++ b/app/main.py @@ -5,7 +5,7 @@ from slack_bolt.adapter.socket_mode import SocketModeHandler from slack_bolt import App from dotenv import load_dotenv -from commands import atip, aws, incident, sre, role +from commands import atip, aws, incident, secret, sre, role from commands.helpers import incident_helper, webhook_helper from server import bot_middleware, server @@ -60,6 +60,11 @@ def main(bot): bot.action("archive_channel")(incident_helper.archive_channel_action) bot.view("view_save_incident_roles")(incident_helper.save_incident_roles) + # Register Secret command + bot.command(f"/{PREFIX}secret")(secret.secret_command) + bot.action("secret_change_locale")(secret.handle_change_locale_button) + bot.view("secret_view")(secret.secret_view_handler) + # Register SRE events bot.command(f"/{PREFIX}sre")(sre.sre_command) diff --git a/app/requirements.txt b/app/requirements.txt index 01059392..09a383a1 100644 --- a/app/requirements.txt +++ b/app/requirements.txt @@ -1,9 +1,9 @@ arrow==1.3.0 Authlib==1.3.0 -Jinja2==3.1.2 -awscli==1.32.15 +Jinja2==3.1.3 +awscli==1.32.19 aws-sns-message-validator==0.0.5 -boto3==1.34.15 +boto3==1.34.19 fastapi==0.109.0 geoip2==4.8.0 google-api-python-client==2.113.0 @@ -11,7 +11,7 @@ google-auth-httplib2==0.2.0 google-auth-oauthlib==0.8.0 httpx==0.26.0 itsdangerous==2.1.2 -Jinja2==3.1.2 +Jinja2==3.1.3 PyJWT==2.8.0 PyYAML!=6.0.0,!=5.4.0,!=5.4.1 python-dotenv==0.21.1 diff --git a/app/tests/commands/test_secret.py b/app/tests/commands/test_secret.py new file mode 100644 index 00000000..2e6294a6 --- /dev/null +++ b/app/tests/commands/test_secret.py @@ -0,0 +1,279 @@ +from commands import secret + +from unittest.mock import MagicMock, patch + + +@patch("commands.secret.generate_secret_command_modal_view") +@patch("commands.secret.get_user_locale") +def test_secret_command(mock_get_user_locale, mock_generate_secret_command_modal_view): + client = MagicMock() + ack = MagicMock() + + mock_get_user_locale.return_value = "en-US" + + command = "secret" + + body = { + "trigger_id": "trigger_id", + "user": {"id": "user_id"}, + } + + secret.secret_command(client, ack, command, body) + + mock_get_user_locale.assert_called_once_with("user_id", client) + mock_generate_secret_command_modal_view.assert_called_once_with( + command, "user_id", "en-US" + ) + + client.views_open.assert_called_once_with( + trigger_id="trigger_id", + view=mock_generate_secret_command_modal_view.return_value, + ) + + +@patch("commands.secret.requests") +@patch("commands.secret.time") +def test_secret_view_handler_with_succesfull_request(mock_time, mock_requests): + ack = MagicMock() + client = MagicMock() + logger = MagicMock() + view = { + "blocks": [ + { + "elements": [ + { + "value": "en-US", + } + ] + } + ], + "state": { + "values": { + "secret_input": { + "secret_submission": { + "value": "secret", + } + }, + "product": { + "secret_ttl": { + "selected_option": { + "value": "1", + } + } + }, + } + }, + "private_metadata": "private_metadata", + } + + mock_time.time.return_value = 0 + + mock_requests.post.return_value.json.return_value = {"id": "id"} + + secret.secret_view_handler(ack, client, view, logger) + + ack.assert_called_once_with() + + mock_time.time.assert_called_once_with() + mock_requests.post.assert_called_once_with( + "https://encrypted-message.cdssandbox.xyz/encrypt", + json={"body": "secret", "ttl": 1}, + timeout=10, + headers={"Content-Type": "application/json"}, + ) + + client.chat_postEphemeral.assert_called_once_with( + channel="private_metadata", + user="private_metadata", + text="Your secret is available at the following link: https://encrypted-message.cdssandbox.xyz/en/view/id", + ) + + +@patch("commands.secret.requests") +@patch("commands.secret.time") +def test_secret_view_handler_with_failed_request(mock_time, mock_requests): + ack = MagicMock() + client = MagicMock() + logger = MagicMock() + view = { + "blocks": [ + { + "elements": [ + { + "value": "en-US", + } + ] + } + ], + "state": { + "values": { + "secret_input": { + "secret_submission": { + "value": "secret", + } + }, + "product": { + "secret_ttl": { + "selected_option": { + "value": "1", + } + } + }, + } + }, + "private_metadata": "private_metadata", + } + + mock_time.time.return_value = 0 + + mock_requests.post.return_value.json.return_value = {} + + secret.secret_view_handler(ack, client, view, logger) + + ack.assert_called_once_with() + + mock_time.time.assert_called_once_with() + mock_requests.post.assert_called_once_with( + "https://encrypted-message.cdssandbox.xyz/encrypt", + json={"body": "secret", "ttl": 1}, + timeout=10, + headers={"Content-Type": "application/json"}, + ) + + client.chat_postEphemeral.assert_called_once_with( + channel="private_metadata", + user="private_metadata", + text="There was an error creating your secret", + ) + + +@patch("commands.secret.generate_secret_command_modal_view") +def test_handle_change_locale_button(mock_generate_secret_command_modal_view): + ack = MagicMock() + client = MagicMock() + body = { + "actions": [ + { + "value": "en-US", + } + ], + "user": {"id": "user_id"}, + "view": { + "id": "view_id", + "state": { + "values": { + "secret_input": { + "secret_submission": { + "value": "secret", + } + } + } + }, + }, + } + + secret.handle_change_locale_button(ack, client, body) + + ack.assert_called_once_with() + + mock_generate_secret_command_modal_view.assert_called_once_with( + {"text": "secret"}, + "user_id", + "fr-FR", + ) + + client.views_update.assert_called_once_with( + view_id="view_id", + view=mock_generate_secret_command_modal_view.return_value, + ) + + +def test_generate_secret_command_modal_view(): + command = {"text": "secret"} + user_id = "user_id" + locale = "fr-FR" + + view = secret.generate_secret_command_modal_view(command, user_id, locale) + assert view == { + "type": "modal", + "private_metadata": "user_id", + "callback_id": "secret_view", + "title": {"type": "plain_text", "text": "Partager secret"}, + "submit": {"type": "plain_text", "text": "Soumettre"}, + "blocks": [ + { + "type": "actions", + "block_id": "locale", + "elements": [ + { + "type": "button", + "text": { + "type": "plain_text", + "text": "English", + "emoji": True, + }, + "value": "fr-FR", + "action_id": "secret_change_locale", + } + ], + }, + { + "type": "input", + "block_id": "secret_input", + "label": {"type": "plain_text", "text": "Secret"}, + "element": { + "type": "plain_text_input", + "action_id": "secret_submission", + "initial_value": "secret", + "placeholder": { + "type": "plain_text", + "text": "Entrez votre secret ici", + }, + }, + }, + { + "block_id": "product", + "type": "input", + "element": { + "type": "static_select", + "placeholder": {"type": "plain_text", "text": "Durée de vie"}, + "options": [ + { + "text": {"type": "plain_text", "text": "7 jours"}, + "value": "604800", + }, + { + "text": {"type": "plain_text", "text": "3 jours"}, + "value": "259200", + }, + { + "text": {"type": "plain_text", "text": "1 jour"}, + "value": "86400", + }, + { + "text": {"type": "plain_text", "text": "12 heures"}, + "value": "43200", + }, + { + "text": {"type": "plain_text", "text": "4 heures"}, + "value": "14400", + }, + { + "text": {"type": "plain_text", "text": "1 heure"}, + "value": "3600", + }, + { + "text": {"type": "plain_text", "text": "30 minutes"}, + "value": "1800", + }, + { + "text": {"type": "plain_text", "text": "5 minutes"}, + "value": "300", + }, + ], + "action_id": "secret_ttl", + }, + "label": {"type": "plain_text", "text": "Durée de vie", "emoji": True}, + }, + ], + } diff --git a/app/tests/intergrations/test_google_drive.py b/app/tests/intergrations/test_google_drive.py index 54357bd1..5cf785f0 100644 --- a/app/tests/intergrations/test_google_drive.py +++ b/app/tests/intergrations/test_google_drive.py @@ -568,3 +568,16 @@ def test_replace_text_between_headings_neither_heading_not_found(mock_service): # Check if batchUpdate was not called as the start heading was not found assert not mock_service.return_value.documents().batchUpdate.called + + +@patch("integrations.google_drive.list_metadata") +def test_healthcheck_healthy(mock_list_metadata): + mock_list_metadata.return_value = {"id": "test_doc"} + assert google_drive.healthcheck() is True + + +@patch("integrations.google_drive.list_metadata") +def test_healthcheck_unhealthy(mock_list_metadata): + mock_list_metadata.return_value = None + assert google_drive.healthcheck() is False + diff --git a/app/tests/intergrations/test_maxmind.py b/app/tests/intergrations/test_maxmind.py index d3d7c00b..c76c7b7d 100644 --- a/app/tests/intergrations/test_maxmind.py +++ b/app/tests/intergrations/test_maxmind.py @@ -31,3 +31,18 @@ def test_geolocate_not_found(geiop2_mock): def test_geolocate_invalid_ip(geiop2_mock): geiop2_mock.database.Reader().city.side_effect = ValueError assert maxmind.geolocate("test_ip") == "Invalid IP address" + + +@patch("integrations.maxmind.geoip2") +def test_healthcheck_healthy(geiop2_mock): + geiop2_mock.database.Reader().city.return_value.country.iso_code = "CA" + geiop2_mock.database.Reader().city.return_value.city.name = "test_city" + geiop2_mock.database.Reader().city.return_value.location.latitude = "test_lat" + geiop2_mock.database.Reader().city.return_value.location.longitude = "test_long" + assert maxmind.healthcheck() is True + + +@patch("integrations.maxmind.geoip2") +def test_healthcheck_unhealthy(geiop2_mock): + geiop2_mock.database.Reader().city.side_effect = ValueError + assert maxmind.healthcheck() is False diff --git a/app/tests/intergrations/test_opsgenie.py b/app/tests/intergrations/test_opsgenie.py index bc6682a6..56cb6c26 100644 --- a/app/tests/intergrations/test_opsgenie.py +++ b/app/tests/intergrations/test_opsgenie.py @@ -86,3 +86,21 @@ def test_api_post_request(urlopen_mock, request_mock): "GenieKey OPSGENIE_KEY", ) urlopen_mock.assert_called_once_with(request_mock.return_value) + + +@patch("integrations.opsgenie.api_get_request") +def test_healthcheck_healthy(api_get_request_mock): + api_get_request_mock.return_value = '{"data": {"name": "test_user"}}' + assert opsgenie.healthcheck() is True + + +@patch("integrations.opsgenie.api_get_request") +def test_healthcheck_unhealthy(api_get_request_mock): + api_get_request_mock.return_value = '{"error": "failed"}' + assert opsgenie.healthcheck() is False + + +@patch("integrations.opsgenie.api_get_request") +def test_healthcheck_unhealthy_error(api_get_request_mock): + api_get_request_mock.return_value = "{]" + assert opsgenie.healthcheck() is False diff --git a/app/tests/jobs/test_scheduled_tasks.py b/app/tests/jobs/test_scheduled_tasks.py index 415b8735..d62802d7 100644 --- a/app/tests/jobs/test_scheduled_tasks.py +++ b/app/tests/jobs/test_scheduled_tasks.py @@ -22,3 +22,37 @@ def test_run_continuously(time_mock, threading_mock, schedule_mock): threading_mock.Event.return_value = cease_continuous_run result = scheduled_tasks.run_continuously(interval=1) assert result == cease_continuous_run + + +@patch("jobs.scheduled_tasks.google_drive") +@patch("jobs.scheduled_tasks.maxmind") +@patch("jobs.scheduled_tasks.opsgenie") +@patch("jobs.scheduled_tasks.logging") +def test_integration_healthchecks_healthy( + mock_logging, mock_opsgenie, mock_maxmind, mock_google_drive +): + mock_google_drive.healthcheck.return_value = True + mock_maxmind.healthcheck.return_value = True + mock_opsgenie.healthcheck.return_value = True + scheduled_tasks.integration_healthchecks() + assert mock_google_drive.healthcheck.call_count == 1 + assert mock_maxmind.healthcheck.call_count == 1 + assert mock_opsgenie.healthcheck.call_count == 1 + assert mock_logging.error.call_count == 0 + + +@patch("jobs.scheduled_tasks.google_drive") +@patch("jobs.scheduled_tasks.maxmind") +@patch("jobs.scheduled_tasks.opsgenie") +@patch("jobs.scheduled_tasks.logging") +def test_integration_healthchecks_unhealthy( + mock_logging, mock_opsgenie, mock_maxmind, mock_google_drive +): + mock_google_drive.healthcheck.return_value = False + mock_maxmind.healthcheck.return_value = False + mock_opsgenie.healthcheck.return_value = True + scheduled_tasks.integration_healthchecks() + assert mock_google_drive.healthcheck.call_count == 1 + assert mock_maxmind.healthcheck.call_count == 1 + assert mock_opsgenie.healthcheck.call_count == 1 + assert mock_logging.error.call_count == 2 diff --git a/app/tests/test_main.py b/app/tests/test_main.py index 53e769bf..188070f8 100644 --- a/app/tests/test_main.py +++ b/app/tests/test_main.py @@ -36,6 +36,10 @@ def test_main_invokes_socket_handler( mock_app.action.assert_any_call("archive_channel") mock_app.view.assert_any_call("view_save_incident_roles") + mock_app.command.assert_any_call("/secret") + mock_app.action.assert_any_call("secret_change_locale") + mock_app.view.assert_any_call("secret_view") + mock_app.command.assert_any_call("/sre") mock_app.view.assert_any_call("create_webhooks_view") diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 13ac7de4..f6857bef 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -350,9 +350,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.4.tgz", - "integrity": "sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", + "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -3619,9 +3619,9 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.21.tgz", - "integrity": "sha512-SRfKmRe1KvYnxjEMtxEr+J4HIeMX5YBg/qhRHpxEIGjhX1rshcHlnFUE9K0GazhVKWM7B+nARSkV8LuvJdJ5/g==", + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", + "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -3633,14 +3633,14 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, "node_modules/@mui/base": { - "version": "5.0.0-beta.31", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.31.tgz", - "integrity": "sha512-+uNbP3OHJuZVI00WyMg7xfLZotaEY7LgvYXDfONVJbrS+K9wyjCIPNfjy8r9XJn4fbHo/5ibiZqjWnU9LMNv+A==", + "version": "5.0.0-beta.33", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.33.tgz", + "integrity": "sha512-WcSpoJUw/UYHXpvgtl4HyMar2Ar97illUpqiS/X1gtSBp6sdDW6kB2BJ9OlVQ+Kk/RL2GDp/WHA9sbjAYV35ow==", "dependencies": { - "@babel/runtime": "^7.23.7", - "@floating-ui/react-dom": "^2.0.5", + "@babel/runtime": "^7.23.8", + "@floating-ui/react-dom": "^2.0.6", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.4", + "@mui/utils": "^5.15.6", "@popperjs/core": "^2.11.8", "clsx": "^2.1.0", "prop-types": "^15.8.1" @@ -3664,20 +3664,20 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.4.tgz", - "integrity": "sha512-0OZN9O6hAtBpx70mMNFOPaAIol/ytwZYPY+z7Rf9dK3+1Xlzwvj5/IeShJKvtp76S1qJyhPuvZg0+BGqQaUnUw==", + "version": "5.15.6", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.6.tgz", + "integrity": "sha512-0aoWS4qvk1uzm9JBs83oQmIMIQeTBUeqqu8u+3uo2tMznrB5fIKqQVCbCgq+4Tm4jG+5F7dIvnjvQ2aV7UKtdw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.4.tgz", - "integrity": "sha512-q/Yk7aokN8qGMpR7bwoDpBSeaNe6Bv7vaY9yHYodP37c64TM6ime05ueb/wgksOVszrKkNXC67E/XYbRWOoUFA==", + "version": "5.15.6", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.6.tgz", + "integrity": "sha512-GnkxMtlhs+8ieHLmCytg00ew0vMOiXGFCw8Ra9nxMsBjBqnrOI5gmXqUm+sGggeEU/HG8HyeqC1MX/IxOBJHzA==", "dependencies": { - "@babel/runtime": "^7.23.7" + "@babel/runtime": "^7.23.8" }, "engines": { "node": ">=12.0.0" @@ -3698,16 +3698,16 @@ } }, "node_modules/@mui/material": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.4.tgz", - "integrity": "sha512-T/LGRAC+M0c+D3+y67eHwIN5bSje0TxbcJCWR0esNvU11T0QwrX3jedXItPNBwMupF2F5VWCDHBVLlFnN3+ABA==", - "dependencies": { - "@babel/runtime": "^7.23.7", - "@mui/base": "5.0.0-beta.31", - "@mui/core-downloads-tracker": "^5.15.4", - "@mui/system": "^5.15.4", + "version": "5.15.6", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.6.tgz", + "integrity": "sha512-rw7bDdpi2kzfmcDN78lHp8swArJ5sBCKsn+4G3IpGfu44ycyWAWX0VdlvkjcR9Yrws2KIm7c+8niXpWHUDbWoA==", + "dependencies": { + "@babel/runtime": "^7.23.8", + "@mui/base": "5.0.0-beta.33", + "@mui/core-downloads-tracker": "^5.15.6", + "@mui/system": "^5.15.6", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.4", + "@mui/utils": "^5.15.6", "@types/react-transition-group": "^4.4.10", "clsx": "^2.1.0", "csstype": "^3.1.2", @@ -3742,12 +3742,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.4.tgz", - "integrity": "sha512-9N5myIMEEQTM5WYWPGvvYADzjFo12LgJ7S+2iTZkBNOcJpUxQYM1tvYjkHCDV+t1ocMOEgjR2EfJ9Dus30dBlg==", + "version": "5.15.6", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.6.tgz", + "integrity": "sha512-ZBX9E6VNUSscUOtU8uU462VvpvBS7eFl5VfxAzTRVQBHflzL+5KtnGrebgf6Nd6cdvxa1o0OomiaxSKoN2XDmg==", "dependencies": { - "@babel/runtime": "^7.23.7", - "@mui/utils": "^5.15.4", + "@babel/runtime": "^7.23.8", + "@mui/utils": "^5.15.6", "prop-types": "^15.8.1" }, "engines": { @@ -3768,11 +3768,11 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.4.tgz", - "integrity": "sha512-vtrZUXG5XI8CNiNLcxjIirW4dEbOloR+ikfm6ePBo7jXpJdpXjVzBWetrfE+5eI0cHkKWlTptnJ2voKV8pBRfw==", + "version": "5.15.6", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.6.tgz", + "integrity": "sha512-KAn8P8xP/WigFKMlEYUpU9z2o7jJnv0BG28Qu1dhNQVutsLVIFdRf5Nb+0ijp2qgtcmygQ0FtfRuXv5LYetZTg==", "dependencies": { - "@babel/runtime": "^7.23.7", + "@babel/runtime": "^7.23.8", "@emotion/cache": "^11.11.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" @@ -3799,15 +3799,15 @@ } }, "node_modules/@mui/system": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.4.tgz", - "integrity": "sha512-KCwkHajGBXPs2TK1HJjIyab4NDk0cZoBDYN/TTlXVo1qBAmCjY0vjqrlsjeoG+wrwwcezXMLs/e6OGP66fPCog==", + "version": "5.15.6", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.6.tgz", + "integrity": "sha512-J01D//u8IfXvaEHMBQX5aO2l7Q+P15nt96c4NskX7yp5/+UuZP8XCQJhtBtLuj+M2LLyXHYGmCPeblsmmscP2Q==", "dependencies": { - "@babel/runtime": "^7.23.7", - "@mui/private-theming": "^5.15.4", - "@mui/styled-engine": "^5.15.4", + "@babel/runtime": "^7.23.8", + "@mui/private-theming": "^5.15.6", + "@mui/styled-engine": "^5.15.6", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.4", + "@mui/utils": "^5.15.6", "clsx": "^2.1.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" @@ -3851,11 +3851,11 @@ } }, "node_modules/@mui/utils": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.4.tgz", - "integrity": "sha512-E2wLQGBcs3VR52CpMRjk46cGscC4cbf3Q2uyHNaAeL36yTTm+aVNbtsTCazXtjOP4BDd8lu6VtlTpVC8Rtl4mg==", + "version": "5.15.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.6.tgz", + "integrity": "sha512-qfEhf+zfU9aQdbzo1qrSWlbPQhH1nCgeYgwhOVnj9Bn39shJQitEnXpSQpSNag8+uty5Od6PxmlNKPTnPySRKA==", "dependencies": { - "@babel/runtime": "^7.23.7", + "@babel/runtime": "^7.23.8", "@types/prop-types": "^15.7.11", "prop-types": "^15.8.1", "react-is": "^18.2.0" @@ -3878,9 +3878,9 @@ } }, "node_modules/@mui/x-data-grid": { - "version": "6.18.7", - "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-6.18.7.tgz", - "integrity": "sha512-K1A3pMUPxI4/Mt5A4vrK45fBBQK5rZvBVqRMrB5n8zX++Bj+WLWKvLTtfCmlriUtzuadr/Hl7Z+FDRXUJAx6qg==", + "version": "6.19.1", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-6.19.1.tgz", + "integrity": "sha512-qtmt+XAOdxwb7p3vjk4HcfncAOe+0HzpcC6o6G+rzk9Hqq6MgG3yODrN9mRc/ONg0fD0eVlqDogXxNtJhcFmTQ==", "dependencies": { "@babel/runtime": "^7.23.2", "@mui/utils": "^5.14.16", @@ -5133,9 +5133,9 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "node_modules/@types/node": { - "version": "20.11.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.4.tgz", - "integrity": "sha512-6I0fMH8Aoy2lOejL3s4LhyIYX34DPwY8bl5xlNjBvUEk8OHrcuzsFt+Ied4LvJihbtXPM+8zUqdydfIti86v9g==", + "version": "20.11.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.5.tgz", + "integrity": "sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==", "dependencies": { "undici-types": "~5.26.4" } @@ -6103,9 +6103,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.16", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", - "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==", + "version": "10.4.17", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz", + "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==", "funding": [ { "type": "opencollective", @@ -6121,9 +6121,9 @@ } ], "dependencies": { - "browserslist": "^4.21.10", - "caniuse-lite": "^1.0.30001538", - "fraction.js": "^4.3.6", + "browserslist": "^4.22.2", + "caniuse-lite": "^1.0.30001578", + "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", "postcss-value-parser": "^4.2.0" @@ -6306,12 +6306,12 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.7.tgz", - "integrity": "sha512-LidDk/tEGDfuHW2DWh/Hgo4rmnw3cduK6ZkOI1NPFceSK3n/yAGeOsNT7FLnSGHkXj3RHGSEVkN3FsCTY6w2CQ==", + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz", + "integrity": "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==", "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.4.4", + "@babel/helper-define-polyfill-provider": "^0.5.0", "semver": "^6.3.1" }, "peerDependencies": { @@ -6338,12 +6338,27 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, + "node_modules/babel-plugin-polyfill-corejs3/node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.4.tgz", + "integrity": "sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.4.tgz", - "integrity": "sha512-S/x2iOCvDaCASLYsOOgWOq4bCfKYVqvO/uxjkaYyZ3rVsVE3CeAI/c84NpyuBBymEgNvHgjEot3a9/Z/kXvqsg==", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", + "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.4" + "@babel/helper-define-polyfill-provider": "^0.5.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -6678,9 +6693,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001577", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001577.tgz", - "integrity": "sha512-rs2ZygrG1PNXMfmncM0B5H1hndY5ZCC9b5TkFaVNfZ+AUlyqcMyVIQtc3fsezi0NUCk5XZfDf9WS6WxMxnfdrg==", + "version": "1.0.30001579", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001579.tgz", + "integrity": "sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==", "funding": [ { "type": "opencollective", @@ -7094,9 +7109,9 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/core-js": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.35.0.tgz", - "integrity": "sha512-ntakECeqg81KqMueeGJ79Q5ZgQNR+6eaE8sxGCx62zMbAIj65q+uYvatToew3m6eAGdU4gNZwpZ34NMe4GYswg==", + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.35.1.tgz", + "integrity": "sha512-IgdsbxNyMskrTFxa9lWHyMwAJU5gXOPP+1yO+K59d50VLVAIDAbs7gIv705KzALModfK3ZrSZTPNpC0PQgIZuw==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -7104,9 +7119,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.35.0.tgz", - "integrity": "sha512-5blwFAddknKeNgsjBzilkdQ0+YK8L1PfqPYq40NOYMYFSS38qj+hpTcLLWwpIwA2A5bje/x5jmVn2tzUMg9IVw==", + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.35.1.tgz", + "integrity": "sha512-sftHa5qUJY3rs9Zht1WEnmkvXputCyDBczPnr7QDgL8n3qrF3CMXY4VPSYtOLLiOUJcah2WNXREd48iOl6mQIw==", "dependencies": { "browserslist": "^4.22.2" }, @@ -7116,9 +7131,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.35.0.tgz", - "integrity": "sha512-f+eRYmkou59uh7BPcyJ8MC76DiGhspj1KMxVIcF24tzP8NA9HVa1uC7BTW2tgx7E1QVCzDzsgp7kArrzhlz8Ew==", + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.35.1.tgz", + "integrity": "sha512-zcIdi/CL3MWbBJYo5YCeVAAx+Sy9yJE9I3/u9LkFABwbeaPhTMRWraM8mYFp9jW5Z50hOy7FVzCc8dCrpZqtIQ==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -7212,15 +7227,15 @@ } }, "node_modules/css-loader": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.9.0.tgz", - "integrity": "sha512-3I5Nu4ytWlHvOP6zItjiHlefBNtrH+oehq8tnQa2kO305qpVyx9XNIT1CXIj5bgCJs7qICBCkgCYxQLKPANoLA==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.9.1.tgz", + "integrity": "sha512-OzABOh0+26JKFdMzlK6PY1u5Zx8+Ck7CVRlcGNZoY9qwJjdfu2VWFuprTIpPW+Av5TZTVViYWcFQaEEQURLknQ==", "dependencies": { "icss-utils": "^5.1.0", - "postcss": "^8.4.31", + "postcss": "^8.4.33", "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.3", - "postcss-modules-scope": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.4", + "postcss-modules-scope": "^3.1.1", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", "semver": "^7.5.4" @@ -8224,9 +8239,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.633", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.633.tgz", - "integrity": "sha512-7BvxzXrHFliyQ1oZc6NRMjyEaKOO1Ma1NY98sFZofogWlm+klLWSgrDw7EhatiMgi4R4NV+iWxDdxuIKXtPbOw==" + "version": "1.4.642", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.642.tgz", + "integrity": "sha512-M4+u22ZJGpk4RY7tne6W+APkZhnnhmAH48FNl8iEFK2lEgob+U5rUQsIqQhvAwCXYpfd3H20pHK/ENsCvwTbsA==" }, "node_modules/emittery": { "version": "0.8.1", @@ -14838,9 +14853,9 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", - "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz", + "integrity": "sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==", "dependencies": { "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", @@ -14854,9 +14869,9 @@ } }, "node_modules/postcss-modules-scope": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.0.tgz", - "integrity": "sha512-SaIbK8XW+MZbd0xHPf7kdfA/3eOt7vxJ72IRecn3EzuZVLr1r0orzf0MX/pN8m+NMDoo6X/SQd8oeKqGZd8PXg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz", + "integrity": "sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==", "dependencies": { "postcss-selector-parser": "^6.0.4" }, @@ -15777,9 +15792,9 @@ } }, "node_modules/react-router": { - "version": "6.21.2", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.21.2.tgz", - "integrity": "sha512-jJcgiwDsnaHIeC+IN7atO0XiSRCrOsQAHHbChtJxmgqG2IaYQXSnhqGb5vk2CU/wBQA12Zt+TkbuJjIn65gzbA==", + "version": "6.21.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.21.3.tgz", + "integrity": "sha512-a0H638ZXULv1OdkmiK6s6itNhoy33ywxmUFT/xtSoVyf9VnC7n7+VT4LjVzdIHSaF5TIh9ylUgxMXksHTgGrKg==", "dependencies": { "@remix-run/router": "1.14.2" }, @@ -15791,12 +15806,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.21.2", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.21.2.tgz", - "integrity": "sha512-tE13UukgUOh2/sqYr6jPzZTzmzc70aGRP4pAjG2if0IP3aUT+sBtAKUJh0qMh0zylJHGLmzS+XWVaON4UklHeg==", + "version": "6.21.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.21.3.tgz", + "integrity": "sha512-kNzubk7n4YHSrErzjLK72j0B5i969GsuCGazRl3G6j1zqZBLjuSlYBdVdkDOgzGdPIffUOc9nmgiadTEVoq91g==", "dependencies": { "@remix-run/router": "1.14.2", - "react-router": "6.21.2" + "react-router": "6.21.3" }, "engines": { "node": ">=14.0.0" @@ -17674,9 +17689,9 @@ } }, "node_modules/terser": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz", - "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz", + "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", diff --git a/package-lock.json b/package-lock.json index 3f560080..52471109 100644 --- a/package-lock.json +++ b/package-lock.json @@ -261,14 +261,14 @@ "integrity": "sha512-XxPltXs5R31D6UZeLIV1td3wTXU3jzd3f2DLsXI8tytMGBkIsGcc9sIyiupRtA8y73HAhuSCeweOoBqf6DbWCA==" }, "node_modules/@mui/base": { - "version": "5.0.0-beta.31", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.31.tgz", - "integrity": "sha512-+uNbP3OHJuZVI00WyMg7xfLZotaEY7LgvYXDfONVJbrS+K9wyjCIPNfjy8r9XJn4fbHo/5ibiZqjWnU9LMNv+A==", + "version": "5.0.0-beta.33", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.33.tgz", + "integrity": "sha512-WcSpoJUw/UYHXpvgtl4HyMar2Ar97illUpqiS/X1gtSBp6sdDW6kB2BJ9OlVQ+Kk/RL2GDp/WHA9sbjAYV35ow==", "dependencies": { - "@babel/runtime": "^7.23.7", - "@floating-ui/react-dom": "^2.0.5", + "@babel/runtime": "^7.23.8", + "@floating-ui/react-dom": "^2.0.6", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.4", + "@mui/utils": "^5.15.6", "@popperjs/core": "^2.11.8", "clsx": "^2.1.0", "prop-types": "^15.8.1" @@ -292,20 +292,20 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.4.tgz", - "integrity": "sha512-0OZN9O6hAtBpx70mMNFOPaAIol/ytwZYPY+z7Rf9dK3+1Xlzwvj5/IeShJKvtp76S1qJyhPuvZg0+BGqQaUnUw==", + "version": "5.15.6", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.6.tgz", + "integrity": "sha512-0aoWS4qvk1uzm9JBs83oQmIMIQeTBUeqqu8u+3uo2tMznrB5fIKqQVCbCgq+4Tm4jG+5F7dIvnjvQ2aV7UKtdw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.4.tgz", - "integrity": "sha512-q/Yk7aokN8qGMpR7bwoDpBSeaNe6Bv7vaY9yHYodP37c64TM6ime05ueb/wgksOVszrKkNXC67E/XYbRWOoUFA==", + "version": "5.15.6", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.6.tgz", + "integrity": "sha512-GnkxMtlhs+8ieHLmCytg00ew0vMOiXGFCw8Ra9nxMsBjBqnrOI5gmXqUm+sGggeEU/HG8HyeqC1MX/IxOBJHzA==", "dependencies": { - "@babel/runtime": "^7.23.7" + "@babel/runtime": "^7.23.8" }, "engines": { "node": ">=12.0.0" @@ -326,16 +326,16 @@ } }, "node_modules/@mui/material": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.4.tgz", - "integrity": "sha512-T/LGRAC+M0c+D3+y67eHwIN5bSje0TxbcJCWR0esNvU11T0QwrX3jedXItPNBwMupF2F5VWCDHBVLlFnN3+ABA==", - "dependencies": { - "@babel/runtime": "^7.23.7", - "@mui/base": "5.0.0-beta.31", - "@mui/core-downloads-tracker": "^5.15.4", - "@mui/system": "^5.15.4", + "version": "5.15.6", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.6.tgz", + "integrity": "sha512-rw7bDdpi2kzfmcDN78lHp8swArJ5sBCKsn+4G3IpGfu44ycyWAWX0VdlvkjcR9Yrws2KIm7c+8niXpWHUDbWoA==", + "dependencies": { + "@babel/runtime": "^7.23.8", + "@mui/base": "5.0.0-beta.33", + "@mui/core-downloads-tracker": "^5.15.6", + "@mui/system": "^5.15.6", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.4", + "@mui/utils": "^5.15.6", "@types/react-transition-group": "^4.4.10", "clsx": "^2.1.0", "csstype": "^3.1.2", @@ -370,12 +370,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.4.tgz", - "integrity": "sha512-9N5myIMEEQTM5WYWPGvvYADzjFo12LgJ7S+2iTZkBNOcJpUxQYM1tvYjkHCDV+t1ocMOEgjR2EfJ9Dus30dBlg==", + "version": "5.15.6", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.6.tgz", + "integrity": "sha512-ZBX9E6VNUSscUOtU8uU462VvpvBS7eFl5VfxAzTRVQBHflzL+5KtnGrebgf6Nd6cdvxa1o0OomiaxSKoN2XDmg==", "dependencies": { - "@babel/runtime": "^7.23.7", - "@mui/utils": "^5.15.4", + "@babel/runtime": "^7.23.8", + "@mui/utils": "^5.15.6", "prop-types": "^15.8.1" }, "engines": { @@ -396,11 +396,11 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.4.tgz", - "integrity": "sha512-vtrZUXG5XI8CNiNLcxjIirW4dEbOloR+ikfm6ePBo7jXpJdpXjVzBWetrfE+5eI0cHkKWlTptnJ2voKV8pBRfw==", + "version": "5.15.6", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.6.tgz", + "integrity": "sha512-KAn8P8xP/WigFKMlEYUpU9z2o7jJnv0BG28Qu1dhNQVutsLVIFdRf5Nb+0ijp2qgtcmygQ0FtfRuXv5LYetZTg==", "dependencies": { - "@babel/runtime": "^7.23.7", + "@babel/runtime": "^7.23.8", "@emotion/cache": "^11.11.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" @@ -427,15 +427,15 @@ } }, "node_modules/@mui/system": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.4.tgz", - "integrity": "sha512-KCwkHajGBXPs2TK1HJjIyab4NDk0cZoBDYN/TTlXVo1qBAmCjY0vjqrlsjeoG+wrwwcezXMLs/e6OGP66fPCog==", + "version": "5.15.6", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.6.tgz", + "integrity": "sha512-J01D//u8IfXvaEHMBQX5aO2l7Q+P15nt96c4NskX7yp5/+UuZP8XCQJhtBtLuj+M2LLyXHYGmCPeblsmmscP2Q==", "dependencies": { - "@babel/runtime": "^7.23.7", - "@mui/private-theming": "^5.15.4", - "@mui/styled-engine": "^5.15.4", + "@babel/runtime": "^7.23.8", + "@mui/private-theming": "^5.15.6", + "@mui/styled-engine": "^5.15.6", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.4", + "@mui/utils": "^5.15.6", "clsx": "^2.1.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" @@ -479,11 +479,11 @@ } }, "node_modules/@mui/utils": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.4.tgz", - "integrity": "sha512-E2wLQGBcs3VR52CpMRjk46cGscC4cbf3Q2uyHNaAeL36yTTm+aVNbtsTCazXtjOP4BDd8lu6VtlTpVC8Rtl4mg==", + "version": "5.15.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.6.tgz", + "integrity": "sha512-qfEhf+zfU9aQdbzo1qrSWlbPQhH1nCgeYgwhOVnj9Bn39shJQitEnXpSQpSNag8+uty5Od6PxmlNKPTnPySRKA==", "dependencies": { - "@babel/runtime": "^7.23.7", + "@babel/runtime": "^7.23.8", "@types/prop-types": "^15.7.11", "prop-types": "^15.8.1", "react-is": "^18.2.0" diff --git a/terraform/alarms.tf b/terraform/alarms.tf index b631192e..e1b747da 100644 --- a/terraform/alarms.tf +++ b/terraform/alarms.tf @@ -1,6 +1,6 @@ resource "aws_cloudwatch_log_metric_filter" "sre_bot_error" { name = local.error_logged - pattern = "\"ERROR:slack_bolt.App\"" + pattern = "?ERROR ?Exception" log_group_name = local.api_cloudwatch_log_group metric_transformation { @@ -29,7 +29,7 @@ resource "aws_cloudwatch_metric_alarm" "sre_bot_error" { resource "aws_cloudwatch_log_metric_filter" "sre_bot_warning" { name = local.warning_logged - pattern = "\"WARNING:slack_bolt.App\"" + pattern = "WARNING" log_group_name = local.api_cloudwatch_log_group metric_transformation {