From 6d05beed0b8d6dd76063d26ef759624a0f657670 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Fri, 13 May 2022 06:46:53 +0300 Subject: [PATCH 01/57] update flameshot script to be global - wayland support - experimental local screenshots if domain & key are left empty --- flameshot_example.sh | 27 --------------- screenshot_example.sh | 80 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 27 deletions(-) delete mode 100644 flameshot_example.sh create mode 100644 screenshot_example.sh diff --git a/flameshot_example.sh b/flameshot_example.sh deleted file mode 100644 index e40981e..0000000 --- a/flameshot_example.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -IMAGEPATH="$HOME/Pictures/" # Where to store screenshots before they're deleted -IMAGENAME="ass" # Not really important, tells Flameshot what file to send and delete -KEY="" # Your ass upload token -DOMAIN="" # Your upload domain (without http:// or https://) - -flameshot config -f "$IMAGENAME" # Make sure that Flameshot names the file correctly -flameshot gui -r -p "$IMAGEPATH" > /dev/null # Prompt the screenshot GUI, also append the random gibberish to /dev/null - -FILE="$IMAGEPATH$IMAGENAME.png" # File path and file name combined - -# Check if file exists to handle Curl and rm errors -# then upload the image and copy the response URL -if [ -f "$FILE" ]; then - echo "$FILE exists." - URL=$(curl -X POST \ - -H "Content-Type: multipart/form-data" \ - -H "Accept: application/json" \ - -H "User-Agent: ShareX/13.4.0" \ - -H "Authorization: $KEY" \ - -F "file=@$IMAGEPATH$IMAGENAME.png" "https://$DOMAIN/" | grep -Po '(?<="resource":")[^"]+') - # printf instead of echo as echo appends a newline - printf "%s" "$URL" | xclip -sel clip - rm "$IMAGEPATH$IMAGENAME.png" # Delete the image locally -else - echo "Aborted." -fi diff --git a/screenshot_example.sh b/screenshot_example.sh new file mode 100644 index 0000000..3799103 --- /dev/null +++ b/screenshot_example.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +# File Options +IMAGEPATH="$HOME/Pictures/" # Where to store screenshots before they are deleted +IMAGENAME="ass" # Not really important, tells this script which image to send and delete +FILE="$IMAGEPATH$IMAGENAME" # for future convenience, please do not edit + + +# Authentication +# If left empty, a local screenshot will be taken and copied to your clipboard. +KEY="" # Your ass upload token +DOMAIN="" # Your upload domain (without http:// or https://) + +# helper function to take flameshot screenshots +takeFlameshot () { + flameshot config -f "${IMAGENAME}" + flameshot gui -r -p "${IMAGEPATH}" > /dev/null +} + +# helper function to take screenshots on wayland using grim + slurp for region capture +takeGrimshot () { + grim -g "$(slurp)" "${FILE}.png" > /dev/null +} + +# decide on the screenshot tool(s) based on display backend +if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then + echo -en "Display backend detected as Xorg (x11), using Flameshot\n" # append new line so that Flameshot messages start at a new line + takeFlameshot # call for the flameshot function +elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then + echo -en "Display backend detected as Wayland, using grim & slurp" + takeGrimshot # call for the grim function +else + echo -en "Unknown display backend.\n Assuming Xorg and using Flameshot." + takeFlameshot > ./Flameshot.log # will be full of gibberish, but we try it anyway + echo -en "Done. Make sure you check for any errors and report them.\nLogfile located in $(pwd)" +fi + +# check if the screenshot file actually exists before proceeding with uploading/copying to clipboard +if [[ -f "${FILE}.png" ]]; then + # check if KEY and DOMAIN are correct, + # if they are, upload the file to the ass instance + # if not, copy the image to clipboard and exit + if [[ ( -z ${KEY+x} && -v ${DOMAIN+x} ) ]]; then + URL=$(curl -X POST \ + -H "Content-Type: multipart/form-data" \ + -H "Accept: application/json" \ + -H "User-Agent: ShareX/13.4.0" \ + -H "Authorization: $KEY" \ + -F "file=@$FILE" "https://$DOMAIN/" | grep -Po '(?<="resource":")[^"]+') + if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then + # printf instead of echo as echo appends a newline + printf "%s" "$URL" | xclip -sel clip # it is safe to use xclip on xorg, so we don't need wl-copy + elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then + # if desktop session is wayland instead of xclip, use wl-copy + printf "%s" "$URL" | wl-copy + else + echo -en "Invalid desktop session!\n Exiting." + exit 1 + fi + rm "${FILE}" # Delete the image locally + exit 1 + else + # If domain & key are not set, assume it is a local screenshot and copy the image directly to clipboard + if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then # if display backend is x11, use xclip + # TODO: find a way to copy image to clipboard on qt environments, like KDE Plasma + echo -en "Local screenshots are only available on Wayland (for now).\nExiting..." + exit 1 + elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then # if display backend is wayland, use wl-clipboard (available on AUR or can be self-compiled) + wl-copy < "${FILE}" + exit 1 + else + echo -en "Local screenshots are only available on Wayland (for now).\nExiting..." + #TODO: find a way to copy image to clipboard on qt environments, like KDE Plasma + exit 1 + fi + fi +else + # Abort screenshot if $FILE.png does not exist + echo "Screenshot aborted." +fi From 6b7610a41421b16b09827f5734361a477bb41798 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Fri, 13 May 2022 07:22:19 +0300 Subject: [PATCH 02/57] implement local screenshots on x11 --- screenshot_example.sh | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/screenshot_example.sh b/screenshot_example.sh index 3799103..347dd06 100644 --- a/screenshot_example.sh +++ b/screenshot_example.sh @@ -51,30 +51,26 @@ if [[ -f "${FILE}.png" ]]; then # printf instead of echo as echo appends a newline printf "%s" "$URL" | xclip -sel clip # it is safe to use xclip on xorg, so we don't need wl-copy elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then - # if desktop session is wayland instead of xclip, use wl-copy + # if desktop session is wayland instead of xclip, use wl-copy (wl-clipboard) printf "%s" "$URL" | wl-copy else echo -en "Invalid desktop session!\n Exiting." exit 1 fi - rm "${FILE}" # Delete the image locally - exit 1 + rm "${FILE}.png" # Delete the image locally else # If domain & key are not set, assume it is a local screenshot and copy the image directly to clipboard if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then # if display backend is x11, use xclip - # TODO: find a way to copy image to clipboard on qt environments, like KDE Plasma - echo -en "Local screenshots are only available on Wayland (for now).\nExiting..." - exit 1 + cat "${FILE}.png" | xclip -sel clip -target image/png elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then # if display backend is wayland, use wl-clipboard (available on AUR or can be self-compiled) wl-copy < "${FILE}" - exit 1 else - echo -en "Local screenshots are only available on Wayland (for now).\nExiting..." - #TODO: find a way to copy image to clipboard on qt environments, like KDE Plasma - exit 1 + echo -en "Unknown display backend... Assuming Xorg and using xclip..." + cat "${FILE}.png" | xclip -sel clip -target image/png fi fi + rm "${FILE}.png" else # Abort screenshot if $FILE.png does not exist - echo "Screenshot aborted." + echo -en "Target file was not found.\nAbording screenshot." fi From bda4800fc8a638cdfd98ced92da842e29bdae24f Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Fri, 13 May 2022 07:27:13 +0300 Subject: [PATCH 03/57] performance fix for the shell checker --- ...shot_example.sh => sample_screenshotter.sh | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) rename screenshot_example.sh => sample_screenshotter.sh (50%) diff --git a/screenshot_example.sh b/sample_screenshotter.sh similarity index 50% rename from screenshot_example.sh rename to sample_screenshotter.sh index 347dd06..e0a80a3 100644 --- a/screenshot_example.sh +++ b/sample_screenshotter.sh @@ -66,7 +66,83 @@ if [[ -f "${FILE}.png" ]]; then wl-copy < "${FILE}" else echo -en "Unknown display backend... Assuming Xorg and using xclip..." + #!/bin/bash + +# File Options +IMAGEPATH="$HOME/Pictures/" # Where to store screenshots before they are deleted +IMAGENAME="ass" # Not really important, tells this script which image to send and delete +FILE="$IMAGEPATH$IMAGENAME" # for future convenience, please do not edit + + +# Authentication +# If left empty, a local screenshot will be taken and copied to your clipboard. +KEY="" # Your ass upload token +DOMAIN="" # Your upload domain (without http:// or https://) + +# helper function to take flameshot screenshots +takeFlameshot () { + flameshot config -f "${IMAGENAME}" + flameshot gui -r -p "${IMAGEPATH}" > /dev/null +} + +# helper function to take screenshots on wayland using grim + slurp for region capture +takeGrimshot () { + grim -g "$(slurp)" "${FILE}.png" > /dev/null +} + +# decide on the screenshot tool(s) based on display backend +if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then + echo -en "Display backend detected as Xorg (x11), using Flameshot\n" # append new line so that Flameshot messages start at a new line + takeFlameshot # call for the flameshot function +elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then + echo -en "Display backend detected as Wayland, using grim & slurp" + takeGrimshot # call for the grim function +else + echo -en "Unknown display backend.\n Assuming Xorg and using Flameshot." + takeFlameshot > ./Flameshot.log # will be full of gibberish, but we try it anyway + echo -en "Done. Make sure you check for any errors and report them.\nLogfile located in $(pwd)" +fi + +# check if the screenshot file actually exists before proceeding with uploading/copying to clipboard +if [[ -f "${FILE}.png" ]]; then + # check if KEY and DOMAIN are correct, + # if they are, upload the file to the ass instance + # if not, copy the image to clipboard and exit + if [[ ( -z ${KEY+x} && -v ${DOMAIN+x} ) ]]; then + URL=$(curl -X POST \ + -H "Content-Type: multipart/form-data" \ + -H "Accept: application/json" \ + -H "User-Agent: ShareX/13.4.0" \ + -H "Authorization: $KEY" \ + -F "file=@$FILE" "https://$DOMAIN/" | grep -Po '(?<="resource":")[^"]+') + if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then + # printf instead of echo as echo appends a newline + printf "%s" "$URL" | xclip -sel clip # it is safe to use xclip on xorg, so we don't need wl-copy + elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then + # if desktop session is wayland instead of xclip, use wl-copy (wl-clipboard) + printf "%s" "$URL" | wl-copy + else + echo -en "Invalid desktop session!\n Exiting." + exit 1 + fi + rm "${FILE}.png" # Delete the image locally + else + # If domain & key are not set, assume it is a local screenshot and copy the image directly to clipboard + if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then # if display backend is x11, use xclip cat "${FILE}.png" | xclip -sel clip -target image/png + elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then # if display backend is wayland, use wl-clipboard (available on AUR or can be self-compiled) + wl-copy < "${FILE}" + else + echo -en "Unknown display backend... Assuming Xorg and using xclip..." + xclip -sel clip -target image/png < "${FILE}.png" + fi + fi + rm "${FILE}.png" +else + # Abort screenshot if $FILE.png does not exist + echo -en "Target file was not found.\nAbording screenshot." +fi + fi fi rm "${FILE}.png" From 88c391b02b1dbf7ce5241f1058b5da02eb453e60 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Fri, 13 May 2022 07:31:12 +0300 Subject: [PATCH 04/57] performance fix 2 --- sample_screenshotter.sh | 78 +---------------------------------------- 1 file changed, 1 insertion(+), 77 deletions(-) diff --git a/sample_screenshotter.sh b/sample_screenshotter.sh index e0a80a3..86f9893 100644 --- a/sample_screenshotter.sh +++ b/sample_screenshotter.sh @@ -61,75 +61,7 @@ if [[ -f "${FILE}.png" ]]; then else # If domain & key are not set, assume it is a local screenshot and copy the image directly to clipboard if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then # if display backend is x11, use xclip - cat "${FILE}.png" | xclip -sel clip -target image/png - elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then # if display backend is wayland, use wl-clipboard (available on AUR or can be self-compiled) - wl-copy < "${FILE}" - else - echo -en "Unknown display backend... Assuming Xorg and using xclip..." - #!/bin/bash - -# File Options -IMAGEPATH="$HOME/Pictures/" # Where to store screenshots before they are deleted -IMAGENAME="ass" # Not really important, tells this script which image to send and delete -FILE="$IMAGEPATH$IMAGENAME" # for future convenience, please do not edit - - -# Authentication -# If left empty, a local screenshot will be taken and copied to your clipboard. -KEY="" # Your ass upload token -DOMAIN="" # Your upload domain (without http:// or https://) - -# helper function to take flameshot screenshots -takeFlameshot () { - flameshot config -f "${IMAGENAME}" - flameshot gui -r -p "${IMAGEPATH}" > /dev/null -} - -# helper function to take screenshots on wayland using grim + slurp for region capture -takeGrimshot () { - grim -g "$(slurp)" "${FILE}.png" > /dev/null -} - -# decide on the screenshot tool(s) based on display backend -if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then - echo -en "Display backend detected as Xorg (x11), using Flameshot\n" # append new line so that Flameshot messages start at a new line - takeFlameshot # call for the flameshot function -elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then - echo -en "Display backend detected as Wayland, using grim & slurp" - takeGrimshot # call for the grim function -else - echo -en "Unknown display backend.\n Assuming Xorg and using Flameshot." - takeFlameshot > ./Flameshot.log # will be full of gibberish, but we try it anyway - echo -en "Done. Make sure you check for any errors and report them.\nLogfile located in $(pwd)" -fi - -# check if the screenshot file actually exists before proceeding with uploading/copying to clipboard -if [[ -f "${FILE}.png" ]]; then - # check if KEY and DOMAIN are correct, - # if they are, upload the file to the ass instance - # if not, copy the image to clipboard and exit - if [[ ( -z ${KEY+x} && -v ${DOMAIN+x} ) ]]; then - URL=$(curl -X POST \ - -H "Content-Type: multipart/form-data" \ - -H "Accept: application/json" \ - -H "User-Agent: ShareX/13.4.0" \ - -H "Authorization: $KEY" \ - -F "file=@$FILE" "https://$DOMAIN/" | grep -Po '(?<="resource":")[^"]+') - if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then - # printf instead of echo as echo appends a newline - printf "%s" "$URL" | xclip -sel clip # it is safe to use xclip on xorg, so we don't need wl-copy - elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then - # if desktop session is wayland instead of xclip, use wl-copy (wl-clipboard) - printf "%s" "$URL" | wl-copy - else - echo -en "Invalid desktop session!\n Exiting." - exit 1 - fi - rm "${FILE}.png" # Delete the image locally - else - # If domain & key are not set, assume it is a local screenshot and copy the image directly to clipboard - if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then # if display backend is x11, use xclip - cat "${FILE}.png" | xclip -sel clip -target image/png + xclip -sel clip -target image/png < "${FILE}.png" elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then # if display backend is wayland, use wl-clipboard (available on AUR or can be self-compiled) wl-copy < "${FILE}" else @@ -142,11 +74,3 @@ else # Abort screenshot if $FILE.png does not exist echo -en "Target file was not found.\nAbording screenshot." fi - - fi - fi - rm "${FILE}.png" -else - # Abort screenshot if $FILE.png does not exist - echo -en "Target file was not found.\nAbording screenshot." -fi From 39906e7f7cf91aaa5341c563c526c80bdcd93c49 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Fri, 13 May 2022 07:48:03 +0300 Subject: [PATCH 05/57] ready for production --- sample_screenshotter.sh | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/sample_screenshotter.sh b/sample_screenshotter.sh index 86f9893..0c21a9c 100644 --- a/sample_screenshotter.sh +++ b/sample_screenshotter.sh @@ -11,6 +11,7 @@ FILE="$IMAGEPATH$IMAGENAME" # for future convenience, please do not edit KEY="" # Your ass upload token DOMAIN="" # Your upload domain (without http:// or https://) + # helper function to take flameshot screenshots takeFlameshot () { flameshot config -f "${IMAGENAME}" @@ -27,12 +28,12 @@ if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then echo -en "Display backend detected as Xorg (x11), using Flameshot\n" # append new line so that Flameshot messages start at a new line takeFlameshot # call for the flameshot function elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then - echo -en "Display backend detected as Wayland, using grim & slurp" + echo -en "Display backend detected as Wayland, using grim & slurp\n" takeGrimshot # call for the grim function else - echo -en "Unknown display backend.\n Assuming Xorg and using Flameshot." + echo -en "Unknown display backend.\n Assuming Xorg and using Flameshot.\n" takeFlameshot > ./Flameshot.log # will be full of gibberish, but we try it anyway - echo -en "Done. Make sure you check for any errors and report them.\nLogfile located in $(pwd)" + echo -en "Done. Make sure you check for any errors and report them.\nLogfile located in $(pwd)\n" fi # check if the screenshot file actually exists before proceeding with uploading/copying to clipboard @@ -40,13 +41,14 @@ if [[ -f "${FILE}.png" ]]; then # check if KEY and DOMAIN are correct, # if they are, upload the file to the ass instance # if not, copy the image to clipboard and exit - if [[ ( -z ${KEY+x} && -v ${DOMAIN+x} ) ]]; then + if [[ ( -n "${KEY}" && -n "${DOMAIN}" ) ]]; then + echo -en "KEY & DOMAIN are set\nAttempting to upload to your ass instance.\n" URL=$(curl -X POST \ -H "Content-Type: multipart/form-data" \ -H "Accept: application/json" \ -H "User-Agent: ShareX/13.4.0" \ -H "Authorization: $KEY" \ - -F "file=@$FILE" "https://$DOMAIN/" | grep -Po '(?<="resource":")[^"]+') + -F "file=@${FILE}.png" "https://$DOMAIN/" | grep -Po '(?<="resource":")[^"]+') if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then # printf instead of echo as echo appends a newline printf "%s" "$URL" | xclip -sel clip # it is safe to use xclip on xorg, so we don't need wl-copy @@ -54,23 +56,26 @@ if [[ -f "${FILE}.png" ]]; then # if desktop session is wayland instead of xclip, use wl-copy (wl-clipboard) printf "%s" "$URL" | wl-copy else - echo -en "Invalid desktop session!\n Exiting." + echo -en "Invalid desktop session!\n Exiting.\n" exit 1 fi + echo -en "Process complete.\nRemoving image.\n" rm "${FILE}.png" # Delete the image locally else + echo -en "KEY & DOMAIN are not set\nAttempting local screenshot.\n" # If domain & key are not set, assume it is a local screenshot and copy the image directly to clipboard if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then # if display backend is x11, use xclip xclip -sel clip -target image/png < "${FILE}.png" elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then # if display backend is wayland, use wl-clipboard (available on AUR or can be self-compiled) wl-copy < "${FILE}" else - echo -en "Unknown display backend... Assuming Xorg and using xclip..." + echo -en "Unknown display backend...\nAssuming Xorg and using xclip...\n" xclip -sel clip -target image/png < "${FILE}.png" fi + echo -en "Process complete.\nRemoving image.\n" + rm "${FILE}.png" fi - rm "${FILE}.png" else # Abort screenshot if $FILE.png does not exist - echo -en "Target file was not found.\nAbording screenshot." + echo -en "Target file was not found.\nAbording screenshot.\n" fi From e201da1e5535f3415a6b6089dd02859073a00505 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Sat, 14 Oct 2023 19:23:22 +0300 Subject: [PATCH 06/57] refactor: modularize screenshot script --- sample_screenshotter.sh | 144 ++++++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 65 deletions(-) diff --git a/sample_screenshotter.sh b/sample_screenshotter.sh index 0c21a9c..c577ce1 100644 --- a/sample_screenshotter.sh +++ b/sample_screenshotter.sh @@ -1,81 +1,95 @@ -#!/bin/bash +#!/usr/bin/env bash -# File Options -IMAGEPATH="$HOME/Pictures/" # Where to store screenshots before they are deleted -IMAGENAME="ass" # Not really important, tells this script which image to send and delete -FILE="$IMAGEPATH$IMAGENAME" # for future convenience, please do not edit +# Script Configuration +IMAGEPATH="$HOME/Pictures" +IMAGENAME="ass" +FILE="${IMAGEPATH}/${IMAGENAME}.png" +LOG_DIR=$(pwd) +CONFIG_FILE="config.sh" +# Load configuration if available +# this is useful if you want to source keys from a secret file +if [ -f "$CONFIG_FILE" ]; then + source "${CONFIG_FILE}" +fi -# Authentication -# If left empty, a local screenshot will be taken and copied to your clipboard. -KEY="" # Your ass upload token -DOMAIN="" # Your upload domain (without http:// or https://) +# Function to take Flameshot screenshots +takeFlameshot() { + flameshot config -f "${IMAGENAME}" + flameshot gui -r -p "${IMAGEPATH}" >/dev/null +} +# Function to take Wayland screenshots using grim + slurp +takeGrimshot() { + grim -g "$(slurp)" "${FILE}" >/dev/null +} -# helper function to take flameshot screenshots -takeFlameshot () { - flameshot config -f "${IMAGENAME}" - flameshot gui -r -p "${IMAGEPATH}" > /dev/null +# Function to remove the taken screenshot +removeTargetFile() { + echo -en "Process complete.\nRemoving image.\n" + rm -v "${FILE}" } -# helper function to take screenshots on wayland using grim + slurp for region capture -takeGrimshot () { - grim -g "$(slurp)" "${FILE}.png" > /dev/null +# Function to upload target image to your ass instance +uploadScreenshot() { + echo -en "KEY & DOMAIN are set. Attempting to upload to your ass instance.\n" + URL=$(curl -X POST \ + -H "Content-Type: multipart/form-data" \ + -H "Accept: application/json" \ + -H "User-Agent: ShareX/13.4.0" \ + -H "Authorization: $KEY" \ + -F "file=@${FILE}" "https://$DOMAIN/" | grep -Po '(?<="resource":")[^"]+') + if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then + printf "%s" "$URL" | xclip -sel clip + elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then + printf "%s" "$URL" | wl-copy + else + echo -en "Invalid desktop session!\nExiting.\n" + exit 1 + fi } -# decide on the screenshot tool(s) based on display backend +localScreenshot() { + echo -en "KEY & DOMAIN variables are not set. Attempting local screenshot.\n" + if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then + xclip -sel clip -target image/png <"${FILE}" + elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then + wl-copy <"${FILE}" + else + echo -en "Unknown display backend. Assuming Xorg and using xclip.\n" + xclip -sel clip -target image/png <"${FILE}" + fi +} + +# Check if the screenshot tool based on display backend if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then - echo -en "Display backend detected as Xorg (x11), using Flameshot\n" # append new line so that Flameshot messages start at a new line - takeFlameshot # call for the flameshot function + echo -en "Display backend detected as Xorg (x11), using Flameshot\n" + takeFlameshot elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then - echo -en "Display backend detected as Wayland, using grim & slurp\n" - takeGrimshot # call for the grim function + echo -en "Display backend detected as Wayland, using grim & slurp\n" + takeGrimshot else - echo -en "Unknown display backend.\n Assuming Xorg and using Flameshot.\n" - takeFlameshot > ./Flameshot.log # will be full of gibberish, but we try it anyway - echo -en "Done. Make sure you check for any errors and report them.\nLogfile located in $(pwd)\n" + echo -en "Unknown display backend. Assuming Xorg and using Flameshot\n" + takeFlameshot >"${LOG_DIR}/flameshot.log" + echo -en "Done. Make sure you check for any errors and report them.\nLogfile located in '${LOG_DIR}'\n" fi -# check if the screenshot file actually exists before proceeding with uploading/copying to clipboard -if [[ -f "${FILE}.png" ]]; then - # check if KEY and DOMAIN are correct, - # if they are, upload the file to the ass instance - # if not, copy the image to clipboard and exit - if [[ ( -n "${KEY}" && -n "${DOMAIN}" ) ]]; then - echo -en "KEY & DOMAIN are set\nAttempting to upload to your ass instance.\n" - URL=$(curl -X POST \ - -H "Content-Type: multipart/form-data" \ - -H "Accept: application/json" \ - -H "User-Agent: ShareX/13.4.0" \ - -H "Authorization: $KEY" \ - -F "file=@${FILE}.png" "https://$DOMAIN/" | grep -Po '(?<="resource":")[^"]+') - if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then - # printf instead of echo as echo appends a newline - printf "%s" "$URL" | xclip -sel clip # it is safe to use xclip on xorg, so we don't need wl-copy - elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then - # if desktop session is wayland instead of xclip, use wl-copy (wl-clipboard) - printf "%s" "$URL" | wl-copy - else - echo -en "Invalid desktop session!\n Exiting.\n" - exit 1 - fi - echo -en "Process complete.\nRemoving image.\n" - rm "${FILE}.png" # Delete the image locally - else - echo -en "KEY & DOMAIN are not set\nAttempting local screenshot.\n" - # If domain & key are not set, assume it is a local screenshot and copy the image directly to clipboard - if [[ "${XDG_SESSION_TYPE}" == x11 ]]; then # if display backend is x11, use xclip - xclip -sel clip -target image/png < "${FILE}.png" - elif [[ "${XDG_SESSION_TYPE}" == wayland ]]; then # if display backend is wayland, use wl-clipboard (available on AUR or can be self-compiled) - wl-copy < "${FILE}" - else - echo -en "Unknown display backend...\nAssuming Xorg and using xclip...\n" - xclip -sel clip -target image/png < "${FILE}.png" - fi - echo -en "Process complete.\nRemoving image.\n" - rm "${FILE}.png" - fi +# Check if the screenshot file exists before proceeding +if [[ -f "${FILE}" ]]; then + if [[ -n "$KEY" && -n "$DOMAIN" ]]; then + # Upload the file to the ass instance + uploadImage + + # Remove image + removeTargetFile + else + # Take a screenshot locally + localScreenshot + + # Remove image + removeTargetFile + fi else - # Abort screenshot if $FILE.png does not exist - echo -en "Target file was not found.\nAbording screenshot.\n" + echo -en "Target file ${FILE} was not found. Aborting screenshot.\n" + exit 1 fi From 25a32b387986315c9e33f71757efc97899178e84 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Sat, 14 Oct 2023 19:38:26 +0300 Subject: [PATCH 07/57] feat: sanity checks in sample screenshotter --- sample_screenshotter.sh | 59 ++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/sample_screenshotter.sh b/sample_screenshotter.sh index c577ce1..d6f3603 100644 --- a/sample_screenshotter.sh +++ b/sample_screenshotter.sh @@ -1,26 +1,67 @@ #!/usr/bin/env bash # Script Configuration -IMAGEPATH="$HOME/Pictures" -IMAGENAME="ass" -FILE="${IMAGEPATH}/${IMAGENAME}.png" -LOG_DIR=$(pwd) -CONFIG_FILE="config.sh" - -# Load configuration if available +# Load configuration file if available # this is useful if you want to source keys from a secret file +CONFIG_FILE="config.sh" if [ -f "$CONFIG_FILE" ]; then + # shellcheck disable=1090 source "${CONFIG_FILE}" fi +LOG_DIR=$(pwd) +if [ ! -d "$LOG_DIR" ]; then + echo "The directory you have specified to save the logs does not exist." + echo "Please create the directory with the following command:" + echo "mkdir -p $LOG_DIR" + echo -en "Or specify a different LOG_DIR\n" + exit 1 +fi + +IMAGE_PATH="$HOME/Pictures" +if [ ! -d "$IMAGE_PATH" ]; then + echo "The directory you have specified to save the screenshot does not exist." + echo "Please create the directory with the following command:" + echo "mkdir -p $IMAGE_PATH" + echo -en "Or specify a different IMAGE_PATH\n" + exit 1 +fi + +IMAGE_NAME="ass" +FILE="${IMAGE_PATH}/${IMAGE_NAME}.png" + +# Function to check if a tool is installed +check_tool() { + command -v "$1" >/dev/null 2>&1 +} + # Function to take Flameshot screenshots takeFlameshot() { - flameshot config -f "${IMAGENAME}" - flameshot gui -r -p "${IMAGEPATH}" >/dev/null + # check if flameshot tool is installed + REQUIRED_TOOLS=("flameshot") + + for tool in "${REQUIRED_TOOLS[@]}"; do + if ! check_tool "$tool"; then + echo "Error: $tool is not installed. Please install it before using this script." + exit 1 + fi + done + + flameshot config -f "${IMAGE_NAME}" + flameshot gui -r -p "${IMAGE_PATH}" >/dev/null } # Function to take Wayland screenshots using grim + slurp takeGrimshot() { + # check if grim and slurp are installed + REQUIRED_TOOLS=("grim" "slurp") + for tool in "${REQUIRED_TOOLS[@]}"; do + if ! check_tool "$tool"; then + echo "Error: $tool is not installed. Please install it before using this script." + exit 1 + fi + done + grim -g "$(slurp)" "${FILE}" >/dev/null } From 760a3fac672b9b84f04f836afaed1afa22e7dbb5 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 12:08:29 -0600 Subject: [PATCH 08/57] chore: remove DeepSource config May reconfigure for 15, not sure yet --- .deepsource.toml | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 .deepsource.toml diff --git a/.deepsource.toml b/.deepsource.toml deleted file mode 100644 index 53937b7..0000000 --- a/.deepsource.toml +++ /dev/null @@ -1,12 +0,0 @@ -version = 1 - -[[analyzers]] -name = "shell" -enabled = true - -[[analyzers]] -name = "javascript" -dependency_file_paths = ["package.json"] -environment = ["nodejs", "browser"] -module_system = "commonjs" -enabled = true \ No newline at end of file From 5cc744e6d6a98499888f244c6e32ce6797965863 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 12:09:50 -0600 Subject: [PATCH 09/57] chore: temporarily disable CodeQL (see extended) I'll be reconfiguring CodeQL for ass 15 at some point --- .github/workflows/codeql-analysis.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index dff5c90..9b6c440 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -9,16 +9,16 @@ # the `language` matrix defined below to confirm you have the correct set of # supported CodeQL languages. # -name: "CodeQL" +#name: "CodeQL" -on: - push: - branches: [ master ] - pull_request: +#on: +# push: +# branches: [ master ] +# pull_request: # The branches below must be a subset of the branches above - branches: [ master ] - schedule: - - cron: '24 21 * * 3' +# branches: [ master ] +# schedule: +# - cron: '24 21 * * 3' jobs: analyze: From cb331fe316c8f8e1804eb09671d03a40b7188876 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 12:11:22 -0600 Subject: [PATCH 10/57] fix: comment the entire file? --- .github/workflows/codeql-analysis.yml | 122 +++++++++++++------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 9b6c440..025b884 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,71 +1,71 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -#name: "CodeQL" +# # For most projects, this workflow file will not need changing; you simply need +# # to commit it to your repository. +# # +# # You may wish to alter this file to override the set of languages analyzed, +# # or to provide custom queries or build logic. +# # +# # ******** NOTE ******** +# # We have attempted to detect the languages in your repository. Please check +# # the `language` matrix defined below to confirm you have the correct set of +# # supported CodeQL languages. +# # +# #name: "CodeQL" -#on: -# push: -# branches: [ master ] -# pull_request: - # The branches below must be a subset of the branches above -# branches: [ master ] -# schedule: -# - cron: '24 21 * * 3' +# #on: +# # push: +# # branches: [ master ] +# # pull_request: +# # The branches below must be a subset of the branches above +# # branches: [ master ] +# # schedule: +# # - cron: '24 21 * * 3' -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write +# jobs: +# analyze: +# name: Analyze +# runs-on: ubuntu-latest +# permissions: +# actions: read +# contents: read +# security-events: write - strategy: - fail-fast: false - matrix: - language: [ 'javascript' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] - # Learn more: - # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed +# strategy: +# fail-fast: false +# matrix: +# language: [ 'javascript' ] +# # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] +# # Learn more: +# # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed - steps: - - name: Checkout repository - uses: actions/checkout@v4 +# steps: +# - name: Checkout repository +# uses: actions/checkout@v4 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main +# # Initializes the CodeQL tools for scanning. +# - name: Initialize CodeQL +# uses: github/codeql-action/init@v2 +# with: +# languages: ${{ matrix.language }} +# # If you wish to specify custom queries, you can do so here or in a config file. +# # By default, queries listed here will override any specified in a config file. +# # Prefix the list here with "+" to use these queries and those in the config file. +# # queries: ./path/to/local/query, your-org/your-repo/queries@main - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 +# # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). +# # If this step fails, then you should remove it and run the build manually (see below) +# - name: Autobuild +# uses: github/codeql-action/autobuild@v2 - # ℹī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl +# # ℹī¸ Command-line programs to run using the OS shell. +# # 📚 https://git.io/JvXDl - # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language +# # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines +# # and modify them (or add more) to build your code if your project +# # uses a compiled language - #- run: | - # make bootstrap - # make release +# #- run: | +# # make bootstrap +# # make release - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 +# - name: Perform CodeQL Analysis +# uses: github/codeql-action/analyze@v2 From 72f0087fb07f94378034454d8e1b853e2578b1b7 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 12:12:10 -0600 Subject: [PATCH 11/57] screw you github --- .github/workflows/codeql-analysis.yml | 71 --------------------------- 1 file changed, 71 deletions(-) delete mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 025b884..0000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,71 +0,0 @@ -# # For most projects, this workflow file will not need changing; you simply need -# # to commit it to your repository. -# # -# # You may wish to alter this file to override the set of languages analyzed, -# # or to provide custom queries or build logic. -# # -# # ******** NOTE ******** -# # We have attempted to detect the languages in your repository. Please check -# # the `language` matrix defined below to confirm you have the correct set of -# # supported CodeQL languages. -# # -# #name: "CodeQL" - -# #on: -# # push: -# # branches: [ master ] -# # pull_request: -# # The branches below must be a subset of the branches above -# # branches: [ master ] -# # schedule: -# # - cron: '24 21 * * 3' - -# jobs: -# analyze: -# name: Analyze -# runs-on: ubuntu-latest -# permissions: -# actions: read -# contents: read -# security-events: write - -# strategy: -# fail-fast: false -# matrix: -# language: [ 'javascript' ] -# # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] -# # Learn more: -# # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed - -# steps: -# - name: Checkout repository -# uses: actions/checkout@v4 - -# # Initializes the CodeQL tools for scanning. -# - name: Initialize CodeQL -# uses: github/codeql-action/init@v2 -# with: -# languages: ${{ matrix.language }} -# # If you wish to specify custom queries, you can do so here or in a config file. -# # By default, queries listed here will override any specified in a config file. -# # Prefix the list here with "+" to use these queries and those in the config file. -# # queries: ./path/to/local/query, your-org/your-repo/queries@main - -# # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). -# # If this step fails, then you should remove it and run the build manually (see below) -# - name: Autobuild -# uses: github/codeql-action/autobuild@v2 - -# # ℹī¸ Command-line programs to run using the OS shell. -# # 📚 https://git.io/JvXDl - -# # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines -# # and modify them (or add more) to build your code if your project -# # uses a compiled language - -# #- run: | -# # make bootstrap -# # make release - -# - name: Perform CodeQL Analysis -# uses: github/codeql-action/analyze@v2 From a559866453fb3b1b4a338fac20aa471cbc87f980 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 12:16:22 -0600 Subject: [PATCH 12/57] fix: indicate that I'm not a robot --- .github/workflows/merge-conflict-labeler.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/merge-conflict-labeler.yml b/.github/workflows/merge-conflict-labeler.yml index df04273..0ae960c 100644 --- a/.github/workflows/merge-conflict-labeler.yml +++ b/.github/workflows/merge-conflict-labeler.yml @@ -14,6 +14,6 @@ jobs: if: ${{ github.event_name == 'push' || github.event_name == 'pull_request_target'}} with: dirtyLabel: 'merge conflict' - commentOnDirty: 'This pull request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.' - commentOnClean: "Conflicts have been resolved. A maintainer will review the pull request shortly." + commentOnDirty: '**[AUTOMATED MESSAGE]** 🔴 This Pull Request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.' + commentOnClean: '**[AUTOMATED MESSAGE]** đŸŸĸ Conflicts have been resolved.' repoToken: "${{ secrets.GH_TOKEN }}" From fae0d0b69be30c207d46117fa038f6a65814fc5e Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 12:33:13 -0600 Subject: [PATCH 13/57] refactor: added missing explicit semicolons --- backend/UserConfig.ts | 7 ++----- backend/app.ts | 13 ++++++------- backend/data.ts | 2 +- backend/operations.ts | 33 +++++++++++++++------------------ backend/routers/api.ts | 6 +++--- backend/s3.ts | 2 +- backend/sql/mysql.ts | 2 +- backend/utils.ts | 5 ++--- 8 files changed, 31 insertions(+), 39 deletions(-) diff --git a/backend/UserConfig.ts b/backend/UserConfig.ts index 77bca22..1dddbbc 100644 --- a/backend/UserConfig.ts +++ b/backend/UserConfig.ts @@ -35,10 +35,7 @@ const Checkers: UserConfigTypeChecker = { return false; } }, - idType: (val) => { - const options = ['random', 'original', 'gfycat', 'timestamp', 'zws']; - return options.includes(val); - }, + idType: (val) => ['random', 'original', 'gfycat', 'timestamp', 'zws'].includes(val), idSize: numChecker, gfySize: numChecker, maximumFileSize: numChecker, @@ -61,7 +58,7 @@ const Checkers: UserConfigTypeChecker = { database: basicStringChecker } } -} +}; export class UserConfig { private static _config: UserConfiguration; diff --git a/backend/app.ts b/backend/app.ts index d1d2a2d..b6c56ae 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -14,17 +14,16 @@ import { MySql } from './sql/mysql'; */ export const App = { pkgVersion: '' -} +}; /** * Custom middleware to attach the ass object (and construct the `host` property) */ -function assMetaMiddleware(port: number, proxied: boolean): RequestHandler { - return (req: Request, _res: Response, next: NextFunction) => { +const assMetaMiddleware = (port: number, proxied: boolean): RequestHandler => + (req: Request, _res: Response, next: NextFunction) => { req.ass = { host: `${req.protocol}://${req.hostname}${proxied ? '' : `:${port}`}` }; next(); - } -} + }; /** * Main function. @@ -111,8 +110,8 @@ async function main() { app.get('/.ass.host', (req, res) => res.send(req.ass.host)); // ! I did not want to do it like this how tf did I back myself into this shit - app.get('/admin', (req, res) => res.render('admin', { version: App.pkgVersion })) - app.get('/login', (req, res) => res.render('login', { version: App.pkgVersion })) + app.get('/admin', (req, res) => res.render('admin', { version: App.pkgVersion })); + app.get('/login', (req, res) => res.render('login', { version: App.pkgVersion })); // Routing app.use('/setup', (await import('./routers/setup.js')).router); diff --git a/backend/data.ts b/backend/data.ts index b62a391..65321ab 100644 --- a/backend/data.ts +++ b/backend/data.ts @@ -133,7 +133,7 @@ export const put = (sector: DataSector, key: NID, data: AssFile | AssUser): Prom // ? SQL if (!(await MySql.get('assfiles', key))) await MySql.put('assfiles', key, data); - else return reject(new Error(`File key ${key} already exists`)) + else return reject(new Error(`File key ${key} already exists`)); // todo: modify users SQL files property } diff --git a/backend/operations.ts b/backend/operations.ts index 3855c94..009e89e 100644 --- a/backend/operations.ts +++ b/backend/operations.ts @@ -13,21 +13,19 @@ type SrcDest = { src: string, dest: string }; /** * Strips GPS EXIF data from a file */ -export const removeGPS = (file: string): Promise => { - return new Promise((resolve, reject) => - fs.open(file, 'r+') - .then((fd) => removeLocation(file, - // Read function - (size: number, offset: number): Promise => - fs.read(fd, Buffer.alloc(size), 0, size, offset) - .then(({ buffer }) => Promise.resolve(buffer)), - // Write function - (val: string, offset: number, enc: BufferEncoding): Promise => - fs.write(fd, Buffer.alloc(val.length, val, enc), 0, val.length, offset) - .then(() => Promise.resolve()))) - .then(resolve) - .catch(reject)); -} +export const removeGPS = (file: string): Promise => new Promise((resolve, reject) => + fs.open(file, 'r+') + .then((fd) => removeLocation(file, + // Read function + (size: number, offset: number): Promise => + fs.read(fd, Buffer.alloc(size), 0, size, offset) + .then(({ buffer }) => Promise.resolve(buffer)), + // Write function + (val: string, offset: number, enc: BufferEncoding): Promise => + fs.write(fd, Buffer.alloc(val.length, val, enc), 0, val.length, offset) + .then(() => Promise.resolve()))) + .then(resolve) + .catch(reject)); const VIBRANT = { COLOURS: 256, QUALITY: 3 }; export const vibrant = (file: string, mimetype: string): Promise => new Promise((resolve, reject) => @@ -39,8 +37,7 @@ export const vibrant = (file: string, mimetype: string): Promise => new .quality(VIBRANT.QUALITY) .getPalette()) .then((palettes) => resolve(palettes[Object.keys(palettes).sort((a, b) => palettes[b]!.population - palettes[a]!.population)[0]]!.hex)) - .catch((err) => reject(err)) -) + .catch((err) => reject(err))); /** * Thumbnail operations @@ -64,7 +61,7 @@ export class Thumbnail { } private static getVideoThumbnail({ src, dest }: SrcDest) { - exec(this.getCommand({ src, dest })) + exec(this.getCommand({ src, dest })); } private static getCommand({ src, dest }: SrcDest) { diff --git a/backend/routers/api.ts b/backend/routers/api.ts index a91da49..753e8c9 100644 --- a/backend/routers/api.ts +++ b/backend/routers/api.ts @@ -21,12 +21,12 @@ router.post('/user', BodyParserJson(), async (req, res) => { try { // Username check - if (!newUser.username) issue = 'Missing username' + if (!newUser.username) issue = 'Missing username'; newUser.username.replaceAll(/[^A-z0-9_-]/g, ''); if (newUser.username === '') issue = 'Invalid username'; // Password check - if (!newUser.password) issue = 'Missing password' + if (!newUser.password) issue = 'Missing password'; if (newUser.password === '') issue = 'Invalid password'; newUser.password = newUser.password.substring(0, 128); @@ -48,7 +48,7 @@ router.post('/user', BodyParserJson(), async (req, res) => { // todo: also check duplicate usernames await data.put('users', user.id, user); - } catch (err: any) { issue = `Error: ${err.message}` } + } catch (err: any) { issue = `Error: ${err.message}`; } if (issue) return res.status(400).json({ success: false, messsage: issue }); diff --git a/backend/s3.ts b/backend/s3.ts index 97b1866..2c6a8e2 100644 --- a/backend/s3.ts +++ b/backend/s3.ts @@ -48,7 +48,7 @@ const s3 = (): S3Client | null => { } return _s3client; -} +}; /** * Basic single file upload diff --git a/backend/sql/mysql.ts b/backend/sql/mysql.ts index d4e5122..544e7b5 100644 --- a/backend/sql/mysql.ts +++ b/backend/sql/mysql.ts @@ -87,7 +87,7 @@ export class MySql { if (tablesExist.files && tablesExist.users) log.info('MySQL', 'Tables exist, ready').callback(() => { MySql._ready = true; - resolve(void 0) + resolve(void 0); }); else throw new Error('Table(s) missing!'); } diff --git a/backend/utils.ts b/backend/utils.ts index 60a23b0..64df481 100644 --- a/backend/utils.ts +++ b/backend/utils.ts @@ -6,15 +6,14 @@ export const randomHexColour = () => { // From: https://www.geeksforgeeks.org/ja for (let i = 0; i < 6; i++) colour += letters[(Math.floor(Math.random() * letters.length))]; return colour; -} +}; export const formatTimestamp = (timestamp: number, timeoffset: string) => DateTime.fromMillis(timestamp).setZone(timeoffset).toLocaleString(DateTime.DATETIME_MED); - export const formatBytes = (bytes: number, decimals = 2) => { if (bytes === 0) return '0 Bytes'; const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; const i = Math.floor(Math.log(bytes) / Math.log(1024)); return parseFloat((bytes / Math.pow(1024, i)).toFixed(decimals < 0 ? 0 : decimals)).toString().concat(` ${sizes[i]}`); -} +}; From e94c0bceb8d67b4d95092d07716969f316683b60 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 12:35:22 -0600 Subject: [PATCH 14/57] refactor: delete old Tailwind CSS --- tailwind.old.css | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 tailwind.old.css diff --git a/tailwind.old.css b/tailwind.old.css deleted file mode 100644 index 4a52983..0000000 --- a/tailwind.old.css +++ /dev/null @@ -1,33 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -@layer base {} - -@layer components { - .res-media { - @apply border-l-4 rounded max-h-half-port; - } - - .link { - @apply no-underline hover_no-underline active_no-underline visited_no-underline - - /* regular, visited */ - text-link-primary visited_text-link-primary - border-b-2 visited_border-b-2 - border-transparent visited_border-transparent - rounded-sm visited_rounded-sm - - /* hover */ - hover_text-link-hover - hover_border-hover - - /* active */ - active_text-link-active - - /* transitions */ - ease-linear duration-150 transition-all; - } -} - -@layer utilities {} From 36be2d0bca648dedeee377ae2dabf614db0292b5 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 12:35:43 -0600 Subject: [PATCH 15/57] refactor: delete old Docker deploy scripts (no longer needed) --- install/docker-linux.sh | 31 ------------------------------- install/docker-windows.bat | 28 ---------------------------- 2 files changed, 59 deletions(-) delete mode 100755 install/docker-linux.sh delete mode 100644 install/docker-windows.bat diff --git a/install/docker-linux.sh b/install/docker-linux.sh deleted file mode 100755 index 6a4d3a3..0000000 --- a/install/docker-linux.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -echo "Installing ass-docker for Linux..." - -# Ensure that ./uploads/thumbnails/ exists -mkdir -p ./uploads/thumbnails/ - -# Ensure that ./share/ exists -mkdir -p ./share/ - -# Ensure that files config.json, auth.json, & data.json exist -for value in config.json auth.json data.json -do - if [ ! -f $value ]; then - touch $value - fi -done - -# Wait for user to confirm -echo "Continuing will run docker compose. Continue? (Press Ctrl+C to abort)" -read -n 1 -s -r -p "Press any key to continue..." - -echo Running setup... - -# Bring up the container and run the setup -docker compose up -d && docker compose exec ass npm run setup && docker compose restart - -# Done! -echo "ass-docker for Linux installed!" -echo "Run the following to view commands:" -echo "$ docker compose logs -f --tail=50 --no-log-prefix ass" diff --git a/install/docker-windows.bat b/install/docker-windows.bat deleted file mode 100644 index 34cce34..0000000 --- a/install/docker-windows.bat +++ /dev/null @@ -1,28 +0,0 @@ -@echo off - -ECHO Installing ass-docker for Windows... - -REM Ensure that ./uploads/thumbnails/ exists -if not exist "./uploads/thumbnails/" md "./uploads/thumbnails/" - -REM Ensure that ./share/ exists -if not exist "./share/" md "./share/" - -REM Ensure that files config.json, auth.json, & data.json exist -if not exist "./config.json" echo. >> "./config.json" -if not exist "./auth.json" echo. >> "./auth.json" -if not exist "./data.json" echo. >> "./data.json" - -REM Wait for user to confirm -ECHO Continuing will run docker compose. Continue? (Press Ctrl+C to abort) -PAUSE - -ECHO Running setup... - -REM Bring up the container and run the setup -docker compose up -d && docker compose exec ass npm run setup && docker compose restart - -REM Done! -ECHO ass-docker for Windows installed! -ECHO Run the following to view commands: -ECHO > docker compose logs -f --tail=50 --no-log-prefix ass From 6acf0807b9601c1959ec8f05df845f1e2f675f88 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 13:04:24 -0600 Subject: [PATCH 16/57] fix: copy changes from `dev/0.15.0` branch --- .../workflows/{automation.yml => merge-conflict-labeler.yml} | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) rename .github/workflows/{automation.yml => merge-conflict-labeler.yml} (64%) diff --git a/.github/workflows/automation.yml b/.github/workflows/merge-conflict-labeler.yml similarity index 64% rename from .github/workflows/automation.yml rename to .github/workflows/merge-conflict-labeler.yml index c2d27d8..0ae960c 100644 --- a/.github/workflows/automation.yml +++ b/.github/workflows/merge-conflict-labeler.yml @@ -1,7 +1,6 @@ name: Merge Conflict Labeler on: - push: pull_request_target: types: [ synchronize ] @@ -15,6 +14,6 @@ jobs: if: ${{ github.event_name == 'push' || github.event_name == 'pull_request_target'}} with: dirtyLabel: 'merge conflict' - commentOnDirty: 'This pull request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.' - commentOnClean: "Conflicts have been resolved. A maintainer will review the pull request shortly." + commentOnDirty: '**[AUTOMATED MESSAGE]** 🔴 This Pull Request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.' + commentOnClean: '**[AUTOMATED MESSAGE]** đŸŸĸ Conflicts have been resolved.' repoToken: "${{ secrets.GH_TOKEN }}" From 35fcee6ec16de51e26c76afa218c06ec7410445f Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 13:15:54 -0600 Subject: [PATCH 17/57] feat: added ass version to Request metadata (see #223 for info) --- backend/app.ts | 9 +++++++-- common/global.d.ts | 5 +++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/backend/app.ts b/backend/app.ts index b6c56ae..0320827 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -21,7 +21,10 @@ export const App = { */ const assMetaMiddleware = (port: number, proxied: boolean): RequestHandler => (req: Request, _res: Response, next: NextFunction) => { - req.ass = { host: `${req.protocol}://${req.hostname}${proxied ? '' : `:${port}`}` }; + req.ass = { + host: `${req.protocol}://${req.hostname}${proxied ? '' : `:${port}`}`, + version: App.pkgVersion + }; next(); }; @@ -107,7 +110,9 @@ async function main() { warn: (warning: Error) => log.warn('PostCSS', warning.toString()) })); - app.get('/.ass.host', (req, res) => res.send(req.ass.host)); + // Metadata routes + app.get('/.ass.host', (req, res) => res.type('text').send(req.ass.host)); + app.get('/.ass.version', (req, res) => res.type('text').send(req.ass.version)); // ! I did not want to do it like this how tf did I back myself into this shit app.get('/admin', (req, res) => res.render('admin', { version: App.pkgVersion })); diff --git a/common/global.d.ts b/common/global.d.ts index 543d8e7..124845e 100644 --- a/common/global.d.ts +++ b/common/global.d.ts @@ -14,6 +14,11 @@ declare global { * Combination of {protocol}://{hostname} */ host: string + + /** + * ass version + */ + version: string } files: { [key: string]: BusBoyFile } From 6dc40708101c2b1a37ea78a91c06ae9bdf49c024 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 13:25:15 -0600 Subject: [PATCH 18/57] build: use `@tsconfig/node20` [docker build] --- backend/tsconfig.json | 2 +- frontend/tsconfig.json | 2 +- package-lock.json | 10 +++++----- package.json | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/backend/tsconfig.json b/backend/tsconfig.json index e45f761..7888404 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@tsconfig/node18/tsconfig.json", + "extends": "@tsconfig/node20/tsconfig.json", "compilerOptions": { "outDir": "../dist-backend", "strictPropertyInitialization": false diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 6727cae..cc3cd25 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@tsconfig/node18/tsconfig.json", + "extends": "@tsconfig/node20/tsconfig.json", "compilerOptions": { "outDir": "../dist-frontend", "lib": [ diff --git a/package-lock.json b/package-lock.json index d12e60c..7526b32 100755 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@aws-sdk/client-s3": "^3.421.0", "@shoelace-style/shoelace": "^2.9.0", "@tinycreek/postcss-font-magician": "^4.1.0", - "@tsconfig/node18": "^18.2.2", + "@tsconfig/node20": "^20.1.2", "@tycrek/discord-hookr": "^0.1.0", "@tycrek/express-postcss": "^0.4.0", "@tycrek/joint": "^1.0.0-1", @@ -2350,10 +2350,10 @@ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" }, - "node_modules/@tsconfig/node18": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node18/-/node18-18.2.2.tgz", - "integrity": "sha512-d6McJeGsuoRlwWZmVIeE8CUA27lu6jLjvv1JzqmpsytOYYbVi1tHZEnwCNVOXnj4pyLvneZlFlpXUK+X9wBWyw==" + "node_modules/@tsconfig/node20": { + "version": "20.1.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.2.tgz", + "integrity": "sha512-madaWq2k+LYMEhmcp0fs+OGaLFk0OenpHa4gmI4VEmCKX4PJntQ6fnnGADVFrVkBj0wIdAlQnK/MrlYTHsa1gQ==" }, "node_modules/@tycrek/discord-hookr": { "version": "0.1.0", diff --git a/package.json b/package.json index bedce17..b6b2e4c 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "@aws-sdk/client-s3": "^3.421.0", "@shoelace-style/shoelace": "^2.9.0", "@tinycreek/postcss-font-magician": "^4.1.0", - "@tsconfig/node18": "^18.2.2", + "@tsconfig/node20": "^20.1.2", "@tycrek/discord-hookr": "^0.1.0", "@tycrek/express-postcss": "^0.4.0", "@tycrek/joint": "^1.0.0-1", From fce65a29921e2436612e09eded32a12eb3b885a1 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 14:40:17 -0600 Subject: [PATCH 19/57] feat: make util style --- tailwind.css | 6 +++++- views/login.pug | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tailwind.css b/tailwind.css index 07a21b6..6e62757 100644 --- a/tailwind.css +++ b/tailwind.css @@ -26,4 +26,8 @@ } } -@layer utilities {} \ No newline at end of file +@layer utilities { + .flex-center { + @apply items-center justify-center; + } +} \ No newline at end of file diff --git a/views/login.pug b/views/login.pug index dbb25c2..29292de 100644 --- a/views/login.pug +++ b/views/login.pug @@ -2,5 +2,5 @@ extends _base_ block section span login block content - .flex.flex-col.items-center.justify-center.h-full + .flex.flex-col.flex-center.h-full h1.text-3xl Login \ No newline at end of file From 8065100a4b22901db6f488a06714207a4063a8d5 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 14:51:18 -0600 Subject: [PATCH 20/57] feat: added basic login UI (non-functional) --- views/login.pug | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/views/login.pug b/views/login.pug index 29292de..54a2bf1 100644 --- a/views/login.pug +++ b/views/login.pug @@ -2,5 +2,10 @@ extends _base_ block section span login block content - .flex.flex-col.flex-center.h-full - h1.text-3xl Login \ No newline at end of file + .flex.flex-col.flex-center.h-full: .setup-panel + h3 Username + sl-input#login-username(type='text' placeholder='username' clearable): sl-icon(slot='prefix' name='fas-user' library='fa') + h3 Password + sl-input#login-password(type='password' placeholder='password' clearable): sl-icon(slot='prefix' name='fas-lock' library='fa') + sl-button.mt-4#login-submit(type='primary' submit) Login + //- script(src='/setup/login.js') \ No newline at end of file From 98826a08be51d89b02751a412cd3f10f22303b4c Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 15:10:40 -0600 Subject: [PATCH 21/57] feat: added login router --- backend/app.ts | 2 +- backend/routers/login.ts | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 backend/routers/login.ts diff --git a/backend/app.ts b/backend/app.ts index 0320827..52c290f 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -116,10 +116,10 @@ async function main() { // ! I did not want to do it like this how tf did I back myself into this shit app.get('/admin', (req, res) => res.render('admin', { version: App.pkgVersion })); - app.get('/login', (req, res) => res.render('login', { version: App.pkgVersion })); // Routing app.use('/setup', (await import('./routers/setup.js')).router); + app.use('/login', (await import('./routers/login.js')).router); app.use('/api', (await import('./routers/api.js')).router); app.use('/', (await import('./routers/index.js')).router); diff --git a/backend/routers/login.ts b/backend/routers/login.ts new file mode 100644 index 0000000..3d07501 --- /dev/null +++ b/backend/routers/login.ts @@ -0,0 +1,16 @@ +import { path } from '@tycrek/joint'; +import { Router, json as BodyParserJson } from 'express'; +import { log } from '../log'; +import { UserConfig } from '../UserConfig'; +import { App } from '../app'; + +const router = Router({ caseSensitive: true }); + +// Static routes +router.get('/', (req, res) => !UserConfig.ready ? res.redirect('/') : res.render('login', { version: App.pkgVersion })); +router.get('/ui.js', (req, res) => !UserConfig.ready ? res.send('') : res.type('text/javascript').sendFile(path.join('dist-frontend/login.mjs'))); + +router.post('/', BodyParserJson(), async (req, res) => { +}); + +export { router }; From 789f91ecebc355bed391c2d096a821159576f9ca Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 15:10:56 -0600 Subject: [PATCH 22/57] feat: added base login frontend JS --- frontend/login.mts | 4 ++++ views/login.pug | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 frontend/login.mts diff --git a/frontend/login.mts b/frontend/login.mts new file mode 100644 index 0000000..9138bed --- /dev/null +++ b/frontend/login.mts @@ -0,0 +1,4 @@ +import { SlInput, SlButton } from '@shoelace-style/shoelace'; + +// * Wait for the document to be ready +document.addEventListener('DOMContentLoaded', () => console.log('Login page')); \ No newline at end of file diff --git a/views/login.pug b/views/login.pug index 54a2bf1..4d621a4 100644 --- a/views/login.pug +++ b/views/login.pug @@ -8,4 +8,4 @@ block content h3 Password sl-input#login-password(type='password' placeholder='password' clearable): sl-icon(slot='prefix' name='fas-lock' library='fa') sl-button.mt-4#login-submit(type='primary' submit) Login - //- script(src='/setup/login.js') \ No newline at end of file + script(src='/login/ui.js') \ No newline at end of file From de41cd04ff80b65f4d682a49d5bb21bff9c77c14 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 15:11:23 -0600 Subject: [PATCH 23/57] feat: improved `fix-frontend-js.js` to fix multiple files --- common/fix-frontend-js.js | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/common/fix-frontend-js.js b/common/fix-frontend-js.js index 789d45c..d3f4439 100644 --- a/common/fix-frontend-js.js +++ b/common/fix-frontend-js.js @@ -2,13 +2,24 @@ const fs = require('fs-extra'); const { path } = require('@tycrek/joint'); const log = new (require('@tycrek/log').TLog)(); -log.info('Fixing frontend JS'); +const FILES = { + prefix: 'dist-frontend', + suffix: '.mjs', + pages: [ + 'setup', + 'login' + ] +}; -// Read & fix file data -const setupUiFile = path.join('dist-frontend/setup.mjs'); -const setupUiNew = fs.readFileSync(setupUiFile).toString().replace('export {};', ''); +const fixFile = (page) => { + const filePath = path.join(FILES.prefix, `${page}${FILES.suffix}`); + const fixed = fs.readFileSync(filePath).toString().replace('export {};', ''); -// Write new file -fs.writeFileSync(setupUiFile, setupUiNew); + return fs.writeFile(filePath, fixed); +}; + +log.info('Fixing frontend JS', `${FILES.pages.length} files`); +Promise.all(FILES.pages.map(fixFile)) + .then(() => log.success('Fixed.')) + .catch(console.error); -log.success('Fixed.'); From 701c808f7aa2e1947fd560a07ca0e3adb27aee32 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 15:27:07 -0600 Subject: [PATCH 24/57] feat: set up initial frontend JS --- frontend/login.mts | 24 +++++++++++++++++++++++- frontend/setup.mts | 2 +- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/frontend/login.mts b/frontend/login.mts index 9138bed..74e8c3d 100644 --- a/frontend/login.mts +++ b/frontend/login.mts @@ -1,4 +1,26 @@ import { SlInput, SlButton } from '@shoelace-style/shoelace'; // * Wait for the document to be ready -document.addEventListener('DOMContentLoaded', () => console.log('Login page')); \ No newline at end of file +document.addEventListener('DOMContentLoaded', () => { + + const Elements = { + usernameInput: document.querySelector('#login-username') as SlInput, + passwordInput: document.querySelector('#login-password') as SlInput, + submitButton: document.querySelector('#login-submit') as SlButton + }; + + // * Login button click handler + Elements.submitButton.addEventListener('click', async () => { + Elements.submitButton.disabled = true; + + // Make sure fields are filled + const errorReset = (message: string) => (Elements.submitButton.disabled = false, alert(message)); + if (Elements.usernameInput.value == null || Elements.usernameInput.value === '') + return errorReset('Username is required!'); + if (Elements.passwordInput.value == null || Elements.passwordInput.value === '') + return errorReset('Password is required!'); + + alert(`Attempting to login user [${Elements.usernameInput.value}]`); + Elements.submitButton.disabled = false; + }); +}); diff --git a/frontend/setup.mts b/frontend/setup.mts index 0d8b70a..2db940c 100644 --- a/frontend/setup.mts +++ b/frontend/setup.mts @@ -106,7 +106,7 @@ document.addEventListener('DOMContentLoaded', () => { message: string }) => { alert(data.message); - if (data.success) window.location.href = '/admin'; + if (data.success) window.location.href = '/login'; }); }) .catch((err) => errAlert('POST to /setup failed!', err)) From 72a58295aee9267dc766fa0a14c8bf48d664be05 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 15:34:18 -0600 Subject: [PATCH 25/57] feat: added base implementation of admin routing --- backend/app.ts | 6 ++---- backend/routers/admin.ts | 16 ++++++++++++++++ common/fix-frontend-js.js | 3 ++- frontend/admin.mts | 4 ++++ views/admin.pug | 4 +++- 5 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 backend/routers/admin.ts create mode 100644 frontend/admin.mts diff --git a/backend/app.ts b/backend/app.ts index 52c290f..0712164 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -114,12 +114,10 @@ async function main() { app.get('/.ass.host', (req, res) => res.type('text').send(req.ass.host)); app.get('/.ass.version', (req, res) => res.type('text').send(req.ass.version)); - // ! I did not want to do it like this how tf did I back myself into this shit - app.get('/admin', (req, res) => res.render('admin', { version: App.pkgVersion })); - - // Routing + // Routers app.use('/setup', (await import('./routers/setup.js')).router); app.use('/login', (await import('./routers/login.js')).router); + app.use('/admin', (await import('./routers/admin.js')).router); app.use('/api', (await import('./routers/api.js')).router); app.use('/', (await import('./routers/index.js')).router); diff --git a/backend/routers/admin.ts b/backend/routers/admin.ts new file mode 100644 index 0000000..b3c55f0 --- /dev/null +++ b/backend/routers/admin.ts @@ -0,0 +1,16 @@ +import { path } from '@tycrek/joint'; +import { Router, json as BodyParserJson } from 'express'; +import { log } from '../log'; +import { UserConfig } from '../UserConfig'; +import { App } from '../app'; + +const router = Router({ caseSensitive: true }); + +// Static routes +router.get('/', (req, res) => !UserConfig.ready ? res.redirect('/') : res.render('admin', { version: App.pkgVersion })); +router.get('/ui.js', (req, res) => !UserConfig.ready ? res.send('') : res.type('text/javascript').sendFile(path.join('dist-frontend/admin.mjs'))); + +router.post('/', BodyParserJson(), async (req, res) => { +}); + +export { router }; diff --git a/common/fix-frontend-js.js b/common/fix-frontend-js.js index d3f4439..401a564 100644 --- a/common/fix-frontend-js.js +++ b/common/fix-frontend-js.js @@ -7,7 +7,8 @@ const FILES = { suffix: '.mjs', pages: [ 'setup', - 'login' + 'login', + 'admin', ] }; diff --git a/frontend/admin.mts b/frontend/admin.mts new file mode 100644 index 0000000..62f94c6 --- /dev/null +++ b/frontend/admin.mts @@ -0,0 +1,4 @@ +import { SlInput, SlButton } from '@shoelace-style/shoelace'; + +// * Wait for the document to be ready +document.addEventListener('DOMContentLoaded', () => console.log('Admin page loaded')); diff --git a/views/admin.pug b/views/admin.pug index 086cff4..65b04af 100644 --- a/views/admin.pug +++ b/views/admin.pug @@ -4,4 +4,6 @@ block title block section span admin block content - h1.text-3xl Coming soon. \ No newline at end of file + h1.text-3xl Coming soon. + + script(src='/admin/ui.js') From 9d3dc96aecc45b964e38052f22c2300a9d059f93 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 15:40:42 -0600 Subject: [PATCH 26/57] feat: added base implementation of user routing --- backend/app.ts | 1 + backend/routers/user.ts | 16 ++++++++++++++++ common/fix-frontend-js.js | 1 + frontend/user.mts | 4 ++++ views/user.pug | 9 +++++++++ 5 files changed, 31 insertions(+) create mode 100644 backend/routers/user.ts create mode 100644 frontend/user.mts create mode 100644 views/user.pug diff --git a/backend/app.ts b/backend/app.ts index 0712164..e08eb66 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -118,6 +118,7 @@ async function main() { app.use('/setup', (await import('./routers/setup.js')).router); app.use('/login', (await import('./routers/login.js')).router); app.use('/admin', (await import('./routers/admin.js')).router); + app.use('/user', (await import('./routers/user.js')).router); app.use('/api', (await import('./routers/api.js')).router); app.use('/', (await import('./routers/index.js')).router); diff --git a/backend/routers/user.ts b/backend/routers/user.ts new file mode 100644 index 0000000..60a5ab1 --- /dev/null +++ b/backend/routers/user.ts @@ -0,0 +1,16 @@ +import { path } from '@tycrek/joint'; +import { Router, json as BodyParserJson } from 'express'; +import { log } from '../log'; +import { UserConfig } from '../UserConfig'; +import { App } from '../app'; + +const router = Router({ caseSensitive: true }); + +// Static routes +router.get('/', (req, res) => !UserConfig.ready ? res.redirect('/') : res.render('user', { version: App.pkgVersion })); +router.get('/ui.js', (req, res) => !UserConfig.ready ? res.send('') : res.type('text/javascript').sendFile(path.join('dist-frontend/user.mjs'))); + +router.post('/', BodyParserJson(), async (req, res) => { +}); + +export { router }; diff --git a/common/fix-frontend-js.js b/common/fix-frontend-js.js index 401a564..4bd00a1 100644 --- a/common/fix-frontend-js.js +++ b/common/fix-frontend-js.js @@ -9,6 +9,7 @@ const FILES = { 'setup', 'login', 'admin', + 'user', ] }; diff --git a/frontend/user.mts b/frontend/user.mts new file mode 100644 index 0000000..49c9bea --- /dev/null +++ b/frontend/user.mts @@ -0,0 +1,4 @@ +import { SlInput, SlButton } from '@shoelace-style/shoelace'; + +// * Wait for the document to be ready +document.addEventListener('DOMContentLoaded', () => console.log('User page loaded')); diff --git a/views/user.pug b/views/user.pug new file mode 100644 index 0000000..39fd493 --- /dev/null +++ b/views/user.pug @@ -0,0 +1,9 @@ +extends _base_ +block title + title ass user 🍑 +block section + span user +block content + h1.text-3xl Coming soon. + + script(src='/user/ui.js') From b62a1eacf4c2c09f97880017464bbb099bb7d771 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 16:00:53 -0600 Subject: [PATCH 27/57] build: add session packages --- package-lock.json | 109 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 ++ 2 files changed, 112 insertions(+) diff --git a/package-lock.json b/package-lock.json index 7526b32..ce13bff 100755 --- a/package-lock.json +++ b/package-lock.json @@ -28,9 +28,11 @@ "cssnano": "^6.0.1", "express": "^4.18.2", "express-busboy": "^10.1.0", + "express-session": "^1.17.3", "ffmpeg-static": "^5.2.0", "fs-extra": "^11.1.1", "luxon": "^3.4.3", + "memorystore": "^1.6.7", "mysql2": "^3.6.1", "node-fetch": "^2.6.7", "node-vibrant": "^3.1.6", @@ -47,6 +49,7 @@ "@types/bcrypt": "^5.0.0", "@types/express": "^4.17.18", "@types/express-busboy": "^8.0.1", + "@types/express-session": "^1.17.8", "@types/ffmpeg-static": "^3.0.1", "@types/fs-extra": "^9.0.13", "@types/luxon": "^3.3.2", @@ -2542,6 +2545,15 @@ "@types/send": "*" } }, + "node_modules/@types/express-session": { + "version": "1.17.8", + "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.8.tgz", + "integrity": "sha512-bFF7/3wOldMn+56XyFRGY9ZzCr3JWhNSP2ajMPgTlbZR6BQOCHdAbNA9W5dMBPgMywpIP4zkmhxP6Opm/NRYMQ==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, "node_modules/@types/ffmpeg-static": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/ffmpeg-static/-/ffmpeg-static-3.0.1.tgz", @@ -3934,6 +3946,45 @@ "uuid": "^8.3.2" } }, + "node_modules/express-session": { + "version": "1.17.3", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", + "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==", + "dependencies": { + "cookie": "0.4.2", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/express-session/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express-session/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express-session/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -4892,6 +4943,32 @@ "node": ">= 0.6" } }, + "node_modules/memorystore": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/memorystore/-/memorystore-1.6.7.tgz", + "integrity": "sha512-OZnmNY/NDrKohPQ+hxp0muBcBKrzKNtHr55DbqSx9hLsYVNnomSAMRAtI7R64t3gf3ID7tHQA7mG4oL3Hu9hdw==", + "dependencies": { + "debug": "^4.3.0", + "lru-cache": "^4.0.3" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/memorystore/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/memorystore/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -5345,6 +5422,14 @@ "node": ">= 0.8" } }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -6082,6 +6167,11 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" + }, "node_modules/pug": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", @@ -6251,6 +6341,14 @@ "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" }, + "node_modules/random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -7119,6 +7217,17 @@ "node": ">=14.17" } }, + "node_modules/uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "dependencies": { + "random-bytes": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", diff --git a/package.json b/package.json index b6b2e4c..74b3e76 100644 --- a/package.json +++ b/package.json @@ -47,9 +47,11 @@ "cssnano": "^6.0.1", "express": "^4.18.2", "express-busboy": "^10.1.0", + "express-session": "^1.17.3", "ffmpeg-static": "^5.2.0", "fs-extra": "^11.1.1", "luxon": "^3.4.3", + "memorystore": "^1.6.7", "mysql2": "^3.6.1", "node-fetch": "^2.6.7", "node-vibrant": "^3.1.6", @@ -66,6 +68,7 @@ "@types/bcrypt": "^5.0.0", "@types/express": "^4.17.18", "@types/express-busboy": "^8.0.1", + "@types/express-session": "^1.17.8", "@types/ffmpeg-static": "^3.0.1", "@types/fs-extra": "^9.0.13", "@types/luxon": "^3.3.2", From b7f79a49fd03cb6df0f416ff27feebf99e4d8aee Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 16:02:19 -0600 Subject: [PATCH 28/57] feat: added session types & set up session storage --- backend/app.ts | 15 +++++++++++++++ common/global.d.ts | 7 +++++++ 2 files changed, 22 insertions(+) diff --git a/backend/app.ts b/backend/app.ts index e08eb66..857bae3 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -1,4 +1,6 @@ import express, { Request, Response, NextFunction, RequestHandler, json as BodyParserJson } from 'express'; +import session from 'express-session'; +import MemoryStore from 'memorystore'; import fs from 'fs-extra'; import { path, isProd } from '@tycrek/joint'; import { epcss } from '@tycrek/express-postcss'; @@ -83,9 +85,22 @@ async function main() { // Set up Express const app = express(); + // Configure sessions + const DAY = 86_400_000; + app.use(session({ + name: 'ass', + resave: true, + saveUninitialized: false, + cookie: { maxAge: DAY, secure: isProd() }, + secret: (Math.random() * 100).toString(), + store: new (MemoryStore(session))({ checkPeriod: DAY }) as any, + })); + + // Configure Express features app.enable('case sensitive routing'); app.disable('x-powered-by'); + // Set Express variables app.set('trust proxy', serverConfig.proxied); app.set('view engine', 'pug'); app.set('views', 'views/'); diff --git a/common/global.d.ts b/common/global.d.ts index 124845e..f14f79a 100644 --- a/common/global.d.ts +++ b/common/global.d.ts @@ -1,6 +1,13 @@ import { BusBoyFile } from 'ass'; import { Request, Response } from 'express'; +declare module 'express-session' { + interface SessionData { + uid: string; + token: string; + } +} + declare global { namespace Express { interface Request { From 7f04d365b69e97e7e0077dc4daa46a49ea17d915 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 16:25:40 -0600 Subject: [PATCH 29/57] feat: made basic page routers universal --- backend/app.ts | 11 +++++++---- backend/routers/_frontend.ts | 30 ++++++++++++++++++++++++++++++ backend/routers/admin.ts | 16 ---------------- backend/routers/login.ts | 16 ---------------- backend/routers/user.ts | 16 ---------------- 5 files changed, 37 insertions(+), 52 deletions(-) create mode 100644 backend/routers/_frontend.ts delete mode 100644 backend/routers/admin.ts delete mode 100644 backend/routers/login.ts delete mode 100644 backend/routers/user.ts diff --git a/backend/app.ts b/backend/app.ts index 857bae3..6d6c9cb 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -10,6 +10,7 @@ import { ensureFiles } from './data'; import { UserConfig } from './UserConfig'; import { ServerConfiguration } from 'ass'; import { MySql } from './sql/mysql'; +import { buildFrontendRouter } from './routers/_frontend'; /** * Top-level metadata exports @@ -129,11 +130,13 @@ async function main() { app.get('/.ass.host', (req, res) => res.type('text').send(req.ass.host)); app.get('/.ass.version', (req, res) => res.type('text').send(req.ass.version)); - // Routers + // Basic page routers + app.use('/login', buildFrontendRouter('login')); + app.use('/admin', buildFrontendRouter('admin')); + app.use('/user', buildFrontendRouter('user')); + + // Advanced routers app.use('/setup', (await import('./routers/setup.js')).router); - app.use('/login', (await import('./routers/login.js')).router); - app.use('/admin', (await import('./routers/admin.js')).router); - app.use('/user', (await import('./routers/user.js')).router); app.use('/api', (await import('./routers/api.js')).router); app.use('/', (await import('./routers/index.js')).router); diff --git a/backend/routers/_frontend.ts b/backend/routers/_frontend.ts new file mode 100644 index 0000000..9a830db --- /dev/null +++ b/backend/routers/_frontend.ts @@ -0,0 +1,30 @@ +import { path } from '@tycrek/joint'; +import { Router } from 'express'; +import { UserConfig } from '../UserConfig'; +import { App } from '../app'; + +/** + * Builds a basic router for loading a page with frontend JS + */ +export const buildFrontendRouter = (page: string, onConfigReady = true) => { + + // Config readiness checker + const ready = () => (onConfigReady) + ? UserConfig.ready + : !UserConfig.ready; + + // Set up a router + const router = Router({ caseSensitive: true }); + + // Render the page + router.get('/', (_req, res) => ready() + ? res.render(page, { version: App.pkgVersion }) + : res.redirect('/')); + + // Load frontend JS + router.get('/ui.js', (_req, res) => ready() + ? res.type('text/javascript').sendFile(path.join(`dist-frontend/${page}.mjs`)) + : res.sendStatus(403)); + + return router; +}; diff --git a/backend/routers/admin.ts b/backend/routers/admin.ts deleted file mode 100644 index b3c55f0..0000000 --- a/backend/routers/admin.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { path } from '@tycrek/joint'; -import { Router, json as BodyParserJson } from 'express'; -import { log } from '../log'; -import { UserConfig } from '../UserConfig'; -import { App } from '../app'; - -const router = Router({ caseSensitive: true }); - -// Static routes -router.get('/', (req, res) => !UserConfig.ready ? res.redirect('/') : res.render('admin', { version: App.pkgVersion })); -router.get('/ui.js', (req, res) => !UserConfig.ready ? res.send('') : res.type('text/javascript').sendFile(path.join('dist-frontend/admin.mjs'))); - -router.post('/', BodyParserJson(), async (req, res) => { -}); - -export { router }; diff --git a/backend/routers/login.ts b/backend/routers/login.ts deleted file mode 100644 index 3d07501..0000000 --- a/backend/routers/login.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { path } from '@tycrek/joint'; -import { Router, json as BodyParserJson } from 'express'; -import { log } from '../log'; -import { UserConfig } from '../UserConfig'; -import { App } from '../app'; - -const router = Router({ caseSensitive: true }); - -// Static routes -router.get('/', (req, res) => !UserConfig.ready ? res.redirect('/') : res.render('login', { version: App.pkgVersion })); -router.get('/ui.js', (req, res) => !UserConfig.ready ? res.send('') : res.type('text/javascript').sendFile(path.join('dist-frontend/login.mjs'))); - -router.post('/', BodyParserJson(), async (req, res) => { -}); - -export { router }; diff --git a/backend/routers/user.ts b/backend/routers/user.ts deleted file mode 100644 index 60a5ab1..0000000 --- a/backend/routers/user.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { path } from '@tycrek/joint'; -import { Router, json as BodyParserJson } from 'express'; -import { log } from '../log'; -import { UserConfig } from '../UserConfig'; -import { App } from '../app'; - -const router = Router({ caseSensitive: true }); - -// Static routes -router.get('/', (req, res) => !UserConfig.ready ? res.redirect('/') : res.render('user', { version: App.pkgVersion })); -router.get('/ui.js', (req, res) => !UserConfig.ready ? res.send('') : res.type('text/javascript').sendFile(path.join('dist-frontend/user.mjs'))); - -router.post('/', BodyParserJson(), async (req, res) => { -}); - -export { router }; From 5e7016a0c6ef92b1ae4bdf0368057543689eb80f Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 16:31:25 -0600 Subject: [PATCH 30/57] feat: move setup POST to /api/setup --- backend/app.ts | 2 +- backend/routers/api.ts | 25 +++++++++++++++++++++++++ backend/routers/setup.ts | 39 --------------------------------------- frontend/setup.mts | 4 ++-- 4 files changed, 28 insertions(+), 42 deletions(-) delete mode 100644 backend/routers/setup.ts diff --git a/backend/app.ts b/backend/app.ts index 6d6c9cb..7d4d60f 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -131,12 +131,12 @@ async function main() { app.get('/.ass.version', (req, res) => res.type('text').send(req.ass.version)); // Basic page routers + app.use('/setup', buildFrontendRouter('setup', false)); app.use('/login', buildFrontendRouter('login')); app.use('/admin', buildFrontendRouter('admin')); app.use('/user', buildFrontendRouter('user')); // Advanced routers - app.use('/setup', (await import('./routers/setup.js')).router); app.use('/api', (await import('./routers/api.js')).router); app.use('/', (await import('./routers/index.js')).router); diff --git a/backend/routers/api.ts b/backend/routers/api.ts index 753e8c9..60f44d0 100644 --- a/backend/routers/api.ts +++ b/backend/routers/api.ts @@ -5,9 +5,34 @@ import { UserConfig } from '../UserConfig'; import * as data from '../data'; import { AssUser, AssUserNewReq } from 'ass'; import { nanoid } from '../generators'; +import { MySql } from '../sql/mysql'; const router = Router({ caseSensitive: true }); +// Setup route +router.post('/setup', BodyParserJson(), async (req, res) => { + if (UserConfig.ready) + return res.status(409).json({ success: false, message: 'User config already exists' }); + + log.debug('Setup initiated'); + + try { + // Parse body + new UserConfig(req.body); + + // Save config + await UserConfig.saveConfigFile(); + + // Set data storage (not files) to SQL if required + if (UserConfig.config.sql?.mySql != null) + await Promise.all([MySql.configure(), data.setDataModeToSql()]); + + return res.json({ success: true }); + } catch (err: any) { + return res.status(400).json({ success: false, message: err.message }); + } +}); + // todo: authenticate API endpoints router.post('/user', BodyParserJson(), async (req, res) => { if (!UserConfig.ready) diff --git a/backend/routers/setup.ts b/backend/routers/setup.ts deleted file mode 100644 index e84c70b..0000000 --- a/backend/routers/setup.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { path } from '@tycrek/joint'; -import { Router, json as BodyParserJson } from 'express'; -import { log } from '../log'; -import { UserConfig } from '../UserConfig'; -import { setDataModeToSql } from '../data'; -import { MySql } from '../sql/mysql'; -import { App } from '../app'; - -const router = Router({ caseSensitive: true }); - -// Static routes -router.get('/', (req, res) => UserConfig.ready ? res.redirect('/') : res.render('setup', { version: App.pkgVersion })); -router.get('/ui.js', (req, res) => UserConfig.ready ? res.send('') : res.type('text/javascript').sendFile(path.join('dist-frontend/setup.mjs'))); - -// Setup route -router.post('/', BodyParserJson(), async (req, res) => { - if (UserConfig.ready) - return res.status(409).json({ success: false, message: 'User config already exists' }); - - log.debug('Setup initiated'); - - try { - // Parse body - new UserConfig(req.body); - - // Save config - await UserConfig.saveConfigFile(); - - // Set data storage (not files) to SQL if required - if (UserConfig.config.sql?.mySql != null) - await Promise.all([MySql.configure(), setDataModeToSql()]); - - return res.json({ success: true }); - } catch (err: any) { - return res.status(400).json({ success: false, message: err.message }); - } -}); - -export { router }; diff --git a/frontend/setup.mts b/frontend/setup.mts index 2db940c..f0452c5 100644 --- a/frontend/setup.mts +++ b/frontend/setup.mts @@ -79,7 +79,7 @@ document.addEventListener('DOMContentLoaded', () => { return adminErrReset('Admin password is required!'); // Do setup - fetch('/setup', { + fetch('/api/setup', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(config) @@ -109,7 +109,7 @@ document.addEventListener('DOMContentLoaded', () => { if (data.success) window.location.href = '/login'; }); }) - .catch((err) => errAlert('POST to /setup failed!', err)) + .catch((err) => errAlert('POST to /api/setup failed!', err)) .finally(() => Elements.submitButton.disabled = false); }); }); From 38c235c8367bc575e899a11efb07f9bdbb1b857b Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 16:37:20 -0600 Subject: [PATCH 31/57] feat: improve setup logs --- backend/routers/api.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/routers/api.ts b/backend/routers/api.ts index 60f44d0..67f2805 100644 --- a/backend/routers/api.ts +++ b/backend/routers/api.ts @@ -14,7 +14,7 @@ router.post('/setup', BodyParserJson(), async (req, res) => { if (UserConfig.ready) return res.status(409).json({ success: false, message: 'User config already exists' }); - log.debug('Setup initiated'); + log.info('Setup', 'initiated'); try { // Parse body @@ -27,6 +27,8 @@ router.post('/setup', BodyParserJson(), async (req, res) => { if (UserConfig.config.sql?.mySql != null) await Promise.all([MySql.configure(), data.setDataModeToSql()]); + log.success('Setup', 'completed'); + return res.json({ success: true }); } catch (err: any) { return res.status(400).json({ success: false, message: err.message }); From 1a07edf3cfb51aa02ed8b40abdfbf3aff0defd0b Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 16:37:39 -0600 Subject: [PATCH 32/57] build: added new NPM script `fresh` for clean runs --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 74b3e76..254bd66 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ }, "scripts": { "dev": "npm run build && npm start", + "fresh": "rm -dr .ass-data/ & npm run dev", "build": "rm -dr dist-*/ & npm run build:backend && npm run build:frontend", "build:backend": "tsc -p backend/", "build:frontend": "tsc -p frontend/", From 49bd572d03676d3a44d9cdde6afdadc0ef60302e Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 22:28:46 -0600 Subject: [PATCH 33/57] feat: made these functions universal (will be non-duplicate soon) --- frontend/login.mts | 9 ++++++--- frontend/setup.mts | 6 +++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/frontend/login.mts b/frontend/login.mts index 74e8c3d..1c1ffb6 100644 --- a/frontend/login.mts +++ b/frontend/login.mts @@ -1,5 +1,9 @@ import { SlInput, SlButton } from '@shoelace-style/shoelace'; +const genericErrorAlert = () => alert('An error occured, please check the console for details'); +const errAlert = (logTitle: string, err: any, stream: 'error' | 'warn' = 'error') => (console[stream](logTitle, err), genericErrorAlert()); +const errReset = (message: string, element: SlButton) => (element.disabled = false, alert(message)); + // * Wait for the document to be ready document.addEventListener('DOMContentLoaded', () => { @@ -14,11 +18,10 @@ document.addEventListener('DOMContentLoaded', () => { Elements.submitButton.disabled = true; // Make sure fields are filled - const errorReset = (message: string) => (Elements.submitButton.disabled = false, alert(message)); if (Elements.usernameInput.value == null || Elements.usernameInput.value === '') - return errorReset('Username is required!'); + return errReset('Username is required!', Elements.submitButton); if (Elements.passwordInput.value == null || Elements.passwordInput.value === '') - return errorReset('Password is required!'); + return errReset('Password is required!', Elements.submitButton); alert(`Attempting to login user [${Elements.usernameInput.value}]`); Elements.submitButton.disabled = false; diff --git a/frontend/setup.mts b/frontend/setup.mts index f0452c5..15c5511 100644 --- a/frontend/setup.mts +++ b/frontend/setup.mts @@ -3,6 +3,7 @@ import { IdType, UserConfiguration } from 'ass'; const genericErrorAlert = () => alert('An error occured, please check the console for details'); const errAlert = (logTitle: string, err: any, stream: 'error' | 'warn' = 'error') => (console[stream](logTitle, err), genericErrorAlert()); +const errReset = (message: string, element: SlButton) => (element.disabled = false, alert(message)); // * Wait for the document to be ready document.addEventListener('DOMContentLoaded', () => { @@ -72,11 +73,10 @@ document.addEventListener('DOMContentLoaded', () => { } // ! Make sure the admin user fields are set - const adminErrReset = (message: string) => (Elements.submitButton.disabled = false, alert(message)); if (Elements.userUsername.value == null || Elements.userUsername.value === '') - return adminErrReset('Admin username is required!'); + return errReset('Admin username is required!', Elements.submitButton); if (Elements.userPassword.value == null || Elements.userPassword.value === '') - return adminErrReset('Admin password is required!'); + return errReset('Admin password is required!', Elements.submitButton); // Do setup fetch('/api/setup', { From 69f1776c7aaf4bbef3d60d10314db24b72bf2c30 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 22:34:27 -0600 Subject: [PATCH 34/57] feat: added base implementation of login validation middleware --- backend/routers/api.ts | 20 +++++++++++++++++++- common/global.d.ts | 8 ++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/backend/routers/api.ts b/backend/routers/api.ts index 67f2805..555ef05 100644 --- a/backend/routers/api.ts +++ b/backend/routers/api.ts @@ -1,4 +1,4 @@ -import { Router, json as BodyParserJson } from 'express'; +import { Router, json as BodyParserJson, RequestHandler } from 'express'; import * as bcrypt from 'bcrypt' import { log } from '../log'; import { UserConfig } from '../UserConfig'; @@ -7,6 +7,18 @@ import { AssUser, AssUserNewReq } from 'ass'; import { nanoid } from '../generators'; import { MySql } from '../sql/mysql'; +/** + * Validates a user login session + */ +const validateSessions: RequestHandler = (req, res, next) => { + if (!req.session.ass) (log.debug('Session missing'), req.session.ass = {}); + + // todo: actually authenticate (data.get needs to be updated for subproperties maybe) + // data.get('') + + next(); +}; + const router = Router({ caseSensitive: true }); // Setup route @@ -35,6 +47,12 @@ router.post('/setup', BodyParserJson(), async (req, res) => { } }); +// User login +router.post('/login', BodyParserJson(), validateSessions, async (req, res) => { + log.success('User logged in', req.body.username); + res.json({ success: true, message: `User [${req.body.username}] logged in` }); +}); + // todo: authenticate API endpoints router.post('/user', BodyParserJson(), async (req, res) => { if (!UserConfig.ready) diff --git a/common/global.d.ts b/common/global.d.ts index f14f79a..42fdcf2 100644 --- a/common/global.d.ts +++ b/common/global.d.ts @@ -3,8 +3,12 @@ import { Request, Response } from 'express'; declare module 'express-session' { interface SessionData { - uid: string; - token: string; + ass: { + auth?: { + uid: string; + token: string; + } + } } } From c2577184107d47cd714210b10d35ec1bd10c0ce3 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 14 Oct 2023 22:34:41 -0600 Subject: [PATCH 35/57] feat: added login flow to frontend --- frontend/login.mts | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/frontend/login.mts b/frontend/login.mts index 1c1ffb6..19c1497 100644 --- a/frontend/login.mts +++ b/frontend/login.mts @@ -24,6 +24,24 @@ document.addEventListener('DOMContentLoaded', () => { return errReset('Password is required!', Elements.submitButton); alert(`Attempting to login user [${Elements.usernameInput.value}]`); - Elements.submitButton.disabled = false; + + fetch('/api/login', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + username: Elements.usernameInput.value, + password: Elements.passwordInput.value + }) + }) + .then((res) => res.json()) + .then((data: { + success: boolean, + message: string + }) => { + if (!data.success) alert(data.message); + else window.location.href = '/user'; + }) + .catch((err) => errAlert('POST to /api/login failed!', err)) + .finally(() => Elements.submitButton.disabled = false); }); }); From b4ebe8b5d5a75eea15c08e54bee926382cc0688d Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sun, 15 Oct 2023 12:00:12 -0600 Subject: [PATCH 36/57] feat: added UNTESTED MySQL getAll --- backend/sql/mysql.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/backend/sql/mysql.ts b/backend/sql/mysql.ts index 544e7b5..e26dc0a 100644 --- a/backend/sql/mysql.ts +++ b/backend/sql/mysql.ts @@ -129,4 +129,24 @@ VALUES ('${key}', '${JSON.stringify(data)}'); } }); } + + // todo: unknown if this works + public static getAll(table: TableNamesType): Promise { + return new Promise(async (resolve, reject) => { + try { + // Run query // ! this may not work as expected + const [rowz, _fields] = await MySql._pool.query(`SELECT Data FROM ${table}`); + + // Interpret results this is pain + const rows = (rowz as unknown as { [key: string]: string }[]); + + // console.log(rows); + + // aaaaaaaaaaaa + resolve(undefined); + } catch (err) { + reject(err); + } + }); + } } From 285e5ccc6a1495e428f739d376a6f6cf3d0958cd Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sun, 15 Oct 2023 12:00:51 -0600 Subject: [PATCH 37/57] feat: added getAll to `data.ts` (MySQL is UNTESTED) --- backend/data.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/backend/data.ts b/backend/data.ts index 65321ab..2295faf 100644 --- a/backend/data.ts +++ b/backend/data.ts @@ -178,3 +178,15 @@ export const get = (sector: DataSector, key: NID): Promise => new Promise(async (resolve, reject) => { + try { + const data: { [key: string]: AssFile | AssUser } | undefined = (MySql.ready) + // todo: fix MySQL + ? (await MySql.getAll(sector === 'files' ? 'assfiles' : 'assusers') as /* AssFile[] | AssUser[] | */ undefined) + : (await fs.readJson(PATHS[sector]))[sector]; + (!data) ? resolve(false) : resolve(data); + } catch (err) { + reject(err); + } +}); From 5832a696a8ed4e3a57114e92a91c4ac52f7f4ee4 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sun, 15 Oct 2023 12:06:04 -0600 Subject: [PATCH 38/57] feat: authenticate sessions with bcrypt --- backend/routers/api.ts | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/backend/routers/api.ts b/backend/routers/api.ts index 555ef05..a39b6ba 100644 --- a/backend/routers/api.ts +++ b/backend/routers/api.ts @@ -48,9 +48,29 @@ router.post('/setup', BodyParserJson(), async (req, res) => { }); // User login -router.post('/login', BodyParserJson(), validateSessions, async (req, res) => { - log.success('User logged in', req.body.username); - res.json({ success: true, message: `User [${req.body.username}] logged in` }); +router.post('/login', BodyParserJson(), validateSessions, (req, res) => { + const { username, password } = req.body; + + data.getAll('users') + .then((users) => { + if (!users) throw new Error('Missing users data'); + else return Object.entries(users as { [key: string]: AssUser }) + .filter(([_uid, user]: [string, AssUser]) => user.username === username)[0][1]; // [0] is the first item in the filter results, [1] is is AssUser + }) + .then((user) => Promise.all([bcrypt.compare(password, user.password), user])) + .then(([success, user]) => { + success ? log.success('User logged in', user.username) + : log.warn('User failed to log in', user.username); + + // Set up the session information + if (success) req.session.ass!.auth = { + uid: user.id, + token: '' + }; + + res.json({ success, message: `User [${user.username}] ${success ? 'logged' : 'failed to log'} in` }); + }) + .catch((err) => res.status(400).json({ success: false, message: err.message })); }); // todo: authenticate API endpoints From 5d06745cebbeb2d24919a4c9fbd747cb477b2d3f Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sun, 15 Oct 2023 18:33:12 -0600 Subject: [PATCH 39/57] refactor: use consistent import ordering - global modules - NPM modules (defaults first, then expansions) - local modules --- backend/UserConfig.ts | 4 +++- backend/app.ts | 10 ++++++---- backend/data.ts | 6 ++++-- backend/generators.ts | 2 +- backend/operations.ts | 3 ++- backend/routers/_frontend.ts | 5 +++-- backend/routers/api.ts | 10 ++++++---- backend/routers/index.ts | 14 ++++++++------ backend/s3.ts | 5 +++-- backend/sql/mysql.ts | 6 ++++-- 10 files changed, 40 insertions(+), 25 deletions(-) diff --git a/backend/UserConfig.ts b/backend/UserConfig.ts index 1dddbbc..0a90031 100644 --- a/backend/UserConfig.ts +++ b/backend/UserConfig.ts @@ -1,6 +1,8 @@ +import { UserConfiguration, UserConfigTypeChecker } from 'ass'; + import fs from 'fs-extra'; import { path } from '@tycrek/joint'; -import { UserConfiguration, UserConfigTypeChecker } from 'ass'; + import { log } from './log'; const FILEPATH = path.join('.ass-data/userconfig.json'); diff --git a/backend/app.ts b/backend/app.ts index 7d4d60f..c443e2f 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -1,14 +1,16 @@ -import express, { Request, Response, NextFunction, RequestHandler, json as BodyParserJson } from 'express'; +import { ServerConfiguration } from 'ass'; + +import fs from 'fs-extra'; +import tailwindcss from 'tailwindcss'; import session from 'express-session'; import MemoryStore from 'memorystore'; -import fs from 'fs-extra'; +import express, { Request, Response, NextFunction, RequestHandler, json as BodyParserJson } from 'express'; import { path, isProd } from '@tycrek/joint'; import { epcss } from '@tycrek/express-postcss'; -import tailwindcss from 'tailwindcss'; + import { log } from './log'; import { ensureFiles } from './data'; import { UserConfig } from './UserConfig'; -import { ServerConfiguration } from 'ass'; import { MySql } from './sql/mysql'; import { buildFrontendRouter } from './routers/_frontend'; diff --git a/backend/data.ts b/backend/data.ts index 2295faf..85ae645 100644 --- a/backend/data.ts +++ b/backend/data.ts @@ -1,8 +1,10 @@ +import { AssFile, AssUser, NID, FilesSchema, UsersSchema } from 'ass'; + import fs from 'fs-extra'; import { path } from '@tycrek/joint'; -import { nanoid } from './generators'; + import { log } from './log'; -import { AssFile, AssUser, NID, FilesSchema, UsersSchema } from 'ass'; +import { nanoid } from './generators'; import { UserConfig } from './UserConfig'; import { MySql } from './sql/mysql'; diff --git a/backend/generators.ts b/backend/generators.ts index 51e144f..dba3999 100644 --- a/backend/generators.ts +++ b/backend/generators.ts @@ -1,6 +1,6 @@ import fs from 'fs-extra'; -import { randomBytes, getRandomValues } from 'crypto'; import cryptoRandomString from 'crypto-random-string'; +import { randomBytes, getRandomValues } from 'crypto'; import { path } from '@tycrek/joint'; type Length = { length: number, gfyLength?: number }; diff --git a/backend/operations.ts b/backend/operations.ts index 009e89e..a33399d 100644 --- a/backend/operations.ts +++ b/backend/operations.ts @@ -3,8 +3,9 @@ import sharp from 'sharp'; import Vibrant from 'node-vibrant'; import ffmpeg from 'ffmpeg-static'; import { exec } from 'child_process'; -import { removeLocation } from '@xoi/gps-metadata-remover'; import { isProd } from '@tycrek/joint'; +import { removeLocation } from '@xoi/gps-metadata-remover'; + //@ts-ignore import shell from 'any-shell-escape'; diff --git a/backend/routers/_frontend.ts b/backend/routers/_frontend.ts index 9a830db..9a84c9c 100644 --- a/backend/routers/_frontend.ts +++ b/backend/routers/_frontend.ts @@ -1,7 +1,8 @@ -import { path } from '@tycrek/joint'; import { Router } from 'express'; -import { UserConfig } from '../UserConfig'; +import { path } from '@tycrek/joint'; + import { App } from '../app'; +import { UserConfig } from '../UserConfig'; /** * Builds a basic router for loading a page with frontend JS diff --git a/backend/routers/api.ts b/backend/routers/api.ts index a39b6ba..20c63ce 100644 --- a/backend/routers/api.ts +++ b/backend/routers/api.ts @@ -1,10 +1,12 @@ -import { Router, json as BodyParserJson, RequestHandler } from 'express'; +import { AssUser, AssUserNewReq } from 'ass'; + import * as bcrypt from 'bcrypt' -import { log } from '../log'; -import { UserConfig } from '../UserConfig'; +import { Router, json as BodyParserJson, RequestHandler } from 'express'; + import * as data from '../data'; -import { AssUser, AssUserNewReq } from 'ass'; +import { log } from '../log'; import { nanoid } from '../generators'; +import { UserConfig } from '../UserConfig'; import { MySql } from '../sql/mysql'; /** diff --git a/backend/routers/index.ts b/backend/routers/index.ts index e3bbf2b..cf44fbd 100644 --- a/backend/routers/index.ts +++ b/backend/routers/index.ts @@ -1,15 +1,17 @@ +import { BusBoyFile, AssFile } from 'ass'; + import fs from 'fs-extra'; import bb from 'express-busboy'; -import { Router } from 'express'; import crypto from 'crypto'; -import { log } from '../log'; -import { UserConfig } from '../UserConfig'; -import { random } from '../generators'; -import { BusBoyFile, AssFile } from 'ass'; -import { getFileS3, uploadFileS3 } from '../s3'; +import { Router } from 'express'; import { Readable } from 'stream'; + import * as data from '../data'; +import { log } from '../log'; import { App } from '../app'; +import { random } from '../generators'; +import { UserConfig } from '../UserConfig'; +import { getFileS3, uploadFileS3 } from '../s3'; const router = Router({ caseSensitive: true }); diff --git a/backend/s3.ts b/backend/s3.ts index 2c6a8e2..16c39ef 100644 --- a/backend/s3.ts +++ b/backend/s3.ts @@ -1,5 +1,3 @@ -import { UserConfig } from './UserConfig'; -import { log } from './log'; import { S3Client, S3ClientConfig, @@ -14,6 +12,9 @@ import { AbortMultipartUploadCommand, } from "@aws-sdk/client-s3"; +import { log } from './log'; +import { UserConfig } from './UserConfig'; + const NYR = 'S3 not ready'; /** diff --git a/backend/sql/mysql.ts b/backend/sql/mysql.ts index e26dc0a..5d25a5a 100644 --- a/backend/sql/mysql.ts +++ b/backend/sql/mysql.ts @@ -1,7 +1,9 @@ +import { AssFile, AssUser, NID, UploadToken } from 'ass'; + import mysql, { Pool } from 'mysql2/promise'; -import { UserConfig } from '../UserConfig'; + import { log } from '../log'; -import { AssFile, AssUser, NID, UploadToken } from 'ass'; +import { UserConfig } from '../UserConfig'; type TableNamesType = 'assfiles' | 'assusers' | 'asstokens'; From 04ef991fbcc9468bfe83f4953dbc8e37ae36ecc2 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 21 Oct 2023 21:43:48 -0600 Subject: [PATCH 40/57] fix: remove unnecessary function & move session setup step to exist... ing middleware --- backend/app.ts | 5 +++++ backend/routers/api.ts | 14 +------------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/backend/app.ts b/backend/app.ts index c443e2f..5a2d82f 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -30,6 +30,11 @@ const assMetaMiddleware = (port: number, proxied: boolean): RequestHandler => host: `${req.protocol}://${req.hostname}${proxied ? '' : `:${port}`}`, version: App.pkgVersion }; + + // Set up Session if required + if (!req.session.ass) + (log.debug('Session missing'), req.session.ass = {}); + next(); }; diff --git a/backend/routers/api.ts b/backend/routers/api.ts index 20c63ce..1101c78 100644 --- a/backend/routers/api.ts +++ b/backend/routers/api.ts @@ -9,18 +9,6 @@ import { nanoid } from '../generators'; import { UserConfig } from '../UserConfig'; import { MySql } from '../sql/mysql'; -/** - * Validates a user login session - */ -const validateSessions: RequestHandler = (req, res, next) => { - if (!req.session.ass) (log.debug('Session missing'), req.session.ass = {}); - - // todo: actually authenticate (data.get needs to be updated for subproperties maybe) - // data.get('') - - next(); -}; - const router = Router({ caseSensitive: true }); // Setup route @@ -50,7 +38,7 @@ router.post('/setup', BodyParserJson(), async (req, res) => { }); // User login -router.post('/login', BodyParserJson(), validateSessions, (req, res) => { +router.post('/login', BodyParserJson(), (req, res) => { const { username, password } = req.body; data.getAll('users') From b46198eb472aebd7ca02d59fb064114e58c87f14 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 21 Oct 2023 22:02:35 -0600 Subject: [PATCH 41/57] feat: added login checker/redirection flow --- backend/app.ts | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/backend/app.ts b/backend/app.ts index 5a2d82f..bb8fc5a 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -1,4 +1,4 @@ -import { ServerConfiguration } from 'ass'; +import { AssUser, ServerConfiguration } from 'ass'; import fs from 'fs-extra'; import tailwindcss from 'tailwindcss'; @@ -9,7 +9,7 @@ import { path, isProd } from '@tycrek/joint'; import { epcss } from '@tycrek/express-postcss'; import { log } from './log'; -import { ensureFiles } from './data'; +import { ensureFiles, get } from './data'; import { UserConfig } from './UserConfig'; import { MySql } from './sql/mysql'; import { buildFrontendRouter } from './routers/_frontend'; @@ -38,6 +38,24 @@ const assMetaMiddleware = (port: number, proxied: boolean): RequestHandler => next(); }; +/** + * Custom middleware to verify user access + */ +const loginRedirectMiddleware = async (req: Request, res: Response, next: NextFunction) => { + + // If auth doesn't exist yet, make the user login + if (!req.session.ass?.auth) res.redirect('/login'); + else { + const user = (await get('users', req.session.ass.auth.uid)) as AssUser; + + // Check if user is admin + if (req.baseUrl === '/admin' && !user.admin) { + log.warn('Admin verification failed', user.username, user.id); + res.sendStatus(403); + } else next(); + } +}; + /** * Main function. * Yes I'm using main() in TS, cry about it @@ -140,8 +158,8 @@ async function main() { // Basic page routers app.use('/setup', buildFrontendRouter('setup', false)); app.use('/login', buildFrontendRouter('login')); - app.use('/admin', buildFrontendRouter('admin')); - app.use('/user', buildFrontendRouter('user')); + app.use('/admin', loginRedirectMiddleware, buildFrontendRouter('admin')); + app.use('/user', loginRedirectMiddleware, buildFrontendRouter('user')); // Advanced routers app.use('/api', (await import('./routers/api.js')).router); From 4b68cb7c3187602776dde898cf0e997e567f7acc Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 21 Oct 2023 22:23:27 -0600 Subject: [PATCH 42/57] feat: redirect user to the page they originally requested --- backend/app.ts | 6 +++++- backend/routers/api.ts | 6 +++++- common/global.d.ts | 1 + frontend/login.mts | 5 +++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/backend/app.ts b/backend/app.ts index bb8fc5a..a8e9d57 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -44,7 +44,11 @@ const assMetaMiddleware = (port: number, proxied: boolean): RequestHandler => const loginRedirectMiddleware = async (req: Request, res: Response, next: NextFunction) => { // If auth doesn't exist yet, make the user login - if (!req.session.ass?.auth) res.redirect('/login'); + if (!req.session.ass?.auth) { + req.session.ass!.preLoginPath = req.baseUrl; + log.warn('User not logged in', req.baseUrl); + res.redirect('/login'); + } else { const user = (await get('users', req.session.ass.auth.uid)) as AssUser; diff --git a/backend/routers/api.ts b/backend/routers/api.ts index 1101c78..fd7dee0 100644 --- a/backend/routers/api.ts +++ b/backend/routers/api.ts @@ -58,7 +58,11 @@ router.post('/login', BodyParserJson(), (req, res) => { token: '' }; - res.json({ success, message: `User [${user.username}] ${success ? 'logged' : 'failed to log'} in` }); + // Respond + res.json({ success, message: `User [${user.username}] ${success ? 'logged' : 'failed to log'} in`, meta: { redirectTo: req.session.ass?.preLoginPath ?? '/user' } }); + + // Delete the pre-login path after successful login + if (success) delete req.session.ass?.preLoginPath; }) .catch((err) => res.status(400).json({ success: false, message: err.message })); }); diff --git a/common/global.d.ts b/common/global.d.ts index 42fdcf2..d7d892e 100644 --- a/common/global.d.ts +++ b/common/global.d.ts @@ -8,6 +8,7 @@ declare module 'express-session' { uid: string; token: string; } + preLoginPath?: string; } } } diff --git a/frontend/login.mts b/frontend/login.mts index 19c1497..2f4952c 100644 --- a/frontend/login.mts +++ b/frontend/login.mts @@ -36,10 +36,11 @@ document.addEventListener('DOMContentLoaded', () => { .then((res) => res.json()) .then((data: { success: boolean, - message: string + message: string, + meta: { redirectTo: string } }) => { if (!data.success) alert(data.message); - else window.location.href = '/user'; + else window.location.href = data.meta.redirectTo; }) .catch((err) => errAlert('POST to /api/login failed!', err)) .finally(() => Elements.submitButton.disabled = false); From c2509388d3d5193396af5cc68e2c9e47b5c8bc20 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 21 Oct 2023 22:38:19 -0600 Subject: [PATCH 43/57] fix: add proper type here (excuse to do a [docker build] ) --- backend/app.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app.ts b/backend/app.ts index a8e9d57..feeecf4 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -41,7 +41,7 @@ const assMetaMiddleware = (port: number, proxied: boolean): RequestHandler => /** * Custom middleware to verify user access */ -const loginRedirectMiddleware = async (req: Request, res: Response, next: NextFunction) => { +const loginRedirectMiddleware: RequestHandler = async (req: Request, res: Response, next: NextFunction) => { // If auth doesn't exist yet, make the user login if (!req.session.ass?.auth) { From c84f507deab104d66188830cb68d622a29008515 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 21 Oct 2023 23:03:57 -0600 Subject: [PATCH 44/57] chore: minor cleanup --- backend/app.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/backend/app.ts b/backend/app.ts index feeecf4..253e48c 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -45,11 +45,14 @@ const loginRedirectMiddleware: RequestHandler = async (req: Request, res: Respon // If auth doesn't exist yet, make the user login if (!req.session.ass?.auth) { - req.session.ass!.preLoginPath = req.baseUrl; log.warn('User not logged in', req.baseUrl); + + // Set pre-login path so user is directed to their requested page + req.session.ass!.preLoginPath = req.baseUrl; + + // Redirect res.redirect('/login'); - } - else { + } else { const user = (await get('users', req.session.ass.auth.uid)) as AssUser; // Check if user is admin From 1c12615e0160f4c57b7ced16935cd014c2f663ec Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 21 Oct 2023 23:05:50 -0600 Subject: [PATCH 45/57] feat: add `requireAdmin` optional param --- backend/app.ts | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/backend/app.ts b/backend/app.ts index 253e48c..a0b2cc2 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -41,27 +41,28 @@ const assMetaMiddleware = (port: number, proxied: boolean): RequestHandler => /** * Custom middleware to verify user access */ -const loginRedirectMiddleware: RequestHandler = async (req: Request, res: Response, next: NextFunction) => { - - // If auth doesn't exist yet, make the user login - if (!req.session.ass?.auth) { - log.warn('User not logged in', req.baseUrl); - - // Set pre-login path so user is directed to their requested page - req.session.ass!.preLoginPath = req.baseUrl; - - // Redirect - res.redirect('/login'); - } else { - const user = (await get('users', req.session.ass.auth.uid)) as AssUser; - - // Check if user is admin - if (req.baseUrl === '/admin' && !user.admin) { - log.warn('Admin verification failed', user.username, user.id); - res.sendStatus(403); - } else next(); - } -}; +const loginRedirectMiddleware = (requireAdmin = false): RequestHandler => + async (req: Request, res: Response, next: NextFunction) => { + + // If auth doesn't exist yet, make the user login + if (!req.session.ass?.auth) { + log.warn('User not logged in', req.baseUrl); + + // Set pre-login path so user is directed to their requested page + req.session.ass!.preLoginPath = req.baseUrl; + + // Redirect + res.redirect('/login'); + } else { + const user = (await get('users', req.session.ass.auth.uid)) as AssUser; + + // Check if user is admin + if ((requireAdmin || req.baseUrl === '/admin') && !user.admin) { + log.warn('Admin verification failed', user.username, user.id); + res.sendStatus(403); + } else next(); + } + }; /** * Main function. @@ -165,8 +166,8 @@ async function main() { // Basic page routers app.use('/setup', buildFrontendRouter('setup', false)); app.use('/login', buildFrontendRouter('login')); - app.use('/admin', loginRedirectMiddleware, buildFrontendRouter('admin')); - app.use('/user', loginRedirectMiddleware, buildFrontendRouter('user')); + app.use('/admin', loginRedirectMiddleware(), buildFrontendRouter('admin')); + app.use('/user', loginRedirectMiddleware(), buildFrontendRouter('user')); // Advanced routers app.use('/api', (await import('./routers/api.js')).router); From 2746a3e32ac1fe2e69939aeeb02f2004dba895de Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 21 Oct 2023 23:16:00 -0600 Subject: [PATCH 46/57] fix: reduce alerts to improve user flow --- frontend/login.mts | 2 -- frontend/setup.mts | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/frontend/login.mts b/frontend/login.mts index 2f4952c..7a76a74 100644 --- a/frontend/login.mts +++ b/frontend/login.mts @@ -23,8 +23,6 @@ document.addEventListener('DOMContentLoaded', () => { if (Elements.passwordInput.value == null || Elements.passwordInput.value === '') return errReset('Password is required!', Elements.submitButton); - alert(`Attempting to login user [${Elements.usernameInput.value}]`); - fetch('/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, diff --git a/frontend/setup.mts b/frontend/setup.mts index 15c5511..1ef28a2 100644 --- a/frontend/setup.mts +++ b/frontend/setup.mts @@ -105,8 +105,8 @@ document.addEventListener('DOMContentLoaded', () => { success: boolean, message: string }) => { - alert(data.message); - if (data.success) window.location.href = '/login'; + if (data.success) window.location.href = '/admin'; + else alert(data.message); }); }) .catch((err) => errAlert('POST to /api/setup failed!', err)) From 3d0a6eb794abab33cb9f6954b84e91a155625bef Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Sat, 21 Oct 2023 23:17:36 -0600 Subject: [PATCH 47/57] build: update packages [docker build] --- package-lock.json | 1385 +++++++++++++++++++++++---------------------- 1 file changed, 702 insertions(+), 683 deletions(-) diff --git a/package-lock.json b/package-lock.json index ce13bff..ef902eb 100755 --- a/package-lock.json +++ b/package-lock.json @@ -214,63 +214,63 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@aws-sdk/client-s3": { - "version": "3.427.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.427.0.tgz", - "integrity": "sha512-YKjJ9zgn0oE393HURKgvjNoX6lxUjb+dkTBE1GymFnGCPl6VxQbKXajXWNqUyN+oPPlZ2osEiljPaN0RserUjA==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.433.0.tgz", + "integrity": "sha512-gCuV4kmmHPFrQIl53VxddIylqItarwyX9+ykNIxMoMcEcBVmJhmshV6M9Re+wzS8eUPB6maqurOKGu83YUMpIA==", "dependencies": { "@aws-crypto/sha1-browser": "3.0.0", "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.427.0", - "@aws-sdk/credential-provider-node": "3.427.0", - "@aws-sdk/middleware-bucket-endpoint": "3.425.0", - "@aws-sdk/middleware-expect-continue": "3.425.0", - "@aws-sdk/middleware-flexible-checksums": "3.425.0", - "@aws-sdk/middleware-host-header": "3.425.0", - "@aws-sdk/middleware-location-constraint": "3.425.0", - "@aws-sdk/middleware-logger": "3.425.0", - "@aws-sdk/middleware-recursion-detection": "3.425.0", - "@aws-sdk/middleware-sdk-s3": "3.427.0", - "@aws-sdk/middleware-signing": "3.425.0", - "@aws-sdk/middleware-ssec": "3.425.0", - "@aws-sdk/middleware-user-agent": "3.427.0", - "@aws-sdk/region-config-resolver": "3.425.0", - "@aws-sdk/signature-v4-multi-region": "3.425.0", - "@aws-sdk/types": "3.425.0", - "@aws-sdk/util-endpoints": "3.427.0", - "@aws-sdk/util-user-agent-browser": "3.425.0", - "@aws-sdk/util-user-agent-node": "3.425.0", + "@aws-sdk/client-sts": "3.433.0", + "@aws-sdk/credential-provider-node": "3.433.0", + "@aws-sdk/middleware-bucket-endpoint": "3.433.0", + "@aws-sdk/middleware-expect-continue": "3.433.0", + "@aws-sdk/middleware-flexible-checksums": "3.433.0", + "@aws-sdk/middleware-host-header": "3.433.0", + "@aws-sdk/middleware-location-constraint": "3.433.0", + "@aws-sdk/middleware-logger": "3.433.0", + "@aws-sdk/middleware-recursion-detection": "3.433.0", + "@aws-sdk/middleware-sdk-s3": "3.433.0", + "@aws-sdk/middleware-signing": "3.433.0", + "@aws-sdk/middleware-ssec": "3.433.0", + "@aws-sdk/middleware-user-agent": "3.433.0", + "@aws-sdk/region-config-resolver": "3.433.0", + "@aws-sdk/signature-v4-multi-region": "3.433.0", + "@aws-sdk/types": "3.433.0", + "@aws-sdk/util-endpoints": "3.433.0", + "@aws-sdk/util-user-agent-browser": "3.433.0", + "@aws-sdk/util-user-agent-node": "3.433.0", "@aws-sdk/xml-builder": "3.310.0", - "@smithy/config-resolver": "^2.0.11", - "@smithy/eventstream-serde-browser": "^2.0.10", - "@smithy/eventstream-serde-config-resolver": "^2.0.10", - "@smithy/eventstream-serde-node": "^2.0.10", - "@smithy/fetch-http-handler": "^2.2.1", - "@smithy/hash-blob-browser": "^2.0.10", - "@smithy/hash-node": "^2.0.10", - "@smithy/hash-stream-node": "^2.0.10", - "@smithy/invalid-dependency": "^2.0.10", - "@smithy/md5-js": "^2.0.10", - "@smithy/middleware-content-length": "^2.0.12", - "@smithy/middleware-endpoint": "^2.0.10", - "@smithy/middleware-retry": "^2.0.13", - "@smithy/middleware-serde": "^2.0.10", - "@smithy/middleware-stack": "^2.0.4", - "@smithy/node-config-provider": "^2.0.13", - "@smithy/node-http-handler": "^2.1.6", - "@smithy/protocol-http": "^3.0.6", - "@smithy/smithy-client": "^2.1.9", - "@smithy/types": "^2.3.4", - "@smithy/url-parser": "^2.0.10", + "@smithy/config-resolver": "^2.0.16", + "@smithy/eventstream-serde-browser": "^2.0.12", + "@smithy/eventstream-serde-config-resolver": "^2.0.12", + "@smithy/eventstream-serde-node": "^2.0.12", + "@smithy/fetch-http-handler": "^2.2.4", + "@smithy/hash-blob-browser": "^2.0.12", + "@smithy/hash-node": "^2.0.12", + "@smithy/hash-stream-node": "^2.0.12", + "@smithy/invalid-dependency": "^2.0.12", + "@smithy/md5-js": "^2.0.12", + "@smithy/middleware-content-length": "^2.0.14", + "@smithy/middleware-endpoint": "^2.1.3", + "@smithy/middleware-retry": "^2.0.18", + "@smithy/middleware-serde": "^2.0.12", + "@smithy/middleware-stack": "^2.0.6", + "@smithy/node-config-provider": "^2.1.3", + "@smithy/node-http-handler": "^2.1.8", + "@smithy/protocol-http": "^3.0.8", + "@smithy/smithy-client": "^2.1.12", + "@smithy/types": "^2.4.0", + "@smithy/url-parser": "^2.0.12", "@smithy/util-base64": "^2.0.0", "@smithy/util-body-length-browser": "^2.0.0", "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.13", - "@smithy/util-defaults-mode-node": "^2.0.15", - "@smithy/util-retry": "^2.0.3", - "@smithy/util-stream": "^2.0.14", + "@smithy/util-defaults-mode-browser": "^2.0.16", + "@smithy/util-defaults-mode-node": "^2.0.21", + "@smithy/util-retry": "^2.0.5", + "@smithy/util-stream": "^2.0.17", "@smithy/util-utf8": "^2.0.0", - "@smithy/util-waiter": "^2.0.10", + "@smithy/util-waiter": "^2.0.12", "fast-xml-parser": "4.2.5", "tslib": "^2.5.0" }, @@ -279,42 +279,42 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.427.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.427.0.tgz", - "integrity": "sha512-sFVFEmsQ1rmgYO1SgrOTxE/MTKpeE4hpOkm1WqhLQK7Ij136vXpjCxjH1JYZiHiUzO1wr9t4ex4dlB5J3VS/Xg==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.433.0.tgz", + "integrity": "sha512-L7ksMP7UnYH+w52ly+m+s5vk8662VtyqJ+UduFEMPqKUHTFEm7w+CCw4Xfk3hl5GlVvqPvYWqBqv8eLKSHpCEQ==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/middleware-host-header": "3.425.0", - "@aws-sdk/middleware-logger": "3.425.0", - "@aws-sdk/middleware-recursion-detection": "3.425.0", - "@aws-sdk/middleware-user-agent": "3.427.0", - "@aws-sdk/region-config-resolver": "3.425.0", - "@aws-sdk/types": "3.425.0", - "@aws-sdk/util-endpoints": "3.427.0", - "@aws-sdk/util-user-agent-browser": "3.425.0", - "@aws-sdk/util-user-agent-node": "3.425.0", - "@smithy/config-resolver": "^2.0.11", - "@smithy/fetch-http-handler": "^2.2.1", - "@smithy/hash-node": "^2.0.10", - "@smithy/invalid-dependency": "^2.0.10", - "@smithy/middleware-content-length": "^2.0.12", - "@smithy/middleware-endpoint": "^2.0.10", - "@smithy/middleware-retry": "^2.0.13", - "@smithy/middleware-serde": "^2.0.10", - "@smithy/middleware-stack": "^2.0.4", - "@smithy/node-config-provider": "^2.0.13", - "@smithy/node-http-handler": "^2.1.6", - "@smithy/protocol-http": "^3.0.6", - "@smithy/smithy-client": "^2.1.9", - "@smithy/types": "^2.3.4", - "@smithy/url-parser": "^2.0.10", + "@aws-sdk/middleware-host-header": "3.433.0", + "@aws-sdk/middleware-logger": "3.433.0", + "@aws-sdk/middleware-recursion-detection": "3.433.0", + "@aws-sdk/middleware-user-agent": "3.433.0", + "@aws-sdk/region-config-resolver": "3.433.0", + "@aws-sdk/types": "3.433.0", + "@aws-sdk/util-endpoints": "3.433.0", + "@aws-sdk/util-user-agent-browser": "3.433.0", + "@aws-sdk/util-user-agent-node": "3.433.0", + "@smithy/config-resolver": "^2.0.16", + "@smithy/fetch-http-handler": "^2.2.4", + "@smithy/hash-node": "^2.0.12", + "@smithy/invalid-dependency": "^2.0.12", + "@smithy/middleware-content-length": "^2.0.14", + "@smithy/middleware-endpoint": "^2.1.3", + "@smithy/middleware-retry": "^2.0.18", + "@smithy/middleware-serde": "^2.0.12", + "@smithy/middleware-stack": "^2.0.6", + "@smithy/node-config-provider": "^2.1.3", + "@smithy/node-http-handler": "^2.1.8", + "@smithy/protocol-http": "^3.0.8", + "@smithy/smithy-client": "^2.1.12", + "@smithy/types": "^2.4.0", + "@smithy/url-parser": "^2.0.12", "@smithy/util-base64": "^2.0.0", "@smithy/util-body-length-browser": "^2.0.0", "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.13", - "@smithy/util-defaults-mode-node": "^2.0.15", - "@smithy/util-retry": "^2.0.3", + "@smithy/util-defaults-mode-browser": "^2.0.16", + "@smithy/util-defaults-mode-node": "^2.0.21", + "@smithy/util-retry": "^2.0.5", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" }, @@ -323,45 +323,45 @@ } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.427.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.427.0.tgz", - "integrity": "sha512-le2wLJKILyWuRfPz2HbyaNtu5kEki+ojUkTqCU6FPDRrqUvEkaaCBH9Awo/2AtrCfRkiobop8RuTTj6cAnpiJg==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.433.0.tgz", + "integrity": "sha512-hQ+NLIcA1KRJ2qPdrtkJ3fOEVnehLLMlnB/I5mjg9K2UKjuiOufLao6tc5SyW9fseIL9AdX3fjJ8Unhg+y1RWg==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/credential-provider-node": "3.427.0", - "@aws-sdk/middleware-host-header": "3.425.0", - "@aws-sdk/middleware-logger": "3.425.0", - "@aws-sdk/middleware-recursion-detection": "3.425.0", - "@aws-sdk/middleware-sdk-sts": "3.425.0", - "@aws-sdk/middleware-signing": "3.425.0", - "@aws-sdk/middleware-user-agent": "3.427.0", - "@aws-sdk/region-config-resolver": "3.425.0", - "@aws-sdk/types": "3.425.0", - "@aws-sdk/util-endpoints": "3.427.0", - "@aws-sdk/util-user-agent-browser": "3.425.0", - "@aws-sdk/util-user-agent-node": "3.425.0", - "@smithy/config-resolver": "^2.0.11", - "@smithy/fetch-http-handler": "^2.2.1", - "@smithy/hash-node": "^2.0.10", - "@smithy/invalid-dependency": "^2.0.10", - "@smithy/middleware-content-length": "^2.0.12", - "@smithy/middleware-endpoint": "^2.0.10", - "@smithy/middleware-retry": "^2.0.13", - "@smithy/middleware-serde": "^2.0.10", - "@smithy/middleware-stack": "^2.0.4", - "@smithy/node-config-provider": "^2.0.13", - "@smithy/node-http-handler": "^2.1.6", - "@smithy/protocol-http": "^3.0.6", - "@smithy/smithy-client": "^2.1.9", - "@smithy/types": "^2.3.4", - "@smithy/url-parser": "^2.0.10", + "@aws-sdk/credential-provider-node": "3.433.0", + "@aws-sdk/middleware-host-header": "3.433.0", + "@aws-sdk/middleware-logger": "3.433.0", + "@aws-sdk/middleware-recursion-detection": "3.433.0", + "@aws-sdk/middleware-sdk-sts": "3.433.0", + "@aws-sdk/middleware-signing": "3.433.0", + "@aws-sdk/middleware-user-agent": "3.433.0", + "@aws-sdk/region-config-resolver": "3.433.0", + "@aws-sdk/types": "3.433.0", + "@aws-sdk/util-endpoints": "3.433.0", + "@aws-sdk/util-user-agent-browser": "3.433.0", + "@aws-sdk/util-user-agent-node": "3.433.0", + "@smithy/config-resolver": "^2.0.16", + "@smithy/fetch-http-handler": "^2.2.4", + "@smithy/hash-node": "^2.0.12", + "@smithy/invalid-dependency": "^2.0.12", + "@smithy/middleware-content-length": "^2.0.14", + "@smithy/middleware-endpoint": "^2.1.3", + "@smithy/middleware-retry": "^2.0.18", + "@smithy/middleware-serde": "^2.0.12", + "@smithy/middleware-stack": "^2.0.6", + "@smithy/node-config-provider": "^2.1.3", + "@smithy/node-http-handler": "^2.1.8", + "@smithy/protocol-http": "^3.0.8", + "@smithy/smithy-client": "^2.1.12", + "@smithy/types": "^2.4.0", + "@smithy/url-parser": "^2.0.12", "@smithy/util-base64": "^2.0.0", "@smithy/util-body-length-browser": "^2.0.0", "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.13", - "@smithy/util-defaults-mode-node": "^2.0.15", - "@smithy/util-retry": "^2.0.3", + "@smithy/util-defaults-mode-browser": "^2.0.16", + "@smithy/util-defaults-mode-node": "^2.0.21", + "@smithy/util-retry": "^2.0.5", "@smithy/util-utf8": "^2.0.0", "fast-xml-parser": "4.2.5", "tslib": "^2.5.0" @@ -371,13 +371,13 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.425.0.tgz", - "integrity": "sha512-J20etnLvMKXRVi5FK4F8yOCNm2RTaQn5psQTGdDEPWJNGxohcSpzzls8U2KcMyUJ+vItlrThr4qwgpHG3i/N0w==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.433.0.tgz", + "integrity": "sha512-Vl7Qz5qYyxBurMn6hfSiNJeUHSqfVUlMt0C1Bds3tCkl3IzecRWwyBOlxtxO3VCrgVeW3HqswLzCvhAFzPH6nQ==", "dependencies": { - "@aws-sdk/types": "3.425.0", + "@aws-sdk/types": "3.433.0", "@smithy/property-provider": "^2.0.0", - "@smithy/types": "^2.3.4", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -385,19 +385,19 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.427.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.427.0.tgz", - "integrity": "sha512-NmH1cO/w98CKMltYec3IrJIIco19wRjATFNiw83c+FGXZ+InJwReqBnruxIOmKTx2KDzd6fwU1HOewS7UjaaaQ==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.425.0", - "@aws-sdk/credential-provider-process": "3.425.0", - "@aws-sdk/credential-provider-sso": "3.427.0", - "@aws-sdk/credential-provider-web-identity": "3.425.0", - "@aws-sdk/types": "3.425.0", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.433.0.tgz", + "integrity": "sha512-T+YhCOORyA4+i4T86FfFCmi/jPsmLOP6GAtScHp/K8XzB9XuVvJSZ+T8SUKeW6/9G9z3Az7dqeBVLcMdC6fFDA==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.433.0", + "@aws-sdk/credential-provider-process": "3.433.0", + "@aws-sdk/credential-provider-sso": "3.433.0", + "@aws-sdk/credential-provider-web-identity": "3.433.0", + "@aws-sdk/types": "3.433.0", "@smithy/credential-provider-imds": "^2.0.0", "@smithy/property-provider": "^2.0.0", "@smithy/shared-ini-file-loader": "^2.0.6", - "@smithy/types": "^2.3.4", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -405,20 +405,20 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.427.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.427.0.tgz", - "integrity": "sha512-wYYbQ57nKL8OfgRbl8k6uXcdnYml+p3LSSfDUAuUEp1HKlQ8lOXFJ3BdLr5qrk7LhpyppSRnWBmh2c3kWa7ANQ==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.425.0", - "@aws-sdk/credential-provider-ini": "3.427.0", - "@aws-sdk/credential-provider-process": "3.425.0", - "@aws-sdk/credential-provider-sso": "3.427.0", - "@aws-sdk/credential-provider-web-identity": "3.425.0", - "@aws-sdk/types": "3.425.0", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.433.0.tgz", + "integrity": "sha512-uOTBJszqGJIX5SrH2YdN501cv9rW4ghuSkasxI9DL+sVV5YRMd/bwu6I3PphRyK7z4dosDEbJ1xoIuVR/W04HQ==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.433.0", + "@aws-sdk/credential-provider-ini": "3.433.0", + "@aws-sdk/credential-provider-process": "3.433.0", + "@aws-sdk/credential-provider-sso": "3.433.0", + "@aws-sdk/credential-provider-web-identity": "3.433.0", + "@aws-sdk/types": "3.433.0", "@smithy/credential-provider-imds": "^2.0.0", "@smithy/property-provider": "^2.0.0", "@smithy/shared-ini-file-loader": "^2.0.6", - "@smithy/types": "^2.3.4", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -426,14 +426,14 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.425.0.tgz", - "integrity": "sha512-YY6tkLdvtb1Fgofp3b1UWO+5vwS14LJ/smGmuGpSba0V7gFJRdcrJ9bcb9vVgAGuMdjzRJ+bUKlLLtqXkaykEw==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.433.0.tgz", + "integrity": "sha512-W7FcGlQjio9Y/PepcZGRyl5Bpwb0uWU7qIUCh+u4+q2mW4D5ZngXg8V/opL9/I/p4tUH9VXZLyLGwyBSkdhL+A==", "dependencies": { - "@aws-sdk/types": "3.425.0", + "@aws-sdk/types": "3.433.0", "@smithy/property-provider": "^2.0.0", "@smithy/shared-ini-file-loader": "^2.0.6", - "@smithy/types": "^2.3.4", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -441,16 +441,16 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.427.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.427.0.tgz", - "integrity": "sha512-c+tXyS/i49erHs4bAp6vKNYeYlyQ0VNMBgoco0LCn1rL0REtHbfhWMnqDLF6c2n3yIWDOTrQu0D73Idnpy16eA==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.433.0.tgz", + "integrity": "sha512-vuc2X7q/1HUAO/NowfnNMpRDoHw8H2lyZZzUc0lmamy6PDrEFBi/VTm1nStGPuS9egCFrYlkRHsfp50ukYGa5w==", "dependencies": { - "@aws-sdk/client-sso": "3.427.0", - "@aws-sdk/token-providers": "3.427.0", - "@aws-sdk/types": "3.425.0", + "@aws-sdk/client-sso": "3.433.0", + "@aws-sdk/token-providers": "3.433.0", + "@aws-sdk/types": "3.433.0", "@smithy/property-provider": "^2.0.0", "@smithy/shared-ini-file-loader": "^2.0.6", - "@smithy/types": "^2.3.4", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -458,13 +458,13 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.425.0.tgz", - "integrity": "sha512-/0R65TgRzL01JU3SzloivWNwdkbIhr06uY/F5pBHf/DynQqaspKNfdHn6AiozgSVDfwRHFjKBTUy6wvf3QFkuA==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.433.0.tgz", + "integrity": "sha512-RlwjP1I5wO+aPpwyCp23Mk8nmRbRL33hqRASy73c4JA2z2YiRua+ryt6MalIxehhwQU6xvXUKulJnPG9VaMFZg==", "dependencies": { - "@aws-sdk/types": "3.425.0", + "@aws-sdk/types": "3.433.0", "@smithy/property-provider": "^2.0.0", - "@smithy/types": "^2.3.4", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -472,15 +472,15 @@ } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.425.0.tgz", - "integrity": "sha512-7UTfA10fmDw9cgHLApxRUNPywZTG4S/1TNZgTxndO/1OM9ZHtIatw1iLbqJD35gHrpEYI8Vo14YvcnD2ITuiMw==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.433.0.tgz", + "integrity": "sha512-Lk1xIu2tWTRa1zDw5hCF1RrpWQYSodUhrS/q3oKz8IAoFqEy+lNaD5jx+fycuZb5EkE4IzWysT+8wVkd0mAnOg==", "dependencies": { - "@aws-sdk/types": "3.425.0", + "@aws-sdk/types": "3.433.0", "@aws-sdk/util-arn-parser": "3.310.0", - "@smithy/node-config-provider": "^2.0.13", - "@smithy/protocol-http": "^3.0.6", - "@smithy/types": "^2.3.4", + "@smithy/node-config-provider": "^2.1.3", + "@smithy/protocol-http": "^3.0.8", + "@smithy/types": "^2.4.0", "@smithy/util-config-provider": "^2.0.0", "tslib": "^2.5.0" }, @@ -489,13 +489,13 @@ } }, "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.425.0.tgz", - "integrity": "sha512-CqAmnDST2o7+sKKw2/ffHKiYKE+jZb/Ce9U0P//ZYzqp9R1Wb016ID+W6DoxufyPJAS9dpRMcUDnAssmMIC/EA==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.433.0.tgz", + "integrity": "sha512-Uq2rPIsjz0CR2sulM/HyYr5WiqiefrSRLdwUZuA7opxFSfE808w5DBWSprHxbH3rbDSQR4nFiOiVYIH8Eth7nA==", "dependencies": { - "@aws-sdk/types": "3.425.0", - "@smithy/protocol-http": "^3.0.6", - "@smithy/types": "^2.3.4", + "@aws-sdk/types": "3.433.0", + "@smithy/protocol-http": "^3.0.8", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -503,16 +503,16 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.425.0.tgz", - "integrity": "sha512-BDwn2vVVsC/AzmHXQlaZhEpKXL7GfKFpH7ZFccZuwEQBcyn8lVCcwtfaRe5P1mEe2wklVzOXd1dw8bt0+BOUPA==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.433.0.tgz", + "integrity": "sha512-Ptssx373+I7EzFUWjp/i/YiNFt6I6sDuRHz6DOUR9nmmRTlHHqmdcBXlJL2d9wwFxoBRCN8/PXGsTc/DJ4c95Q==", "dependencies": { "@aws-crypto/crc32": "3.0.0", "@aws-crypto/crc32c": "3.0.0", - "@aws-sdk/types": "3.425.0", + "@aws-sdk/types": "3.433.0", "@smithy/is-array-buffer": "^2.0.0", - "@smithy/protocol-http": "^3.0.6", - "@smithy/types": "^2.3.4", + "@smithy/protocol-http": "^3.0.8", + "@smithy/types": "^2.4.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" }, @@ -521,13 +521,13 @@ } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.425.0.tgz", - "integrity": "sha512-E5Gt41LObQ+cr8QnLthwsH3MtVSNXy1AKJMowDr85h0vzqA/FHUkgHyOGntgozzjXT5M0MaSRYxS0xwTR5D4Ew==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.433.0.tgz", + "integrity": "sha512-mBTq3UWv1UzeHG+OfUQ2MB/5GEkt5LTKFaUqzL7ESwzW8XtpBgXnjZvIwu3Vcd3sEetMwijwaGiJhY0ae/YyaA==", "dependencies": { - "@aws-sdk/types": "3.425.0", - "@smithy/protocol-http": "^3.0.6", - "@smithy/types": "^2.3.4", + "@aws-sdk/types": "3.433.0", + "@smithy/protocol-http": "^3.0.8", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -535,12 +535,12 @@ } }, "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.425.0.tgz", - "integrity": "sha512-3rt0LpGmL1LCRFuEObS1yERd9OEV+AEIAvhY7b53M7u7SyrjWQtpntWkI365L/QljhgMXQBfps2qO4JtrhQnsA==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.433.0.tgz", + "integrity": "sha512-2YD860TGntwZifIUbxm+lFnNJJhByR/RB/+fV1I8oGKg+XX2rZU+94pRfHXRywoZKlCA0L+LGDA1I56jxrB9sw==", "dependencies": { - "@aws-sdk/types": "3.425.0", - "@smithy/types": "^2.3.4", + "@aws-sdk/types": "3.433.0", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -548,12 +548,12 @@ } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.425.0.tgz", - "integrity": "sha512-INE9XWRXx2f4a/r2vOU0tAmgctVp7nEaEasemNtVBYhqbKLZvr9ndLBSgKGgJ8LIcXAoISipaMuFiqIGkFsm7A==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.433.0.tgz", + "integrity": "sha512-We346Fb5xGonTGVZC9Nvqtnqy74VJzYuTLLiuuftA5sbNzftBDy/22QCfvYSTOAl3bvif+dkDUzQY2ihc5PwOQ==", "dependencies": { - "@aws-sdk/types": "3.425.0", - "@smithy/types": "^2.3.4", + "@aws-sdk/types": "3.433.0", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -561,13 +561,13 @@ } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.425.0.tgz", - "integrity": "sha512-77gnzJ5b91bgD75L/ugpOyerx6lR3oyS4080X1YI58EzdyBMkDrHM4FbMcY2RynETi3lwXCFzLRyZjWXY1mRlw==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.433.0.tgz", + "integrity": "sha512-HEvYC9PQlWY/ccUYtLvAlwwf1iCif2TSAmLNr3YTBRVa98x6jKL0hlCrHWYklFeqOGSKy6XhE+NGJMUII0/HaQ==", "dependencies": { - "@aws-sdk/types": "3.425.0", - "@smithy/protocol-http": "^3.0.6", - "@smithy/types": "^2.3.4", + "@aws-sdk/types": "3.433.0", + "@smithy/protocol-http": "^3.0.8", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -575,15 +575,15 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.427.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.427.0.tgz", - "integrity": "sha512-virGCf9vsqYCLpmngLOZOVSYgVr2cCOCvTuRoT9vf5tD/63JwaC173jnbdoJO6CWI7ID5Iz0eNdgITXVQ2mpew==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.433.0.tgz", + "integrity": "sha512-mkn3DiSuMVh4NTLsduC42Av+ApcOor52LMoQY0Wc6M5Mx7Xd05U+G1j8sjI9n/1bs5cZ/PoeRYJ/9bL1Xxznnw==", "dependencies": { - "@aws-sdk/types": "3.425.0", + "@aws-sdk/types": "3.433.0", "@aws-sdk/util-arn-parser": "3.310.0", - "@smithy/protocol-http": "^3.0.6", - "@smithy/smithy-client": "^2.1.9", - "@smithy/types": "^2.3.4", + "@smithy/protocol-http": "^3.0.8", + "@smithy/smithy-client": "^2.1.12", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -591,13 +591,13 @@ } }, "node_modules/@aws-sdk/middleware-sdk-sts": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.425.0.tgz", - "integrity": "sha512-JFojrg76oKAoBknnr9EL5N2aJ1mRCtBqXoZYST58GSx8uYdFQ89qS65VNQ8JviBXzsrCNAn4vDhZ5Ch5E6TxGQ==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.433.0.tgz", + "integrity": "sha512-ORYbJnBejUyonFl5FwIqhvI3Cq6sAp9j+JpkKZtFNma9tFPdrhmYgfCeNH32H/wGTQV/tUoQ3luh0gA4cuk6DA==", "dependencies": { - "@aws-sdk/middleware-signing": "3.425.0", - "@aws-sdk/types": "3.425.0", - "@smithy/types": "^2.3.4", + "@aws-sdk/middleware-signing": "3.433.0", + "@aws-sdk/types": "3.433.0", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -605,16 +605,16 @@ } }, "node_modules/@aws-sdk/middleware-signing": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.425.0.tgz", - "integrity": "sha512-ZpOfgJHk7ovQ0sSwg3tU4NxFOnz53lJlkJRf7S+wxQALHM0P2MJ6LYBrZaFMVsKiJxNIdZBXD6jclgHg72ZW6Q==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.433.0.tgz", + "integrity": "sha512-jxPvt59NZo/epMNLNTu47ikmP8v0q217I6bQFGJG7JVFnfl36zDktMwGw+0xZR80qiK47/2BWrNpta61Zd2FxQ==", "dependencies": { - "@aws-sdk/types": "3.425.0", + "@aws-sdk/types": "3.433.0", "@smithy/property-provider": "^2.0.0", - "@smithy/protocol-http": "^3.0.6", + "@smithy/protocol-http": "^3.0.8", "@smithy/signature-v4": "^2.0.0", - "@smithy/types": "^2.3.4", - "@smithy/util-middleware": "^2.0.3", + "@smithy/types": "^2.4.0", + "@smithy/util-middleware": "^2.0.5", "tslib": "^2.5.0" }, "engines": { @@ -622,12 +622,12 @@ } }, "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.425.0.tgz", - "integrity": "sha512-9HTuXnHYAZWkwPC8x9tElsQjFPxDT//orbIFauS7VF5HkLCKn9J6O6lW1wKMxrEnDwfN/Vi3nw479MoPj5Ss0Q==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.433.0.tgz", + "integrity": "sha512-2AMaPx0kYfCiekxoL7aqFqSSoA9du+yI4zefpQNLr+1cZOerYiDxdsZ4mbqStR1CVFaX6U6hrYokXzjInsvETw==", "dependencies": { - "@aws-sdk/types": "3.425.0", - "@smithy/types": "^2.3.4", + "@aws-sdk/types": "3.433.0", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -635,14 +635,14 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.427.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.427.0.tgz", - "integrity": "sha512-y9HxYsNvnA3KqDl8w1jHeCwz4P9CuBEtu/G+KYffLeAMBsMZmh4SIkFFCO9wE/dyYg6+yo07rYcnnIfy7WA0bw==", - "dependencies": { - "@aws-sdk/types": "3.425.0", - "@aws-sdk/util-endpoints": "3.427.0", - "@smithy/protocol-http": "^3.0.6", - "@smithy/types": "^2.3.4", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.433.0.tgz", + "integrity": "sha512-jMgA1jHfisBK4oSjMKrtKEZf0sl2vzADivkFmyZFzORpSZxBnF6hC21RjaI+70LJLcc9rSCzLgcoz5lHb9LLDg==", + "dependencies": { + "@aws-sdk/types": "3.433.0", + "@aws-sdk/util-endpoints": "3.433.0", + "@smithy/protocol-http": "^3.0.8", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -650,14 +650,14 @@ } }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.425.0.tgz", - "integrity": "sha512-u7uv/iUOapIJdRgRkO3wnpYsUgV6ponsZJQgVg/8L+n+Vo5PQL5gAcIuAOwcYSKQPFaeK+KbmByI4SyOK203Vw==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.433.0.tgz", + "integrity": "sha512-xpjRjCZW+CDFdcMmmhIYg81ST5UAnJh61IHziQEk0FXONrg4kjyYPZAOjEdzXQ+HxJQuGQLKPhRdzxmQnbX7pg==", "dependencies": { - "@smithy/node-config-provider": "^2.0.13", - "@smithy/types": "^2.3.4", + "@smithy/node-config-provider": "^2.1.3", + "@smithy/types": "^2.4.0", "@smithy/util-config-provider": "^2.0.0", - "@smithy/util-middleware": "^2.0.3", + "@smithy/util-middleware": "^2.0.5", "tslib": "^2.5.0" }, "engines": { @@ -665,14 +665,14 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.425.0.tgz", - "integrity": "sha512-7n2FRPE9rLaVa26xXQJ8TExrt53dWN824axQd1a0r5va0SmMQYG/iV5LBmwUlAntUSq46Lse4Q5YnbOVedGOmw==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.433.0.tgz", + "integrity": "sha512-wl2j1dos4VOKFawbapPm/0CNa3cIgpJXbEx+sp+DI3G8tSuP3c5UGtm0pXjM85egxZulhHVK1RVde0iD8j63pQ==", "dependencies": { - "@aws-sdk/types": "3.425.0", - "@smithy/protocol-http": "^3.0.6", + "@aws-sdk/types": "3.433.0", + "@smithy/protocol-http": "^3.0.8", "@smithy/signature-v4": "^2.0.0", - "@smithy/types": "^2.3.4", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -680,43 +680,43 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.427.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.427.0.tgz", - "integrity": "sha512-4E5E+4p8lJ69PBY400dJXF06LUHYx5lkKzBEsYqWWhoZcoftrvi24ltIhUDoGVLkrLcTHZIWSdFAWSos4hXqeg==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.433.0.tgz", + "integrity": "sha512-Q6aYVaQKB+CkBLHQQlN8MHVpOzZv9snRfVz7SxIpdbHkRuGEHiLliCY3fg6Sonvu3AKEPERPuHcaC75tnNpOBw==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/middleware-host-header": "3.425.0", - "@aws-sdk/middleware-logger": "3.425.0", - "@aws-sdk/middleware-recursion-detection": "3.425.0", - "@aws-sdk/middleware-user-agent": "3.427.0", - "@aws-sdk/types": "3.425.0", - "@aws-sdk/util-endpoints": "3.427.0", - "@aws-sdk/util-user-agent-browser": "3.425.0", - "@aws-sdk/util-user-agent-node": "3.425.0", - "@smithy/config-resolver": "^2.0.11", - "@smithy/fetch-http-handler": "^2.2.1", - "@smithy/hash-node": "^2.0.10", - "@smithy/invalid-dependency": "^2.0.10", - "@smithy/middleware-content-length": "^2.0.12", - "@smithy/middleware-endpoint": "^2.0.10", - "@smithy/middleware-retry": "^2.0.13", - "@smithy/middleware-serde": "^2.0.10", - "@smithy/middleware-stack": "^2.0.4", - "@smithy/node-config-provider": "^2.0.13", - "@smithy/node-http-handler": "^2.1.6", + "@aws-sdk/middleware-host-header": "3.433.0", + "@aws-sdk/middleware-logger": "3.433.0", + "@aws-sdk/middleware-recursion-detection": "3.433.0", + "@aws-sdk/middleware-user-agent": "3.433.0", + "@aws-sdk/types": "3.433.0", + "@aws-sdk/util-endpoints": "3.433.0", + "@aws-sdk/util-user-agent-browser": "3.433.0", + "@aws-sdk/util-user-agent-node": "3.433.0", + "@smithy/config-resolver": "^2.0.16", + "@smithy/fetch-http-handler": "^2.2.4", + "@smithy/hash-node": "^2.0.12", + "@smithy/invalid-dependency": "^2.0.12", + "@smithy/middleware-content-length": "^2.0.14", + "@smithy/middleware-endpoint": "^2.1.3", + "@smithy/middleware-retry": "^2.0.18", + "@smithy/middleware-serde": "^2.0.12", + "@smithy/middleware-stack": "^2.0.6", + "@smithy/node-config-provider": "^2.1.3", + "@smithy/node-http-handler": "^2.1.8", "@smithy/property-provider": "^2.0.0", - "@smithy/protocol-http": "^3.0.6", + "@smithy/protocol-http": "^3.0.8", "@smithy/shared-ini-file-loader": "^2.0.6", - "@smithy/smithy-client": "^2.1.9", - "@smithy/types": "^2.3.4", - "@smithy/url-parser": "^2.0.10", + "@smithy/smithy-client": "^2.1.12", + "@smithy/types": "^2.4.0", + "@smithy/url-parser": "^2.0.12", "@smithy/util-base64": "^2.0.0", "@smithy/util-body-length-browser": "^2.0.0", "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.13", - "@smithy/util-defaults-mode-node": "^2.0.15", - "@smithy/util-retry": "^2.0.3", + "@smithy/util-defaults-mode-browser": "^2.0.16", + "@smithy/util-defaults-mode-node": "^2.0.21", + "@smithy/util-retry": "^2.0.5", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" }, @@ -725,11 +725,11 @@ } }, "node_modules/@aws-sdk/types": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.425.0.tgz", - "integrity": "sha512-6lqbmorwerN4v+J5dqbHPAsjynI0mkEF+blf+69QTaKKGaxBBVaXgqoqul9RXYcK5MMrrYRbQIMd0zYOoy90kA==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.433.0.tgz", + "integrity": "sha512-0jEE2mSrNDd8VGFjTc1otYrwYPIkzZJEIK90ZxisKvQ/EURGBhNzWn7ejWB9XCMFT6XumYLBR0V9qq5UPisWtA==", "dependencies": { - "@smithy/types": "^2.3.4", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -748,12 +748,11 @@ } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.427.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.427.0.tgz", - "integrity": "sha512-rSyiAIFF/EVvity/+LWUqoTMJ0a25RAc9iqx0WZ4tf1UjuEXRRXxZEb+jEZg1bk+pY84gdLdx9z5E+MSJCZxNQ==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.433.0.tgz", + "integrity": "sha512-LFNUh9FH7RMtYjSjPGz9lAJQMzmJ3RcXISzc5X5k2R/9mNwMK7y1k2VAfvx+RbuDbll6xwsXlgv6QHcxVdF2zw==", "dependencies": { - "@aws-sdk/types": "3.425.0", - "@smithy/node-config-provider": "^2.0.13", + "@aws-sdk/types": "3.433.0", "tslib": "^2.5.0" }, "engines": { @@ -772,24 +771,24 @@ } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.425.0.tgz", - "integrity": "sha512-22Y9iMtjGcFjGILR6/xdp1qRezlHVLyXtnpEsbuPTiernRCPk6zfAnK/ATH77r02MUjU057tdxVkd5umUBTn9Q==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.433.0.tgz", + "integrity": "sha512-2Cf/Lwvxbt5RXvWFXrFr49vXv0IddiUwrZoAiwhDYxvsh+BMnh+NUFot+ZQaTrk/8IPZVDeLPWZRdVy00iaVXQ==", "dependencies": { - "@aws-sdk/types": "3.425.0", - "@smithy/types": "^2.3.4", + "@aws-sdk/types": "3.433.0", + "@smithy/types": "^2.4.0", "bowser": "^2.11.0", "tslib": "^2.5.0" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.425.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.425.0.tgz", - "integrity": "sha512-SIR4F5uQeeVAi8lv4OgRirtdtNi5zeyogTuQgGi9su8F/WP1N6JqxofcwpUY5f8/oJ2UlXr/tx1f09UHfJJzvA==", + "version": "3.433.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.433.0.tgz", + "integrity": "sha512-yT1tO4MbbsUBLl5+S+jVv8wxiAtP5TKjKib9B2KQ2x0OtWWTrIf2o+IZK8va+zQqdV4MVMjezdxdE20hOdB4yQ==", "dependencies": { - "@aws-sdk/types": "3.425.0", - "@smithy/node-config-provider": "^2.0.13", - "@smithy/types": "^2.3.4", + "@aws-sdk/types": "3.433.0", + "@smithy/node-config-provider": "^2.1.3", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -1555,22 +1554,14 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@lit-labs/react": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@lit-labs/react/-/react-2.1.1.tgz", - "integrity": "sha512-wr15ZOCZ7t2yB8UEfQ6oSRCmfxpIjhzDkN8DlgSOwsbJzWQTk8hxHRLy7Rra6mxrIajqvrMWQB2VskUU2uuoRA==", - "dependencies": { - "@lit/react": "1.0.0" - } - }, "node_modules/@lit-labs/ssr-dom-shim": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.2.tgz", @@ -1585,11 +1576,11 @@ } }, "node_modules/@lit/reactive-element": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz", - "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.0.tgz", + "integrity": "sha512-wn+2+uDcs62ROBmVAwssO4x5xue/uKD3MGGZOXL2sMxReTRIT0JXKyMXeu7gh0aJ4IJNEIG/3aOnUaQvM7BMzQ==", "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.0.0" + "@lit-labs/ssr-dom-shim": "^1.1.2-pre.0" } }, "node_modules/@mapbox/node-pre-gyp": { @@ -1688,17 +1679,17 @@ "integrity": "sha512-Hf45HeO+vdQblabpyZOTxJ4ZeZsmIUYXXPmoYrrR4OJ5OKxL+bhMz5mK8JXgl7HsoEowfz7+e248UGi861de9Q==" }, "node_modules/@shoelace-style/shoelace": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/@shoelace-style/shoelace/-/shoelace-2.9.0.tgz", - "integrity": "sha512-nxvDDYlTuACLLBuuR8TmTKiU0mrhzzwnbXbA4lpvaF+Ee5bS/VgKzr0nWrMXT3scpUEu/LPtqfoZcqWqaU/7DQ==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@shoelace-style/shoelace/-/shoelace-2.11.0.tgz", + "integrity": "sha512-qSwiQTF8TRahlWBWYMOiZJAqYkG3g5Hil1COfqwQKfvGXEUmflPbRiXRDBG0F6clLYN6yYn7sqZ7kv11kw2Y/Q==", "dependencies": { - "@ctrl/tinycolor": "^4.0.1", - "@floating-ui/dom": "^1.2.1", - "@lit-labs/react": "^2.0.3", + "@ctrl/tinycolor": "^4.0.2", + "@floating-ui/dom": "^1.5.3", + "@lit/react": "^1.0.0", "@shoelace-style/animations": "^1.1.0", - "@shoelace-style/localize": "^3.1.1", + "@shoelace-style/localize": "^3.1.2", "composed-offset-position": "^0.0.4", - "lit": "^2.7.5", + "lit": "^3.0.0", "qr-creator": "^1.0.0" }, "engines": { @@ -1710,11 +1701,11 @@ } }, "node_modules/@smithy/abort-controller": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.11.tgz", - "integrity": "sha512-MSzE1qR2JNyb7ot3blIOT3O3H0Jn06iNDEgHRaqZUwBgx5EG+VIx24Y21tlKofzYryIOcWpIohLrIIyocD6LMA==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.12.tgz", + "integrity": "sha512-YIJyefe1mi3GxKdZxEBEuzYOeQ9xpYfqnFmWzojCssRAuR7ycxwpoRQgp965vuW426xUAQhCV5rCaWElQ7XsaA==", "dependencies": { - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -1739,14 +1730,14 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.0.14.tgz", - "integrity": "sha512-K1K+FuWQoy8j/G7lAmK85o03O89s2Vvh6kMFmzEmiHUoQCRH1rzbDtMnGNiaMHeSeYJ6y79IyTusdRG+LuWwtg==", + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.0.16.tgz", + "integrity": "sha512-1k+FWHQDt2pfpXhJsOmNMmlAZ3NUQ98X5tYsjQhVGq+0X6cOBMhfh6Igd0IX3Ut6lEO6DQAdPMI/blNr3JZfMQ==", "dependencies": { - "@smithy/node-config-provider": "^2.1.1", - "@smithy/types": "^2.3.5", + "@smithy/node-config-provider": "^2.1.3", + "@smithy/types": "^2.4.0", "@smithy/util-config-provider": "^2.0.0", - "@smithy/util-middleware": "^2.0.4", + "@smithy/util-middleware": "^2.0.5", "tslib": "^2.5.0" }, "engines": { @@ -1754,14 +1745,14 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.0.16.tgz", - "integrity": "sha512-tKa2xF+69TvGxJT+lnJpGrKxUuAZDLYXFhqnPEgnHz+psTpkpcB4QRjHj63+uj83KaeFJdTfW201eLZeRn6FfA==", - "dependencies": { - "@smithy/node-config-provider": "^2.1.1", - "@smithy/property-provider": "^2.0.12", - "@smithy/types": "^2.3.5", - "@smithy/url-parser": "^2.0.11", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.0.18.tgz", + "integrity": "sha512-QnPBi6D2zj6AHJdUTo5zXmk8vwHJ2bNevhcVned1y+TZz/OI5cizz5DsYNkqFUIDn8tBuEyKNgbmKVNhBbuY3g==", + "dependencies": { + "@smithy/node-config-provider": "^2.1.3", + "@smithy/property-provider": "^2.0.13", + "@smithy/types": "^2.4.0", + "@smithy/url-parser": "^2.0.12", "tslib": "^2.5.0" }, "engines": { @@ -1769,23 +1760,23 @@ } }, "node_modules/@smithy/eventstream-codec": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.0.11.tgz", - "integrity": "sha512-BQCTjxhCYRZIfXapa2LmZSaH8QUBGwMZw7XRN83hrdixbLjIcj+o549zjkedFS07Ve2TlvWUI6BTzP+nv7snBA==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.0.12.tgz", + "integrity": "sha512-ZZQLzHBJkbiAAdj2C5K+lBlYp/XJ+eH2uy+jgJgYIFW/o5AM59Hlj7zyI44/ZTDIQWmBxb3EFv/c5t44V8/g8A==", "dependencies": { "@aws-crypto/crc32": "3.0.0", - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "@smithy/util-hex-encoding": "^2.0.0", "tslib": "^2.5.0" } }, "node_modules/@smithy/eventstream-serde-browser": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-2.0.11.tgz", - "integrity": "sha512-p9IK4uvwT6B3pT1VGlODvcVBfPVikjBFHAcKpvvNF+7lAEI+YiC6d0SROPkpjnvCgVBYyGXa3ciqrWnFze6mwQ==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-2.0.12.tgz", + "integrity": "sha512-0pi8QlU/pwutNshoeJcbKR1p7Ie5STd8UFAMX5xhSoSJjNlxIv/OsHbF023jscMRN2Prrqd6ToGgdCnsZVQjvg==", "dependencies": { - "@smithy/eventstream-serde-universal": "^2.0.11", - "@smithy/types": "^2.3.5", + "@smithy/eventstream-serde-universal": "^2.0.12", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -1793,11 +1784,11 @@ } }, "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-2.0.11.tgz", - "integrity": "sha512-vN32E8yExo0Z8L7kXhlU9KRURrhqOpPdLxQMp3MwfMThrjiqbr1Sk5srUXc1ed2Ygl/l0TEN9vwNG0bQHg6AjQ==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-2.0.12.tgz", + "integrity": "sha512-I0XfwQkIX3gAnbrU5rLMkBSjTM9DHttdbLwf12CXmj7SSI5dT87PxtKLRrZGanaCMbdf2yCep+MW5/4M7IbvQA==", "dependencies": { - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -1805,12 +1796,12 @@ } }, "node_modules/@smithy/eventstream-serde-node": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-2.0.11.tgz", - "integrity": "sha512-Gjqbpg7UmD+YzkpgNShNcDNZcUpBWIkvX2XCGptz5PoxJU/UQbuF9eSc93ZlIb7j4aGjtFfqk23HUMW8Hopg2Q==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-2.0.12.tgz", + "integrity": "sha512-vf1vMHGOkG3uqN9x1zKOhnvW/XgvhJXWqjV6zZiT2FMjlEayugQ1mzpSqr7uf89+BzjTzuZKERmOsEAmewLbxw==", "dependencies": { - "@smithy/eventstream-serde-universal": "^2.0.11", - "@smithy/types": "^2.3.5", + "@smithy/eventstream-serde-universal": "^2.0.12", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -1818,12 +1809,12 @@ } }, "node_modules/@smithy/eventstream-serde-universal": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.0.11.tgz", - "integrity": "sha512-F8FsxLTbFN4+Esgpo+nNKcEajrgRZJ+pG9c8+MhLM4Odp5ejLHw2GMCXd81cGsgmfcbnzdDEXazPPVzOwj89MQ==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.0.12.tgz", + "integrity": "sha512-xZ3ZNpCxIND+q+UCy7y1n1/5VQEYicgSTNCcPqsKawX+Vd+6OcFX7gUHMyPzL8cZr+GdmJuxNleqHlH4giK2tw==", "dependencies": { - "@smithy/eventstream-codec": "^2.0.11", - "@smithy/types": "^2.3.5", + "@smithy/eventstream-codec": "^2.0.12", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -1831,34 +1822,34 @@ } }, "node_modules/@smithy/fetch-http-handler": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.2.3.tgz", - "integrity": "sha512-0G9sePU+0R+8d7cie+OXzNbbkjnD4RfBlVCs46ZEuQAMcxK8OniemYXSSkOc80CCk8Il4DnlYZcUSvsIs2OB2w==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.2.4.tgz", + "integrity": "sha512-gIPRFEGi+c6V52eauGKrjDzPWF2Cu7Z1r5F8A3j2wcwz25sPG/t8kjsbEhli/tS/2zJp/ybCZXe4j4ro3yv/HA==", "dependencies": { - "@smithy/protocol-http": "^3.0.7", - "@smithy/querystring-builder": "^2.0.11", - "@smithy/types": "^2.3.5", + "@smithy/protocol-http": "^3.0.8", + "@smithy/querystring-builder": "^2.0.12", + "@smithy/types": "^2.4.0", "@smithy/util-base64": "^2.0.0", "tslib": "^2.5.0" } }, "node_modules/@smithy/hash-blob-browser": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-2.0.11.tgz", - "integrity": "sha512-/6vq/NiH2EN3mWdwcLdjVohP+VCng+ZA1GnlUdx959egsfgIlLWQvCyjnB2ze9Hr6VHV5XEFLLpLQH2dHA6Sgw==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-2.0.12.tgz", + "integrity": "sha512-riLnV16f27yyePX8UF0deRHAeccUK8SrOxyTykSTrnVkgS3DsjNapZtTbd8OGNKEbI60Ncdb5GwN3rHZudXvog==", "dependencies": { "@smithy/chunked-blob-reader": "^2.0.0", "@smithy/chunked-blob-reader-native": "^2.0.0", - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" } }, "node_modules/@smithy/hash-node": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.0.11.tgz", - "integrity": "sha512-PbleVugN2tbhl1ZoNWVrZ1oTFFas/Hq+s6zGO8B9bv4w/StTriTKA9W+xZJACOj9X7zwfoTLbscM+avCB1KqOQ==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.0.12.tgz", + "integrity": "sha512-fDZnTr5j9t5qcbeJ037aMZXxMka13Znqwrgy3PAqYj6Dm3XHXHftTH3q+NWgayUxl1992GFtQt1RuEzRMy3NnQ==", "dependencies": { - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "@smithy/util-buffer-from": "^2.0.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" @@ -1868,11 +1859,11 @@ } }, "node_modules/@smithy/hash-stream-node": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-2.0.11.tgz", - "integrity": "sha512-Jn2yl+Dn0kvwKvSavvR1/BFVYa2wIkaJKWeTH48kno89gqHAJxMh1hrtBN6SJ7F8VhodNZTiNOlQVqCSfLheNQ==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-2.0.12.tgz", + "integrity": "sha512-x/DrSynPKrW0k00q7aZ/vy531a3mRw79mOajHp+cIF0TrA1SqEMFoy/B8X0XtoAtlJWt/vvgeDNqt/KAeaAqMw==", "dependencies": { - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" }, @@ -1881,11 +1872,11 @@ } }, "node_modules/@smithy/invalid-dependency": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.0.11.tgz", - "integrity": "sha512-zazq99ujxYv/NOf9zh7xXbNgzoVLsqE0wle8P/1zU/XdhPi/0zohTPKWUzIxjGdqb5hkkwfBkNkl5H+LE0mvgw==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.0.12.tgz", + "integrity": "sha512-p5Y+iMHV3SoEpy3VSR7mifbreHQwVSvHSAz/m4GdoXfOzKzaYC8hYv10Ks7Deblkf7lhas8U+lAp9ThbBM+ZXA==", "dependencies": { - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" } }, @@ -1901,22 +1892,22 @@ } }, "node_modules/@smithy/md5-js": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-2.0.11.tgz", - "integrity": "sha512-YBIv+e95qeGvQA05ucwstmTeQ/bUzWgU+nO2Ffmif5awu6IzSR0Jfk3XLYh4mdy7f8DCgsn8qA63u7N9Lu0+5A==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-2.0.12.tgz", + "integrity": "sha512-OgDt+Xnrw+W5z3MSl5KZZzebqmXrYl9UdbCiBYnnjErmNywwSjV6QB/Oic3/7hnsPniSU81n7Rvlhz2kH4EREQ==", "dependencies": { - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" } }, "node_modules/@smithy/middleware-content-length": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.0.13.tgz", - "integrity": "sha512-Md2kxWpaec3bXp1oERFPQPBhOXCkGSAF7uc1E+4rkwjgw3/tqAXRtbjbggu67HJdwaif76As8AV6XxbD1HzqTQ==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.0.14.tgz", + "integrity": "sha512-poUNgKTw9XwPXfX9nEHpVgrMNVpaSMZbshqvPxFVoalF4wp6kRzYKOfdesSVectlQ51VtigoLfbXcdyPwvxgTg==", "dependencies": { - "@smithy/protocol-http": "^3.0.7", - "@smithy/types": "^2.3.5", + "@smithy/protocol-http": "^3.0.8", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -1924,15 +1915,16 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.1.0.tgz", - "integrity": "sha512-e6HZbfrp9CNTJqIPSgkydB9mNQXiq5pkHF3ZB6rOzPPR9PkJBoGFo9TcM7FaaKFUaH4Kc20AX6WwwVyIlNhXTA==", - "dependencies": { - "@smithy/middleware-serde": "^2.0.11", - "@smithy/node-config-provider": "^2.1.1", - "@smithy/types": "^2.3.5", - "@smithy/url-parser": "^2.0.11", - "@smithy/util-middleware": "^2.0.4", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.1.3.tgz", + "integrity": "sha512-ZrQ0/YX6hNVTxqMEHtEaDbDv6pNeEji/a5Vk3HuFC5R3ZY8lfoATyxmOGxBVYnF3NUvZLNC7umEv1WzWGWvCGQ==", + "dependencies": { + "@smithy/middleware-serde": "^2.0.12", + "@smithy/node-config-provider": "^2.1.3", + "@smithy/shared-ini-file-loader": "^2.2.2", + "@smithy/types": "^2.4.0", + "@smithy/url-parser": "^2.0.12", + "@smithy/util-middleware": "^2.0.5", "tslib": "^2.5.0" }, "engines": { @@ -1940,16 +1932,16 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.0.16.tgz", - "integrity": "sha512-Br5+0yoiMS0ugiOAfJxregzMMGIRCbX4PYo1kDHtLgvkA/d++aHbnHB819m5zOIAMPvPE7AThZgcsoK+WOsUTA==", - "dependencies": { - "@smithy/node-config-provider": "^2.1.1", - "@smithy/protocol-http": "^3.0.7", - "@smithy/service-error-classification": "^2.0.4", - "@smithy/types": "^2.3.5", - "@smithy/util-middleware": "^2.0.4", - "@smithy/util-retry": "^2.0.4", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.0.18.tgz", + "integrity": "sha512-VyrHQRldGSb3v9oFOB5yPxmLT7U2sQic2ytylOnYlnsmVOLlFIaI6sW22c+w2675yq+XZ6HOuzV7x2OBYCWRNA==", + "dependencies": { + "@smithy/node-config-provider": "^2.1.3", + "@smithy/protocol-http": "^3.0.8", + "@smithy/service-error-classification": "^2.0.5", + "@smithy/types": "^2.4.0", + "@smithy/util-middleware": "^2.0.5", + "@smithy/util-retry": "^2.0.5", "tslib": "^2.5.0", "uuid": "^8.3.2" }, @@ -1958,11 +1950,11 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.0.11.tgz", - "integrity": "sha512-NuxnjMyf4zQqhwwdh0OTj5RqpnuT6HcH5Xg5GrPijPcKzc2REXVEVK4Yyk8ckj8ez1XSj/bCmJ+oNjmqB02GWA==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.0.12.tgz", + "integrity": "sha512-IBeco157lIScecq2Z+n0gq56i4MTnfKxS7rbfrAORveDJgnbBAaEQgYqMqp/cYqKrpvEXcyTjwKHrBjCCIZh2A==", "dependencies": { - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -1970,11 +1962,11 @@ } }, "node_modules/@smithy/middleware-stack": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.0.5.tgz", - "integrity": "sha512-bVQU/rZzBY7CbSxIrDTGZYnBWKtIw+PL/cRc9B7etZk1IKSOe0NvKMJyWllfhfhrTeMF6eleCzOihIQympAvPw==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.0.6.tgz", + "integrity": "sha512-YSvNZeOKWLJ0M/ycxwDIe2Ztkp6Qixmcml1ggsSv2fdHKGkBPhGrX5tMzPGMI1yyx55UEYBi2OB4s+RriXX48A==", "dependencies": { - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -1982,13 +1974,13 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.1.1.tgz", - "integrity": "sha512-1lF6s1YWBi1LBu2O30tD3jyTgMtuvk/Z1twzXM4GPYe4dmZix4nNREPJIPOcfFikNU2o0eTYP80+izx5F2jIJA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.1.3.tgz", + "integrity": "sha512-J6lXvRHGVnSX3n1PYi+e1L5HN73DkkJpUviV3Ebf+8wSaIjAf+eVNbzyvh/S5EQz7nf4KVfwbD5vdoZMAthAEQ==", "dependencies": { - "@smithy/property-provider": "^2.0.12", - "@smithy/shared-ini-file-loader": "^2.2.0", - "@smithy/types": "^2.3.5", + "@smithy/property-provider": "^2.0.13", + "@smithy/shared-ini-file-loader": "^2.2.2", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -1996,14 +1988,14 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.1.7.tgz", - "integrity": "sha512-PQIKZXlp3awCDn/xNlCSTFE7aYG/5Tx33M05NfQmWYeB5yV1GZZOSz4dXpwiNJYTXb9jPqjl+ueXXkwtEluFFA==", - "dependencies": { - "@smithy/abort-controller": "^2.0.11", - "@smithy/protocol-http": "^3.0.7", - "@smithy/querystring-builder": "^2.0.11", - "@smithy/types": "^2.3.5", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.1.8.tgz", + "integrity": "sha512-KZylM7Wff/So5SmCiwg2kQNXJ+RXgz34wkxS7WNwIUXuZrZZpY/jKJCK+ZaGyuESDu3TxcaY+zeYGJmnFKbQsA==", + "dependencies": { + "@smithy/abort-controller": "^2.0.12", + "@smithy/protocol-http": "^3.0.8", + "@smithy/querystring-builder": "^2.0.12", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -2011,11 +2003,11 @@ } }, "node_modules/@smithy/property-provider": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.0.12.tgz", - "integrity": "sha512-Un/OvvuQ1Kg8WYtoMCicfsFFuHb/TKL3pCA6ZIo/WvNTJTR94RtoRnL7mY4XkkUAoFMyf6KjcQJ76y1FX7S5rw==", + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.0.13.tgz", + "integrity": "sha512-VJqUf2CbsQX6uUiC5dUPuoEATuFjkbkW3lJHbRnpk9EDC9X+iKqhfTK+WP+lve5EQ9TcCI1Q6R7hrg41FyC54w==", "dependencies": { - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -2023,11 +2015,11 @@ } }, "node_modules/@smithy/protocol-http": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-3.0.7.tgz", - "integrity": "sha512-HnZW8y+r66ntYueCDbLqKwWcMNWW8o3eVpSrHNluwtBJ/EUWfQHRKSiu6vZZtc6PGfPQWgVfucoCE/C3QufMAA==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-3.0.8.tgz", + "integrity": "sha512-SHJvYeWq8q0FK8xHk+xjV9dzDUDjFMT+G1pZbV+XB6OVoac/FSVshlMNPeUJ8AmSkcDKHRu5vASnRqZHgD3qhw==", "dependencies": { - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -2035,11 +2027,11 @@ } }, "node_modules/@smithy/querystring-builder": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.0.11.tgz", - "integrity": "sha512-b4kEbVMxpmfv2VWUITn2otckTi7GlMteZQxi+jlwedoATOGEyrCJPfRcYQJjbCi3fZ2QTfh3PcORvB27+j38Yg==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.0.12.tgz", + "integrity": "sha512-cDbF07IuCjiN8CdGvPzfJjXIrmDSelScRfyJYrYBNBbKl2+k7QD/KqiHhtRyEKgID5mmEVrV6KE6L/iPJ98sFw==", "dependencies": { - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "@smithy/util-uri-escape": "^2.0.0", "tslib": "^2.5.0" }, @@ -2048,11 +2040,11 @@ } }, "node_modules/@smithy/querystring-parser": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.0.11.tgz", - "integrity": "sha512-YXe7jhi7s3dQ0Fu9dLoY/gLu6NCyy8tBWJL/v2c9i7/RLpHgKT+uT96/OqZkHizCJ4kr0ZD46tzMjql/o60KLg==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.0.12.tgz", + "integrity": "sha512-fytyTcXaMzPBuNtPlhj5v6dbl4bJAnwKZFyyItAGt4Tgm9HFPZNo7a9r1SKPr/qdxUEBzvL9Rh+B9SkTX3kFxg==", "dependencies": { - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -2060,22 +2052,22 @@ } }, "node_modules/@smithy/service-error-classification": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.0.4.tgz", - "integrity": "sha512-77506l12I5gxTZqBkx3Wb0RqMG81bMYLaVQ+EqIWFwQDJRs5UFeXogKxSKojCmz1wLUziHZQXm03MBzPQiumQw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.0.5.tgz", + "integrity": "sha512-M0SeJnEgD2ywJyV99Fb1yKFzmxDe9JfpJiYTVSRMyRLc467BPU0qsuuDPzMCdB1mU8M8u1rVOdkqdoyFN8UFTw==", "dependencies": { - "@smithy/types": "^2.3.5" + "@smithy/types": "^2.4.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.2.0.tgz", - "integrity": "sha512-xFXqs4vAb5BdkzHSRrTapFoaqS4/3m/CGZzdw46fBjYZ0paYuLAoMY60ICCn1FfGirG+PiJ3eWcqJNe4/SkfyA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.2.2.tgz", + "integrity": "sha512-noyQUPn7b1M8uB0GEXc/Zyxq+5K2b7aaqWnLp+hgJ7+xu/FCvtyWy5eWLDjQEsHnAet2IZhS5QF8872OR69uNg==", "dependencies": { - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -2083,15 +2075,15 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.0.11.tgz", - "integrity": "sha512-EFVU1dT+2s8xi227l1A9O27edT/GNKvyAK6lZnIZ0zhIHq/jSLznvkk15aonGAM1kmhmZBVGpI7Tt0odueZK9A==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.0.12.tgz", + "integrity": "sha512-6Kc2lCZEVmb1nNYngyNbWpq0d82OZwITH11SW/Q0U6PX5fH7B2cIcFe7o6eGEFPkTZTP8itTzmYiGcECL0D0Lw==", "dependencies": { - "@smithy/eventstream-codec": "^2.0.11", + "@smithy/eventstream-codec": "^2.0.12", "@smithy/is-array-buffer": "^2.0.0", - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "@smithy/util-hex-encoding": "^2.0.0", - "@smithy/util-middleware": "^2.0.4", + "@smithy/util-middleware": "^2.0.5", "@smithy/util-uri-escape": "^2.0.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" @@ -2101,13 +2093,13 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.1.11.tgz", - "integrity": "sha512-okjMbuBBCTiieK665OFN/ap6u9+Z9z55PMphS5FYCsS6Zfp137Q3qlnt0OgBAnUVnH/mNGyoJV0LBX9gkTWptg==", + "version": "2.1.12", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.1.12.tgz", + "integrity": "sha512-XXqhridfkKnpj+lt8vM6HRlZbqUAqBjVC74JIi13F/AYQd/zTj9SOyGfxnbp4mjY9q28LityxIuV8CTinr9r5w==", "dependencies": { - "@smithy/middleware-stack": "^2.0.5", - "@smithy/types": "^2.3.5", - "@smithy/util-stream": "^2.0.16", + "@smithy/middleware-stack": "^2.0.6", + "@smithy/types": "^2.4.0", + "@smithy/util-stream": "^2.0.17", "tslib": "^2.5.0" }, "engines": { @@ -2115,9 +2107,9 @@ } }, "node_modules/@smithy/types": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.3.5.tgz", - "integrity": "sha512-ehyDt8M9hehyxrLQGoA1BGPou8Js1Ocoh5M0ngDhJMqbFmNK5N6Xhr9/ZExWkyIW8XcGkiMPq3ZUEE0ScrhbuQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.4.0.tgz", + "integrity": "sha512-iH1Xz68FWlmBJ9vvYeHifVMWJf82ONx+OybPW8ZGf5wnEv2S0UXcU4zwlwJkRXuLKpcSLHrraHbn2ucdVXLb4g==", "dependencies": { "tslib": "^2.5.0" }, @@ -2126,12 +2118,12 @@ } }, "node_modules/@smithy/url-parser": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.0.11.tgz", - "integrity": "sha512-h89yXMCCF+S5k9XIoKltMIWTYj+FcEkU/IIFZ6RtE222fskOTL4Iak6ZRG+ehSvZDt8yKEcxqheTDq7JvvtK3g==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.0.12.tgz", + "integrity": "sha512-qgkW2mZqRvlNUcBkxYB/gYacRaAdck77Dk3/g2iw0S9F0EYthIS3loGfly8AwoWpIvHKhkTsCXXQfzksgZ4zIA==", "dependencies": { - "@smithy/querystring-parser": "^2.0.11", - "@smithy/types": "^2.3.5", + "@smithy/querystring-parser": "^2.0.12", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" } }, @@ -2190,13 +2182,13 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.15.tgz", - "integrity": "sha512-2raMZOYKSuke7QlDg/HDcxQdrp0zteJ8z+S0B9Rn23J55ZFNK1+IjG4HkN6vo/0u3Xy/JOdJ93ibiBSB8F7kOw==", + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.16.tgz", + "integrity": "sha512-Uv5Cu8nVkuvLn0puX+R9zWbSNpLIR3AxUlPoLJ7hC5lvir8B2WVqVEkJLwtixKAncVLasnTVjPDCidtAUTGEQw==", "dependencies": { - "@smithy/property-provider": "^2.0.12", - "@smithy/smithy-client": "^2.1.11", - "@smithy/types": "^2.3.5", + "@smithy/property-provider": "^2.0.13", + "@smithy/smithy-client": "^2.1.12", + "@smithy/types": "^2.4.0", "bowser": "^2.11.0", "tslib": "^2.5.0" }, @@ -2205,16 +2197,16 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.19.tgz", - "integrity": "sha512-7pScU4jBFADB2MBYKM3zb5onMh6Nn0X3IfaFVLYPyCarTIZDLUtUl1GtruzEUJPmDzP+uGeqOtU589HDY0Ni6g==", - "dependencies": { - "@smithy/config-resolver": "^2.0.14", - "@smithy/credential-provider-imds": "^2.0.16", - "@smithy/node-config-provider": "^2.1.1", - "@smithy/property-provider": "^2.0.12", - "@smithy/smithy-client": "^2.1.11", - "@smithy/types": "^2.3.5", + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.21.tgz", + "integrity": "sha512-cUEsttVZ79B7Al2rWK2FW03HBpD9LyuqFtm+1qFty5u9sHSdesr215gS2Ln53fTopNiPgeXpdoM3IgjvIO0rJw==", + "dependencies": { + "@smithy/config-resolver": "^2.0.16", + "@smithy/credential-provider-imds": "^2.0.18", + "@smithy/node-config-provider": "^2.1.3", + "@smithy/property-provider": "^2.0.13", + "@smithy/smithy-client": "^2.1.12", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -2233,11 +2225,11 @@ } }, "node_modules/@smithy/util-middleware": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.0.4.tgz", - "integrity": "sha512-Pbu6P4MBwRcjrLgdTR1O4Y3c0sTZn2JdOiJNcgL7EcIStcQodj+6ZTXtbyU/WTEU3MV2NMA10LxFc3AWHZ3+4A==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.0.5.tgz", + "integrity": "sha512-1lyT3TcaMJQe+OFfVI+TlomDkPuVzb27NZYdYtmSTltVmLaUjdCyt4KE+OH1CnhZKsz4/cdCL420Lg9UH5Z2Mw==", "dependencies": { - "@smithy/types": "^2.3.5", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -2245,12 +2237,12 @@ } }, "node_modules/@smithy/util-retry": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.0.4.tgz", - "integrity": "sha512-b+n1jBBKc77C1E/zfBe1Zo7S9OXGBiGn55N0apfhZHxPUP/fMH5AhFUUcWaJh7NAnah284M5lGkBKuhnr3yK5w==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.0.5.tgz", + "integrity": "sha512-x3t1+MQAJ6QONk3GTbJNcugCFDVJ+Bkro5YqQQK1EyVesajNDqxFtCx9WdOFNGm/Cbm7tUdwVEmfKQOJoU2Vtw==", "dependencies": { - "@smithy/service-error-classification": "^2.0.4", - "@smithy/types": "^2.3.5", + "@smithy/service-error-classification": "^2.0.5", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -2258,13 +2250,13 @@ } }, "node_modules/@smithy/util-stream": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.0.16.tgz", - "integrity": "sha512-b5ZSRh1KzUzC7LoJcpfk7+iXGoRr3WylEfmPd4FnBLm90OwxSB9VgK1fDZwicfYxSEvWHdYXgvvjPtenEYBBhw==", + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.0.17.tgz", + "integrity": "sha512-fP/ZQ27rRvHsqItds8yB7jerwMpZFTL3QqbQbidUiG0+mttMoKdP0ZqnvM8UK5q0/dfc3/pN7g4XKPXOU7oRWw==", "dependencies": { - "@smithy/fetch-http-handler": "^2.2.3", - "@smithy/node-http-handler": "^2.1.7", - "@smithy/types": "^2.3.5", + "@smithy/fetch-http-handler": "^2.2.4", + "@smithy/node-http-handler": "^2.1.8", + "@smithy/types": "^2.4.0", "@smithy/util-base64": "^2.0.0", "@smithy/util-buffer-from": "^2.0.0", "@smithy/util-hex-encoding": "^2.0.0", @@ -2299,12 +2291,12 @@ } }, "node_modules/@smithy/util-waiter": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-2.0.11.tgz", - "integrity": "sha512-8SJWUl9O1YhjC77EccgltI3q4XZQp3vp9DGEW6o0OdkUcwqm/H4qOLnMkA2n+NDojuM5Iia2jWoCdbluIiG7TA==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-2.0.12.tgz", + "integrity": "sha512-3sENmyVa1NnOPoiT2NCApPmu7ukP7S/v7kL9IxNmnygkDldn7/yK0TP42oPJLwB2k3mospNsSePIlqdXEUyPHA==", "dependencies": { - "@smithy/abort-controller": "^2.0.11", - "@smithy/types": "^2.3.5", + "@smithy/abort-controller": "^2.0.12", + "@smithy/types": "^2.4.0", "tslib": "^2.5.0" }, "engines": { @@ -2319,20 +2311,28 @@ "postcss": "^8.4.21" } }, + "node_modules/@tinycreek/google-fonts-complete": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@tinycreek/google-fonts-complete/-/google-fonts-complete-3.0.0.tgz", + "integrity": "sha512-ukuQFCUYCnuR/DFVUA5NbNV+aQpzH2b4XRqWcgqVL9biIIo6KnTDER4GV51WJnHRJMYtISi8wR9qKC8NHyJB6Q==", + "peerDependencies": { + "postcss": "^8.4.31" + } + }, "node_modules/@tinycreek/postcss-font-magician": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@tinycreek/postcss-font-magician/-/postcss-font-magician-4.1.0.tgz", - "integrity": "sha512-PAZM4z03ui5HdkZhwG4b6UBdt9A14sgTmhKIouhefCJMKe0JMJHGG9xVet5A42IvIKqa0bRCPBbAaFFBHcxvLA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@tinycreek/postcss-font-magician/-/postcss-font-magician-4.2.0.tgz", + "integrity": "sha512-PRQTM/RdLA7faxxmmRIls9FKWYWemmflH9e+HA+0JKOjDen63qTS47/5bttX+PixhoubI34eR3aEU3toeDM0jg==", "dependencies": { "@tinycreek/bootstrap-fonts-complete": "^2.0.0", - "directory-fonts-complete": "^1.2.0", - "google-fonts-complete": "^2.1.1" + "@tinycreek/google-fonts-complete": "^3.0.0", + "directory-fonts-complete": "^1.2.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "postcss": "^8.4.21" + "postcss": "^8.4.31" } }, "node_modules/@tokenizer/token": { @@ -2409,9 +2409,9 @@ "integrity": "sha512-+pio93ejHN4nINX4pXqfnR/fPLRtJBaT4ORaa5RH0Oc1zoYmo2B2koG+M328CQhHKn1Wj6FcOxCDFXAot9NhvA==" }, "node_modules/@tycrek/express-postcss/node_modules/@types/fs-extra": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.2.tgz", - "integrity": "sha512-c0hrgAOVYr21EX8J0jBMXGLMgJqVf/v6yxi0dLaJboW9aQPh16Id+z6w2Tx1hm+piJOLv8xPfVKZCLfjPw/IMQ==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.3.tgz", + "integrity": "sha512-sF59BlXtUdzEAL1u0MSvuzWd7PdZvZEtnaVkzX5mjpdWTJ8brG0jUqve3jPCzSzvAKKMHTG8F8o/WMQLtleZdQ==", "dependencies": { "@types/jsonfile": "*", "@types/node": "*" @@ -2468,44 +2468,44 @@ } }, "node_modules/@types/bcrypt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz", - "integrity": "sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.1.tgz", + "integrity": "sha512-dIIrEsLV1/v0AUNI8oHMaRRTSeVjoy5ID8oclJavtPj8CwPJoD1eFoNXEypuu6k091brEzBeOo3LlxeAH9zRZg==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/body-parser": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.3.tgz", - "integrity": "sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ==", + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.4.tgz", + "integrity": "sha512-N7UDG0/xiPQa2D/XrVJXjkWbpqHCd2sBaB32ggRF2l83RhPfamgKGF8gwwqyksS95qUS5ZYF9aF+lLPRlwI2UA==", "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "node_modules/@types/busboy": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@types/busboy/-/busboy-1.5.1.tgz", - "integrity": "sha512-JAymE2skNionWnBUwby3MatzPUw4D/6/7FX1qxBXLzmRnFxmqU0luIof7om0I8R3B/rSr9FKUnFCqxZ/NeGbrw==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@types/busboy/-/busboy-1.5.2.tgz", + "integrity": "sha512-OYkRy+dkQWwoGch3oyQ9UE08PO1jSte7aBtPemLXAP9evwh7fNAfikWdB2VMeP8syY3H/XvGq+pB38dDvTe06g==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect": { - "version": "3.4.36", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", - "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", + "version": "3.4.37", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.37.tgz", + "integrity": "sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect-busboy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/connect-busboy/-/connect-busboy-1.0.1.tgz", - "integrity": "sha512-87uJti52mU41seY/hSUhDZlLmlzrTyM7P8Qn80vEJ6WVPS5s2nStHoJhLfxFUjV0SnFHtQpQBM9L6dwvSDdFEg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/connect-busboy/-/connect-busboy-1.0.2.tgz", + "integrity": "sha512-1Zop8D+8pRZYhmzRFcrHa+Ovuv8Vk2Y2LA9i8CI36wIWlesKYTFULmax93sFVxdCA7gFKxifK32QGvv1/ymsbg==", "dev": true, "dependencies": { "@types/busboy": "*", @@ -2514,9 +2514,9 @@ } }, "node_modules/@types/express": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.19.tgz", - "integrity": "sha512-UtOfBtzN9OvpZPPbnnYunfjM7XCI4jyk1NvnFhTVz5krYAnW4o5DCoIekvms+8ApqhB4+9wSge1kBijdfTSmfg==", + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.20.tgz", + "integrity": "sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw==", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -2525,9 +2525,9 @@ } }, "node_modules/@types/express-busboy": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@types/express-busboy/-/express-busboy-8.0.1.tgz", - "integrity": "sha512-l4xzZnCEpiMvQChUqVS0+JaVPqrSra9Sw4bXRdQK4X4ABZbUr3LqLiPHd/N40T5pPkmxOUFnLHhl5iLbP38jKg==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@types/express-busboy/-/express-busboy-8.0.2.tgz", + "integrity": "sha512-+yrqUwhMHaJC4AWoRNzkWcQQEagCS1fFHEVEXvUjKY+s0j15YMidz0sl/TKQAaPpnvRhsnMHz1rPDYlycN+Wrg==", "dev": true, "dependencies": { "@types/connect-busboy": "*", @@ -2535,9 +2535,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.37", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.37.tgz", - "integrity": "sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg==", + "version": "4.17.39", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.39.tgz", + "integrity": "sha512-BiEUfAiGCOllomsRAZOiMFP7LAnrifHpt56pc4Z7l9K6ACyN06Ns1JLMBxwkfLOjJRlSf06NwWsT7yzfpaVpyQ==", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -2546,18 +2546,18 @@ } }, "node_modules/@types/express-session": { - "version": "1.17.8", - "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.8.tgz", - "integrity": "sha512-bFF7/3wOldMn+56XyFRGY9ZzCr3JWhNSP2ajMPgTlbZR6BQOCHdAbNA9W5dMBPgMywpIP4zkmhxP6Opm/NRYMQ==", + "version": "1.17.9", + "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.9.tgz", + "integrity": "sha512-yIqficLlTPdloeEPhOVenpOUWILkdaXHUWhTOqFGx9JoSuTgeatNjb97k8VvJehbTk0kUSUAHy5r27PXMga89Q==", "dev": true, "dependencies": { "@types/express": "*" } }, "node_modules/@types/ffmpeg-static": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/ffmpeg-static/-/ffmpeg-static-3.0.1.tgz", - "integrity": "sha512-hEJdQMv/g1olk9qTiWqh23BfbKsDKE6Tc7DilNJWF1MgZsU9fYOPKrgQ448vfT7aP2Yt5re9vgJDVv9TXEoTyQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/ffmpeg-static/-/ffmpeg-static-3.0.2.tgz", + "integrity": "sha512-hEgrO6mk9OkBAEGLh5fqnW7LXVcTHGWncVPVgeroTvD+X95xd0Q6Mpd7hI96B1yzh0oTEKgTzR98FX7V54UNuw==", "dev": true }, "node_modules/@types/fs-extra": { @@ -2570,43 +2570,43 @@ } }, "node_modules/@types/http-errors": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.2.tgz", - "integrity": "sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.3.tgz", + "integrity": "sha512-pP0P/9BnCj1OVvQR2lF41EkDG/lWWnDyA203b/4Fmi2eTyORnBtcDoKDwjWQthELrBvWkMOrvSOnZ8OVlW6tXA==" }, "node_modules/@types/jsonfile": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.2.tgz", - "integrity": "sha512-8t92P+oeW4d/CRQfJaSqEwXujrhH4OEeHRjGU3v1Q8mUS8GPF3yiX26sw4svv6faL2HfBtGTe2xWIoVgN3dy9w==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.3.tgz", + "integrity": "sha512-/yqTk2SZ1wIezK0hiRZD7RuSf4B3whFxFamB1kGStv+8zlWScTMcHanzfc0XKWs5vA1TkHeckBlOyM8jxU8nHA==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/lodash": { - "version": "4.14.199", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.199.tgz", - "integrity": "sha512-Vrjz5N5Ia4SEzWWgIVwnHNEnb1UE1XMkvY5DGXrAeOGE9imk0hgTHh5GyDjLDJi9OTCn9oo9dXH1uToK1VRfrg==" + "version": "4.14.200", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.200.tgz", + "integrity": "sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q==" }, "node_modules/@types/luxon": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.3.2.tgz", - "integrity": "sha512-l5cpE57br4BIjK+9BSkFBOsWtwv6J9bJpC7gdXIzZyI0vuKvNTk0wZZrkQxMGsUAuGW9+WMNWF2IJMD7br2yeQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.3.3.tgz", + "integrity": "sha512-/BJF3NT0pRMuxrenr42emRUF67sXwcZCd+S1ksG/Fcf9O7C3kKCY4uJSbKBE4KDUIYr3WMsvfmWD8hRjXExBJQ==", "dev": true }, "node_modules/@types/mime": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.3.tgz", - "integrity": "sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg==" + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.4.tgz", + "integrity": "sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw==" }, "node_modules/@types/node": { - "version": "18.18.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.4.tgz", - "integrity": "sha512-t3rNFBgJRugIhackit2mVcLfF6IRc0JE4oeizPQL8Zrm8n2WY/0wOdpOPhdtG0V9Q2TlW/axbF1MJ6z+Yj/kKQ==" + "version": "18.18.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.6.tgz", + "integrity": "sha512-wf3Vz+jCmOQ2HV1YUJuCWdL64adYxumkrxtc+H1VUQlnQI04+5HtH+qZCOE21lBE7gIrt+CwX2Wv8Acrw5Ak6w==" }, "node_modules/@types/node-fetch": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.6.tgz", - "integrity": "sha512-95X8guJYhfqiuVVhRFxVQcf4hW/2bCuoPwDasMf/531STFoNoWTT7YDnWdXHEZKqAGUigmpG31r2FE70LwnzJw==", + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-lX17GZVpJ/fuCjguZ5b3TjEbSENxmEk1B2z02yoXSK9WMEWRivhdSY73wWMn6bpcCDAOh6qAdktpKHIlkDk2lg==", "dev": true, "dependencies": { "@types/node": "*", @@ -2614,25 +2614,25 @@ } }, "node_modules/@types/prop-types": { - "version": "15.7.8", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.8.tgz", - "integrity": "sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==", + "version": "15.7.9", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.9.tgz", + "integrity": "sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==", "peer": true }, "node_modules/@types/qs": { - "version": "6.9.8", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", - "integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==" + "version": "6.9.9", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.9.tgz", + "integrity": "sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg==" }, "node_modules/@types/range-parser": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.5.tgz", - "integrity": "sha512-xrO9OoVPqFuYyR/loIHjnbvvyRZREYKLjxV4+dY6v3FQR3stQ9ZxIGkaclF7YhI9hfjpuTbu14hZEy94qKLtOA==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.6.tgz", + "integrity": "sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA==" }, "node_modules/@types/react": { - "version": "18.2.28", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.28.tgz", - "integrity": "sha512-ad4aa/RaaJS3hyGz0BGegdnSRXQBkd1CCYDCdNjBPg90UUpLgo+WlJqb9fMYUxtehmzF3PJaTWqRZjko6BRzBg==", + "version": "18.2.31", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.31.tgz", + "integrity": "sha512-c2UnPv548q+5DFh03y8lEDeMfDwBn9G3dRwfkrxQMo/dOtRHUUO57k6pHvBIfH/VF4Nh+98mZ5aaSe+2echD5g==", "peer": true, "dependencies": { "@types/prop-types": "*", @@ -2641,24 +2641,24 @@ } }, "node_modules/@types/scheduler": { - "version": "0.16.4", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.4.tgz", - "integrity": "sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ==", + "version": "0.16.5", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.5.tgz", + "integrity": "sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw==", "peer": true }, "node_modules/@types/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.2.tgz", - "integrity": "sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw==", + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.3.tgz", + "integrity": "sha512-/7fKxvKUoETxjFUsuFlPB9YndePpxxRAOfGC/yJdc9kTjTeP5kRCTzfnE8kPUKCeyiyIZu0YQ76s50hCedI1ug==", "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "node_modules/@types/serve-static": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.3.tgz", - "integrity": "sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.4.tgz", + "integrity": "sha512-aqqNfs1XTF0HDrFdlY//+SGUxmdSUbjeRXb5iaZc3x0/vMbYmdw9qvOgHWOyyLFxSSRnUuP5+724zBgfw8/WAw==", "dependencies": { "@types/http-errors": "*", "@types/mime": "*", @@ -2686,9 +2686,9 @@ } }, "node_modules/@types/trusted-types": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.4.tgz", - "integrity": "sha512-IDaobHimLQhjwsQ/NMwRVfa/yL7L/wriQPMhw1ZJall0KX6E1oxk29XMDeilW5qTIg5aoiqf5Udy8U/51aNoQQ==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.5.tgz", + "integrity": "sha512-I3pkr8j/6tmQtKV/ZzHtuaqYSQvyjGRKH4go60Rr0IDLlFxuRT5V32uvB1mecM5G1EVAUyF/4r4QZ1GHgz+mxA==" }, "node_modules/@types/uuid": { "version": "8.3.4", @@ -3163,12 +3163,13 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3194,9 +3195,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001547", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz", - "integrity": "sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==", + "version": "1.0.30001551", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001551.tgz", + "integrity": "sha512-vtBAez47BoGMMzlbYhfXrMV1kvRF2WP/lqiMuDu1Sb4EE4LKEgjopFDSRtZfdVnslNRpOqV/woE+Xgrwj6VQlg==", "funding": [ { "type": "opencollective", @@ -3663,6 +3664,19 @@ "node": ">=4.0.0" } }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -3799,9 +3813,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.551", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.551.tgz", - "integrity": "sha512-/Ng/W/kFv7wdEHYzxdK7Cv0BHEGSkSB3M0Ssl8Ndr1eMiYeas/+Mv4cNaDqamqWx6nd2uQZfPz6g25z25M/sdw==" + "version": "1.4.563", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.563.tgz", + "integrity": "sha512-dg5gj5qOgfZNkPNeyKBZQAQitIQ/xwfIDmEQJHCbXaD9ebTZxwJXUsDYcBlAvZGZLi+/354l35J1wkmP6CqYaw==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -4204,9 +4218,9 @@ } }, "node_modules/fraction.js": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.6.tgz", - "integrity": "sha512-n2aZ9tNfYDwaHhvFTkhFErqOMIb8uyzSQ+vGJBjZyanAKZVbGUQ1sngfk9FdkBw7G26O7AgNjLcecLffD1c7eg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", "engines": { "node": "*" }, @@ -4287,9 +4301,12 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/gauge": { "version": "3.0.2", @@ -4328,14 +4345,14 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4403,33 +4420,15 @@ "node": ">=4" } }, - "node_modules/google-fonts-complete": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/google-fonts-complete/-/google-fonts-complete-2.1.1.tgz", - "integrity": "sha512-6e7jXyadmW4iHrrmYitcsoyVpcymjndBsgXLeo0XXXbAqU9xhM06OxxJAiPqSrp9Xn2bvBueOTe091lwkKVc1g==", - "dependencies": { - "postcss": "^7.0.18" - } - }, - "node_modules/google-fonts-complete/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/google-fonts-complete/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" + "get-intrinsic": "^1.1.3" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/graceful-fs": { @@ -4437,14 +4436,6 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, - "node_modules/has": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", - "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -4453,6 +4444,17 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", @@ -4494,6 +4496,17 @@ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -4621,11 +4634,11 @@ } }, "node_modules/is-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4837,29 +4850,29 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/lit": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz", - "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.0.0.tgz", + "integrity": "sha512-nQ0teRzU1Kdj++VdmttS2WvIen8M79wChJ6guRKIIym2M3Ansg3Adj9O6yuQh2IpjxiUXlNuS81WKlQ4iL3BmA==", "dependencies": { - "@lit/reactive-element": "^1.6.0", - "lit-element": "^3.3.0", - "lit-html": "^2.8.0" + "@lit/reactive-element": "^2.0.0", + "lit-element": "^4.0.0", + "lit-html": "^3.0.0" } }, "node_modules/lit-element": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz", - "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.0.0.tgz", + "integrity": "sha512-N6+f7XgusURHl69DUZU6sTBGlIN+9Ixfs3ykkNDfgfTkDYGGOWwHAYBhDqVswnFGyWgQYR2KiSpu4J76Kccs/A==", "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.1.0", - "@lit/reactive-element": "^1.3.0", - "lit-html": "^2.8.0" + "@lit-labs/ssr-dom-shim": "^1.1.2-pre.0", + "@lit/reactive-element": "^2.0.0", + "lit-html": "^3.0.0" } }, "node_modules/lit-html": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz", - "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.0.0.tgz", + "integrity": "sha512-DNJIE8dNY0dQF2Gs0sdMNUppMQT2/CvV4OVnSdg7BXAsGqkVwsE5bqQ04POfkYH5dBIuGnJYdFz5fYYyNnOxiA==", "dependencies": { "@types/trusted-types": "^2.0.2" } @@ -5128,9 +5141,9 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/mysql2": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.6.1.tgz", - "integrity": "sha512-O7FXjLtNkjcMBpLURwkXIhyVbX9i4lq4nNRCykPNOXfceq94kJ0miagmTEGCZieuO8JtwtXaZ41U6KT4eF9y3g==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.6.2.tgz", + "integrity": "sha512-m5erE6bMoWfPXW1D5UrVwlT8PowAoSX69KcZzPuARQ3wY1RJ52NW9PdvdPo076XiSIkQ5IBTis7hxdlrQTlyug==", "dependencies": { "denque": "^2.1.0", "generate-function": "^2.3.1", @@ -5224,9 +5237,9 @@ } }, "node_modules/node-abi": { - "version": "3.50.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.50.0.tgz", - "integrity": "sha512-2Gxu7Eq7vnBIRfYSmqPruEllMM14FjOQFJSoqdGWthVn+tmwEXzmdPpya6cvvwf0uZA3F5N1fMFr9mijZBplFA==", + "version": "3.51.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.51.0.tgz", + "integrity": "sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA==", "dependencies": { "semver": "^7.3.5" }, @@ -5399,9 +5412,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -6613,6 +6626,20 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -6769,14 +6796,6 @@ "is-arrayish": "^0.3.1" } }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -7446,9 +7465,9 @@ "peer": true }, "node_modules/yaml": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz", - "integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz", + "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==", "engines": { "node": ">= 14" } From c648533469ddda92621e494557023112388e943c Mon Sep 17 00:00:00 2001 From: xwashere Date: Wed, 25 Oct 2023 10:25:06 -0400 Subject: [PATCH 48/57] feat: configurable rate limiting --- backend/UserConfig.ts | 11 ++++++++++ backend/ratelimit.ts | 41 +++++++++++++++++++++++++++++++++++ backend/routers/api.ts | 5 +++-- backend/routers/index.ts | 3 ++- common/types.d.ts | 42 +++++++++++++++++++++++++++++++++++ frontend/setup.mts | 47 ++++++++++++++++++++++++++++++++++++++++ package-lock.json | 12 ++++++++++ package.json | 1 + views/setup.pug | 16 ++++++++++++++ 9 files changed, 175 insertions(+), 3 deletions(-) create mode 100644 backend/ratelimit.ts diff --git a/backend/UserConfig.ts b/backend/UserConfig.ts index 0a90031..de49982 100644 --- a/backend/UserConfig.ts +++ b/backend/UserConfig.ts @@ -59,6 +59,10 @@ const Checkers: UserConfigTypeChecker = { password: basicStringChecker, database: basicStringChecker } + }, + + rateLimit: { + endpoint: (val) => val == null || (val != null && (numChecker(val.requests) && numChecker(val.duration))) } }; @@ -107,6 +111,13 @@ export class UserConfig { if (!Checkers.sql.mySql.database(config.sql.mySql.database)) throw new Error('Invalid MySql Database'); } + // * optional rate limit config + if (config.rateLimit != null) { + if (!Checkers.rateLimit.endpoint(config.rateLimit.login)) throw new Error('Invalid rate limit configuration'); + if (!Checkers.rateLimit.endpoint(config.rateLimit.upload)) throw new Error('Invalid rate limit configuration'); + if (!Checkers.rateLimit.endpoint(config.rateLimit.api)) throw new Error('Invalid rate limit configuration'); + } + // All is fine, carry on! return config; } diff --git a/backend/ratelimit.ts b/backend/ratelimit.ts new file mode 100644 index 0000000..ce2df56 --- /dev/null +++ b/backend/ratelimit.ts @@ -0,0 +1,41 @@ +import { EndpointRateLimitConfiguration } from 'ass'; +import { NextFunction, Request, Response } from 'express'; +import { rateLimit } from 'express-rate-limit'; + +/** + * map that contains rate limiter middleware for each group + */ +let rateLimiterGroups = new Map void>(); + +/** + * creates middleware for rate limiting + */ +export const rateLimiterMiddleware = (group: string, config: EndpointRateLimitConfiguration | undefined): (req: Request, res: Response, next: NextFunction) => void => { + if (rateLimiterGroups.has(group)) return rateLimiterGroups.get(group)!; + + if (config == null) { // config might be null if the user doesnt want a rate limit + rateLimiterGroups.set(group, (req, res, next) => { + next(); + }); + + return rateLimiterGroups.get(group)!; + } else { + rateLimiterGroups.set(group, rateLimit({ + limit: config.requests, + windowMs: config.duration * 1000, + skipFailedRequests: true, + legacyHeaders: false, + standardHeaders: "draft-7", + keyGenerator: (req, res) => { + return req.ip || 'disconnected'; + }, + handler: (req, res) => { + res.status(429); + res.contentType('json'); + res.send('{"success":false,"message":"Rate limit exceeded, try again later"}'); + } + })); + + return rateLimiterGroups.get(group)!; + } +}; \ No newline at end of file diff --git a/backend/routers/api.ts b/backend/routers/api.ts index fd7dee0..9dd7bf0 100644 --- a/backend/routers/api.ts +++ b/backend/routers/api.ts @@ -8,6 +8,7 @@ import { log } from '../log'; import { nanoid } from '../generators'; import { UserConfig } from '../UserConfig'; import { MySql } from '../sql/mysql'; +import { rateLimiterMiddleware } from '../ratelimit'; const router = Router({ caseSensitive: true }); @@ -38,7 +39,7 @@ router.post('/setup', BodyParserJson(), async (req, res) => { }); // User login -router.post('/login', BodyParserJson(), (req, res) => { +router.post('/login', rateLimiterMiddleware("login", UserConfig.config.rateLimit?.login), BodyParserJson(), (req, res) => { const { username, password } = req.body; data.getAll('users') @@ -68,7 +69,7 @@ router.post('/login', BodyParserJson(), (req, res) => { }); // todo: authenticate API endpoints -router.post('/user', BodyParserJson(), async (req, res) => { +router.post('/user', rateLimiterMiddleware("api", UserConfig.config.rateLimit?.api), BodyParserJson(), async (req, res) => { if (!UserConfig.ready) return res.status(409).json({ success: false, message: 'User config not ready' }); diff --git a/backend/routers/index.ts b/backend/routers/index.ts index cf44fbd..e49df5e 100644 --- a/backend/routers/index.ts +++ b/backend/routers/index.ts @@ -12,6 +12,7 @@ import { App } from '../app'; import { random } from '../generators'; import { UserConfig } from '../UserConfig'; import { getFileS3, uploadFileS3 } from '../s3'; +import { rateLimiterMiddleware } from '../ratelimit'; const router = Router({ caseSensitive: true }); @@ -29,7 +30,7 @@ bb.extend(router, { router.get('/', (req, res) => UserConfig.ready ? res.render('index', { version: App.pkgVersion }) : res.redirect('/setup')); // Upload flow -router.post('/', async (req, res) => { +router.post('/', rateLimiterMiddleware("upload", UserConfig.config.rateLimit?.upload), async (req, res) => { // Check user config if (!UserConfig.ready) return res.status(500).type('text').send('Configuration missing!'); diff --git a/common/types.d.ts b/common/types.d.ts index 3f04c21..d9ca35f 100644 --- a/common/types.d.ts +++ b/common/types.d.ts @@ -25,6 +25,8 @@ declare module 'ass' { s3?: S3Configuration; sql?: SqlConfiguration; + + rateLimit?: RateLimitConfiguration; } interface S3Configuration { @@ -57,6 +59,43 @@ declare module 'ass' { database: string; } } + + /** + * rate limiter configuration + * @since 0.15.0 + */ + interface RateLimitConfiguration { + /** + * rate limit for the login endpoints + */ + login?: EndpointRateLimitConfiguration; + + /** + * rate limit for parts of the api not covered by other rate limits + */ + api?: EndpointRateLimitConfiguration; + + /** + * rate limit for file uploads + */ + upload?: EndpointRateLimitConfiguration; + } + + /** + * rate limiter per-endpoint configuration + * @since 0.15.0 + */ + interface EndpointRateLimitConfiguration { + /** + * maximum number of requests per duration + */ + requests: number; + + /** + * rate limiting window in seconds + */ + duration: number; + } interface UserConfigTypeChecker { uploadsDir: (val: any) => boolean; @@ -81,6 +120,9 @@ declare module 'ass' { database: (val: any) => boolean; } } + rateLimit: { + endpoint: (val: any) => boolean; + } } /** diff --git a/frontend/setup.mts b/frontend/setup.mts index 1ef28a2..fe2d043 100644 --- a/frontend/setup.mts +++ b/frontend/setup.mts @@ -4,6 +4,26 @@ import { IdType, UserConfiguration } from 'ass'; const genericErrorAlert = () => alert('An error occured, please check the console for details'); const errAlert = (logTitle: string, err: any, stream: 'error' | 'warn' = 'error') => (console[stream](logTitle, err), genericErrorAlert()); const errReset = (message: string, element: SlButton) => (element.disabled = false, alert(message)); +const genericRateLimit = (config: object, category: string, submitButton: SlButton, requests: SlInput, time: SlInput) => { + if ((requests.value || time.value) != '') { + if (requests.value == '') { + errReset(`No count for ${category} rate limit`, submitButton); + return true; // this should probably be false but this lets us chain this until we see an error + } + + if (time.value == '') { + errReset(`No time for ${category} rate limit`, submitButton); + return true; + } + + (config as any)[category] = { + requests: parseInt(requests.value), + duration: parseInt(time.value), + }; + } + + return false; +}; // * Wait for the document to be ready document.addEventListener('DOMContentLoaded', () => { @@ -29,6 +49,13 @@ document.addEventListener('DOMContentLoaded', () => { userUsername: document.querySelector('#user-username') as SlInput, userPassword: document.querySelector('#user-password') as SlInput, + ratelimitLoginRequests: document.querySelector('#ratelimit-login-requests') as SlInput, + ratelimitLoginTime: document.querySelector('#ratelimit-login-time') as SlInput, + ratelimitApiRequests: document.querySelector('#ratelimit-api-requests') as SlInput, + ratelimitApiTime: document.querySelector('#ratelimit-api-time') as SlInput, + ratelimitUploadRequests: document.querySelector('#ratelimit-upload-requests') as SlInput, + ratelimitUploadTime: document.querySelector('#ratelimit-upload-time') as SlInput, + submitButton: document.querySelector('#submit') as SlButton, }; @@ -72,6 +99,26 @@ document.addEventListener('DOMContentLoaded', () => { }; } + // append rate limit config, if specified + if (( + Elements.ratelimitLoginRequests.value + || Elements.ratelimitLoginTime.value + || Elements.ratelimitUploadRequests.value + || Elements.ratelimitUploadTime.value + || Elements.ratelimitApiRequests.value + || Elements.ratelimitApiTime.value) != '' + ) { + if (!config.rateLimit) config.rateLimit = {}; + + if ( + genericRateLimit(config.rateLimit, 'login', Elements.submitButton, Elements.ratelimitLoginRequests, Elements.ratelimitLoginTime) + || genericRateLimit(config.rateLimit, 'api', Elements.submitButton, Elements.ratelimitApiRequests, Elements.ratelimitApiTime) + || genericRateLimit(config.rateLimit, 'upload', Elements.submitButton, Elements.ratelimitUploadRequests, Elements.ratelimitUploadTime) + ) { + return; + } + } + // ! Make sure the admin user fields are set if (Elements.userUsername.value == null || Elements.userUsername.value === '') return errReset('Admin username is required!', Elements.submitButton); diff --git a/package-lock.json b/package-lock.json index ef902eb..4fe2967 100755 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "cssnano": "^6.0.1", "express": "^4.18.2", "express-busboy": "^10.1.0", + "express-rate-limit": "^7.1.2", "express-session": "^1.17.3", "ffmpeg-static": "^5.2.0", "fs-extra": "^11.1.1", @@ -3960,6 +3961,17 @@ "uuid": "^8.3.2" } }, + "node_modules/express-rate-limit": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.1.2.tgz", + "integrity": "sha512-uvkFt5JooXDhUhrfgqXLyIsAMRCtU1o8W/p0Q2p5U2ude7fEOfFaP0kSYbHOHmPbA9ZEm1JqrRne3vL9pVCBXA==", + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "express": "^4 || ^5" + } + }, "node_modules/express-session": { "version": "1.17.3", "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", diff --git a/package.json b/package.json index 254bd66..afaf7ba 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "cssnano": "^6.0.1", "express": "^4.18.2", "express-busboy": "^10.1.0", + "express-rate-limit": "^7.1.2", "express-session": "^1.17.3", "ffmpeg-static": "^5.2.0", "fs-extra": "^11.1.1", diff --git a/views/setup.pug b/views/setup.pug index acff4db..6446068 100644 --- a/views/setup.pug +++ b/views/setup.pug @@ -55,6 +55,22 @@ block content sl-input#mysql-password(type='password' placeholder='super-secure' clearable): sl-icon(slot='prefix' name='fas-lock' library='fa') h3.setup-text-item-title Database sl-input#mysql-database(type='text' placeholder='assdb' clearable): sl-icon(slot='prefix' name='fas-database' library='fa') + + //- * Rate Limits + h2.setup-text-section-header.mt-4 Rate Limits #[span.setup-text-optional optional] + .setup-panel + h3.setup-text-item-title Generic API - Requests + sl-input#ratelimit-api-requests(type='text' placeholder='120' clearable): sl-icon(slot='prefix' name='fas-hashtag' library='fa') + h3.setup-text-item-title Generic API - Seconds per reset + sl-input#ratelimit-api-time(type='text' placeholder='60' clearable): sl-icon(slot='prefix' name='fas-clock' library='fa') + h3.setup-text-item-title Login - Requests + sl-input#ratelimit-login-requests(type='text' placeholder='5' clearable): sl-icon(slot='prefix' name='fas-hashtag' library='fa') + h3.setup-text-item-title Login - Seconds per reset + sl-input#ratelimit-login-time(type='text' placeholder='30' clearable): sl-icon(slot='prefix' name='fas-clock' library='fa') + h3.setup-text-item-title File upload - Requests + sl-input#ratelimit-upload-requests(type='text' placeholder='120' clearable): sl-icon(slot='prefix' name='fas-hashtag' library='fa') + h3.setup-text-item-title File upload - Seconds per reset + sl-input#ratelimit-upload-time(type='text' placeholder='60' clearable): sl-icon(slot='prefix' name='fas-clock' library='fa') sl-button.w-32.mt-2.self-center#submit(type='primary' submit) Submit script(src='/setup/ui.js') \ No newline at end of file From 3709a6958eef39ddc03b5962e6dfe9f7218acd22 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 25 Oct 2023 10:22:12 -0600 Subject: [PATCH 49/57] chore: vsc autoformat --- backend/UserConfig.ts | 1 - backend/ratelimit.ts | 8 ++++---- backend/routers/api.ts | 4 ++-- common/types.d.ts | 2 +- frontend/setup.mts | 10 +++++----- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/backend/UserConfig.ts b/backend/UserConfig.ts index de49982..ded2ead 100644 --- a/backend/UserConfig.ts +++ b/backend/UserConfig.ts @@ -2,7 +2,6 @@ import { UserConfiguration, UserConfigTypeChecker } from 'ass'; import fs from 'fs-extra'; import { path } from '@tycrek/joint'; - import { log } from './log'; const FILEPATH = path.join('.ass-data/userconfig.json'); diff --git a/backend/ratelimit.ts b/backend/ratelimit.ts index ce2df56..d2c9d8c 100644 --- a/backend/ratelimit.ts +++ b/backend/ratelimit.ts @@ -21,11 +21,11 @@ export const rateLimiterMiddleware = (group: string, config: EndpointRateLimitCo return rateLimiterGroups.get(group)!; } else { rateLimiterGroups.set(group, rateLimit({ - limit: config.requests, - windowMs: config.duration * 1000, + limit: config.requests, + windowMs: config.duration * 1000, skipFailedRequests: true, - legacyHeaders: false, - standardHeaders: "draft-7", + legacyHeaders: false, + standardHeaders: 'draft-7', keyGenerator: (req, res) => { return req.ip || 'disconnected'; }, diff --git a/backend/routers/api.ts b/backend/routers/api.ts index 9dd7bf0..3ef56db 100644 --- a/backend/routers/api.ts +++ b/backend/routers/api.ts @@ -39,7 +39,7 @@ router.post('/setup', BodyParserJson(), async (req, res) => { }); // User login -router.post('/login', rateLimiterMiddleware("login", UserConfig.config.rateLimit?.login), BodyParserJson(), (req, res) => { +router.post('/login', rateLimiterMiddleware('login', UserConfig.config.rateLimit?.login), BodyParserJson(), (req, res) => { const { username, password } = req.body; data.getAll('users') @@ -69,7 +69,7 @@ router.post('/login', rateLimiterMiddleware("login", UserConfig.config.rateLimit }); // todo: authenticate API endpoints -router.post('/user', rateLimiterMiddleware("api", UserConfig.config.rateLimit?.api), BodyParserJson(), async (req, res) => { +router.post('/user', rateLimiterMiddleware('api', UserConfig.config.rateLimit?.api), BodyParserJson(), async (req, res) => { if (!UserConfig.ready) return res.status(409).json({ success: false, message: 'User config not ready' }); diff --git a/common/types.d.ts b/common/types.d.ts index d9ca35f..af05700 100644 --- a/common/types.d.ts +++ b/common/types.d.ts @@ -59,7 +59,7 @@ declare module 'ass' { database: string; } } - + /** * rate limiter configuration * @since 0.15.0 diff --git a/frontend/setup.mts b/frontend/setup.mts index fe2d043..306e608 100644 --- a/frontend/setup.mts +++ b/frontend/setup.mts @@ -55,7 +55,7 @@ document.addEventListener('DOMContentLoaded', () => { ratelimitApiTime: document.querySelector('#ratelimit-api-time') as SlInput, ratelimitUploadRequests: document.querySelector('#ratelimit-upload-requests') as SlInput, ratelimitUploadTime: document.querySelector('#ratelimit-upload-time') as SlInput, - + submitButton: document.querySelector('#submit') as SlButton, }; @@ -101,7 +101,7 @@ document.addEventListener('DOMContentLoaded', () => { // append rate limit config, if specified if (( - Elements.ratelimitLoginRequests.value + Elements.ratelimitLoginRequests.value || Elements.ratelimitLoginTime.value || Elements.ratelimitUploadRequests.value || Elements.ratelimitUploadTime.value @@ -110,11 +110,11 @@ document.addEventListener('DOMContentLoaded', () => { ) { if (!config.rateLimit) config.rateLimit = {}; - if ( - genericRateLimit(config.rateLimit, 'login', Elements.submitButton, Elements.ratelimitLoginRequests, Elements.ratelimitLoginTime) + if ( + genericRateLimit(config.rateLimit, 'login', Elements.submitButton, Elements.ratelimitLoginRequests, Elements.ratelimitLoginTime) || genericRateLimit(config.rateLimit, 'api', Elements.submitButton, Elements.ratelimitApiRequests, Elements.ratelimitApiTime) || genericRateLimit(config.rateLimit, 'upload', Elements.submitButton, Elements.ratelimitUploadRequests, Elements.ratelimitUploadTime) - ) { + ) { return; } } From 304f499cace6cc7ca4b29cef6cf2de39311c868e Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 25 Oct 2023 10:22:32 -0600 Subject: [PATCH 50/57] fix: use const & specify which config was invaldi --- backend/UserConfig.ts | 6 +++--- backend/ratelimit.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/UserConfig.ts b/backend/UserConfig.ts index ded2ead..c31b903 100644 --- a/backend/UserConfig.ts +++ b/backend/UserConfig.ts @@ -112,9 +112,9 @@ export class UserConfig { // * optional rate limit config if (config.rateLimit != null) { - if (!Checkers.rateLimit.endpoint(config.rateLimit.login)) throw new Error('Invalid rate limit configuration'); - if (!Checkers.rateLimit.endpoint(config.rateLimit.upload)) throw new Error('Invalid rate limit configuration'); - if (!Checkers.rateLimit.endpoint(config.rateLimit.api)) throw new Error('Invalid rate limit configuration'); + if (!Checkers.rateLimit.endpoint(config.rateLimit.login)) throw new Error('Invalid Login rate limit configuration'); + if (!Checkers.rateLimit.endpoint(config.rateLimit.upload)) throw new Error('Invalid Upload rate limit configuration'); + if (!Checkers.rateLimit.endpoint(config.rateLimit.api)) throw new Error('Invalid API rate limit configuration'); } // All is fine, carry on! diff --git a/backend/ratelimit.ts b/backend/ratelimit.ts index d2c9d8c..0706ade 100644 --- a/backend/ratelimit.ts +++ b/backend/ratelimit.ts @@ -5,7 +5,7 @@ import { rateLimit } from 'express-rate-limit'; /** * map that contains rate limiter middleware for each group */ -let rateLimiterGroups = new Map void>(); +const rateLimiterGroups = new Map void>(); /** * creates middleware for rate limiting From 5360dfcbfb7083d89b9ce0be57c8c81a829a487c Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 25 Oct 2023 10:25:26 -0600 Subject: [PATCH 51/57] build: update packages --- package-lock.json | 438 +++++++++++++++++++++++++--------------------- 1 file changed, 234 insertions(+), 204 deletions(-) diff --git a/package-lock.json b/package-lock.json index 58bac97..b8d0c5f 100755 --- a/package-lock.json +++ b/package-lock.json @@ -165,18 +165,18 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.20.tgz", - "integrity": "sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.2.tgz", + "integrity": "sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==", "peer": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.0.tgz", - "integrity": "sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.2.tgz", + "integrity": "sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==", "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -184,10 +184,10 @@ "@babel/generator": "^7.23.0", "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-module-transforms": "^7.23.0", - "@babel/helpers": "^7.23.0", + "@babel/helpers": "^7.23.2", "@babel/parser": "^7.23.0", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.0", + "@babel/traverse": "^7.23.2", "@babel/types": "^7.23.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -436,13 +436,13 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.1.tgz", - "integrity": "sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", + "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", "peer": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.0", + "@babel/traverse": "^7.23.2", "@babel/types": "^7.23.0" }, "engines": { @@ -546,9 +546,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.23.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.1.tgz", - "integrity": "sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", + "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -570,9 +570,9 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.0.tgz", - "integrity": "sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "peer": true, "dependencies": { "@babel/code-frame": "^7.22.13", @@ -829,9 +829,9 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -926,20 +926,28 @@ "postcss": "^8.4.21" } }, + "node_modules/@tinycreek/google-fonts-complete": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@tinycreek/google-fonts-complete/-/google-fonts-complete-3.0.0.tgz", + "integrity": "sha512-ukuQFCUYCnuR/DFVUA5NbNV+aQpzH2b4XRqWcgqVL9biIIo6KnTDER4GV51WJnHRJMYtISi8wR9qKC8NHyJB6Q==", + "peerDependencies": { + "postcss": "^8.4.31" + } + }, "node_modules/@tinycreek/postcss-font-magician": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@tinycreek/postcss-font-magician/-/postcss-font-magician-4.1.0.tgz", - "integrity": "sha512-PAZM4z03ui5HdkZhwG4b6UBdt9A14sgTmhKIouhefCJMKe0JMJHGG9xVet5A42IvIKqa0bRCPBbAaFFBHcxvLA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@tinycreek/postcss-font-magician/-/postcss-font-magician-4.2.0.tgz", + "integrity": "sha512-PRQTM/RdLA7faxxmmRIls9FKWYWemmflH9e+HA+0JKOjDen63qTS47/5bttX+PixhoubI34eR3aEU3toeDM0jg==", "dependencies": { "@tinycreek/bootstrap-fonts-complete": "^2.0.0", - "directory-fonts-complete": "^1.2.0", - "google-fonts-complete": "^2.1.1" + "@tinycreek/google-fonts-complete": "^3.0.0", + "directory-fonts-complete": "^1.2.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "postcss": "^8.4.21" + "postcss": "^8.4.31" } }, "node_modules/@tokenizer/token": { @@ -973,21 +981,21 @@ } }, "node_modules/@tycrek/discord-hookr/node_modules/@types/node": { - "version": "18.18.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.1.tgz", - "integrity": "sha512-3G42sxmm0fF2+Vtb9TJQpnjmP+uKlWvFa8KoEGquh4gqRmoUG/N0ufuhikw6HEsdG2G2oIKhog1GCTfz9v5NdQ==" + "version": "18.18.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.6.tgz", + "integrity": "sha512-wf3Vz+jCmOQ2HV1YUJuCWdL64adYxumkrxtc+H1VUQlnQI04+5HtH+qZCOE21lBE7gIrt+CwX2Wv8Acrw5Ak6w==" }, "node_modules/@tycrek/express-postcss": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@tycrek/express-postcss/-/express-postcss-0.4.0.tgz", - "integrity": "sha512-4gJnxAvrVoWj2G7r0XDAAIM3WzHZ0CVe70l2GvLMovLy7jdDG6hdu7sX+FMJK0CAKeBcHLLroF60LNOUkCXqSA==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tycrek/express-postcss/-/express-postcss-0.4.1.tgz", + "integrity": "sha512-jIAuEaQ/Sf08m1+lxhe/3rz15KKQrkfG2i0boaB9oWuW4v8xmsJmhGqlweabRM6qH4VOS8jKsHneqnhMPtk00w==", "dependencies": { - "@tsconfig/node16": "^1.0.3", - "@types/express": "^4.17.15", - "@types/fs-extra": "^11.0.1", - "fs-extra": "^11.1.0", - "postcss": "^8.4.21", - "typescript": "^4.9.4" + "@tsconfig/node16": "^16.1.1", + "@types/express": "^4.17.18", + "@types/fs-extra": "^11.0.2", + "fs-extra": "^11.1.1", + "postcss": "^8.4.31", + "typescript": "^5.2.2" }, "engines": { "node": ">=16.14.x", @@ -998,15 +1006,32 @@ "url": "https://patreon.com/tycrek" } }, + "node_modules/@tycrek/express-postcss/node_modules/@tsconfig/node16": { + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-16.1.1.tgz", + "integrity": "sha512-+pio93ejHN4nINX4pXqfnR/fPLRtJBaT4ORaa5RH0Oc1zoYmo2B2koG+M328CQhHKn1Wj6FcOxCDFXAot9NhvA==" + }, "node_modules/@tycrek/express-postcss/node_modules/@types/fs-extra": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.2.tgz", - "integrity": "sha512-c0hrgAOVYr21EX8J0jBMXGLMgJqVf/v6yxi0dLaJboW9aQPh16Id+z6w2Tx1hm+piJOLv8xPfVKZCLfjPw/IMQ==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.3.tgz", + "integrity": "sha512-sF59BlXtUdzEAL1u0MSvuzWd7PdZvZEtnaVkzX5mjpdWTJ8brG0jUqve3jPCzSzvAKKMHTG8F8o/WMQLtleZdQ==", "dependencies": { "@types/jsonfile": "*", "@types/node": "*" } }, + "node_modules/@tycrek/express-postcss/node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/@tycrek/joint": { "version": "1.0.0-1", "resolved": "https://registry.npmjs.org/@tycrek/joint/-/joint-1.0.0-1.tgz", @@ -1058,44 +1083,44 @@ } }, "node_modules/@types/bcrypt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz", - "integrity": "sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.1.tgz", + "integrity": "sha512-dIIrEsLV1/v0AUNI8oHMaRRTSeVjoy5ID8oclJavtPj8CwPJoD1eFoNXEypuu6k091brEzBeOo3LlxeAH9zRZg==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/body-parser": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.3.tgz", - "integrity": "sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ==", + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.4.tgz", + "integrity": "sha512-N7UDG0/xiPQa2D/XrVJXjkWbpqHCd2sBaB32ggRF2l83RhPfamgKGF8gwwqyksS95qUS5ZYF9aF+lLPRlwI2UA==", "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "node_modules/@types/busboy": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@types/busboy/-/busboy-1.5.1.tgz", - "integrity": "sha512-JAymE2skNionWnBUwby3MatzPUw4D/6/7FX1qxBXLzmRnFxmqU0luIof7om0I8R3B/rSr9FKUnFCqxZ/NeGbrw==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@types/busboy/-/busboy-1.5.2.tgz", + "integrity": "sha512-OYkRy+dkQWwoGch3oyQ9UE08PO1jSte7aBtPemLXAP9evwh7fNAfikWdB2VMeP8syY3H/XvGq+pB38dDvTe06g==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect": { - "version": "3.4.36", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", - "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", + "version": "3.4.37", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.37.tgz", + "integrity": "sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect-busboy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/connect-busboy/-/connect-busboy-1.0.1.tgz", - "integrity": "sha512-87uJti52mU41seY/hSUhDZlLmlzrTyM7P8Qn80vEJ6WVPS5s2nStHoJhLfxFUjV0SnFHtQpQBM9L6dwvSDdFEg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/connect-busboy/-/connect-busboy-1.0.2.tgz", + "integrity": "sha512-1Zop8D+8pRZYhmzRFcrHa+Ovuv8Vk2Y2LA9i8CI36wIWlesKYTFULmax93sFVxdCA7gFKxifK32QGvv1/ymsbg==", "dev": true, "dependencies": { "@types/busboy": "*", @@ -1104,15 +1129,15 @@ } }, "node_modules/@types/escape-html": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/escape-html/-/escape-html-1.0.2.tgz", - "integrity": "sha512-gaBLT8pdcexFztLSPRtriHeXY/Kn4907uOCZ4Q3lncFBkheAWOuNt53ypsF8szgxbEJ513UeBzcf4utN0EzEwA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-QbNxKa2IX2y/9eGiy4w8rrwk//ERHXA6zwYVRA3+ayA/D3pkz+/bLL4b5uSLA0L0kPuNX1Jbv9HyPzv9T4zbJQ==", "dev": true }, "node_modules/@types/express": { - "version": "4.17.18", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.18.tgz", - "integrity": "sha512-Sxv8BSLLgsBYmcnGdGjjEjqET2U+AKAdCRODmMiq02FgjwuV75Ut85DRpvFjyw/Mk0vgUOliGRU0UUmuuZHByQ==", + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.20.tgz", + "integrity": "sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw==", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -1121,9 +1146,9 @@ } }, "node_modules/@types/express-busboy": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@types/express-busboy/-/express-busboy-8.0.1.tgz", - "integrity": "sha512-l4xzZnCEpiMvQChUqVS0+JaVPqrSra9Sw4bXRdQK4X4ABZbUr3LqLiPHd/N40T5pPkmxOUFnLHhl5iLbP38jKg==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@types/express-busboy/-/express-busboy-8.0.2.tgz", + "integrity": "sha512-+yrqUwhMHaJC4AWoRNzkWcQQEagCS1fFHEVEXvUjKY+s0j15YMidz0sl/TKQAaPpnvRhsnMHz1rPDYlycN+Wrg==", "dev": true, "dependencies": { "@types/connect-busboy": "*", @@ -1131,9 +1156,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.37", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.37.tgz", - "integrity": "sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg==", + "version": "4.17.39", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.39.tgz", + "integrity": "sha512-BiEUfAiGCOllomsRAZOiMFP7LAnrifHpt56pc4Z7l9K6ACyN06Ns1JLMBxwkfLOjJRlSf06NwWsT7yzfpaVpyQ==", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -1142,9 +1167,9 @@ } }, "node_modules/@types/ffmpeg-static": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/ffmpeg-static/-/ffmpeg-static-3.0.1.tgz", - "integrity": "sha512-hEJdQMv/g1olk9qTiWqh23BfbKsDKE6Tc7DilNJWF1MgZsU9fYOPKrgQ448vfT7aP2Yt5re9vgJDVv9TXEoTyQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/ffmpeg-static/-/ffmpeg-static-3.0.2.tgz", + "integrity": "sha512-hEgrO6mk9OkBAEGLh5fqnW7LXVcTHGWncVPVgeroTvD+X95xd0Q6Mpd7hI96B1yzh0oTEKgTzR98FX7V54UNuw==", "dev": true }, "node_modules/@types/fs-extra": { @@ -1157,22 +1182,22 @@ } }, "node_modules/@types/http-errors": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.2.tgz", - "integrity": "sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.3.tgz", + "integrity": "sha512-pP0P/9BnCj1OVvQR2lF41EkDG/lWWnDyA203b/4Fmi2eTyORnBtcDoKDwjWQthELrBvWkMOrvSOnZ8OVlW6tXA==" }, "node_modules/@types/jsonfile": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.2.tgz", - "integrity": "sha512-8t92P+oeW4d/CRQfJaSqEwXujrhH4OEeHRjGU3v1Q8mUS8GPF3yiX26sw4svv6faL2HfBtGTe2xWIoVgN3dy9w==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.3.tgz", + "integrity": "sha512-/yqTk2SZ1wIezK0hiRZD7RuSf4B3whFxFamB1kGStv+8zlWScTMcHanzfc0XKWs5vA1TkHeckBlOyM8jxU8nHA==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/luxon": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.3.2.tgz", - "integrity": "sha512-l5cpE57br4BIjK+9BSkFBOsWtwv6J9bJpC7gdXIzZyI0vuKvNTk0wZZrkQxMGsUAuGW9+WMNWF2IJMD7br2yeQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.3.3.tgz", + "integrity": "sha512-/BJF3NT0pRMuxrenr42emRUF67sXwcZCd+S1ksG/Fcf9O7C3kKCY4uJSbKBE4KDUIYr3WMsvfmWD8hRjXExBJQ==", "dev": true }, "node_modules/@types/marked": { @@ -1182,19 +1207,19 @@ "dev": true }, "node_modules/@types/mime": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.3.tgz", - "integrity": "sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg==" + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.4.tgz", + "integrity": "sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw==" }, "node_modules/@types/node": { - "version": "16.18.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.55.tgz", - "integrity": "sha512-Y1zz/LIuJek01+hlPNzzXQhmq/Z2BCP96j18MSXC0S0jSu/IG4FFxmBs7W4/lI2vPJ7foVfEB0hUVtnOjnCiTg==" + "version": "16.18.59", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.59.tgz", + "integrity": "sha512-PJ1w2cNeKUEdey4LiPra0ZuxZFOGvetswE8qHRriV/sUkL5Al4tTmPV9D2+Y/TPIxTHHgxTfRjZVKWhPw/ORhQ==" }, "node_modules/@types/node-fetch": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.6.tgz", - "integrity": "sha512-95X8guJYhfqiuVVhRFxVQcf4hW/2bCuoPwDasMf/531STFoNoWTT7YDnWdXHEZKqAGUigmpG31r2FE70LwnzJw==", + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-lX17GZVpJ/fuCjguZ5b3TjEbSENxmEk1B2z02yoXSK9WMEWRivhdSY73wWMn6bpcCDAOh6qAdktpKHIlkDk2lg==", "dev": true, "dependencies": { "@types/node": "*", @@ -1202,28 +1227,28 @@ } }, "node_modules/@types/qs": { - "version": "6.9.8", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", - "integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==" + "version": "6.9.9", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.9.tgz", + "integrity": "sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg==" }, "node_modules/@types/range-parser": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.5.tgz", - "integrity": "sha512-xrO9OoVPqFuYyR/loIHjnbvvyRZREYKLjxV4+dY6v3FQR3stQ9ZxIGkaclF7YhI9hfjpuTbu14hZEy94qKLtOA==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.6.tgz", + "integrity": "sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA==" }, "node_modules/@types/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.2.tgz", - "integrity": "sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw==", + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.3.tgz", + "integrity": "sha512-/7fKxvKUoETxjFUsuFlPB9YndePpxxRAOfGC/yJdc9kTjTeP5kRCTzfnE8kPUKCeyiyIZu0YQ76s50hCedI1ug==", "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "node_modules/@types/serve-static": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.3.tgz", - "integrity": "sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.4.tgz", + "integrity": "sha512-aqqNfs1XTF0HDrFdlY//+SGUxmdSUbjeRXb5iaZc3x0/vMbYmdw9qvOgHWOyyLFxSSRnUuP5+724zBgfw8/WAw==", "dependencies": { "@types/http-errors": "*", "@types/mime": "*", @@ -1240,9 +1265,9 @@ } }, "node_modules/@types/stream-to-array": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@types/stream-to-array/-/stream-to-array-2.3.1.tgz", - "integrity": "sha512-OqV/DIumEm5pT+m4LYGpDFRRLZ0VJRvrz58C8q8rjLGVgP5gRHxThG8eLZfhmK3GVAq9iq3eSvZ0vkZJ5ZH/Pg==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/stream-to-array/-/stream-to-array-2.3.2.tgz", + "integrity": "sha512-odC06lSyrPTJWwsmMC485nv3TBe8XlVucZKSA4DTQKWnuKgzy39txHlZeBNL/riOjREt2EF0BW3gFeoI225D/Q==", "dev": true, "dependencies": { "@types/node": "*" @@ -1564,9 +1589,9 @@ } }, "node_modules/aws-sdk": { - "version": "2.1467.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1467.0.tgz", - "integrity": "sha512-XJNbV2ORQB6XanyBLPJBjvm6axWlblFdyFHa+ZaUK4Kp3cZBggy53+0PMxS3bAGJKcP6h2pZQio9xZMCoebAKQ==", + "version": "2.1480.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1480.0.tgz", + "integrity": "sha512-4VwmhifDT7M/xHcX7Vou/6Gil2s/1oAY4aTJbmkfVNY4kGylYaRiwm536DuSHNAYNxakyFA2yzkF7eFXG+8tuA==", "dependencies": { "buffer": "4.9.2", "events": "1.1.1", @@ -1886,12 +1911,13 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1925,9 +1951,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001541", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001541.tgz", - "integrity": "sha512-bLOsqxDgTqUBkzxbNlSBt8annkDpQB9NdzdTbO2ooJ+eC/IQcvDspDc058g84ejCelF7vHUx57KIOjEecOHXaw==", + "version": "1.0.30001554", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001554.tgz", + "integrity": "sha512-A2E3U//MBwbJVzebddm1YfNp7Nud5Ip+IPn4BozBmn4KqVX7AvluoIDFWjsv5OkGnKUXQVmMSoMKLa3ScCblcQ==", "funding": [ { "type": "opencollective", @@ -2518,6 +2544,19 @@ "node": ">=4.0.0" } }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -2646,9 +2685,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.537", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.537.tgz", - "integrity": "sha512-W1+g9qs9hviII0HAwOdehGYkr+zt7KKdmCcJcjH0mYg6oL8+ioT3Skjmt7BLoAQqXhjf40AXd+HlR4oAWMlXjA==" + "version": "1.4.566", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.566.tgz", + "integrity": "sha512-mv+fAy27uOmTVlUULy15U3DVJ+jg+8iyKH1bpwboCRhtDC69GKf1PPTZvEIhCyDr81RFqfxZJYrbgp933a1vtg==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -3043,9 +3082,9 @@ } }, "node_modules/fraction.js": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.6.tgz", - "integrity": "sha512-n2aZ9tNfYDwaHhvFTkhFErqOMIb8uyzSQ+vGJBjZyanAKZVbGUQ1sngfk9FdkBw7G26O7AgNjLcecLffD1c7eg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", "engines": { "node": "*" }, @@ -3126,9 +3165,12 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/gauge": { "version": "3.0.2", @@ -3164,14 +3206,14 @@ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" }, "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3250,35 +3292,6 @@ "node": ">=4" } }, - "node_modules/google-fonts-complete": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/google-fonts-complete/-/google-fonts-complete-2.1.1.tgz", - "integrity": "sha512-6e7jXyadmW4iHrrmYitcsoyVpcymjndBsgXLeo0XXXbAqU9xhM06OxxJAiPqSrp9Xn2bvBueOTe091lwkKVc1g==", - "dependencies": { - "postcss": "^7.0.18" - } - }, - "node_modules/google-fonts-complete/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/google-fonts-complete/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -3295,17 +3308,6 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3314,6 +3316,17 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", @@ -3355,6 +3368,17 @@ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/helmet": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/helmet/-/helmet-7.0.0.tgz", @@ -3510,11 +3534,11 @@ } }, "node_modules/is-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4122,9 +4146,9 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "node_modules/node-abi": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.47.0.tgz", - "integrity": "sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A==", + "version": "3.51.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.51.0.tgz", + "integrity": "sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA==", "dependencies": { "semver": "^7.3.5" }, @@ -4349,9 +4373,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5508,9 +5532,9 @@ "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==" }, "node_modules/resolve": { - "version": "1.22.6", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", - "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -5686,6 +5710,20 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -5836,14 +5874,6 @@ "is-arrayish": "^0.3.1" } }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -6079,19 +6109,19 @@ } }, "node_modules/tailwindcss": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz", - "integrity": "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.5.tgz", + "integrity": "sha512-5SEZU4J7pxZgSkv7FP1zY8i2TIAOooNZ1e/OGtxIEv6GltpoiXUqWvLy89+a10qYTB1N5Ifkuw9lqQkN9sscvA==", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.5.3", "didyoumean": "^1.2.2", "dlv": "^1.1.3", - "fast-glob": "^3.2.12", + "fast-glob": "^3.3.0", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "jiti": "^1.18.2", + "jiti": "^1.19.1", "lilconfig": "^2.1.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", @@ -6472,12 +6502,12 @@ "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" }, "node_modules/which-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", "dependencies": { "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "call-bind": "^1.0.4", "for-each": "^0.3.3", "gopd": "^1.0.1", "has-tostringtag": "^1.0.0" @@ -6651,9 +6681,9 @@ "peer": true }, "node_modules/yaml": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz", - "integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz", + "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==", "engines": { "node": ">= 14" } From 75e56ccafc587b19ac410d30e3c348710ed0c997 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 25 Oct 2023 10:27:38 -0600 Subject: [PATCH 52/57] build: remove submodules (& old frontend injection) --- package-lock.json | 518 ---------------------------------------------- package.json | 1 - src/ass.ts | 3 +- 3 files changed, 1 insertion(+), 521 deletions(-) diff --git a/package-lock.json b/package-lock.json index b8d0c5f..b00b4d4 100755 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,6 @@ "sanitize-filename": "^1.6.3", "sharp": "^0.32.6", "stream-to-array": "^2.3.0", - "submodule": "^1.2.1", "tailwindcss": "^3.3.3", "typescript": "^4.9.5", "uuid": "^8.3.2" @@ -1923,14 +1922,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } - }, "node_modules/camelcase-css": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", @@ -2073,63 +2064,6 @@ "node": ">=10" } }, - "node_modules/cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dependencies": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "engines": { - "node": ">=4" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", @@ -2294,29 +2228,6 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, - "node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/crypto-random-string": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-3.3.1.tgz", @@ -2514,14 +2425,6 @@ } } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/decompress-response": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", @@ -2774,23 +2677,6 @@ "node": ">=0.4.x" } }, - "node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/exif-parser": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", @@ -3011,17 +2897,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/follow-redirects": { "version": "1.15.3", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", @@ -3200,11 +3075,6 @@ "node": ">=6.9.0" } }, - "node_modules/get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" - }, "node_modules/get-intrinsic": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", @@ -3219,17 +3089,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/gifwrap": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.4.tgz", @@ -3475,14 +3334,6 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, - "node_modules/invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "engines": { - "node": ">=4" - } - }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -3646,14 +3497,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-ttf": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/is-ttf/-/is-ttf-0.2.2.tgz", @@ -3700,11 +3543,6 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -3790,17 +3628,6 @@ "promise": "^7.0.1" } }, - "node_modules/lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dependencies": { - "invert-kv": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", @@ -3829,18 +3656,6 @@ "xtend": "^4.0.0" } }, - "node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -3887,17 +3702,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dependencies": { - "p-defer": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/map-values": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-values/-/map-values-1.0.1.tgz", @@ -3916,19 +3720,6 @@ "node": ">= 0.6" } }, - "node_modules/mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dependencies": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -3992,14 +3783,6 @@ "node": ">= 0.6" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, "node_modules/mimic-response": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", @@ -4140,11 +3923,6 @@ "node": ">= 0.6" } }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, "node_modules/node-abi": { "version": "3.51.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.51.0.tgz", @@ -4310,17 +4088,6 @@ "node": ">=0.10.0" } }, - "node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/npmlog": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", @@ -4343,14 +4110,6 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -4404,76 +4163,6 @@ "wrappy": "1" } }, - "node_modules/os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dependencies": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "engines": { - "node": ">=4" - } - }, - "node_modules/p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -4528,14 +4217,6 @@ "node": ">= 0.8" } }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "engines": { - "node": ">=4" - } - }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -4544,14 +4225,6 @@ "node": ">=0.10.0" } }, - "node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "engines": { - "node": ">=4" - } - }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -5518,19 +5191,6 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==" - }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -5786,25 +5446,6 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, - "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -5960,14 +5601,6 @@ "node": ">=8" } }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -6007,14 +5640,6 @@ "postcss": "^8.2.15" } }, - "node_modules/submodule": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/submodule/-/submodule-1.2.1.tgz", - "integrity": "sha512-taovk+A2xG9rLKKxeqVVg51Ys3uThSZBZwsz/lWSFTZfIQob9EwO66bbrzy9zLQ+YZe+u6mOM/Y+7FlwGMnyoA==", - "dependencies": { - "yargs": "^12.0.1" - } - }, "node_modules/sucrase": { "version": "3.34.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", @@ -6485,22 +6110,6 @@ "webidl-conversions": "^3.0.0" } }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" - }, "node_modules/which-typed-array": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", @@ -6565,61 +6174,6 @@ "node": ">= 10.0.0" } }, - "node_modules/wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -6669,11 +6223,6 @@ "node": ">=0.4" } }, - "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -6687,73 +6236,6 @@ "engines": { "node": ">= 14" } - }, - "node_modules/yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dependencies": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } - }, - "node_modules/yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "engines": { - "node": ">=4" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } } } } diff --git a/package.json b/package.json index 4fbdbaa..badde4a 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,6 @@ "sanitize-filename": "^1.6.3", "sharp": "^0.32.6", "stream-to-array": "^2.3.0", - "submodule": "^1.2.1", "tailwindcss": "^3.3.3", "typescript": "^4.9.5", "uuid": "^8.3.2" diff --git a/src/ass.ts b/src/ass.ts index 14f5e4b..c03f9dd 100644 --- a/src/ass.ts +++ b/src/ass.ts @@ -87,8 +87,7 @@ app.get('/', (req, res, next) => res.redirect(homepage)) // Set up custom frontend -const ASS_FRONTEND = fs.existsSync(path(`./${frontendName}/package.json`)) ? (require('submodule'), require(`../${frontendName}`)) : { enabled: false }; -ASS_FRONTEND.enabled && app.use(ASS_FRONTEND.endpoint, ASS_FRONTEND.router); // skipcq: JS-0093 +const ASS_FRONTEND = { enabled: false }; // ! Disabled in 0.14.7 // Upload router (has to come after custom frontends as express-busboy interferes with all POST calls) app.use('/', ROUTERS.upload); From b8b9846aafc2db662aec6a7deaa918d0ec3ae1c7 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 25 Oct 2023 10:29:43 -0600 Subject: [PATCH 53/57] fix: forgot to further disable stuff --- src/ass.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ass.ts b/src/ass.ts index c03f9dd..e1959fd 100644 --- a/src/ass.ts +++ b/src/ass.ts @@ -126,7 +126,7 @@ app.use((err: ErrWrap, _req: Request, res: Response) => { .info('Users', `${users.length}`) .info('Files', `${data().size}`) .info('Data engine', data().name, data().type) - .info('Frontend', ASS_FRONTEND.enabled ? ASS_FRONTEND.brand : 'disabled', `${ASS_FRONTEND.enabled ? `${getTrueHttp()}${getTrueDomain()}${ASS_FRONTEND.endpoint}` : ''}`) + .info('Frontend', 'disabled') .info('Custom index', ASS_INDEX ?? 'disabled') .blank() .callback(() => app.listen(port, host, () => log.success('Ready for uploads', `Storing resources ${s3enabled ? 'in S3' : 'on disk'}`))); From f4febd0e0d78513fe7dc6236f48476196f3f170d Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 25 Oct 2023 11:01:06 -0600 Subject: [PATCH 54/57] build: update explicit packages --- package-lock.json | 4 ++-- package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index b00b4d4..0a83f09 100755 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,10 @@ "version": "0.14.6", "license": "ISC", "dependencies": { - "@tinycreek/postcss-font-magician": "^4.1.0", + "@tinycreek/postcss-font-magician": "^4.2.0", "@tsconfig/node16": "^1.0.1", "@tycrek/discord-hookr": "^0.1.0", - "@tycrek/express-postcss": "^0.4.0", + "@tycrek/express-postcss": "^0.4.1", "@tycrek/joint": "^1.0.0-1", "@tycrek/log": "^0.7.1", "@tycrek/papito": "^0.3.4", diff --git a/package.json b/package.json index badde4a..1c40cdd 100644 --- a/package.json +++ b/package.json @@ -42,10 +42,10 @@ "url": "https://patreon.com/tycrek" }, "dependencies": { - "@tinycreek/postcss-font-magician": "^4.1.0", + "@tinycreek/postcss-font-magician": "^4.2.0", "@tsconfig/node16": "^1.0.1", "@tycrek/discord-hookr": "^0.1.0", - "@tycrek/express-postcss": "^0.4.0", + "@tycrek/express-postcss": "^0.4.1", "@tycrek/joint": "^1.0.0-1", "@tycrek/log": "^0.7.1", "@tycrek/papito": "^0.3.4", From 61af1bb5351e92a9cee9a62dfaacaf148e3becda Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 25 Oct 2023 11:01:31 -0600 Subject: [PATCH 55/57] =?UTF-8?q?=F0=9F=8D=91=200.14.7=20=F0=9F=8D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0a83f09..64360a1 100755 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ass", - "version": "0.14.6", + "version": "0.14.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ass", - "version": "0.14.6", + "version": "0.14.7", "license": "ISC", "dependencies": { "@tinycreek/postcss-font-magician": "^4.2.0", diff --git a/package.json b/package.json index 1c40cdd..6418220 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ass", - "version": "0.14.6", + "version": "0.14.7", "description": "The simple self-hosted ShareX server", "main": "ass.js", "engines": { From 7bd08debe61a55a8aa932d4aec79627ba0a0ddc4 Mon Sep 17 00:00:00 2001 From: xwashere Date: Thu, 26 Oct 2023 10:24:05 -0400 Subject: [PATCH 56/57] fix: oh god oh fuck oh god oh no oh cherry pick from xutils/dev/0.15.0 --- backend/ratelimit.ts | 17 +++++++++++------ backend/routers/api.ts | 11 ++++++++--- backend/routers/index.ts | 2 +- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/backend/ratelimit.ts b/backend/ratelimit.ts index 0706ade..7e6a31d 100644 --- a/backend/ratelimit.ts +++ b/backend/ratelimit.ts @@ -7,12 +7,7 @@ import { rateLimit } from 'express-rate-limit'; */ const rateLimiterGroups = new Map void>(); -/** - * creates middleware for rate limiting - */ -export const rateLimiterMiddleware = (group: string, config: EndpointRateLimitConfiguration | undefined): (req: Request, res: Response, next: NextFunction) => void => { - if (rateLimiterGroups.has(group)) return rateLimiterGroups.get(group)!; - +export const setRateLimiter = (group: string, config: EndpointRateLimitConfiguration | undefined): (req: Request, res: Response, next: NextFunction) => void => { if (config == null) { // config might be null if the user doesnt want a rate limit rateLimiterGroups.set(group, (req, res, next) => { next(); @@ -38,4 +33,14 @@ export const rateLimiterMiddleware = (group: string, config: EndpointRateLimitCo return rateLimiterGroups.get(group)!; } +} +/** + * creates middleware for rate limiting + */ +export const rateLimiterMiddleware = (group: string, config: EndpointRateLimitConfiguration | undefined): (req: Request, res: Response, next: NextFunction) => void => { + if (rateLimiterGroups.has(group)) setRateLimiter(group, config); + + return (req, res, next) => { + return rateLimiterGroups.get(group)!(req, res, next); + }; }; \ No newline at end of file diff --git a/backend/routers/api.ts b/backend/routers/api.ts index 3ef56db..2117bcd 100644 --- a/backend/routers/api.ts +++ b/backend/routers/api.ts @@ -8,7 +8,7 @@ import { log } from '../log'; import { nanoid } from '../generators'; import { UserConfig } from '../UserConfig'; import { MySql } from '../sql/mysql'; -import { rateLimiterMiddleware } from '../ratelimit'; +import { rateLimiterMiddleware, setRateLimiter } from '../ratelimit'; const router = Router({ caseSensitive: true }); @@ -30,6 +30,11 @@ router.post('/setup', BodyParserJson(), async (req, res) => { if (UserConfig.config.sql?.mySql != null) await Promise.all([MySql.configure(), data.setDataModeToSql()]); + // set rate limits + if (UserConfig.config.rateLimit?.api) setRateLimiter('api', UserConfig.config.rateLimit.api); + if (UserConfig.config.rateLimit?.login) setRateLimiter('login', UserConfig.config.rateLimit.login); + if (UserConfig.config.rateLimit?.upload) setRateLimiter('upload', UserConfig.config.rateLimit.upload); + log.success('Setup', 'completed'); return res.json({ success: true }); @@ -39,7 +44,7 @@ router.post('/setup', BodyParserJson(), async (req, res) => { }); // User login -router.post('/login', rateLimiterMiddleware('login', UserConfig.config.rateLimit?.login), BodyParserJson(), (req, res) => { +router.post('/login', rateLimiterMiddleware('login', UserConfig.config?.rateLimit?.login), BodyParserJson(), (req, res) => { const { username, password } = req.body; data.getAll('users') @@ -69,7 +74,7 @@ router.post('/login', rateLimiterMiddleware('login', UserConfig.config.rateLimit }); // todo: authenticate API endpoints -router.post('/user', rateLimiterMiddleware('api', UserConfig.config.rateLimit?.api), BodyParserJson(), async (req, res) => { +router.post('/user', rateLimiterMiddleware('api', UserConfig.config?.rateLimit?.api), BodyParserJson(), async (req, res) => { if (!UserConfig.ready) return res.status(409).json({ success: false, message: 'User config not ready' }); diff --git a/backend/routers/index.ts b/backend/routers/index.ts index e49df5e..eed8d13 100644 --- a/backend/routers/index.ts +++ b/backend/routers/index.ts @@ -30,7 +30,7 @@ bb.extend(router, { router.get('/', (req, res) => UserConfig.ready ? res.render('index', { version: App.pkgVersion }) : res.redirect('/setup')); // Upload flow -router.post('/', rateLimiterMiddleware("upload", UserConfig.config.rateLimit?.upload), async (req, res) => { +router.post('/', rateLimiterMiddleware("upload", UserConfig.config?.rateLimit?.upload), async (req, res) => { // Check user config if (!UserConfig.ready) return res.status(500).type('text').send('Configuration missing!'); From a833f8c585fea078b8a6b7c88acfee314d602955 Mon Sep 17 00:00:00 2001 From: xwashere Date: Thu, 26 Oct 2023 10:47:58 -0400 Subject: [PATCH 57/57] fix this --- backend/ratelimit.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/ratelimit.ts b/backend/ratelimit.ts index 7e6a31d..77115f1 100644 --- a/backend/ratelimit.ts +++ b/backend/ratelimit.ts @@ -38,7 +38,7 @@ export const setRateLimiter = (group: string, config: EndpointRateLimitConfigura * creates middleware for rate limiting */ export const rateLimiterMiddleware = (group: string, config: EndpointRateLimitConfiguration | undefined): (req: Request, res: Response, next: NextFunction) => void => { - if (rateLimiterGroups.has(group)) setRateLimiter(group, config); + if (!rateLimiterGroups.has(group)) setRateLimiter(group, config); return (req, res, next) => { return rateLimiterGroups.get(group)!(req, res, next);