Merge branch 'main' into update-icons
This commit is contained in:
2
.github/workflows/server-publish.yml
vendored
2
.github/workflows/server-publish.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
registry: ghcr.io
|
||||
enableBuildKit: true
|
||||
multiPlatform: true
|
||||
platform: linux/amd64,linux/arm64,linux/arm/v7
|
||||
platform: linux/amd64,linux/arm64
|
||||
buildArgs: GIT_COMMIT=${{ inputs.commit }}
|
||||
tags: ${{ inputs.commit }}, latest
|
||||
username: ${{ github.actor }}
|
||||
|
||||
@@ -39,11 +39,15 @@
|
||||
{
|
||||
"title": "Bloom Host",
|
||||
"slug": "bloom_host",
|
||||
"altNames": ["Bloom Host Billing"]
|
||||
"altNames": [
|
||||
"Bloom Host Billing"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "BorgBase",
|
||||
"altNames": ["borg"],
|
||||
"altNames": [
|
||||
"borg"
|
||||
],
|
||||
"slug": "BorgBase"
|
||||
},
|
||||
{
|
||||
@@ -74,6 +78,12 @@
|
||||
"title": "ConfigCat",
|
||||
"slug": "configcat"
|
||||
},
|
||||
{
|
||||
"title": "CoinDCX"
|
||||
},
|
||||
{
|
||||
"title": "ConfigCat"
|
||||
},
|
||||
{
|
||||
"title": "Control D",
|
||||
"slug": "controld",
|
||||
@@ -84,7 +94,9 @@
|
||||
},
|
||||
{
|
||||
"title": "DCS",
|
||||
"altNames": ["Digital Combat Simulator"],
|
||||
"altNames": [
|
||||
"Digital Combat Simulator"
|
||||
],
|
||||
"slug": "dcs"
|
||||
},
|
||||
{
|
||||
@@ -144,7 +156,9 @@
|
||||
},
|
||||
{
|
||||
"title": "Gosuslugi",
|
||||
"altNames": ["Госуслуги"],
|
||||
"altNames": [
|
||||
"Госуслуги"
|
||||
],
|
||||
"slug": "Gosuslugi"
|
||||
},
|
||||
{
|
||||
@@ -220,7 +234,11 @@
|
||||
{
|
||||
"title": "Local",
|
||||
"slug": "local_wp",
|
||||
"altNames": ["LocalWP", "Local WP", "Local Wordpress"]
|
||||
"altNames": [
|
||||
"LocalWP",
|
||||
"Local WP",
|
||||
"Local Wordpress"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Marketplace.tf",
|
||||
@@ -228,14 +246,23 @@
|
||||
},
|
||||
{
|
||||
"title": "Mastodon",
|
||||
"altNames": ["mstdn", "fediscience", "mathstodon", "fosstodon"],
|
||||
"altNames": [
|
||||
"mstdn",
|
||||
"fediscience",
|
||||
"mathstodon",
|
||||
"fosstodon"
|
||||
],
|
||||
"slug": "mastodon",
|
||||
"hex": "6364FF"
|
||||
},
|
||||
{
|
||||
"title": "Mercado Livre",
|
||||
"slug": "mercado_livre",
|
||||
"altNames": ["Mercado Libre", "MercadoLibre", "MercadoLivre"]
|
||||
"altNames": [
|
||||
"Mercado Libre",
|
||||
"MercadoLibre",
|
||||
"MercadoLivre"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Microsoft"
|
||||
@@ -251,7 +278,9 @@
|
||||
},
|
||||
{
|
||||
"title": "Murena",
|
||||
"altNames": ["eCloud"],
|
||||
"altNames": [
|
||||
"eCloud"
|
||||
],
|
||||
"slug": "ecloud"
|
||||
},
|
||||
{
|
||||
@@ -342,7 +371,11 @@
|
||||
{
|
||||
"title": "Registro br",
|
||||
"slug": "registro_br",
|
||||
"altNames": ["Registro br", "registrobr", "Registro.br"]
|
||||
"altNames": [
|
||||
"Registro br",
|
||||
"registrobr",
|
||||
"Registro.br"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Render"
|
||||
@@ -408,7 +441,10 @@
|
||||
},
|
||||
{
|
||||
"title": "Techlore",
|
||||
"altNames": ["Techlore Courses", "Techlore Forums"]
|
||||
"altNames": [
|
||||
"Techlore Courses",
|
||||
"Techlore Forums"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Termius",
|
||||
@@ -440,7 +476,10 @@
|
||||
},
|
||||
{
|
||||
"title": "Twitch",
|
||||
"altNames": ["Twitch.tv", "Twitch tv"]
|
||||
"altNames": [
|
||||
"Twitch.tv",
|
||||
"Twitch tv"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Ubisoft",
|
||||
@@ -476,23 +515,32 @@
|
||||
{
|
||||
"title": "WorkOS",
|
||||
"slug": "workos",
|
||||
"altNames": ["Work OS"]
|
||||
"altNames": [
|
||||
"Work OS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "X",
|
||||
"altNames": ["twitter"],
|
||||
"altNames": [
|
||||
"twitter"
|
||||
],
|
||||
"slug": "x"
|
||||
},
|
||||
{
|
||||
"title": "Yandex",
|
||||
"altNames": ["Ya", "Яндекс"],
|
||||
"altNames": [
|
||||
"Ya",
|
||||
"Яндекс"
|
||||
],
|
||||
"slug": "Yandex"
|
||||
},
|
||||
{
|
||||
"title": "YNAB",
|
||||
"altNames": ["You Need A Budget"],
|
||||
"altNames": [
|
||||
"You Need A Budget"
|
||||
],
|
||||
"slug": "ynab",
|
||||
"hex": "3B5EDA"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
4
auth/assets/custom-icons/icons/coindcx.svg
Normal file
4
auth/assets/custom-icons/icons/coindcx.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 500">
|
||||
<path fill="#182954" d="m75.705 269.386 12.606 10.812a40.902 40.902 0 0 1-8.642 8.853 53.365 53.365 0 0 1-13.599 7.73 45.769 45.769 0 0 1-16.998 3.094 49.02 49.02 0 0 1-25.212-6.466A45.84 45.84 0 0 1 6.72 275.84a50.83 50.83 0 0 1-6.212-25.287 52.621 52.621 0 0 1 3.525-19.394 49.28 49.28 0 0 1 10.2-16.022 46.603 46.603 0 0 1 15.44-10.812 49.626 49.626 0 0 1 19.969-3.938 45.9 45.9 0 0 1 23.51 5.48A49.016 49.016 0 0 1 88.308 219.5l-12.744 11.244A39.368 39.368 0 0 0 64.938 220.2a27.358 27.358 0 0 0-15.296-3.933 27.636 27.636 0 0 0-16.147 4.632 30.695 30.695 0 0 0-10.478 12.508 38.957 38.957 0 0 0-3.688 16.879 36.724 36.724 0 0 0 3.684 16.442 29.719 29.719 0 0 0 10.184 11.793 27.208 27.208 0 0 0 15.44 4.358c4.608.197 9.203-.62 13.456-2.391a27.765 27.765 0 0 0 8.214-5.622l5.381-5.481M93.275 264.047a35.477 35.477 0 0 1 4.535-17.71 34.84 34.84 0 0 1 12.748-12.929 39.497 39.497 0 0 1 18.838-4.778 39.497 39.497 0 0 1 18.838 4.778 34.846 34.846 0 0 1 12.749 12.928 36.889 36.889 0 0 1 4.532 17.709 36.891 36.891 0 0 1-4.532 17.708 36.519 36.519 0 0 1-13.365 13.153 36.875 36.875 0 0 1-18.181 4.837 36.88 36.88 0 0 1-18.203-4.756 36.513 36.513 0 0 1-13.424-13.092 35.479 35.479 0 0 1-4.535-17.707v-.141zm35.979 21.224a16.949 16.949 0 0 0 10.623-3.23c2.804-2.121 5-4.93 6.375-8.151a24.848 24.848 0 0 0 2.124-9.698 24.293 24.293 0 0 0-2.124-9.697 20.265 20.265 0 0 0-6.375-8.15 19.056 19.056 0 0 0-10.623-3.233 19.057 19.057 0 0 0-10.625 3.233 20.118 20.118 0 0 0-6.231 8.009 24.296 24.296 0 0 0-2.125 9.697 24.713 24.713 0 0 0 2.125 9.839 19.985 19.985 0 0 0 6.374 8.15 16.949 16.949 0 0 0 10.624 3.231M168.905 202.628h16.856v17.71h-16.856v-17.71zm0 28.11h16.856v66.758h-16.856v-66.758zM192.416 297.495V230.88h16.147l.42 7.589a35.937 35.937 0 0 1 7.505-5.905 23.656 23.656 0 0 1 12.749-3.094 24.38 24.38 0 0 1 10.396 1.612 24.22 24.22 0 0 1 8.726 5.836 29.047 29.047 0 0 1 6.66 20.097v40.477H238.02v-40.335a13.257 13.257 0 0 0-.76-5.278 13.337 13.337 0 0 0-2.78-4.561 12.19 12.19 0 0 0-4.164-2.694 12.27 12.27 0 0 0-4.902-.82 14.974 14.974 0 0 0-6.377 1.24 14.87 14.87 0 0 0-5.236 3.82 18.046 18.046 0 0 0-4.534 12.51v36.118l-16.851.004z"/>
|
||||
<path fill="#FA4A29" d="m463.25 246.618 29.754-44.007h-28.187l-15.44 24.596-15.883-24.596h-31.163l1.416 1.967-.993-.416a63.329 63.329 0 0 0-23.083-4.046 50.453 50.453 0 0 0-25.92 6.607 46.609 46.609 0 0 0-14.308 12.929 40.334 40.334 0 0 0-15.582-11.806 65.028 65.028 0 0 0-26.344-5.077h-36.686v94.727h36.544a64.026 64.026 0 0 0 26.344-5.202A41.612 41.612 0 0 0 339.3 280.63c3.87 5.299 8.846 9.709 14.59 12.928a51.44 51.44 0 0 0 25.777 6.325 55.023 55.023 0 0 0 24.646-5.34l-1.982 2.953h27.76l18.558-29.108 19.122 29.108h31.73l-36.252-50.878zm-147.452 21.624a25.772 25.772 0 0 1-8.902 5.504 25.916 25.916 0 0 1-10.376 1.523h-10.334v-50.573h10.338c3.62-.305 7.264.165 10.685 1.378a25.427 25.427 0 0 1 9.147 5.65 26.146 26.146 0 0 1 6.374 18.271 24.821 24.821 0 0 1-1.597 9.836 24.965 24.965 0 0 1-5.343 8.436l.008-.025zm101.549 6.911-12.04-11.228a38.572 38.572 0 0 1-10.197 9.149 27.09 27.09 0 0 1-13.6 2.952 25.509 25.509 0 0 1-13.314-3.372 22.838 22.838 0 0 1-8.8-9.415 29.459 29.459 0 0 1-3.118-13.63c-.091-4.623.929-9.2 2.975-13.353a23.258 23.258 0 0 1 8.642-9.415 25.653 25.653 0 0 1 13.738-3.513 24.798 24.798 0 0 1 12.748 3.23 32.061 32.061 0 0 1 9.639 8.733l12.606-12.508 18.415 26.28-17.694 26.09z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -27,3 +27,6 @@ include:
|
||||
- libffi.so.8
|
||||
- libtiff.so.5
|
||||
- libjpeg.so.8
|
||||
|
||||
supported_mime_type:
|
||||
- x-scheme-handler/enteauth
|
||||
@@ -31,4 +31,4 @@ categories:
|
||||
startup_notify: false
|
||||
|
||||
supported_mime_type:
|
||||
- x-scheme-handler/ente
|
||||
- x-scheme-handler/enteauth
|
||||
|
||||
@@ -28,4 +28,4 @@ categories:
|
||||
startup_notify: false
|
||||
|
||||
supported_mime_type:
|
||||
- x-scheme-handler/ente
|
||||
- x-scheme-handler/enteauth
|
||||
|
||||
@@ -45,10 +45,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: archive
|
||||
sha256: "0763b45fa9294197a2885c8567927e2830ade852e5c896fd4ab7e0e348d0f373"
|
||||
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.5.0"
|
||||
version: "3.6.1"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -117,10 +117,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1"
|
||||
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.1"
|
||||
version: "4.0.2"
|
||||
build_resolvers:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -133,18 +133,18 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22"
|
||||
sha256: "644dc98a0f179b872f612d3eb627924b578897c629788e858157fa5e704ca0c7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.9"
|
||||
version: "2.4.11"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799"
|
||||
sha256: e3c79f69a64bdfcd8a776a3c28db4eb6e3fb5356d013ae5eb2e52007706d5dbe
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.3.0"
|
||||
version: "7.3.1"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -415,10 +415,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: file_saver
|
||||
sha256: bdebc720e17b3e01aba59da69b6d47020a7e5ba7d5c75bd9194f9618d5f16ef4
|
||||
sha256: d375b351e3331663abbaf99747abd72f159260c58fbbdbca9f926f02c01bdc48
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.12"
|
||||
version: "0.2.13"
|
||||
fixnum:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -444,10 +444,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_bloc
|
||||
sha256: f0ecf6e6eb955193ca60af2d5ca39565a86b8a142452c5b24d96fb477428f4d2
|
||||
sha256: b594505eac31a0518bdcb4b5b79573b8d9117b193cc80cc12e17d639b10aa27a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.1.5"
|
||||
version: "8.1.6"
|
||||
flutter_context_menu:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -586,18 +586,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_plugin_android_lifecycle
|
||||
sha256: "8cf40eebf5dec866a6d1956ad7b4f7016e6c0cc69847ab946833b7d43743809f"
|
||||
sha256: c6b0b4c05c458e1c01ad9bcc14041dd7b1f6783d487be4386f793f47a8a4d03e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.19"
|
||||
version: "2.0.20"
|
||||
flutter_secure_storage:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_secure_storage
|
||||
sha256: ffdbb60130e4665d2af814a0267c481bcf522c41ae2e43caf69fa0146876d685
|
||||
sha256: "165164745e6afb5c0e3e3fcc72a012fb9e58496fb26ffb92cf22e16a821e85d0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.0.0"
|
||||
version: "9.2.2"
|
||||
flutter_secure_storage_linux:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
@@ -611,34 +611,34 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_macos
|
||||
sha256: bd33935b4b628abd0b86c8ca20655c5b36275c3a3f5194769a7b3f37c905369c
|
||||
sha256: "1693ab11121a5f925bbea0be725abfcfbbcf36c1e29e571f84a0c0f436147a81"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.1.2"
|
||||
flutter_secure_storage_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_platform_interface
|
||||
sha256: "0d4d3a5dd4db28c96ae414d7ba3b8422fd735a8255642774803b2532c9a61d7e"
|
||||
sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "1.1.2"
|
||||
flutter_secure_storage_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_web
|
||||
sha256: "30f84f102df9dcdaa2241866a958c2ec976902ebdaa8883fbfe525f1f2f3cf20"
|
||||
sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "1.2.1"
|
||||
flutter_secure_storage_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_windows
|
||||
sha256: "5809c66f9dd3b4b93b0a6e2e8561539405322ee767ac2f64d084e2ab5429d108"
|
||||
sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
version: "3.1.2"
|
||||
flutter_slidable:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -685,10 +685,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: fluttertoast
|
||||
sha256: "81b68579e23fcbcada2db3d50302813d2371664afe6165bc78148050ab94bf66"
|
||||
sha256: "7eae679e596a44fdf761853a706f74979f8dd3cd92cf4e23cae161fda091b847"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.2.5"
|
||||
version: "8.2.6"
|
||||
freezed_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -725,10 +725,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: gradient_borders
|
||||
sha256: "69eeaff519d145a4c6c213ada1abae386bcc8981a4970d923e478ce7ba19e309"
|
||||
sha256: b1cd969552c83f458ff755aa68e13a0327d09f06c3f42f471b423b01427f21f8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
version: "1.0.1"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -757,10 +757,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: hashlib_codecs
|
||||
sha256: "49e2a471f74b15f1854263e58c2ac11f2b631b5b12c836f9708a35397d36d626"
|
||||
sha256: a1c7b5d89ff29e81fd8e8c0b35966db4c935e149fc4ebe1ebf71e358c15863ab
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "2.4.0"
|
||||
hex:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -805,10 +805,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image
|
||||
sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e"
|
||||
sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.7"
|
||||
version: "4.2.0"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -893,18 +893,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: local_auth_android
|
||||
sha256: e0e5b1ea247c5a0951c13a7ee13dc1beae69750e6a2e1910d1ed6a3cd4d56943
|
||||
sha256: "48dfb2d954da8ef6a77adfc93a29998f7729e9308eaa817e91dea4500317b2c8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.38"
|
||||
version: "1.0.39"
|
||||
local_auth_darwin:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: local_auth_darwin
|
||||
sha256: "33381a15b0de2279523eca694089393bb146baebdce72a404555d03174ebc1e9"
|
||||
sha256: e424ebf90d5233452be146d4a7da4bcd7a70278b67791592f3fde1bda8eef9e2
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
version: "1.3.1"
|
||||
local_auth_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -973,10 +973,10 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: mocktail
|
||||
sha256: c4b5007d91ca4f67256e720cb1b6d704e79a510183a12fa551021f652577dce6
|
||||
sha256: "890df3f9688106f25755f26b1c60589a92b3ab91a22b8b224947ad041bf172d8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
version: "1.0.4"
|
||||
modal_bottom_sheet:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -1085,18 +1085,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
|
||||
sha256: "9c96da072b421e98183f9ea7464898428e764bc0ce5567f27ec8693442e72514"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.4"
|
||||
version: "2.2.5"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_foundation
|
||||
sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f"
|
||||
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
version: "2.4.0"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1141,10 +1141,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
|
||||
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
version: "3.1.5"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1157,10 +1157,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: pointycastle
|
||||
sha256: "79fbafed02cfdbe85ef3fd06c7f4bc2cbcba0177e61b765264853d4253b21744"
|
||||
sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.9.0"
|
||||
version: "3.9.1"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1205,10 +1205,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367
|
||||
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.3"
|
||||
version: "1.3.0"
|
||||
qr:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1245,18 +1245,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sentry
|
||||
sha256: e572d33a3ff1d69549f33ee828a8ff514047d43ca8eea4ab093d72461205aa3e
|
||||
sha256: "57514bc72d441ffdc463f498d6886aa586a2494fa467a1eb9d649c28010d7ee3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.20.1"
|
||||
version: "7.20.2"
|
||||
sentry_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sentry_flutter
|
||||
sha256: ac8cf6bb849f3560353ae33672e17b2713809a4e8de0d3cf372e9e9c42013757
|
||||
sha256: "9723d58470ca43a360681ddd26abb71ca7b815f706bc8d3747afd054cf639ded"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.20.1"
|
||||
version: "7.20.2"
|
||||
share_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -1285,18 +1285,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_android
|
||||
sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2"
|
||||
sha256: "93d0ec9dd902d85f326068e6a899487d1f65ffcd5798721a95330b26c8131577"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.2"
|
||||
version: "2.2.3"
|
||||
shared_preferences_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_foundation
|
||||
sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
|
||||
sha256: "0a8a893bf4fd1152f93fec03a415d11c27c74454d96e2318a7ac38dd18683ab7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.5"
|
||||
version: "2.4.0"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1341,10 +1341,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
|
||||
sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "2.0.0"
|
||||
shortid:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1370,10 +1370,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sodium_libs
|
||||
sha256: f7f6719b7ab3e8512ce7a5ecd7bc8d865482431cdd5a07a46b55b13c152b54e1
|
||||
sha256: "441444f6f433032bae3444c2ef5ed2cf5bc0def77f104abdff20aedcf79a7c7a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1+1"
|
||||
version: "2.2.1+5"
|
||||
source_gen:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1411,10 +1411,10 @@ packages:
|
||||
description:
|
||||
path: sqflite
|
||||
ref: HEAD
|
||||
resolved-ref: f281785e12e8b1abf2f9d41a587fc83d810724cf
|
||||
resolved-ref: "3309d399dd7d695bbfa7c05f643bb16765cef4ee"
|
||||
url: "https://github.com/tekartik/sqflite"
|
||||
source: git
|
||||
version: "2.3.3"
|
||||
version: "2.3.3+1"
|
||||
sqflite_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1435,18 +1435,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sqlite3
|
||||
sha256: "1abbeb84bf2b1a10e5e1138c913123c8aa9d83cd64e5f9a0dd847b3c83063202"
|
||||
sha256: b384f598b813b347c5a7e5ffad82cbaff1bec3d1561af267041e66f6f0899295
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
version: "2.4.3"
|
||||
sqlite3_flutter_libs:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sqlite3_flutter_libs
|
||||
sha256: fb2a106a2ea6042fe57de2c47074cc31539a941819c91e105b864744605da3f5
|
||||
sha256: "9f89a7e7dc36eac2035808427eba1c3fbd79e59c3a22093d8dace6d36b1fe89e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.21"
|
||||
version: "0.5.23"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1547,10 +1547,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: tray_manager
|
||||
sha256: e0ac9a88b2700f366b8629b97e8663b6ef450a2f169560a685dc167bfe9c9c29
|
||||
sha256: c9a63fd88bd3546287a7eb8ccc978d707eef82c775397af17dda3a4f4c039e64
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.2"
|
||||
version: "0.2.3"
|
||||
tuple:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -1579,26 +1579,26 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: url_launcher
|
||||
sha256: "6ce1e04375be4eed30548f10a315826fd933c1e493206eab82eed01f438c8d2e"
|
||||
sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.6"
|
||||
version: "6.3.0"
|
||||
url_launcher_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_android
|
||||
sha256: "360a6ed2027f18b73c8d98e159dda67a61b7f2e0f6ec26e86c3ada33b0621775"
|
||||
sha256: ceb2625f0c24ade6ef6778d1de0b2e44f2db71fded235eb52295247feba8c5cf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.1"
|
||||
version: "6.3.3"
|
||||
url_launcher_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_ios
|
||||
sha256: "9149d493b075ed740901f3ee844a38a00b33116c7c5c10d7fb27df8987fb51d5"
|
||||
sha256: "7068716403343f6ba4969b4173cbf3b84fc768042124bc2c011e5d782b24fe89"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.5"
|
||||
version: "6.3.0"
|
||||
url_launcher_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1611,10 +1611,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_macos
|
||||
sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234
|
||||
sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
version: "3.2.0"
|
||||
url_launcher_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1703,22 +1703,30 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.1"
|
||||
web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket
|
||||
sha256: "24301d8c293ce6fe327ffe6f59d8fd8834735f0ec36e4fd383ec7ff8a64aa078"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42"
|
||||
sha256: a2d56211ee4d35d9b344d9d4ce60f362e4f5d1aafb988302906bd732bc731276
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.5"
|
||||
version: "3.0.0"
|
||||
win32:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: win32
|
||||
sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
|
||||
sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.5.0"
|
||||
version: "5.5.1"
|
||||
win32_registry:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1768,5 +1776,5 @@ packages:
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
sdks:
|
||||
dart: ">=3.3.0 <4.0.0"
|
||||
flutter: ">=3.19.0"
|
||||
dart: ">=3.4.0 <4.0.0"
|
||||
flutter: ">=3.22.0"
|
||||
|
||||
@@ -17,9 +17,10 @@ on:
|
||||
#
|
||||
- cron: "45 2 * * 1-6"
|
||||
push:
|
||||
# Run when a tag matching the pattern "v*"" is pushed.
|
||||
# Run when a tag matching the pattern "vd.d.d"" is pushed. Crucially for
|
||||
# us, this excludes the "-rc" tags.
|
||||
tags:
|
||||
- "v*"
|
||||
- "v[0-9]+.[0-9]+.[0-9]+"
|
||||
|
||||
jobs:
|
||||
release:
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v1.7.1 (Unreleased)
|
||||
## v1.7.2 (Unreleased)
|
||||
|
||||
- .
|
||||
|
||||
## v1.7.1
|
||||
|
||||
- Support for passkeys as a second factor authentication mechanism.
|
||||
- Remember the window size across app restarts.
|
||||
|
||||
@@ -53,23 +53,24 @@ This'll trigger the workflow and create a new pre-release. We can edit this to
|
||||
add the release notes, convert it to a release. Once it is marked as latest, the
|
||||
release goes live.
|
||||
|
||||
We are done at this point, and can now create a new pre-release to host
|
||||
We are done at this point, and can now update the other pre-release that hosts
|
||||
subsequent nightly builds.
|
||||
|
||||
1. Update `package.json` in the source repo to use version `1.x.x-rc`, and
|
||||
merge these changes into `main`.
|
||||
|
||||
2. In the release repo:
|
||||
2. In the release repo, delete the existing _nightly_ pre-release, then:
|
||||
|
||||
```sh
|
||||
git tag 1.x.x-rc
|
||||
git push origin 1.x.x-rc
|
||||
```
|
||||
|
||||
3. Once the workflow finishes and the pre-release is created, edit its
|
||||
description to "Nightly builds".
|
||||
3. Start a new run of the workflow (`gh workflow run desktop-release.yml`).
|
||||
|
||||
4. Delete the pre-release for the previous (already released) version.
|
||||
Once the workflow finishes and the 1.x.x-rc pre-release is created, edit its
|
||||
description to "Nightly builds". Subsequent scheduled nightly builds will update
|
||||
this pre-release.
|
||||
|
||||
## Workflow - Extra pre-releases
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ente",
|
||||
"version": "1.7.1-rc",
|
||||
"version": "1.7.2-rc",
|
||||
"private": true,
|
||||
"description": "Desktop client for Ente Photos",
|
||||
"repository": "github:ente-io/photos-desktop",
|
||||
|
||||
@@ -5,11 +5,6 @@ description: Using passkeys as a second factor for your Ente account
|
||||
|
||||
# Passkeys
|
||||
|
||||
> [!CAUTION]
|
||||
>
|
||||
> This is preview documentation for an upcoming feature. This feature has not
|
||||
> yet been released yet, so the steps below will not work currently.
|
||||
|
||||
Passkeys are a new authentication mechanism that uses strong cryptography built
|
||||
into devices, like Windows Hello or Apple's Touch ID. **You can use passkeys as
|
||||
a second factor to secure your Ente account.**
|
||||
@@ -17,9 +12,13 @@ a second factor to secure your Ente account.**
|
||||
> [!TIP]
|
||||
>
|
||||
> Passkeys are the colloquial term for a WebAuthn (Web Authentication)
|
||||
> credentials. To know more technical details about how our passkey verification
|
||||
> works, you can see this
|
||||
> [technical note in our source code](https://github.com/ente-io/ente/blob/main/web/docs/webauthn-passkeys.md).
|
||||
> credentials.
|
||||
>
|
||||
> - More details about why and how are in the Passkeys announcement
|
||||
> [blog post](https://ente.io/blog/introducing-passkeys-on-ente/).
|
||||
> - And to know more technical details about how our passkey verification
|
||||
> works, you can see this
|
||||
> [technical note in our source code](https://github.com/ente-io/ente/blob/main/web/docs/webauthn-passkeys.md).
|
||||
|
||||
## Passkeys and TOTP
|
||||
|
||||
|
||||
@@ -20,8 +20,12 @@ start it, then you might need to install the VC++ runtime from Microsoft.
|
||||
|
||||
This is what the error looks like:
|
||||
|
||||
<div style="border: 1px solid black">
|
||||
|
||||
{width=500px}
|
||||
|
||||
</div>
|
||||
|
||||
You can install the Microsoft VC++ redistributable runtime from here:<br/>
|
||||
https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-microsoft-visual-c-redistributable-version
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/** Proxy file and thumbnail requests for the cast web app */
|
||||
/** Proxy file and thumbnail requests for the cast web app. */
|
||||
|
||||
export default {
|
||||
async fetch(request: Request) {
|
||||
@@ -28,12 +28,12 @@ const handleOPTIONS = (request: Request) => {
|
||||
};
|
||||
|
||||
const isAllowedOrigin = (origin: string | null) => {
|
||||
const allowed = ["cast.ente.io", "cast.ente.sh", "localhost"];
|
||||
|
||||
if (!origin) return false;
|
||||
try {
|
||||
const url = new URL(origin);
|
||||
return ["cast.ente.io", "cast.ente.sh", "localhost"].includes(
|
||||
url.hostname
|
||||
);
|
||||
return allowed.includes(url.hostname);
|
||||
} catch {
|
||||
// origin is likely an invalid URL
|
||||
return false;
|
||||
@@ -42,22 +42,27 @@ const isAllowedOrigin = (origin: string | null) => {
|
||||
|
||||
const handleGET = async (request: Request) => {
|
||||
const url = new URL(request.url);
|
||||
const castToken =
|
||||
request.headers.get("X-Cast-Access-Token") ??
|
||||
url.searchParams.get("castToken");
|
||||
|
||||
const fileID = url.searchParams.get("fileID");
|
||||
if (!fileID) return new Response(null, { status: 400 });
|
||||
|
||||
let castToken = request.headers.get("X-Cast-Access-Token");
|
||||
if (!castToken) {
|
||||
console.warn("Using deprecated castToken query param");
|
||||
castToken = url.searchParams.get("castToken");
|
||||
}
|
||||
|
||||
if (!castToken) {
|
||||
console.error("No cast token provided");
|
||||
return new Response(null, { status: 400 });
|
||||
}
|
||||
|
||||
const fileID = url.searchParams.get("fileID");
|
||||
const pathname = url.pathname;
|
||||
|
||||
const params = new URLSearchParams({ castToken });
|
||||
|
||||
let response = await fetch(
|
||||
`https://api.ente.io/cast/files${pathname}${fileID}?${params.toString()}`
|
||||
);
|
||||
|
||||
response = new Response(response.body, response);
|
||||
response.headers.set("Access-Control-Allow-Origin", "*");
|
||||
return response;
|
||||
|
||||
10
infra/workers/files/package.json
Normal file
10
infra/workers/files/package.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "files",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20240614.0",
|
||||
"typescript": "^5",
|
||||
"wrangler": "^3"
|
||||
},
|
||||
"packageManager": "yarn@1.22.22"
|
||||
}
|
||||
101
infra/workers/files/src/index.ts
Normal file
101
infra/workers/files/src/index.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
/** Proxy requests for files. */
|
||||
|
||||
export default {
|
||||
async fetch(request: Request) {
|
||||
switch (request.method) {
|
||||
case "OPTIONS":
|
||||
return handleOPTIONS(request);
|
||||
case "GET":
|
||||
return handleGET(request);
|
||||
default:
|
||||
console.log(`Unsupported HTTP method ${request.method}`);
|
||||
return new Response(null, { status: 405 });
|
||||
}
|
||||
},
|
||||
} satisfies ExportedHandler;
|
||||
|
||||
const handleOPTIONS = (request: Request) => {
|
||||
const origin = request.headers.get("Origin");
|
||||
if (!isAllowedOrigin(origin)) console.warn("Unknown origin", origin);
|
||||
const headers = request.headers.get("Access-Control-Request-Headers");
|
||||
if (!areAllowedHeaders(headers))
|
||||
console.warn("Unknown header in list", headers);
|
||||
return new Response("", {
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Methods": "GET, OPTIONS",
|
||||
"Access-Control-Max-Age": "86400",
|
||||
// "Access-Control-Allow-Headers": "X-Auth-Token, X-Client-Package",
|
||||
"Access-Control-Allow-Headers": "*",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const isAllowedOrigin = (origin: string | null) => {
|
||||
const desktopApp = "ente://app";
|
||||
const allowedHostnames = [
|
||||
"web.ente.io",
|
||||
"photos.ente.io",
|
||||
"photos.ente.sh",
|
||||
"localhost",
|
||||
];
|
||||
|
||||
if (!origin) return false;
|
||||
try {
|
||||
const url = new URL(origin);
|
||||
return origin == desktopApp || allowedHostnames.includes(url.hostname);
|
||||
} catch {
|
||||
// origin is likely an invalid URL
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const areAllowedHeaders = (headers: string | null) => {
|
||||
const allowed = ["x-auth-token", "x-client-package"];
|
||||
|
||||
if (!headers) return true;
|
||||
for (const header of headers.split(",")) {
|
||||
if (!allowed.includes(header.trim().toLowerCase())) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const handleGET = async (request: Request) => {
|
||||
const url = new URL(request.url);
|
||||
|
||||
// Random bots keep trying to pentest causing noise in the logs. If the
|
||||
// request doesn't have a fileID, we can just safely ignore it thereafter.
|
||||
const fileID = url.searchParams.get("fileID");
|
||||
if (!fileID) return new Response(null, { status: 400 });
|
||||
|
||||
let token = request.headers.get("X-Auth-Token");
|
||||
if (!token) {
|
||||
console.warn("Using deprecated token query param");
|
||||
token = url.searchParams.get("token");
|
||||
}
|
||||
|
||||
if (!token) {
|
||||
console.error("No token provided");
|
||||
// return new Response(null, { status: 400 });
|
||||
}
|
||||
|
||||
// We forward the auth token as a query parameter to museum. This is so that
|
||||
// it does not get preserved when museum does a redirect to the presigned S3
|
||||
// URL that serves the actual thumbnail.
|
||||
//
|
||||
// See: [Note: Passing credentials for self-hosted file fetches]
|
||||
const params = new URLSearchParams();
|
||||
if (token) params.set("token", token);
|
||||
|
||||
let response = await fetch(
|
||||
`https://api.ente.io/files/download/${fileID}?${params.toString()}`,
|
||||
{
|
||||
headers: {
|
||||
"User-Agent": request.headers.get("User-Agent") ?? "",
|
||||
},
|
||||
}
|
||||
);
|
||||
response = new Response(response.body, response);
|
||||
response.headers.set("Access-Control-Allow-Origin", "*");
|
||||
return response;
|
||||
};
|
||||
1
infra/workers/files/tsconfig.json
Normal file
1
infra/workers/files/tsconfig.json
Normal file
@@ -0,0 +1 @@
|
||||
{ "extends": "../tsconfig.base.json", "include": ["src"] }
|
||||
11
infra/workers/files/wrangler.toml
Normal file
11
infra/workers/files/wrangler.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
name = "files"
|
||||
main = "src/index.ts"
|
||||
compatibility_date = "2024-06-14"
|
||||
|
||||
routes = [
|
||||
{ pattern = "files.ente.io", custom_domain = true }
|
||||
]
|
||||
|
||||
tail_consumers = [
|
||||
{ service = "tail" }
|
||||
]
|
||||
10
infra/workers/health-check/package.json
Normal file
10
infra/workers/health-check/package.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "health-check",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20240614.0",
|
||||
"typescript": "^5",
|
||||
"wrangler": "^3"
|
||||
},
|
||||
"packageManager": "yarn@1.22.22"
|
||||
}
|
||||
48
infra/workers/health-check/src/index.ts
Normal file
48
infra/workers/health-check/src/index.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
/** Ping api.ente.io every minute and yell if it doesn't pong. */
|
||||
|
||||
export default {
|
||||
async scheduled(_, env: Env, ctx: ExecutionContext) {
|
||||
ctx.waitUntil(ping(env, ctx));
|
||||
},
|
||||
} satisfies ExportedHandler<Env>;
|
||||
|
||||
interface Env {
|
||||
NOTIFY_URL: string;
|
||||
CHAT_ID: string;
|
||||
}
|
||||
|
||||
const ping = async (env: Env, ctx: ExecutionContext) => {
|
||||
const notify = async (msg: string) =>
|
||||
sendMessage(`${msg} on ${Date()}`, env);
|
||||
|
||||
try {
|
||||
let timeout = setTimeout(() => {
|
||||
ctx.waitUntil(notify("Ping timed out"));
|
||||
}, 5000);
|
||||
const res = await fetch("https://api.ente.io/ping", {
|
||||
headers: {
|
||||
"User-Agent": "health-check",
|
||||
},
|
||||
});
|
||||
clearTimeout(timeout);
|
||||
if (!res.ok) await notify(`Ping failed (HTTP ${res.status})`);
|
||||
} catch (e) {
|
||||
await notify(`Ping failed (${e instanceof Error ? e.message : e})`);
|
||||
}
|
||||
};
|
||||
|
||||
const sendMessage = async (message: string, env: Env) => {
|
||||
console.log(message);
|
||||
const res = await fetch(env.NOTIFY_URL, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
chat_id: parseInt(env.CHAT_ID),
|
||||
parse_mode: "html",
|
||||
text: message,
|
||||
}),
|
||||
});
|
||||
if (!res.ok) throw new Error(`Failed to sendMessage (HTTP ${res.status})`);
|
||||
};
|
||||
1
infra/workers/health-check/tsconfig.json
Normal file
1
infra/workers/health-check/tsconfig.json
Normal file
@@ -0,0 +1 @@
|
||||
{ "extends": "../tsconfig.base.json", "include": ["src"] }
|
||||
17
infra/workers/health-check/wrangler.toml
Normal file
17
infra/workers/health-check/wrangler.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
name = "health-check"
|
||||
main = "src/index.ts"
|
||||
compatibility_date = "2024-06-14"
|
||||
|
||||
# Disable the default route, this worker does not handle fetch.
|
||||
workers_dev = false
|
||||
|
||||
tail_consumers = [{ service = "tail" }]
|
||||
|
||||
[vars]
|
||||
# Added as a secret via the Cloudflare dashboard
|
||||
# NOTIFY_URL = ""
|
||||
# CHAT_ID = ""
|
||||
|
||||
[triggers]
|
||||
# Every minute
|
||||
crons = [ "*/1 * * * *" ]
|
||||
10
infra/workers/public-albums/package.json
Normal file
10
infra/workers/public-albums/package.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "public-albums",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20240614.0",
|
||||
"typescript": "^5",
|
||||
"wrangler": "^3"
|
||||
},
|
||||
"packageManager": "yarn@1.22.22"
|
||||
}
|
||||
98
infra/workers/public-albums/src/index.ts
Normal file
98
infra/workers/public-albums/src/index.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
/** Proxy requests for files and thumbnails in public albums. */
|
||||
|
||||
export default {
|
||||
async fetch(request: Request) {
|
||||
switch (request.method) {
|
||||
case "OPTIONS":
|
||||
return handleOPTIONS(request);
|
||||
case "GET":
|
||||
return handleGET(request);
|
||||
default:
|
||||
console.log(`Unsupported HTTP method ${request.method}`);
|
||||
return new Response(null, { status: 405 });
|
||||
}
|
||||
},
|
||||
} satisfies ExportedHandler;
|
||||
|
||||
const handleOPTIONS = (request: Request) => {
|
||||
const origin = request.headers.get("Origin");
|
||||
if (!isAllowedOrigin(origin)) console.warn("Unknown origin", origin);
|
||||
const headers = request.headers.get("Access-Control-Request-Headers");
|
||||
if (!areAllowedHeaders(headers))
|
||||
console.warn("Unknown header in list", headers);
|
||||
return new Response("", {
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Methods": "GET, OPTIONS",
|
||||
"Access-Control-Max-Age": "86400",
|
||||
// "Access-Control-Allow-Headers": "X-Auth-Access-Token, X-Auth-Access-Token-JWT",
|
||||
// "Access-Control-Allow-Headers": "X-Auth-Access-Token, X-Auth-Access-Token-JWT, x-client-package",
|
||||
"Access-Control-Allow-Headers": "*",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const isAllowedOrigin = (origin: string | null) => {
|
||||
const allowed = ["albums.ente.io", "albums.ente.sh", "localhost"];
|
||||
|
||||
if (!origin) return false;
|
||||
try {
|
||||
const url = new URL(origin);
|
||||
return allowed.includes(url.hostname);
|
||||
} catch {
|
||||
// origin is likely an invalid URL
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const areAllowedHeaders = (headers: string | null) => {
|
||||
// TODO(MR): Stop sending "x-client-package"
|
||||
const allowed = [
|
||||
"x-auth-access-token",
|
||||
"x-auth-access-token-jwt",
|
||||
"x-client-package",
|
||||
];
|
||||
|
||||
if (!headers) return true;
|
||||
for (const header of headers.split(",")) {
|
||||
if (!allowed.includes(header.trim().toLowerCase())) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const handleGET = async (request: Request) => {
|
||||
const url = new URL(request.url);
|
||||
|
||||
const fileID = url.searchParams.get("fileID");
|
||||
if (!fileID) return new Response(null, { status: 400 });
|
||||
|
||||
let accessToken = request.headers.get("X-Auth-Access-Token");
|
||||
if (accessToken === undefined) {
|
||||
console.warn("Using deprecated accessToken query param");
|
||||
accessToken = url.searchParams.get("accessToken");
|
||||
}
|
||||
|
||||
if (!accessToken) {
|
||||
console.error("No accessToken provided");
|
||||
// return new Response(null, { status: 400 });
|
||||
}
|
||||
|
||||
let accessTokenJWT = request.headers.get("X-Auth-Access-Token-JWT");
|
||||
if (accessTokenJWT === undefined) {
|
||||
console.warn("Using deprecated accessTokenJWT query param");
|
||||
accessTokenJWT = url.searchParams.get("accessTokenJWT");
|
||||
}
|
||||
|
||||
const pathname = url.pathname;
|
||||
|
||||
const params = new URLSearchParams();
|
||||
if (accessToken) params.set("accessToken", accessToken);
|
||||
if (accessTokenJWT) params.set("accessTokenJWT", accessTokenJWT);
|
||||
|
||||
let response = await fetch(
|
||||
`https://api.ente.io/public-collection/files${pathname}${fileID}?${params.toString()}`
|
||||
);
|
||||
response = new Response(response.body, response);
|
||||
response.headers.set("Access-Control-Allow-Origin", "*");
|
||||
return response;
|
||||
};
|
||||
1
infra/workers/public-albums/tsconfig.json
Normal file
1
infra/workers/public-albums/tsconfig.json
Normal file
@@ -0,0 +1 @@
|
||||
{ "extends": "../tsconfig.base.json", "include": ["src"] }
|
||||
11
infra/workers/public-albums/wrangler.toml
Normal file
11
infra/workers/public-albums/wrangler.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
name = "public-albums"
|
||||
main = "src/index.ts"
|
||||
compatibility_date = "2024-06-14"
|
||||
|
||||
routes = [
|
||||
{ pattern = "public-albums.ente.io", custom_domain = true }
|
||||
]
|
||||
|
||||
tail_consumers = [
|
||||
{ service = "tail" }
|
||||
]
|
||||
@@ -2,6 +2,9 @@ name = "tail"
|
||||
main = "src/index.ts"
|
||||
compatibility_date = "2024-06-14"
|
||||
|
||||
# Disable the default route, this worker does not handle fetch.
|
||||
workers_dev = false
|
||||
|
||||
[vars]
|
||||
# Added as a secret via the Cloudflare dashboard
|
||||
# LOKI_PUSH_URL = "https://${loki_base_url}>/loki/api/v1/push"
|
||||
|
||||
10
infra/workers/thumbnails/package.json
Normal file
10
infra/workers/thumbnails/package.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "thumbnails",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20240614.0",
|
||||
"typescript": "^5",
|
||||
"wrangler": "^3"
|
||||
},
|
||||
"packageManager": "yarn@1.22.22"
|
||||
}
|
||||
89
infra/workers/thumbnails/src/index.ts
Normal file
89
infra/workers/thumbnails/src/index.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
/** Proxy requests for thumbnails. */
|
||||
|
||||
export default {
|
||||
async fetch(request: Request) {
|
||||
switch (request.method) {
|
||||
case "OPTIONS":
|
||||
return handleOPTIONS(request);
|
||||
case "GET":
|
||||
return handleGET(request);
|
||||
default:
|
||||
console.log(`Unsupported HTTP method ${request.method}`);
|
||||
return new Response(null, { status: 405 });
|
||||
}
|
||||
},
|
||||
} satisfies ExportedHandler;
|
||||
|
||||
const handleOPTIONS = (request: Request) => {
|
||||
const origin = request.headers.get("Origin");
|
||||
if (!isAllowedOrigin(origin)) console.warn("Unknown origin", origin);
|
||||
const headers = request.headers.get("Access-Control-Request-Headers");
|
||||
if (!areAllowedHeaders(headers))
|
||||
console.warn("Unknown header in list", headers);
|
||||
return new Response("", {
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Methods": "GET, OPTIONS",
|
||||
"Access-Control-Max-Age": "86400",
|
||||
// "Access-Control-Allow-Headers": "X-Auth-Token, X-Client-Package",
|
||||
"Access-Control-Allow-Headers": "*",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const isAllowedOrigin = (origin: string | null) => {
|
||||
const desktopApp = "ente://app";
|
||||
const allowedHostnames = [
|
||||
"web.ente.io",
|
||||
"photos.ente.io",
|
||||
"photos.ente.sh",
|
||||
"localhost",
|
||||
];
|
||||
|
||||
if (!origin) return false;
|
||||
try {
|
||||
const url = new URL(origin);
|
||||
return origin == desktopApp || allowedHostnames.includes(url.hostname);
|
||||
} catch {
|
||||
// origin is likely an invalid URL
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const areAllowedHeaders = (headers: string | null) => {
|
||||
const allowed = ["x-auth-token", "x-client-package"];
|
||||
|
||||
if (!headers) return true;
|
||||
for (const header of headers.split(",")) {
|
||||
if (!allowed.includes(header.trim().toLowerCase())) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const handleGET = async (request: Request) => {
|
||||
const url = new URL(request.url);
|
||||
|
||||
const fileID = url.searchParams.get("fileID");
|
||||
if (!fileID) return new Response(null, { status: 400 });
|
||||
|
||||
let token = request.headers.get("X-Auth-Token");
|
||||
if (!token) {
|
||||
console.warn("Using deprecated token query param");
|
||||
token = url.searchParams.get("token");
|
||||
}
|
||||
|
||||
if (!token) {
|
||||
console.error("No token provided");
|
||||
// return new Response(null, { status: 400 });
|
||||
}
|
||||
|
||||
const params = new URLSearchParams();
|
||||
if (token) params.set("token", token);
|
||||
|
||||
let response = await fetch(
|
||||
`https://api.ente.io/files/preview/${fileID}?${params.toString()}`
|
||||
);
|
||||
response = new Response(response.body, response);
|
||||
response.headers.set("Access-Control-Allow-Origin", "*");
|
||||
return response;
|
||||
};
|
||||
1
infra/workers/thumbnails/tsconfig.json
Normal file
1
infra/workers/thumbnails/tsconfig.json
Normal file
@@ -0,0 +1 @@
|
||||
{ "extends": "../tsconfig.base.json", "include": ["src"] }
|
||||
11
infra/workers/thumbnails/wrangler.toml
Normal file
11
infra/workers/thumbnails/wrangler.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
name = "thumbnails"
|
||||
main = "src/index.ts"
|
||||
compatibility_date = "2024-06-14"
|
||||
|
||||
routes = [
|
||||
{ pattern = "thumbnails.ente.io", custom_domain = true }
|
||||
]
|
||||
|
||||
tail_consumers = [
|
||||
{ service = "tail" }
|
||||
]
|
||||
10
infra/workers/uploader/package.json
Normal file
10
infra/workers/uploader/package.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "uploader",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20240614.0",
|
||||
"typescript": "^5",
|
||||
"wrangler": "^3"
|
||||
},
|
||||
"packageManager": "yarn@1.22.22"
|
||||
}
|
||||
124
infra/workers/uploader/src/index.ts
Normal file
124
infra/workers/uploader/src/index.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* Proxy file uploads.
|
||||
*
|
||||
* See: https://ente.io/blog/tech/making-uploads-faster/
|
||||
*/
|
||||
|
||||
export default {
|
||||
async fetch(request: Request) {
|
||||
switch (request.method) {
|
||||
case "OPTIONS":
|
||||
return handleOPTIONS(request);
|
||||
case "POST":
|
||||
return handlePOSTOrPUT(request);
|
||||
case "PUT":
|
||||
return handlePOSTOrPUT(request);
|
||||
default:
|
||||
console.log(`Unsupported HTTP method ${request.method}`);
|
||||
return new Response(null, { status: 405 });
|
||||
}
|
||||
},
|
||||
} satisfies ExportedHandler;
|
||||
|
||||
const handleOPTIONS = (request: Request) => {
|
||||
const origin = request.headers.get("Origin");
|
||||
if (!isAllowedOrigin(origin)) console.warn("Unknown origin", origin);
|
||||
const headers = request.headers.get("Access-Control-Request-Headers");
|
||||
if (!areAllowedHeaders(headers))
|
||||
console.warn("Unknown header in list", headers);
|
||||
return new Response("", {
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Methods": "POST, PUT, OPTIONS",
|
||||
"Access-Control-Max-Age": "86400",
|
||||
// "Access-Control-Allow-Headers": "Content-Type", "UPLOAD-URL, X-Client-Package",
|
||||
"Access-Control-Allow-Headers": "*",
|
||||
"Access-Control-Expose-Headers": "X-Request-Id, CF-Ray",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const isAllowedOrigin = (origin: string | null) => {
|
||||
const desktopApp = "ente://app";
|
||||
const allowedHostnames = [
|
||||
"web.ente.io",
|
||||
"photos.ente.io",
|
||||
"photos.ente.sh",
|
||||
"localhost",
|
||||
];
|
||||
|
||||
if (!origin) return false;
|
||||
try {
|
||||
const url = new URL(origin);
|
||||
return origin == desktopApp || allowedHostnames.includes(url.hostname);
|
||||
} catch {
|
||||
// origin is likely an invalid URL
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const areAllowedHeaders = (headers: string | null) => {
|
||||
const allowed = ["content-type", "upload-url", "x-client-package"];
|
||||
|
||||
if (!headers) return true;
|
||||
for (const header of headers.split(",")) {
|
||||
if (!allowed.includes(header.trim().toLowerCase())) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const handlePOSTOrPUT = async (request: Request) => {
|
||||
const url = new URL(request.url);
|
||||
|
||||
const uploadURL = request.headers.get("UPLOAD-URL");
|
||||
if (!uploadURL) {
|
||||
console.error("No uploadURL provided");
|
||||
return new Response(null, { status: 400 });
|
||||
}
|
||||
|
||||
let response: Response;
|
||||
switch (url.pathname) {
|
||||
case "/file-upload":
|
||||
response = await fetch(uploadURL, {
|
||||
method: request.method,
|
||||
body: request.body,
|
||||
});
|
||||
break;
|
||||
case "/multipart-upload":
|
||||
response = await fetch(uploadURL, {
|
||||
method: request.method,
|
||||
body: request.body,
|
||||
});
|
||||
if (response.ok) {
|
||||
const etag = response.headers.get("etag");
|
||||
if (etag === null) {
|
||||
console.log("No etag in response", response);
|
||||
response = new Response(null, { status: 500 });
|
||||
} else {
|
||||
response = new Response(JSON.stringify({ etag }));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "/multipart-complete":
|
||||
response = await fetch(uploadURL, {
|
||||
method: request.method,
|
||||
body: request.body,
|
||||
headers: {
|
||||
"Content-Type": "text/xml",
|
||||
},
|
||||
});
|
||||
break;
|
||||
default:
|
||||
return new Response(null, { status: 404 });
|
||||
}
|
||||
|
||||
if (!response.ok) console.log("Request failed", response.status);
|
||||
|
||||
response = new Response(response.body, response);
|
||||
response.headers.set("Access-Control-Allow-Origin", "*");
|
||||
response.headers.set(
|
||||
"Access-Control-Expose-Headers",
|
||||
"X-Request-Id, CF-Ray"
|
||||
);
|
||||
return response;
|
||||
};
|
||||
1
infra/workers/uploader/tsconfig.json
Normal file
1
infra/workers/uploader/tsconfig.json
Normal file
@@ -0,0 +1 @@
|
||||
{ "extends": "../tsconfig.base.json", "include": ["src"] }
|
||||
7
infra/workers/uploader/wrangler.toml
Normal file
7
infra/workers/uploader/wrangler.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
name = "uploader"
|
||||
main = "src/index.ts"
|
||||
compatibility_date = "2024-06-14"
|
||||
|
||||
routes = [{ pattern = "uploader.ente.io", custom_domain = true }]
|
||||
|
||||
tail_consumers = [{ service = "tail" }]
|
||||
@@ -38,6 +38,8 @@ export default function Index() {
|
||||
}, [publicKeyB64, privateKeyB64, pairingCode]);
|
||||
|
||||
const pollTick = async () => {
|
||||
if (!publicKeyB64 || !privateKeyB64 || !pairingCode) return;
|
||||
|
||||
const registration = { publicKeyB64, privateKeyB64, pairingCode };
|
||||
try {
|
||||
const data = await getCastData(registration);
|
||||
|
||||
@@ -9,9 +9,8 @@ import { isChromecast } from "services/chromecast";
|
||||
import { imageURLGenerator } from "services/render";
|
||||
|
||||
export default function Slideshow() {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [imageURL, setImageURL] = useState<string | undefined>();
|
||||
const [isEmpty, setIsEmpty] = useState(false);
|
||||
const [imageURL, setImageURL] = useState<string | undefined>();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
@@ -35,7 +34,6 @@ export default function Slideshow() {
|
||||
}
|
||||
|
||||
setImageURL(url);
|
||||
setLoading(false);
|
||||
}
|
||||
} catch (e) {
|
||||
log.error("Failed to prepare generator", e);
|
||||
@@ -50,8 +48,8 @@ export default function Slideshow() {
|
||||
};
|
||||
}, []);
|
||||
|
||||
if (loading) return <PairingComplete />;
|
||||
if (isEmpty) return <NoItems />;
|
||||
if (!imageURL) return <PairingComplete />;
|
||||
|
||||
return isChromecast() ? (
|
||||
<SlideViewChromecast url={imageURL} />
|
||||
|
||||
@@ -19,8 +19,8 @@ export const storeCastData = (payload: unknown) => {
|
||||
// Iterate through all the keys of the payload object and save them to
|
||||
// localStorage. We don't validate here, we'll validate when we read these
|
||||
// values back in `readCastData`.
|
||||
for (const key in payload) {
|
||||
window.localStorage.setItem(key, payload[key]);
|
||||
for (const [key, value] of Object.entries(payload)) {
|
||||
window.localStorage.setItem(key, value);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -141,6 +141,7 @@ const advertiseCode = (cast: Cast) => {
|
||||
const collectionID =
|
||||
data &&
|
||||
typeof data == "object" &&
|
||||
"collectionID" in data &&
|
||||
typeof data["collectionID"] == "string"
|
||||
? data["collectionID"]
|
||||
: undefined;
|
||||
|
||||
@@ -13,7 +13,7 @@ import FileType from "file-type";
|
||||
* For the list of returned extensions, see (for our installed version):
|
||||
* https://github.com/sindresorhus/file-type/blob/main/core.d.ts
|
||||
*/
|
||||
export const detectMediaMIMEType = async (file: File): Promise<string> => {
|
||||
export const detectMediaMIMEType = async (file: File) => {
|
||||
const chunkSizeForTypeDetection = 4100;
|
||||
const fileChunk = file.slice(0, chunkSizeForTypeDetection);
|
||||
const chunk = new Uint8Array(await fileChunk.arrayBuffer());
|
||||
|
||||
@@ -81,7 +81,7 @@ export const register = async (): Promise<Registration> => {
|
||||
await generateKeyPair();
|
||||
|
||||
// Register keypair with museum to get a pairing code.
|
||||
let pairingCode: string;
|
||||
let pairingCode: string | undefined;
|
||||
// eslint has fixed this spurious warning, but we're not on the latest
|
||||
// version yet, so add a disable.
|
||||
// https://github.com/eslint/eslint/pull/18286
|
||||
|
||||
@@ -7,6 +7,7 @@ import { nameAndExtension } from "@/next/file";
|
||||
import log from "@/next/log";
|
||||
import type { ComlinkWorker } from "@/next/worker/comlink-worker";
|
||||
import { shuffled } from "@/utils/array";
|
||||
import { ensure } from "@/utils/ensure";
|
||||
import { wait } from "@/utils/promise";
|
||||
import ComlinkCryptoWorker from "@ente/shared/crypto";
|
||||
import { ApiError } from "@ente/shared/error";
|
||||
@@ -15,7 +16,7 @@ import { apiOrigin, customAPIOrigin } from "@ente/shared/network/api";
|
||||
import type { AxiosResponse } from "axios";
|
||||
import type { CastData } from "services/cast-data";
|
||||
import { detectMediaMIMEType } from "services/detect-type";
|
||||
import {
|
||||
import type {
|
||||
EncryptedEnteFile,
|
||||
EnteFile,
|
||||
FileMagicMetadata,
|
||||
@@ -133,7 +134,7 @@ export const imageURLGenerator = async function* (castData: CastData) {
|
||||
// The last to last element is the one that was shown prior to that,
|
||||
// and now can be safely revoked.
|
||||
if (previousURLs.length > 1)
|
||||
URL.revokeObjectURL(previousURLs.shift());
|
||||
URL.revokeObjectURL(ensure(previousURLs.shift()));
|
||||
|
||||
previousURLs.push(url);
|
||||
|
||||
@@ -207,8 +208,8 @@ const decryptEnteFile = async (
|
||||
metadata.decryptionHeader,
|
||||
fileKey,
|
||||
);
|
||||
let fileMagicMetadata: FileMagicMetadata;
|
||||
let filePubMagicMetadata: FilePublicMagicMetadata;
|
||||
let fileMagicMetadata: FileMagicMetadata | undefined;
|
||||
let filePubMagicMetadata: FilePublicMagicMetadata | undefined;
|
||||
if (magicMetadata?.data) {
|
||||
fileMagicMetadata = {
|
||||
...encryptedFile.magicMetadata,
|
||||
@@ -242,6 +243,8 @@ const decryptEnteFile = async (
|
||||
if (file.pubMagicMetadata?.data.editedName) {
|
||||
file.metadata.title = file.pubMagicMetadata.data.editedName;
|
||||
}
|
||||
// @ts-expect-error TODO: The core types need to be updated to allow the
|
||||
// possibility of missing metadata fiels.
|
||||
return file;
|
||||
};
|
||||
|
||||
@@ -254,7 +257,7 @@ const isFileEligible = (file: EnteFile) => {
|
||||
// extension. To detect the actual type, we need to sniff the MIME type, but
|
||||
// that requires downloading and decrypting the file first.
|
||||
const [, extension] = nameAndExtension(file.metadata.title);
|
||||
if (isNonWebImageFileExtension(extension)) {
|
||||
if (extension && isNonWebImageFileExtension(extension)) {
|
||||
// Of the known non-web types, we support HEIC.
|
||||
return isHEICExtension(extension);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Metadata } from "@/media/types/file";
|
||||
import {
|
||||
import type {
|
||||
EncryptedMagicMetadata,
|
||||
MagicMetadataCore,
|
||||
VISIBILITY_STATE,
|
||||
|
||||
@@ -1,25 +1,17 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"extends": "@/build-config/tsconfig-next.json",
|
||||
"compilerOptions": {
|
||||
/* Set the base directory from which to resolve bare module names */
|
||||
"baseUrl": "./src",
|
||||
"downlevelIteration": true,
|
||||
"jsx": "preserve",
|
||||
"jsxImportSource": "@emotion/react",
|
||||
"lib": ["dom", "dom.iterable", "esnext", "webworker"],
|
||||
"noImplicitAny": false,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"strictNullChecks": false,
|
||||
"target": "es5",
|
||||
"useUnknownInCatchVariables": false
|
||||
|
||||
/* TODO(MR): Enable this */
|
||||
"noUncheckedIndexedAccess": false,
|
||||
/* MUI doesn't play great with exactOptionalPropertyTypes currently. */
|
||||
"exactOptionalPropertyTypes": false
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
"**/*.js",
|
||||
"../../packages/shared/themes/mui-theme.d.ts",
|
||||
"../../packages/accounts/**/*.tsx"
|
||||
],
|
||||
"exclude": ["node_modules", "out", ".next", "thirdparty"]
|
||||
"src",
|
||||
"../../packages/next/global-electron.d.ts",
|
||||
"../../packages/shared/themes/mui-theme.d.ts"
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user