diff --git a/server/poetry.lock b/server/poetry.lock index b69f717a..1d9882ea 100644 --- a/server/poetry.lock +++ b/server/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aioboto3" @@ -890,63 +890,52 @@ cron = ["capturer (>=2.4)"] [[package]] name = "coverage" -version = "7.3.2" +version = "6.4" description = "Code coverage measurement for Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "coverage-7.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf"}, - {file = "coverage-7.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda"}, - {file = "coverage-7.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a"}, - {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c"}, - {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f"}, - {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6"}, - {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148"}, - {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9"}, - {file = "coverage-7.3.2-cp310-cp310-win32.whl", hash = "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f"}, - {file = "coverage-7.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611"}, - {file = "coverage-7.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c"}, - {file = "coverage-7.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074"}, - {file = "coverage-7.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a"}, - {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3"}, - {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a"}, - {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1"}, - {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c"}, - {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312"}, - {file = "coverage-7.3.2-cp311-cp311-win32.whl", hash = "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640"}, - {file = "coverage-7.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2"}, - {file = "coverage-7.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836"}, - {file = "coverage-7.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63"}, - {file = "coverage-7.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216"}, - {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4"}, - {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf"}, - {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf"}, - {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84"}, - {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a"}, - {file = "coverage-7.3.2-cp312-cp312-win32.whl", hash = "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb"}, - {file = "coverage-7.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed"}, - {file = "coverage-7.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738"}, - {file = "coverage-7.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2"}, - {file = "coverage-7.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2"}, - {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c"}, - {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9"}, - {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82"}, - {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901"}, - {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76"}, - {file = "coverage-7.3.2-cp38-cp38-win32.whl", hash = "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92"}, - {file = "coverage-7.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a"}, - {file = "coverage-7.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce"}, - {file = "coverage-7.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9"}, - {file = "coverage-7.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f"}, - {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25"}, - {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9"}, - {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6"}, - {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc"}, - {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083"}, - {file = "coverage-7.3.2-cp39-cp39-win32.whl", hash = "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce"}, - {file = "coverage-7.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f"}, - {file = "coverage-7.3.2-pp38.pp39.pp310-none-any.whl", hash = "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637"}, - {file = "coverage-7.3.2.tar.gz", hash = "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef"}, + {file = "coverage-6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:50ed480b798febce113709846b11f5d5ed1e529c88d8ae92f707806c50297abf"}, + {file = "coverage-6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:26f8f92699756cb7af2b30720de0c5bb8d028e923a95b6d0c891088025a1ac8f"}, + {file = "coverage-6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60c2147921da7f4d2d04f570e1838db32b95c5509d248f3fe6417e91437eaf41"}, + {file = "coverage-6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:750e13834b597eeb8ae6e72aa58d1d831b96beec5ad1d04479ae3772373a8088"}, + {file = "coverage-6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af5b9ee0fc146e907aa0f5fb858c3b3da9199d78b7bb2c9973d95550bd40f701"}, + {file = "coverage-6.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a022394996419142b33a0cf7274cb444c01d2bb123727c4bb0b9acabcb515dea"}, + {file = "coverage-6.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5a78cf2c43b13aa6b56003707c5203f28585944c277c1f3f109c7b041b16bd39"}, + {file = "coverage-6.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9229d074e097f21dfe0643d9d0140ee7433814b3f0fc3706b4abffd1e3038632"}, + {file = "coverage-6.4-cp310-cp310-win32.whl", hash = "sha256:fb45fe08e1abc64eb836d187b20a59172053999823f7f6ef4f18a819c44ba16f"}, + {file = "coverage-6.4-cp310-cp310-win_amd64.whl", hash = "sha256:3cfd07c5889ddb96a401449109a8b97a165be9d67077df6802f59708bfb07720"}, + {file = "coverage-6.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:03014a74023abaf5a591eeeaf1ac66a73d54eba178ff4cb1fa0c0a44aae70383"}, + {file = "coverage-6.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c82f2cd69c71698152e943f4a5a6b83a3ab1db73b88f6e769fabc86074c3b08"}, + {file = "coverage-6.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b546cf2b1974ddc2cb222a109b37c6ed1778b9be7e6b0c0bc0cf0438d9e45a6"}, + {file = "coverage-6.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc173f1ce9ffb16b299f51c9ce53f66a62f4d975abe5640e976904066f3c835d"}, + {file = "coverage-6.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c53ad261dfc8695062fc8811ac7c162bd6096a05a19f26097f411bdf5747aee7"}, + {file = "coverage-6.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:eef5292b60b6de753d6e7f2d128d5841c7915fb1e3321c3a1fe6acfe76c38052"}, + {file = "coverage-6.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:543e172ce4c0de533fa892034cce260467b213c0ea8e39da2f65f9a477425211"}, + {file = "coverage-6.4-cp37-cp37m-win32.whl", hash = "sha256:00c8544510f3c98476bbd58201ac2b150ffbcce46a8c3e4fb89ebf01998f806a"}, + {file = "coverage-6.4-cp37-cp37m-win_amd64.whl", hash = "sha256:b84ab65444dcc68d761e95d4d70f3cfd347ceca5a029f2ffec37d4f124f61311"}, + {file = "coverage-6.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d548edacbf16a8276af13063a2b0669d58bbcfca7c55a255f84aac2870786a61"}, + {file = "coverage-6.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:033ebec282793bd9eb988d0271c211e58442c31077976c19c442e24d827d356f"}, + {file = "coverage-6.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:742fb8b43835078dd7496c3c25a1ec8d15351df49fb0037bffb4754291ef30ce"}, + {file = "coverage-6.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d55fae115ef9f67934e9f1103c9ba826b4c690e4c5bcf94482b8b2398311bf9c"}, + {file = "coverage-6.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cd698341626f3c77784858427bad0cdd54a713115b423d22ac83a28303d1d95"}, + {file = "coverage-6.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:62d382f7d77eeeaff14b30516b17bcbe80f645f5cf02bb755baac376591c653c"}, + {file = "coverage-6.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:016d7f5cf1c8c84f533a3c1f8f36126fbe00b2ec0ccca47cc5731c3723d327c6"}, + {file = "coverage-6.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:69432946f154c6add0e9ede03cc43b96e2ef2733110a77444823c053b1ff5166"}, + {file = "coverage-6.4-cp38-cp38-win32.whl", hash = "sha256:83bd142cdec5e4a5c4ca1d4ff6fa807d28460f9db919f9f6a31babaaa8b88426"}, + {file = "coverage-6.4-cp38-cp38-win_amd64.whl", hash = "sha256:4002f9e8c1f286e986fe96ec58742b93484195defc01d5cc7809b8f7acb5ece3"}, + {file = "coverage-6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e4f52c272fdc82e7c65ff3f17a7179bc5f710ebc8ce8a5cadac81215e8326740"}, + {file = "coverage-6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b5578efe4038be02d76c344007b13119b2b20acd009a88dde8adec2de4f630b5"}, + {file = "coverage-6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8099ea680201c2221f8468c372198ceba9338a5fec0e940111962b03b3f716a"}, + {file = "coverage-6.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a00441f5ea4504f5abbc047589d09e0dc33eb447dc45a1a527c8b74bfdd32c65"}, + {file = "coverage-6.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e76bd16f0e31bc2b07e0fb1379551fcd40daf8cdf7e24f31a29e442878a827c"}, + {file = "coverage-6.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8d2e80dd3438e93b19e1223a9850fa65425e77f2607a364b6fd134fcd52dc9df"}, + {file = "coverage-6.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:341e9c2008c481c5c72d0e0dbf64980a4b2238631a7f9780b0fe2e95755fb018"}, + {file = "coverage-6.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:21e6686a95025927775ac501e74f5940cdf6fe052292f3a3f7349b0abae6d00f"}, + {file = "coverage-6.4-cp39-cp39-win32.whl", hash = "sha256:968ed5407f9460bd5a591cefd1388cc00a8f5099de9e76234655ae48cfdbe2c3"}, + {file = "coverage-6.4-cp39-cp39-win_amd64.whl", hash = "sha256:e35217031e4b534b09f9b9a5841b9344a30a6357627761d4218818b865d45055"}, + {file = "coverage-6.4-pp36.pp37.pp38-none-any.whl", hash = "sha256:e637ae0b7b481905358624ef2e81d7fb0b1af55f5ff99f9ba05442a444b11e45"}, + {file = "coverage-6.4.tar.gz", hash = "sha256:727dafd7f67a6e1cad808dc884bd9c5a2f6ef1f8f6d2f22b37b96cb0080d4f49"}, ] [package.extras] @@ -1169,18 +1158,19 @@ tortoise = ["tortoise-orm (>=0.16.18,<0.21.0)"] [[package]] name = "faster-whisper" -version = "0.10.0" +version = "0.10.1" description = "Faster Whisper transcription with CTranslate2" optional = false python-versions = ">=3.8" files = [ - {file = "faster-whisper-0.10.0.tar.gz", hash = "sha256:591809328b93c8e4594d52097ec6352a270a81fbb7b956254967f28700f7e4da"}, + {file = "faster-whisper-0.10.1.tar.gz", hash = "sha256:48efa06023a2676eaa98254ebfd66ef76fe630918ccf2d02f8d58654ae292675"}, + {file = "faster_whisper-0.10.1-py3-none-any.whl", hash = "sha256:27935ef45598ed53ae954d42e6c696852b4f675daf080cd8d958238136309ff8"}, ] [package.dependencies] av = "==10.*" ctranslate2 = ">=3.22,<4" -huggingface_hub = ">=0.13" +huggingface-hub = ">=0.13" onnxruntime = ">=1.14,<2" tokenizers = ">=0.13,<0.16" @@ -1978,6 +1968,16 @@ files = [ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, @@ -2524,19 +2524,23 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydantic-settings" -version = "2.0.3" +version = "2.2.1" description = "Settings management using Pydantic" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic_settings-2.0.3-py3-none-any.whl", hash = "sha256:ddd907b066622bd67603b75e2ff791875540dc485b7307c4fffc015719da8625"}, - {file = "pydantic_settings-2.0.3.tar.gz", hash = "sha256:962dc3672495aad6ae96a4390fac7e593591e144625e5112d359f8f67fb75945"}, + {file = "pydantic_settings-2.2.1-py3-none-any.whl", hash = "sha256:0235391d26db4d2190cb9b31051c4b46882d28a51533f97440867f012d4da091"}, + {file = "pydantic_settings-2.2.1.tar.gz", hash = "sha256:00b9f6a5e95553590434c0fa01ead0b216c3e10bc54ae02e37f359948643c5ed"}, ] [package.dependencies] -pydantic = ">=2.0.1" +pydantic = ">=2.3.0" python-dotenv = ">=0.21.0" +[package.extras] +toml = ["tomli (>=2.0.1)"] +yaml = ["pyyaml (>=6.0.1)"] + [[package]] name = "pyee" version = "11.0.0" @@ -2904,6 +2908,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2911,8 +2916,16 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2929,6 +2942,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2936,6 +2950,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -3507,6 +3522,7 @@ files = [ {file = "SQLAlchemy-1.4.49-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:03db81b89fe7ef3857b4a00b63dedd632d6183d4ea5a31c5d8a92e000a41fc71"}, {file = "SQLAlchemy-1.4.49-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:95b9df9afd680b7a3b13b38adf6e3a38995da5e162cc7524ef08e3be4e5ed3e1"}, {file = "SQLAlchemy-1.4.49-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a63e43bf3f668c11bb0444ce6e809c1227b8f067ca1068898f3008a273f52b09"}, + {file = "SQLAlchemy-1.4.49-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca46de16650d143a928d10842939dab208e8d8c3a9a8757600cae9b7c579c5cd"}, {file = "SQLAlchemy-1.4.49-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f835c050ebaa4e48b18403bed2c0fda986525896efd76c245bdd4db995e51a4c"}, {file = "SQLAlchemy-1.4.49-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c21b172dfb22e0db303ff6419451f0cac891d2e911bb9fbf8003d717f1bcf91"}, {file = "SQLAlchemy-1.4.49-cp310-cp310-win32.whl", hash = "sha256:5fb1ebdfc8373b5a291485757bd6431de8d7ed42c27439f543c81f6c8febd729"}, @@ -3516,26 +3532,35 @@ files = [ {file = "SQLAlchemy-1.4.49-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5debe7d49b8acf1f3035317e63d9ec8d5e4d904c6e75a2a9246a119f5f2fdf3d"}, {file = "SQLAlchemy-1.4.49-cp311-cp311-win32.whl", hash = "sha256:82b08e82da3756765c2e75f327b9bf6b0f043c9c3925fb95fb51e1567fa4ee87"}, {file = "SQLAlchemy-1.4.49-cp311-cp311-win_amd64.whl", hash = "sha256:171e04eeb5d1c0d96a544caf982621a1711d078dbc5c96f11d6469169bd003f1"}, + {file = "SQLAlchemy-1.4.49-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f23755c384c2969ca2f7667a83f7c5648fcf8b62a3f2bbd883d805454964a800"}, + {file = "SQLAlchemy-1.4.49-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8396e896e08e37032e87e7fbf4a15f431aa878c286dc7f79e616c2feacdb366c"}, + {file = "SQLAlchemy-1.4.49-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66da9627cfcc43bbdebd47bfe0145bb662041472393c03b7802253993b6b7c90"}, + {file = "SQLAlchemy-1.4.49-cp312-cp312-win32.whl", hash = "sha256:9a06e046ffeb8a484279e54bda0a5abfd9675f594a2e38ef3133d7e4d75b6214"}, + {file = "SQLAlchemy-1.4.49-cp312-cp312-win_amd64.whl", hash = "sha256:7cf8b90ad84ad3a45098b1c9f56f2b161601e4670827d6b892ea0e884569bd1d"}, {file = "SQLAlchemy-1.4.49-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:36e58f8c4fe43984384e3fbe6341ac99b6b4e083de2fe838f0fdb91cebe9e9cb"}, {file = "SQLAlchemy-1.4.49-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b31e67ff419013f99ad6f8fc73ee19ea31585e1e9fe773744c0f3ce58c039c30"}, + {file = "SQLAlchemy-1.4.49-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebc22807a7e161c0d8f3da34018ab7c97ef6223578fcdd99b1d3e7ed1100a5db"}, {file = "SQLAlchemy-1.4.49-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c14b29d9e1529f99efd550cd04dbb6db6ba5d690abb96d52de2bff4ed518bc95"}, {file = "SQLAlchemy-1.4.49-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c40f3470e084d31247aea228aa1c39bbc0904c2b9ccbf5d3cfa2ea2dac06f26d"}, {file = "SQLAlchemy-1.4.49-cp36-cp36m-win32.whl", hash = "sha256:706bfa02157b97c136547c406f263e4c6274a7b061b3eb9742915dd774bbc264"}, {file = "SQLAlchemy-1.4.49-cp36-cp36m-win_amd64.whl", hash = "sha256:a7f7b5c07ae5c0cfd24c2db86071fb2a3d947da7bd487e359cc91e67ac1c6d2e"}, {file = "SQLAlchemy-1.4.49-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:4afbbf5ef41ac18e02c8dc1f86c04b22b7a2125f2a030e25bbb4aff31abb224b"}, {file = "SQLAlchemy-1.4.49-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24e300c0c2147484a002b175f4e1361f102e82c345bf263242f0449672a4bccf"}, + {file = "SQLAlchemy-1.4.49-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:393cd06c3b00b57f5421e2133e088df9cabcececcea180327e43b937b5a7caa5"}, {file = "SQLAlchemy-1.4.49-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:201de072b818f8ad55c80d18d1a788729cccf9be6d9dc3b9d8613b053cd4836d"}, {file = "SQLAlchemy-1.4.49-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7653ed6817c710d0c95558232aba799307d14ae084cc9b1f4c389157ec50df5c"}, {file = "SQLAlchemy-1.4.49-cp37-cp37m-win32.whl", hash = "sha256:647e0b309cb4512b1f1b78471fdaf72921b6fa6e750b9f891e09c6e2f0e5326f"}, {file = "SQLAlchemy-1.4.49-cp37-cp37m-win_amd64.whl", hash = "sha256:ab73ed1a05ff539afc4a7f8cf371764cdf79768ecb7d2ec691e3ff89abbc541e"}, {file = "SQLAlchemy-1.4.49-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:37ce517c011560d68f1ffb28af65d7e06f873f191eb3a73af5671e9c3fada08a"}, {file = "SQLAlchemy-1.4.49-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1878ce508edea4a879015ab5215546c444233881301e97ca16fe251e89f1c55"}, + {file = "SQLAlchemy-1.4.49-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95ab792ca493891d7a45a077e35b418f68435efb3e1706cb8155e20e86a9013c"}, {file = "SQLAlchemy-1.4.49-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0e8e608983e6f85d0852ca61f97e521b62e67969e6e640fe6c6b575d4db68557"}, {file = "SQLAlchemy-1.4.49-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ccf956da45290df6e809ea12c54c02ace7f8ff4d765d6d3dfb3655ee876ce58d"}, {file = "SQLAlchemy-1.4.49-cp38-cp38-win32.whl", hash = "sha256:f167c8175ab908ce48bd6550679cc6ea20ae169379e73c7720a28f89e53aa532"}, {file = "SQLAlchemy-1.4.49-cp38-cp38-win_amd64.whl", hash = "sha256:45806315aae81a0c202752558f0df52b42d11dd7ba0097bf71e253b4215f34f4"}, {file = "SQLAlchemy-1.4.49-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:b6d0c4b15d65087738a6e22e0ff461b407533ff65a73b818089efc8eb2b3e1de"}, {file = "SQLAlchemy-1.4.49-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a843e34abfd4c797018fd8d00ffffa99fd5184c421f190b6ca99def4087689bd"}, + {file = "SQLAlchemy-1.4.49-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:738d7321212941ab19ba2acf02a68b8ee64987b248ffa2101630e8fccb549e0d"}, {file = "SQLAlchemy-1.4.49-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1c890421651b45a681181301b3497e4d57c0d01dc001e10438a40e9a9c25ee77"}, {file = "SQLAlchemy-1.4.49-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d26f280b8f0a8f497bc10573849ad6dc62e671d2468826e5c748d04ed9e670d5"}, {file = "SQLAlchemy-1.4.49-cp39-cp39-win32.whl", hash = "sha256:ec2268de67f73b43320383947e74700e95c6770d0c68c4e615e9897e46296294"}, diff --git a/server/reflector/auth/auth_jwt.py b/server/reflector/auth/auth_jwt.py new file mode 100644 index 00000000..ed76d84b --- /dev/null +++ b/server/reflector/auth/auth_jwt.py @@ -0,0 +1,89 @@ +from typing import Annotated, Optional + +from fastapi import Depends, HTTPException +from fastapi.security import OAuth2PasswordBearer +from jose import JWTError, jwt +from pydantic import BaseModel +from reflector.logger import logger +from reflector.settings import settings + +oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token", auto_error=False) + +jwt_public_key = open(f"reflector/auth/jwt/keys/{settings.AUTH_JWT_PUBLIC_KEY}").read() +jwt_algorithm = settings.AUTH_JWT_ALGORITHM +jwt_audience = settings.AUTH_JWT_AUDIENCE + + +class JWTException(Exception): + def __init__(self, status_code: int, detail: str): + self.status_code = status_code + self.detail = detail + + def __str__(self): + return f"" + + +class UserInfo(BaseModel): + sub: str + email: str + + def __getitem__(self, key): + return getattr(self, key) + + +class AccessTokenInfo(BaseModel): + exp: Optional[int] = None + sub: Optional[str] = None + + +class JWTAuth: + def verify_token(self, token: str): + try: + payload = jwt.decode( + token, + jwt_public_key, + algorithms=[jwt_algorithm], + audience=jwt_audience, + ) + return payload + except JWTError as e: + logger.error(f"JWT error: {e}") + raise + + +def authenticated(token: Annotated[str, Depends(oauth2_scheme)]): + if token is None: + raise JWTException(status_code=401, detail="Not authenticated") + return None + + +def current_user( + token: Annotated[Optional[str], Depends(oauth2_scheme)], + jwtauth: JWTAuth = Depends(), +): + if token is None: + raise HTTPException(status_code=401, detail="Not authenticated") + try: + payload = jwtauth.verify_token(token) + sub = payload["sub"] + return UserInfo(sub=sub) + except JWTError as e: + logger.error(f"JWT error: {e}") + raise HTTPException(status_code=401, detail="Invalid authentication") + + +def current_user_optional( + token: Annotated[Optional[str], Depends(oauth2_scheme)], + jwtauth: JWTAuth = Depends(), +): + # we accept no token, but if one is provided, it must be a valid one. + if token is None: + return None + try: + payload = jwtauth.verify_token(token) + sub = payload["sub"] + email = payload["email"] + return UserInfo(sub=sub, email=email) + except JWTError as e: + logger.error(f"JWT error: {e}") + raise HTTPException(status_code=401, detail="Invalid authentication") diff --git a/server/reflector/auth/jwt/keys/authentik.monadical.com_public.pem b/server/reflector/auth/jwt/keys/authentik.monadical.com_public.pem new file mode 100644 index 00000000..19168460 --- /dev/null +++ b/server/reflector/auth/jwt/keys/authentik.monadical.com_public.pem @@ -0,0 +1,14 @@ +-----BEGIN PUBLIC KEY----- +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAknKOuLz60fGurFuKZrzx +8DiDIp9NwVg+NnIN39w5NzVQt0UyRBY1Gw9ZcUe3TLysYELBtqTUVKWpAtHlfXCO +tce4BxWxVW12rJ1x24JoW4Fds9qfiUgxTJMkClVJjrC8Zl4WCPc+y11iCiaGEHd/ +NO7gTXtacXWC20oJXkwGaNrWEYd2oh5Nv3BuLKAOG72s5+w7a58YkdTIW8UqAx1+ +mAFnnwAjNrFXVA8Yy/GxwZhH/i0ZHFsUj/ILwT/GakR0Q7c0QymG8DPlWqiCkAPd +f/T68DOvsMBWFrJzoEPqJDFoNe7bLL6vLscNWDdBME97QJkNzVQi9aC1zrMuczPv +ll91R2pDsq+Idh70pp27wpW2JyjjLkmcOHmnXfqztzgInx3Za0BSeAcHwy3c/SlC +hZZYBwb7rufFLIBv8AunMYZhp3dI9W9QAldtnWGJbRim2a6C+77ZgMyuz/RLRkoY +jM9v3cUFfQMTtq+/GEvOts4sFlXjTSmIbYWSup5xF6nk11tWsUrEotuZs+xgESVi +cYvcjlSQHPIUOSmgnjmxcnhga+SBI63u6a2fhos7q6xz58TpIAY3u9oy/3ijJw4s +pcDkOoO58xQxNT/8X1kVfWEqY1WUOfwd811nslUOEMO+ftawSoUr0vFaZB++cbV4 +WygdqJWrndB+pDqE5f30E5UCAwEAAQ== +-----END PUBLIC KEY----- diff --git a/server/reflector/db/migrate_user.py b/server/reflector/db/migrate_user.py new file mode 100644 index 00000000..507e8f96 --- /dev/null +++ b/server/reflector/db/migrate_user.py @@ -0,0 +1,50 @@ +from reflector.db import database +from reflector.db.meetings import meetings +from reflector.db.rooms import rooms +from reflector.db.transcripts import transcripts + +users_to_migrate = [ + ["123@lifex.pink", "63b727f5-485d-449f-b528-563d779b11ef", None], + ["ana@monadical.com", "1bae2e4d-5c04-49c2-932f-a86266a6ca13", None], + ["cspencer@sprocket.org", "614ed0be-392e-488c-bd19-6a9730fd0e9e", None], + ["daniel.f.lopez.j@gmail.com", "ca9561bd-c989-4a1e-8877-7081cf62ae7f", None], + ["jenalee@monadical.com", "c7c1e79e-b068-4b28-a9f4-29d98b1697ed", None], + ["jennifer@rootandseed.com", "f5321727-7546-4b2b-b69d-095a931ef0c4", None], + ["jose@monadical.com", "221f079c-7ce0-4677-90b7-0359b6315e27", None], + ["labenclayton@gmail.com", "40078cd0-543c-40e4-9c2e-5ce57a686428", None], + ["mathieu@monadical.com", "c7a36151-851e-4afa-9fab-aaca834bfd30", None], + ["michal.flak.96@gmail.com", "3096eb5e-b590-41fc-a0d1-d152c1895402", None], + ["sara@monadical.com", "31ab0cfe-5d2c-4c7a-84de-a29494714c99", None], + ["sara@monadical.com", "b871e5f0-754e-447f-9c3d-19f629f0082b", None], + ["sebastian@monadical.com", "f024f9d0-15d0-480f-8529-43959fc8b639", None], + ["sergey@monadical.com", "5c4798eb-b9ab-4721-a540-bd96fc434156", None], + ["sergey@monadical.com", "9dd8a6b4-247e-48fe-b1fb-4c84dd3c01bc", None], + ["transient.tran@gmail.com", "617ba2d3-09b6-4b1f-a435-a7f41c3ce060", None], +] + + +async def migrate_user(email, user_id): + # if the email match the email in the users_to_migrate list + # reassign all transcripts/rooms/meetings to the new user_id + + user_ids = [user[1] for user in users_to_migrate if user[0] == email] + if not user_ids: + return + + for user_id in user_ids: + query = ( + transcripts.update() + .where(transcripts.c.user_id == user_id) + .values(user_id=user_id) + ) + await database.execute(query) + + query = rooms.update().where(rooms.c.user_id == user_id).values(user_id=user_id) + await database.execute(query) + + query = ( + meetings.update() + .where(meetings.c.user_id == user_id) + .values(user_id=user_id) + ) + await database.execute(query) diff --git a/server/reflector/settings.py b/server/reflector/settings.py index 59cb3f5b..3f571c4d 100644 --- a/server/reflector/settings.py +++ b/server/reflector/settings.py @@ -97,6 +97,11 @@ class Settings(BaseSettings): AUTH_FIEF_CLIENT_ID: str | None = None AUTH_FIEF_CLIENT_SECRET: str | None = None + # User authentication using JWT + AUTH_JWT_ALGORITHM: str = "RS256" + AUTH_JWT_PUBLIC_KEY: str | None = "authentik.monadical.com_public.pem" + AUTH_JWT_AUDIENCE: str | None = None + # API public mode # if set, all anonymous record will be public PUBLIC_MODE: bool = False diff --git a/server/reflector/views/transcripts.py b/server/reflector/views/transcripts.py index 37254b42..4fdc7feb 100644 --- a/server/reflector/views/transcripts.py +++ b/server/reflector/views/transcripts.py @@ -7,6 +7,7 @@ from fastapi_pagination import Page from fastapi_pagination.ext.databases import paginate from jose import jwt from pydantic import BaseModel, Field +from reflector.db.migrate_user import migrate_user from reflector.db.transcripts import ( TranscriptParticipant, TranscriptTopic, @@ -85,6 +86,11 @@ async def transcripts_list( raise HTTPException(status_code=401, detail="Not authenticated") user_id = user["sub"] if user else None + + # for fief to jwt migration, migrate user if needed + if user: + await migrate_user(email=user.get("email"), user_id=user["sub"]) + return await paginate( database, await transcripts_controller.get_all( diff --git a/server/tests/test_transcripts.py b/server/tests/test_transcripts.py index c708d57e..5fac353a 100644 --- a/server/tests/test_transcripts.py +++ b/server/tests/test_transcripts.py @@ -150,8 +150,14 @@ async def authenticated_client(): from reflector.app import app from reflector.auth import current_user, current_user_optional - app.dependency_overrides[current_user] = lambda: {"sub": "randomuserid"} - app.dependency_overrides[current_user_optional] = lambda: {"sub": "randomuserid"} + app.dependency_overrides[current_user] = lambda: { + "sub": "randomuserid", + "email": "test@mail.com", + } + app.dependency_overrides[current_user_optional] = lambda: { + "sub": "randomuserid", + "email": "test@mail.com", + } yield del app.dependency_overrides[current_user] del app.dependency_overrides[current_user_optional] diff --git a/www/.env_template b/www/.env_template index 182b1639..d207c44f 100644 --- a/www/.env_template +++ b/www/.env_template @@ -1,2 +1 @@ -FIEF_CLIENT_SECRET= ZULIP_API_KEY= diff --git a/www/app/(app)/browse/page.tsx b/www/app/(app)/browse/page.tsx index 3c2529fe..dfc658ad 100644 --- a/www/app/(app)/browse/page.tsx +++ b/www/app/(app)/browse/page.tsx @@ -40,7 +40,6 @@ import { } from "@chakra-ui/react"; import { PlusSquareIcon } from "@chakra-ui/icons"; import { ExpandableText } from "../../lib/expandableText"; -// import { useFiefUserinfo } from "@fief/fief/nextjs/react"; export default function TranscriptBrowser() { const [page, setPage] = useState(1); @@ -53,10 +52,6 @@ export default function TranscriptBrowser() { React.useState(); const [deletedItemIds, setDeletedItemIds] = React.useState(); - // Todo: fief add name field to userinfo - // const user = useFiefUserinfo(); - // console.log(user); - useEffect(() => { setDeletedItemIds([]); }, [page, response]); diff --git a/www/app/(app)/transcripts/new/page.tsx b/www/app/(app)/transcripts/new/page.tsx index 62d83ee9..7b8eb2c2 100644 --- a/www/app/(app)/transcripts/new/page.tsx +++ b/www/app/(app)/transcripts/new/page.tsx @@ -10,19 +10,23 @@ import { useRouter } from "next/navigation"; import useCreateTranscript from "../createTranscript"; import SelectSearch from "react-select-search"; import { supportedLanguages } from "../../../supportedLanguages"; -import { useFiefIsAuthenticated } from "@fief/fief/nextjs/react"; +import { useSession } from "next-auth/react"; import { featureEnabled } from "../../../domainContext"; import { Button, Text } from "@chakra-ui/react"; +import { signIn } from "next-auth/react"; +import { Spinner } from "@chakra-ui/react"; const TranscriptCreate = () => { const router = useRouter(); - const isAuthenticated = useFiefIsAuthenticated(); + const { status } = useSession(); + const sessionReady = status !== "loading"; + const isAuthenticated = status === "authenticated"; const requireLogin = featureEnabled("requireLogin"); const [name, setName] = useState(""); const nameChange = (event: React.ChangeEvent) => { setName(event.target.value); }; - const [targetLanguage, setTargetLanguage] = useState(); + const [targetLanguage, setTargetLanguage] = useState("NOTRANSLATION"); const onLanguageChange = (newval) => { (!newval || typeof newval === "string") && setTargetLanguage(newval); @@ -33,16 +37,21 @@ const TranscriptCreate = () => { const [loadingRecord, setLoadingRecord] = useState(false); const [loadingUpload, setLoadingUpload] = useState(false); + const getTargetLanguage = () => { + if (targetLanguage === "NOTRANSLATION") return; + return targetLanguage; + }; + const send = () => { if (loadingRecord || createTranscript.loading || permissionDenied) return; setLoadingRecord(true); - createTranscript.create({ name, target_language: targetLanguage }); + createTranscript.create({ name, target_language: getTargetLanguage() }); }; const uploadFile = () => { if (loadingUpload || createTranscript.loading || permissionDenied) return; setLoadingUpload(true); - createTranscript.create({ name, target_language: targetLanguage }); + createTranscript.create({ name, target_language: getTargetLanguage() }); }; useEffect(() => { @@ -87,10 +96,12 @@ const TranscriptCreate = () => {
- {requireLogin && !isAuthenticated ? ( + {!sessionReady ? ( + + ) : requireLogin && !isAuthenticated ? ( diff --git a/www/app/(app)/transcripts/shareAndPrivacy.tsx b/www/app/(app)/transcripts/shareAndPrivacy.tsx index 5525686a..67e8827c 100644 --- a/www/app/(app)/transcripts/shareAndPrivacy.tsx +++ b/www/app/(app)/transcripts/shareAndPrivacy.tsx @@ -15,8 +15,9 @@ import { Text, } from "@chakra-ui/react"; import { FaShare } from "react-icons/fa"; -import { useFiefUserinfo } from "@fief/fief/build/esm/nextjs/react"; import useApi from "../../lib/useApi"; +import { useSession } from "next-auth/react"; +import { CustomSession } from "../../lib/types"; import { Select } from "chakra-react-select"; import ShareLink from "./shareLink"; import ShareCopy from "./shareCopy"; @@ -69,7 +70,9 @@ export default function ShareAndPrivacy(props: ShareAndPrivacyProps) { setShareLoading(false); }; - const userId = useFiefUserinfo()?.sub; + const { data: session } = useSession(); + const customSession = session as CustomSession; + const userId = customSession?.user?.id; useEffect(() => { setIsOwner(!!(requireLogin && userId === props.transcriptResponse.user_id)); diff --git a/www/app/(app)/transcripts/useMp3.ts b/www/app/(app)/transcripts/useMp3.ts index b8c0a566..79f5b972 100644 --- a/www/app/(app)/transcripts/useMp3.ts +++ b/www/app/(app)/transcripts/useMp3.ts @@ -1,7 +1,6 @@ import { useContext, useEffect, useState } from "react"; import { DomainContext } from "../../domainContext"; import getApi from "../../lib/useApi"; -import { useFiefAccessTokenInfo } from "@fief/fief/build/esm/nextjs/react"; export type Mp3Response = { media: HTMLMediaElement | null; @@ -15,7 +14,8 @@ const useMp3 = (id: string, waiting?: boolean): Mp3Response => { const [loading, setLoading] = useState(false); const api = getApi(); const { api_url } = useContext(DomainContext); - const accessTokenInfo = useFiefAccessTokenInfo(); + const accessTokenInfo = api?.httpRequest?.config?.TOKEN; + const [serviceWorker, setServiceWorker] = useState(null); @@ -37,7 +37,7 @@ const useMp3 = (id: string, waiting?: boolean): Mp3Response => { // Send the token to the service worker navigator.serviceWorker.controller.postMessage({ type: "SET_AUTH_TOKEN", - token: accessTokenInfo?.access_token, + token: accessTokenInfo, }); }, [navigator.serviceWorker, !serviceWorker, accessTokenInfo]); diff --git a/www/app/(auth)/fiefWrapper.tsx b/www/app/(auth)/fiefWrapper.tsx deleted file mode 100644 index bb38f5ee..00000000 --- a/www/app/(auth)/fiefWrapper.tsx +++ /dev/null @@ -1,18 +0,0 @@ -"use client"; - -import { FiefAuthProvider } from "@fief/fief/nextjs/react"; -import { createContext } from "react"; - -export const CookieContext = createContext<{ hasAuthCookie: boolean }>({ - hasAuthCookie: false, -}); - -export default function FiefWrapper({ children, hasAuthCookie }) { - return ( - - - {children} - - - ); -} diff --git a/www/app/(auth)/userInfo.tsx b/www/app/(auth)/userInfo.tsx index 76e55acb..a2958371 100644 --- a/www/app/(auth)/userInfo.tsx +++ b/www/app/(auth)/userInfo.tsx @@ -1,20 +1,35 @@ "use client"; -import { useFiefIsAuthenticated } from "@fief/fief/nextjs/react"; +import { useSession, signOut, signIn } from "next-auth/react"; +import { Spinner } from "@chakra-ui/react"; import Link from "next/link"; export default function UserInfo() { - const isAuthenticated = useFiefIsAuthenticated(); + const { status } = useSession(); + const sessionReady = status !== "loading"; + const isAuthenticated = status === "authenticated"; - return !isAuthenticated ? ( + return !sessionReady ? ( + + ) : !isAuthenticated ? ( - + signIn("authentik")} + className="outline-none" + prefetch={false} + > Log in ) : ( - + signOut({ callbackUrl: "/" })} + className="outline-none" + prefetch={false} + > Log out diff --git a/www/app/[roomName]/page.tsx b/www/app/[roomName]/page.tsx index 9401d433..c2b18f50 100644 --- a/www/app/[roomName]/page.tsx +++ b/www/app/[roomName]/page.tsx @@ -4,7 +4,7 @@ import "@whereby.com/browser-sdk/embed"; import { useCallback, useEffect, useRef } from "react"; import useRoomMeeting from "./useRoomMeeting"; import { useRouter } from "next/navigation"; -import { useFiefIsAuthenticated } from "@fief/fief/build/esm/nextjs/react"; +import { useSession } from "next-auth/react"; export type RoomDetails = { params: { @@ -17,7 +17,9 @@ export default function Room(details: RoomDetails) { const roomName = details.params.roomName; const meeting = useRoomMeeting(roomName); const router = useRouter(); - const isAuthenticated = useFiefIsAuthenticated(); + const { status } = useSession(); + const sessionReady = status !== "loading"; + const isAuthenticated = status === "authenticated"; const roomUrl = meeting?.response?.host_room_url ? meeting?.response?.host_room_url @@ -28,7 +30,7 @@ export default function Room(details: RoomDetails) { }, []); useEffect(() => { - if (!isAuthenticated || !roomUrl) return; + if (!sessionReady || !isAuthenticated || !roomUrl) return; wherebyRef.current?.addEventListener("leave", handleLeave); diff --git a/www/app/api/auth/[...nextauth]/route.ts b/www/app/api/auth/[...nextauth]/route.ts new file mode 100644 index 00000000..915ed04d --- /dev/null +++ b/www/app/api/auth/[...nextauth]/route.ts @@ -0,0 +1,9 @@ +// NextAuth route handler for Authentik +// Refresh rotation has been taken from https://next-auth.js.org/v3/tutorials/refresh-token-rotation even if we are using 4.x + +import NextAuth from "next-auth"; +import { authOptions } from "../../../lib/auth"; + +const handler = NextAuth(authOptions); + +export { handler as GET, handler as POST }; diff --git a/www/app/layout.tsx b/www/app/layout.tsx index ec1c044e..efb3b10d 100644 --- a/www/app/layout.tsx +++ b/www/app/layout.tsx @@ -1,14 +1,12 @@ import "./styles/globals.scss"; import { Poppins } from "next/font/google"; import { Metadata, Viewport } from "next"; -import FiefWrapper from "./(auth)/fiefWrapper"; +import SessionProvider from "./lib/SessionProvider"; import { ErrorProvider } from "./(errors)/errorContext"; import ErrorMessage from "./(errors)/errorMessage"; import { DomainContextProvider } from "./domainContext"; import { getConfig } from "./lib/edgeConfig"; import { ErrorBoundary } from "@sentry/nextjs"; -import { cookies } from "next/dist/client/components/headers"; -import { SESSION_COOKIE_NAME } from "./lib/fief"; import { Providers } from "./providers"; const poppins = Poppins({ subsets: ["latin"], weight: ["200", "400", "600"] }); @@ -67,7 +65,6 @@ export default async function RootLayout({ children: React.ReactNode; }) { const config = await getConfig(); - const hasAuthCookie = !!cookies().get(SESSION_COOKIE_NAME); return ( @@ -76,7 +73,7 @@ export default async function RootLayout({ poppins.className + "h-[100svh] w-[100svw] overflow-hidden relative" } > - + "something went really wrong"

}> @@ -85,7 +82,7 @@ export default async function RootLayout({
-
+ ); diff --git a/www/app/lib/SessionAutoRefresh.tsx b/www/app/lib/SessionAutoRefresh.tsx new file mode 100644 index 00000000..1e230d6c --- /dev/null +++ b/www/app/lib/SessionAutoRefresh.tsx @@ -0,0 +1,36 @@ +/** + * This is a custom hook that automatically refreshes the session when the access token is about to expire. + * When communicating with the reflector API, we need to ensure that the access token is always valid. + * + * We could have implemented that as an interceptor on the API client, but not everything is using the + * API client, or have access to NextJS directly (serviceWorker). + */ +"use client"; + +import { useSession } from "next-auth/react"; +import { useEffect } from "react"; +import { CustomSession } from "./types"; + +export function SessionAutoRefresh({ + children, + refreshInterval = 20 /* seconds */, +}) { + const { data: session, update } = useSession(); + const customSession = session as CustomSession; + const accessTokenExpires = customSession?.accessTokenExpires; + + useEffect(() => { + const interval = setInterval(() => { + if (accessTokenExpires) { + const timeLeft = accessTokenExpires - Date.now(); + if (timeLeft < refreshInterval * 1000) { + update(); + } + } + }, refreshInterval * 1000); + + return () => clearInterval(interval); + }, [accessTokenExpires, refreshInterval, update]); + + return children; +} diff --git a/www/app/lib/SessionProvider.tsx b/www/app/lib/SessionProvider.tsx new file mode 100644 index 00000000..91708774 --- /dev/null +++ b/www/app/lib/SessionProvider.tsx @@ -0,0 +1,11 @@ +"use client"; +import { SessionProvider as SessionProviderNextAuth } from "next-auth/react"; +import { SessionAutoRefresh } from "./SessionAutoRefresh"; + +export default function SessionProvider({ children }) { + return ( + + {children} + + ); +} diff --git a/www/app/lib/auth.ts b/www/app/lib/auth.ts new file mode 100644 index 00000000..b16344bb --- /dev/null +++ b/www/app/lib/auth.ts @@ -0,0 +1,101 @@ +import { AuthOptions } from "next-auth"; +import AuthentikProvider from "next-auth/providers/authentik"; +import { JWT } from "next-auth/jwt"; +import { JWTWithAccessToken, CustomSession } from "./types"; + +const PRETIMEOUT = 60; // seconds before token expires to refresh it + +export const authOptions: AuthOptions = { + providers: [ + AuthentikProvider({ + clientId: process.env.AUTHENTIK_CLIENT_ID as string, + clientSecret: process.env.AUTHENTIK_CLIENT_SECRET as string, + issuer: process.env.AUTHENTIK_ISSUER, + authorization: { + params: { + scope: "openid email profile offline_access", + }, + }, + }), + ], + session: { + strategy: "jwt", + }, + callbacks: { + async jwt({ token, account, user }) { + const extendedToken = token as JWTWithAccessToken; + if (account && user) { + // called only on first login + // XXX account.expires_in used in example is not defined for authentik backend, but expires_at is + const expiresAt = (account.expires_at as number) - PRETIMEOUT; + + return { + ...extendedToken, + accessToken: account.access_token, + accessTokenExpires: expiresAt * 1000, + refreshToken: account.refresh_token, + }; + } + + if (Date.now() < extendedToken.accessTokenExpires) { + return token; + } + + // access token has expired, try to update it + return await refreshAccessToken(token); + }, + async session({ session, token }) { + const extendedToken = token as JWTWithAccessToken; + const customSession = session as CustomSession; + customSession.accessToken = extendedToken.accessToken; + customSession.accessTokenExpires = extendedToken.accessTokenExpires; + customSession.error = extendedToken.error; + customSession.user = { + id: extendedToken.sub, + name: extendedToken.name, + email: extendedToken.email, + }; + return customSession; + }, + }, +}; + +async function refreshAccessToken(token: JWT) { + try { + const url = `${process.env.AUTHENTIK_REFRESH_TOKEN_URL}`; + + const options = { + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + body: new URLSearchParams({ + client_id: process.env.AUTHENTIK_CLIENT_ID as string, + client_secret: process.env.AUTHENTIK_CLIENT_SECRET as string, + grant_type: "refresh_token", + refresh_token: token.refreshToken as string, + }).toString(), + method: "POST", + }; + + const response = await fetch(url, options); + if (!response.ok) { + throw new Error(`Failed to refresh access token: ${response.statusText}`); + } + + const refreshedTokens = await response.json(); + return { + ...token, + accessToken: refreshedTokens.access_token, + accessTokenExpires: + Date.now() + (refreshedTokens.expires_in - PRETIMEOUT) * 1000, + refreshToken: refreshedTokens.refresh_token, + }; + } catch (error) { + console.error("Error refreshing access token", error); + + return { + ...token, + error: "RefreshAccessTokenError", + }; + } +} diff --git a/www/app/lib/fief.ts b/www/app/lib/fief.ts deleted file mode 100644 index 7cf922da..00000000 --- a/www/app/lib/fief.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { Fief, FiefUserInfo } from "@fief/fief"; -import { FiefAuth, IUserInfoCache } from "@fief/fief/nextjs"; -import { getConfig } from "./edgeConfig"; - -export const SESSION_COOKIE_NAME = "reflector-auth"; - -export const fiefClient = new Fief({ - baseURL: process.env.FIEF_URL ?? "", - clientId: process.env.FIEF_CLIENT_ID ?? "", - clientSecret: process.env.FIEF_CLIENT_SECRET ?? "", -}); - -class MemoryUserInfoCache implements IUserInfoCache { - private storage: Record; - - constructor() { - this.storage = {}; - } - - async get(id: string): Promise { - const userinfo = this.storage[id]; - if (userinfo) { - return userinfo; - } - return null; - } - - async set(id: string, userinfo: FiefUserInfo): Promise { - this.storage[id] = userinfo; - } - - async remove(id: string): Promise { - this.storage[id] = undefined; - } - - async clear(): Promise { - this.storage = {}; - } -} - -const FIEF_AUTHS = {} as { [domain: string]: FiefAuth }; - -export const getFiefAuth = async (url: URL) => { - if (FIEF_AUTHS[url.hostname]) { - return FIEF_AUTHS[url.hostname]; - } else { - const config = url && (await getConfig()); - if (config) { - FIEF_AUTHS[url.hostname] = new FiefAuth({ - client: fiefClient, - sessionCookieName: SESSION_COOKIE_NAME, - redirectURI: config.auth_callback_url, - logoutRedirectURI: url.origin, - userInfoCache: new MemoryUserInfoCache(), - }); - return FIEF_AUTHS[url.hostname]; - } else { - throw new Error("Fief intanciation failed"); - } - } -}; - -export const getFiefAuthMiddleware = async (url) => { - const protectedPaths = [ - { - matcher: "/transcripts", - parameters: {}, - }, - { - matcher: "/browse", - parameters: {}, - }, - { - matcher: "/rooms", - parameters: {}, - }, - ]; - return (await getFiefAuth(url))?.middleware(protectedPaths); -}; diff --git a/www/app/lib/types.ts b/www/app/lib/types.ts new file mode 100644 index 00000000..851ee5be --- /dev/null +++ b/www/app/lib/types.ts @@ -0,0 +1,20 @@ +import { Session } from "next-auth"; +import { JWT } from "next-auth/jwt"; + +export interface JWTWithAccessToken extends JWT { + accessToken: string; + accessTokenExpires: number; + refreshToken: string; + error?: string; +} + +export interface CustomSession extends Session { + accessToken: string; + accessTokenExpires: number; + error?: string; + user: { + id?: string; + name?: string | null; + email?: string | null; + }; +} diff --git a/www/app/lib/useApi.ts b/www/app/lib/useApi.ts index 226605a4..b4bd60f4 100644 --- a/www/app/lib/useApi.ts +++ b/www/app/lib/useApi.ts @@ -1,30 +1,40 @@ -import { useFiefAccessTokenInfo } from "@fief/fief/nextjs/react"; +import { useSession, signOut } from "next-auth/react"; import { useContext, useEffect, useState } from "react"; import { DomainContext, featureEnabled } from "../domainContext"; -import { CookieContext } from "../(auth)/fiefWrapper"; import { OpenApi, DefaultService } from "../api"; +import { CustomSession } from "./types"; export default function useApi(): DefaultService | null { - const accessTokenInfo = useFiefAccessTokenInfo(); const api_url = useContext(DomainContext).api_url; - const requireLogin = featureEnabled("requireLogin"); const [api, setApi] = useState(null); - const { hasAuthCookie } = useContext(CookieContext); + const { data: session, status } = useSession(); + const customSession = session as CustomSession; + const accessToken = customSession?.accessToken; if (!api_url) throw new Error("no API URL"); useEffect(() => { - if (hasAuthCookie && requireLogin && !accessTokenInfo) { + if (customSession?.error === "RefreshAccessTokenError") { + signOut(); + } + }, [session]); + + useEffect(() => { + if (status === "loading") { + return; + } + + if (status === "authenticated" && !accessToken) { return; } const openApi = new OpenApi({ BASE: api_url, - TOKEN: accessTokenInfo ? accessTokenInfo?.access_token : undefined, + TOKEN: accessToken, }); setApi(openApi); - }, [!accessTokenInfo, hasAuthCookie]); + }, [accessToken, status]); return api?.default ?? null; } diff --git a/www/app/lib/user.ts b/www/app/lib/user.ts deleted file mode 100644 index 26740e47..00000000 --- a/www/app/lib/user.ts +++ /dev/null @@ -1,21 +0,0 @@ -export async function getCurrentUser(): Promise { - try { - const response = await fetch("/api/current-user"); - - if (!response.ok) { - throw new Error(`HTTP error! Status: ${response.status}`); - } - - const data = await response.json(); - - // Ensure the data structure is as expected - if (data.userinfo && data.access_token_info) { - return data; - } else { - throw new Error("Unexpected data structure"); - } - } catch (error) { - console.error("Error fetching the user data:", error); - throw error; // or you can return an appropriate fallback or error indicator - } -} diff --git a/www/app/supportedLanguages.ts b/www/app/supportedLanguages.ts index 128fa656..431ea718 100644 --- a/www/app/supportedLanguages.ts +++ b/www/app/supportedLanguages.ts @@ -489,6 +489,6 @@ const supportedLanguages: LanguageOption[] = [ }, ]; -supportedLanguages.push({ value: undefined, name: "No Translation" }); +supportedLanguages.push({ value: "NOTRANSLATION", name: "No Translation" }); export { supportedLanguages }; diff --git a/www/middleware.ts b/www/middleware.ts index 94ffc176..8a57ea11 100644 --- a/www/middleware.ts +++ b/www/middleware.ts @@ -1,11 +1,85 @@ +import { withAuth } from "next-auth/middleware"; +import { getConfig } from "./app/lib/edgeConfig"; +import { NextResponse } from "next/server"; + +const LOGIN_REQUIRED_PAGES = [ + "/transcripts/[!new]", + "/browse(.*)", + "/rooms(.*)", +]; + +const PROTECTED_PAGES = new RegExp( + LOGIN_REQUIRED_PAGES.map((page) => `^${page}$`).join("|"), +); + +export const config = { + matcher: [ + "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)", + + // must be a copy of LOGIN_REQUIRED_PAGES + // cannot use anything dynamic (...LOGIN_REQUIRED_PAGES, or .concat(LOGIN_REQUIRED_PAGES)) + // as per https://nextjs.org/docs/messages/invalid-page-config + "/", + "/transcripts(.*)", + "/browse(.*)", + "/rooms(.*)", + ], +}; + +export default withAuth( + async function middleware(request) { + const config = await getConfig(); + const pathname = request.nextUrl.pathname; + + // feature-flags protected paths + if ( + (!config.features.browse && pathname.startsWith("/browse")) || + (!config.features.rooms && pathname.startsWith("/rooms")) + ) { + return NextResponse.redirect(request.nextUrl.origin); + } + }, + { + callbacks: { + async authorized({ req, token }) { + const config = await getConfig(); + + if ( + config.features.requireLogin && + PROTECTED_PAGES.test(req.nextUrl.pathname) + ) { + return !!token; + } + + return true; + }, + }, + }, +); + +/** + import { NextResponse, NextRequest } from "next/server"; -import { getFiefAuthMiddleware } from "./app/lib/fief"; +// import { getFiefAuthMiddleware } from "./app/lib/fief"; +import { getToken } from "next-auth/jwt"; import { getConfig } from "./app/lib/edgeConfig"; +import { authOptions } from "./app/api/auth/[...nextauth]/route"; + export async function middleware(request: NextRequest) { const config = await getConfig(); + console.log( + "---------------------------------------------------------------", + ); + console.log( + "middleware", + "request.nextUrl.pathname", + request.nextUrl.pathname, + ); + console.log("middleware", "config", config); + if ( request.nextUrl.pathname.match( "^/((?!api|_next/static|_next/image|favicon.ico).*)", @@ -17,6 +91,7 @@ export async function middleware(request: NextRequest) { request.nextUrl.pathname.startsWith("/browse")) || (!config.features.rooms && request.nextUrl.pathname.startsWith("/rooms")) ) { + console.log("!! redirecting to", request.nextUrl.origin); return NextResponse.redirect(request.nextUrl.origin); } @@ -29,3 +104,4 @@ export async function middleware(request: NextRequest) { return NextResponse.next(); } +**/ diff --git a/www/package.json b/www/package.json index 84b6a578..e8d10016 100644 --- a/www/package.json +++ b/www/package.json @@ -24,7 +24,6 @@ "@chakra-ui/react-types": "^2.0.6", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@fief/fief": "^0.13.5", "@fortawesome/fontawesome-svg-core": "^6.4.0", "@fortawesome/free-solid-svg-icons": "^6.4.0", "@fortawesome/react-fontawesome": "^0.2.0", @@ -40,6 +39,7 @@ "framer-motion": "^10.16.16", "jest-worker": "^29.6.2", "next": "^14.2.7", + "next-auth": "^4.24.7", "postcss": "8.4.25", "prop-types": "^15.8.1", "react": "^18.2.0", diff --git a/www/pages/_app.jsx b/www/pages/_app.jsx new file mode 100644 index 00000000..819ee566 --- /dev/null +++ b/www/pages/_app.jsx @@ -0,0 +1,12 @@ +import { SessionProvider } from "next-auth/react"; + +export default function App({ + Component, + pageProps: { session, ...pageProps }, +}) { + return ( + + + + ); +} diff --git a/www/pages/api/current-user.ts b/www/pages/api/current-user.ts deleted file mode 100644 index bd53dbc7..00000000 --- a/www/pages/api/current-user.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { getFiefAuth } from "../../app/lib/fief"; -import { NextApiRequest, NextApiResponse } from "next"; - -export default async (req: NextApiRequest, res: NextApiResponse) => { - const fromUrl = req.headers["referer"] && new URL(req.headers["referer"]); - const fief = fromUrl && (await getFiefAuth(fromUrl)); - if (fief) { - return fief.currentUser()(req as any, res as any); - } else { - return res.status(200).json({ userinfo: null, access_token_info: null }); - } -}; diff --git a/www/yarn.lock b/www/yarn.lock index 8c894281..382200e5 100644 --- a/www/yarn.lock +++ b/www/yarn.lock @@ -62,6 +62,13 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.20.13": + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.6.tgz#9afc3289f7184d8d7f98b099884c26317b9264d2" + integrity sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/types@^7.22.15": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.6.tgz#be33fdb151e1f5a56877d704492c240fc71c7ccd" @@ -1061,16 +1068,6 @@ resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.4.tgz#9e69f8bb4031e11df79e03db09f9dbbae1740843" integrity sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ== -"@fief/fief@^0.13.5": - version "0.13.5" - resolved "https://registry.yarnpkg.com/@fief/fief/-/fief-0.13.5.tgz#01ac833ddff0b84f2e1737cc168721568b0e7a39" - integrity sha512-st4+/Rc1rw18B6RtqLmC6t9k0pnYLG7AqMe0JYjKYcamCNnABwl198ZJt6HShtaZKI5maHsh99UoCA3MqpbWsQ== - dependencies: - encoding "^0.1.13" - jose "^4.6.0" - node-fetch "^2.6.7" - path-to-regexp "^6.2.1" - "@floating-ui/core@^1.4.2": version "1.5.2" resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.2.tgz#53a0f7a98c550e63134d504f26804f6b83dbc071" @@ -1316,6 +1313,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@panva/hkdf@^1.0.2": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.2.1.tgz#cb0d111ef700136f4580349ff0226bf25c853f23" + integrity sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw== + "@pkgjs/parseargs@^0.11.0": version "0.11.0" resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" @@ -2572,6 +2574,11 @@ convert-source-map@^1.5.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== +cookie@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + cookiejar@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.4.tgz#ee669c1fea2cf42dc31585469d193fef0d65771b" @@ -2811,13 +2818,6 @@ emoji-regex@^9.2.2: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== -encoding@^0.1.13: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - engine.io-client@~6.5.2: version "6.5.4" resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-6.5.4.tgz#b8bc71ed3f25d0d51d587729262486b4b33bd0d0" @@ -3176,7 +3176,7 @@ event-target-shim@^6.0.2: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-6.0.2.tgz#ea5348c3618ee8b62ff1d344f01908ee2b8a2b71" integrity sha512-8q3LsZjRezbFZ2PN+uP+Q7pnHUMmAOziU2vA2OwoFaKIXxlxl38IylhSSgUorWu/rf4er67w0ikBqjBFk/pomA== -events@^3.3.0, "npm-events-package@npm:events@^3.3.0": +events@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== @@ -3707,13 +3707,6 @@ hyperhtml-style@^0.1.2: resolved "https://registry.yarnpkg.com/hyperhtml-style/-/hyperhtml-style-0.1.3.tgz#ba7f704741c6d2f84c4d67e6544c01ebbd3f21d3" integrity sha512-IvLy8MzHTSJ0fDpSzrb8rcdnla6yROEmNBSxInEMyIFu2DQkbmpadTf6B4fHvnytN6iHL2gGwpe5/jHL3wMi+A== -iconv-lite@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - ieee754@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" @@ -4066,10 +4059,10 @@ jiti@^1.21.6: resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268" integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== -jose@^4.6.0: - version "4.14.4" - resolved "https://registry.yarnpkg.com/jose/-/jose-4.14.4.tgz#59e09204e2670c3164ee24cbfe7115c6f8bff9ca" - integrity sha512-j8GhLiKmUAh+dsFXlX1aJCbt5KMibuKb+d7j1JaOJG6s2UjX1PQlW+OKB/sD4a/5ZYF4RcmYmLSndOoU3Lt/3g== +jose@^4.15.5: + version "4.15.9" + resolved "https://registry.yarnpkg.com/jose/-/jose-4.15.9.tgz#9b68eda29e9a0614c042fa29387196c7dd800100" + integrity sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" @@ -4648,6 +4641,21 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +next-auth@^4.24.7: + version "4.24.7" + resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.24.7.tgz#0a14c1e35b4a2c0c1ecff95c295b74bd48d3817a" + integrity sha512-iChjE8ov/1K/z98gdKbn2Jw+2vLgJtVV39X+rCP5SGnVQuco7QOr19FRNGMIrD8d3LYhHWV9j9sKLzq1aDWWQQ== + dependencies: + "@babel/runtime" "^7.20.13" + "@panva/hkdf" "^1.0.2" + cookie "^0.5.0" + jose "^4.15.5" + oauth "^0.9.15" + openid-client "^5.4.0" + preact "^10.6.3" + preact-render-to-string "^5.1.19" + uuid "^8.3.2" + next@^14.2.7: version "14.2.7" resolved "https://registry.yarnpkg.com/next/-/next-14.2.7.tgz#e02d5d9622ff4b998e5c89adfd660c9bf6435970" @@ -4698,6 +4706,11 @@ normalize-range@^0.1.2: resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== +"npm-events-package@npm:events@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + npm-run-path@^5.1.0: version "5.3.0" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.3.0.tgz#e23353d0ebb9317f174e93417e4a4d82d0249e9f" @@ -4717,11 +4730,21 @@ nypm@^0.3.8: pkg-types "^1.1.1" ufo "^1.5.3" +oauth@^0.9.15: + version "0.9.15" + resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" + integrity sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA== + object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== +object-hash@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" + integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== + object-hash@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz" @@ -4802,6 +4825,11 @@ ohash@^1.1.3: resolved "https://registry.yarnpkg.com/ohash/-/ohash-1.1.3.tgz#f12c3c50bfe7271ce3fd1097d42568122ccdcf07" integrity sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw== +oidc-token-hash@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz#9a229f0a1ce9d4fc89bcaee5478c97a889e7b7b6" + integrity sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw== + once@^1.3.0, once@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" @@ -4816,6 +4844,16 @@ onetime@^6.0.0: dependencies: mimic-fn "^4.0.0" +openid-client@^5.4.0: + version "5.6.5" + resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-5.6.5.tgz#c149ad07b9c399476dc347097e297bbe288b8b00" + integrity sha512-5P4qO9nGJzB5PI0LFlhj4Dzg3m4odt0qsJTfyEtZyOlkgpILwEioOhVVJOrS1iVH494S4Ee5OCjjg6Bf5WOj3w== + dependencies: + jose "^4.15.5" + lru-cache "^6.0.0" + object-hash "^2.2.0" + oidc-token-hash "^5.0.3" + optionator@^0.9.3: version "0.9.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" @@ -4892,11 +4930,6 @@ path-scurry@^1.10.1: lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" -path-to-regexp@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz#d54934d6798eb9e5ef14e7af7962c945906918e5" - integrity sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw== - path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -5008,6 +5041,18 @@ postcss@8.4.31: picocolors "^1.0.0" source-map-js "^1.0.2" +preact-render-to-string@^5.1.19: + version "5.2.6" + resolved "https://registry.yarnpkg.com/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz#0ff0c86cd118d30affb825193f18e92bd59d0604" + integrity sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw== + dependencies: + pretty-format "^3.8.0" + +preact@^10.6.3: + version "10.23.2" + resolved "https://registry.yarnpkg.com/preact/-/preact-10.23.2.tgz#52deec92796ae0f0cc6b034d9c66e0fbc1b837dc" + integrity sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA== + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -5018,6 +5063,11 @@ prettier@^3.0.0: resolved "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz" integrity sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g== +pretty-format@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385" + integrity sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew== + progress@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" @@ -5396,11 +5446,6 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -"safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - sass@^1.63.6: version "1.63.6" resolved "https://registry.npmjs.org/sass/-/sass-1.63.6.tgz" @@ -5557,8 +5602,16 @@ streamsearch@^1.1.0: resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: - name string-width-cjs +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -5625,7 +5678,14 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -6089,6 +6149,11 @@ uuid-validate@^0.0.3: resolved "https://registry.yarnpkg.com/uuid-validate/-/uuid-validate-0.0.3.tgz#e30617f75dc742a0e4f95012a11540faf9d39ab4" integrity sha512-Fykw5U4eZESbq739BeLvEBFRuJODfrlmjx5eJux7W817LjRaq4b7/i4t2zxQmhcX+fAj4nMfRdTzO4tmwLKn0w== +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + uuid@^9.0.0, uuid@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30"