From ea33ee3a62ba8366cf98b0974bda27a65ec9e876 Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Mon, 25 Dec 2023 17:43:03 +0100 Subject: [PATCH 1/8] Revert "[chore] disable oculus downgrade" This reverts commit 891e2338c9536826749dd5883be319f802839d1f. --- assets/jsons/translations/de.json | 3 +-- assets/jsons/translations/en.json | 3 +-- assets/jsons/translations/es.json | 3 +-- assets/jsons/translations/fr.json | 3 +-- assets/jsons/translations/ja.json | 3 +-- assets/jsons/translations/ru.json | 3 +-- assets/jsons/translations/zh-tw.json | 3 +-- assets/jsons/translations/zh.json | 3 +-- .../bs-downgrade/choose-store-modal.component.tsx | 12 ++++-------- 9 files changed, 12 insertions(+), 24 deletions(-) diff --git a/assets/jsons/translations/de.json b/assets/jsons/translations/de.json index 86376aad..d4acba37 100644 --- a/assets/jsons/translations/de.json +++ b/assets/jsons/translations/de.json @@ -505,8 +505,7 @@ "choose-store": { "title": "Welche Plattform?", "body": "Wählen Sie die Plattform, von der Sie Beat Saber herunterladen möchten.", - "set-in-settings": "Die Standardplattform in den Einstellungen festlegen", - "unavailable": "Aufgrund kürzlicher Änderungen von Oculus ist das Downgrade von Oculus-Versionen derzeit nicht mehr verfügbar. Wir untersuchen das Problem und werden Sie auf dem BSManager-Discord-Server auf dem Laufenden halten." + "set-in-settings": "Die Standardplattform in den Einstellungen festlegen" }, "guard": { "title": "Steam Guard", diff --git a/assets/jsons/translations/en.json b/assets/jsons/translations/en.json index fa3534d4..02527bae 100644 --- a/assets/jsons/translations/en.json +++ b/assets/jsons/translations/en.json @@ -505,8 +505,7 @@ "choose-store": { "title": "Which platform?", "body": "Select the platform from which you wish to download Beat Saber.", - "set-in-settings": "Set the default platform in settings", - "unavailable": "Due to recent changes by Oculus, downgrading Oculus versions is currently no longer available. We're investigating the issue and will keep you posted on the BSManager Discord server." + "set-in-settings": "Set the default platform in settings" }, "guard": { "title": "Steam Guard", diff --git a/assets/jsons/translations/es.json b/assets/jsons/translations/es.json index 6bdbd5fc..865c54a5 100644 --- a/assets/jsons/translations/es.json +++ b/assets/jsons/translations/es.json @@ -504,8 +504,7 @@ "choose-store": { "title": "¿Qué plataforma?", "body": "Selecciona la plataforma desde la que deseas descargar Beat Saber.", - "set-in-settings": "Establecer la plataforma predeterminada en los ajustes", - "unavailable": "Debido a cambios recientes de Oculus, la degradación de versiones de Oculus ya no está disponible. Estamos investigando el problema y te mantendremos informado en el servidor de Discord de BSManager." + "set-in-settings": "Establecer la plataforma predeterminada en los ajustes" }, "guard": { "title": "Steam Guard", diff --git a/assets/jsons/translations/fr.json b/assets/jsons/translations/fr.json index 515e03bb..e60ef015 100644 --- a/assets/jsons/translations/fr.json +++ b/assets/jsons/translations/fr.json @@ -501,8 +501,7 @@ "choose-store": { "title": "Quelle plateforme ?", "body": "Sélectionnez la plateforme depuis laquelle vous souhaitez télécharger Beat Saber.", - "set-in-settings": "Définir la platforme par défaut dans les paramètres", - "unavailable": "En raison de récents changements apportés par Oculus, la rétrogradation des versions d'Oculus n'est actuellement plus disponible. Nous étudions le problème et vous tiendrons au courant sur le serveur Discord de BSManager." + "set-in-settings": "Définir la platforme par défaut dans les paramètres" }, "guard": { "title": "Steam Guard", diff --git a/assets/jsons/translations/ja.json b/assets/jsons/translations/ja.json index 206e9326..85393775 100644 --- a/assets/jsons/translations/ja.json +++ b/assets/jsons/translations/ja.json @@ -505,8 +505,7 @@ "choose-store": { "title": "どのプラットフォーム?", "body": "Beat Saberをダウンロードするプラットフォームを選択してください。", - "set-in-settings": "設定からデフォルトのプラットフォームを設定する", - "unavailable": "Oculusによる最近の変更により、現在Oculusのバージョンダウングレードは利用できなくなりました。私たちは問題を調査しており、BSManagerのDiscordサーバーで最新情報をお知らせします。" + "set-in-settings": "設定からデフォルトのプラットフォームを設定する" }, "guard": { "title": "Steamガード", diff --git a/assets/jsons/translations/ru.json b/assets/jsons/translations/ru.json index 118b14f6..93b8c0bf 100644 --- a/assets/jsons/translations/ru.json +++ b/assets/jsons/translations/ru.json @@ -505,8 +505,7 @@ "choose-store": { "title": "Какая платформа?", "body": "Выберите платформу, с которой вы хотите скачать Beat Saber.", - "set-in-settings": "Установить платформу по умолчанию в настройках", - "unavailable": "В связи с недавними изменениями от Oculus, понижение версий Oculus в настоящее время больше не доступно. Мы изучаем проблему и будем держать вас в курсе на сервере BSManager в Discord." + "set-in-settings": "Установить платформу по умолчанию в настройках" }, "guard": { "title": "Steam Guard", diff --git a/assets/jsons/translations/zh-tw.json b/assets/jsons/translations/zh-tw.json index 257550e8..cca5aa27 100644 --- a/assets/jsons/translations/zh-tw.json +++ b/assets/jsons/translations/zh-tw.json @@ -505,8 +505,7 @@ "choose-store": { "title": "選擇哪個平台?", "body": "選擇你希望為其下載 BeatSaber 的平台。", - "set-in-settings": "在設定中設定預設平台", - "unavailable": "由於Oculus最近的更改,目前不再提供降級Oculus版本的服務。我們正在調查此問題,並將在BSManager Discord伺服器上保持更新。" + "set-in-settings": "在設定中設定預設平台" }, "guard": { "title": "Steam Guard", diff --git a/assets/jsons/translations/zh.json b/assets/jsons/translations/zh.json index 29d566bd..8db38707 100644 --- a/assets/jsons/translations/zh.json +++ b/assets/jsons/translations/zh.json @@ -505,8 +505,7 @@ "choose-store": { "title": "选择哪个平台?", "body": "选择你希望为其下载 BeatSaber 的平台。", - "set-in-settings": "在设置中设定默认平台", - "unavailable": "由于Oculus最近的更改,目前不再提供降级Oculus版本的服务。我们正在调查此问题,并将在BSManager Discord服务器上保持更新。" + "set-in-settings": "在设置中设定默认平台" }, "guard": { "title": "Steam Guard", diff --git a/src/renderer/components/modal/modal-types/bs-downgrade/choose-store-modal.component.tsx b/src/renderer/components/modal/modal-types/bs-downgrade/choose-store-modal.component.tsx index 93c1b4d2..b7f15208 100644 --- a/src/renderer/components/modal/modal-types/bs-downgrade/choose-store-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/bs-downgrade/choose-store-modal.component.tsx @@ -7,8 +7,6 @@ import { useState } from "react"; import tailwindConfig from "../../../../../../tailwind.config"; import Color from "color"; import { useNavigate } from "react-router-dom"; -import Tippy from "@tippyjs/react"; -import { followCursor } from "tippy.js"; export const ChooseStore: ModalComponent = ({ resolver }) => { @@ -49,12 +47,10 @@ export const ChooseStore: ModalComponent = ({ resolver }) => {

{t("modals.choose-store.title")}

{t("modals.choose-store.body")}

- -
- -

Oculus Store (PC)

-
-
+
setOculusHover(true)} onMouseLeave={() => setOculusHover(false)} onClick={() => chooseStore(BsStore.OCULUS)} style={{backgroundColor: oculusHover ? bg.dim : bg.bright}}> + +

Oculus Store (PC)

+
setSteamHover(true)} onMouseLeave={() => setSteamHover(false)} onClick={() => chooseStore(BsStore.STEAM)} style={{backgroundColor: steamHover ? bg.dim : bg.bright}}>

Steam

From 0539b0da8d648fc1625ccc0a86b852cf3181fbf6 Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Mon, 25 Dec 2023 17:44:22 +0100 Subject: [PATCH 2/8] Revert "Handle already chosen Oculus as default download platform" This reverts commit 14036b9269284fc1aa188ea7337de9dc96181db2. --- .../components/settings/setting-radio-array.component.tsx | 8 +------- src/renderer/pages/settings-page.component.tsx | 2 +- .../services/bs-version-download/bs-downloader.service.ts | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/renderer/components/settings/setting-radio-array.component.tsx b/src/renderer/components/settings/setting-radio-array.component.tsx index c6607760..60eb44a1 100644 --- a/src/renderer/components/settings/setting-radio-array.component.tsx +++ b/src/renderer/components/settings/setting-radio-array.component.tsx @@ -18,15 +18,10 @@ export function SettingRadioArray({ id, items, selectedItemId, selectedItemVa return item.id === selectedItemId || item.value === selectedItemValue; } - const selectItem = (item: RadioItem) => { - if(item.disabled){ return; } - onItemSelected?.(item); - } - return (
{items.map(i => ( -
selectItem(i)} key={i.id} className={`py-3 w-full flex ${i.disabled ? "cursor-not-allowed" : "cursor-pointer"} ${i.disabled && "brightness-75"} justify-between items-center rounded-md px-2 transition-colors duration-200 ${isSelected(i) ? "bg-light-main-color-3 dark:bg-main-color-3" : "bg-light-main-color-1 dark:bg-main-color-1"} ${i.className}`}> +
onItemSelected(i)} key={i.id} className={`py-3 w-full flex cursor-pointer justify-between items-center rounded-md px-2 transition-colors duration-200 ${isSelected(i) ? "bg-light-main-color-3 dark:bg-main-color-3" : "bg-light-main-color-1 dark:bg-main-color-1"} ${i.className}`}>
@@ -52,5 +47,4 @@ export interface RadioItem { textIcon?: string; className?: string; value?: T; - disabled?: boolean; } diff --git a/src/renderer/pages/settings-page.component.tsx b/src/renderer/pages/settings-page.component.tsx index f813fd9a..bccd2bf6 100644 --- a/src/renderer/pages/settings-page.component.tsx +++ b/src/renderer/pages/settings-page.component.tsx @@ -235,7 +235,7 @@ export function SettingsPage() { }, - { id: 2, text: "Oculus Store (PC)", value: BsStore.OCULUS, icon: , disabled: true}, + { id: 2, text: "Oculus Store (PC)", value: BsStore.OCULUS, icon: }, { id: 0, text: t("pages.settings.steam-and-oculus.download-platform.always-ask"), value: undefined, }, ]} selectedItemValue={downloadStore} onItemSelected={handleChangeBsStore}/> diff --git a/src/renderer/services/bs-version-download/bs-downloader.service.ts b/src/renderer/services/bs-version-download/bs-downloader.service.ts index f36d1876..200a5df8 100644 --- a/src/renderer/services/bs-version-download/bs-downloader.service.ts +++ b/src/renderer/services/bs-version-download/bs-downloader.service.ts @@ -75,7 +75,7 @@ export class BsDownloaderService extends AbstractBsDownloaderService { public async downloadVersion(version: BSVersion, from?: BsStore): Promise { if(!from){ - from = this.defaultStore === BsStore.STEAM ? BsStore.STEAM : await this.chooseStoreToDownloadFrom(); + from = this.defaultStore ?? await this.chooseStoreToDownloadFrom(); } return this.getStoreDownloader(from).downloadBsVersion(version).then(() => { From fa50d909412945f2d577646e02d6d6d9f2cdb4ee Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Tue, 26 Dec 2023 22:41:05 +0100 Subject: [PATCH 3/8] [chore] disable download oculus version with Meta login + Add possibility to store token with password --- assets/jsons/patreons.json | 90 ++++++-- assets/jsons/translations/de.json | 18 +- assets/jsons/translations/en.json | 18 +- assets/jsons/translations/es.json | 18 +- assets/jsons/translations/fr.json | 18 +- assets/jsons/translations/ja.json | 20 +- assets/jsons/translations/ru.json | 18 +- assets/jsons/translations/zh-tw.json | 18 +- assets/jsons/translations/zh.json | 18 +- package-lock.json | 22 ++ package.json | 2 + .../bs-oculus-downloader.service.ts | 1 + .../enter-meta-token-modal.component.tsx | 196 +++++++++++++++--- .../pages/settings-page.component.tsx | 3 +- .../bs-downloader.service.ts | 8 +- .../oculus-downloader.service.ts | 48 ++--- .../services/configuration.service.ts | 10 +- src/shared/helpers/oculus.helpers.ts | 14 +- 18 files changed, 418 insertions(+), 122 deletions(-) diff --git a/assets/jsons/patreons.json b/assets/jsons/patreons.json index 4f579763..4a876ea3 100644 --- a/assets/jsons/patreons.json +++ b/assets/jsons/patreons.json @@ -1,21 +1,71 @@ [ - {"username": "Shidorien"}, - {"username": "iPixelGalaxy"}, - {"username": "Emyte", "type": "gold"}, - {"username": "GoodOldNervy"}, - {"username": "Naysy"}, - {"username": "Falmil"}, - {"username": "K1Lc4m"}, - {"username": "Anonymously42", "type": "diamond", "link": "https://www.twitch.tv/anonymously42tv"}, - {"username": "Burt", "type": "gold"}, - {"username": "Ilnahro"}, - {"username": "Phil", "type": "gold"}, - {"username": "Protocrush", "type": "gold"}, - {"username": "ServerMensch", "type": "gold"}, - {"username": "Karlito", "type": "gold"}, - {"username": "Cathery", "type": "gold"}, - {"username": ".sharkey"}, - {"username": "Z3t4"}, - {"username": "blot455", "type": "diamond"}, - {"username": "Lumberjack462", "type": "diamond", "link": "https://www.youtube.com/@lumberjack462"} -] + { + "username": "Shidorien" + }, + { + "username": "iPixelGalaxy" + }, + { + "username": "Emyte", + "type": "gold" + }, + { + "username": "GoodOldNervy" + }, + { + "username": "Naysy" + }, + { + "username": "Falmil" + }, + { + "username": "K1Lc4m" + }, + { + "username": "Anonymously42", + "type": "diamond", + "link": "https://www.twitch.tv/anonymously42tv" + }, + { + "username": "Burt", + "type": "gold" + }, + { + "username": "Ilnahro" + }, + { + "username": "Phil", + "type": "gold" + }, + { + "username": "Protocrush", + "type": "gold" + }, + { + "username": "ServerMensch", + "type": "gold" + }, + { + "username": "Karlito", + "type": "gold" + }, + { + "username": "Cathery", + "type": "gold" + }, + { + "username": ".sharkey" + }, + { + "username": "Z3t4" + }, + { + "username": "blot455", + "type": "diamond" + }, + { + "username": "Lumberjack462", + "type": "diamond", + "link": "https://www.youtube.com/@lumberjack462" + } +] \ No newline at end of file diff --git a/assets/jsons/translations/de.json b/assets/jsons/translations/de.json index d4acba37..4a631259 100644 --- a/assets/jsons/translations/de.json +++ b/assets/jsons/translations/de.json @@ -707,12 +707,20 @@ "understood": "Verstanden" }, "enter-meta-token": { - "title": "Meta-Token", + "title": "Oculus Token", "body": { - "need-token": "Um Beat Saber herunterzuladen, ist Ihr Meta-Anmelde-Token erforderlich.", - "how-obtain-token": "Wie erhalte ich mein Meta-Token?", - "input-label": "Meta-Token", - "token-is-invalid": "Das Token ist ungültig." + "info-enter-token": "Um Beat Saber herunterzuladen, ist Ihr Oculus-Anmeldetoken erforderlich.", + "how-obtain-token": "Wie erhalte ich mein Oculus Token?", + "oculus-token": "Oculus Token", + "token-is-invalid": "Das Token ist ungültig.", + "save-my-token": "Mein Token speichern", + "have-token-saved": "Ich habe bereits ein Token gespeichert", + "save-token-info": "Dies wird Ihr Token zur einfacheren Wiederverwendung speichern. Sie müssen ein Passwort erstellen, um Ihr Token zu verschlüsseln und zu speichern. Wenn Sie Ihr Passwort vergessen, müssen Sie nur Ihr Token erneut angeben.", + "password": "Passwort", + "password-too-short": "Passwort zu kurz", + "info-enter-password": "Um Beat Saber herunterzuladen, ist Ihr Oculus-Anmeldetoken erforderlich. Geben Sie das Passwort ein, mit dem Ihr Oculus-Token gespeichert wurde.", + "info-disabled-btn-password": "Der mit dem angegebenen Passwort entschlüsselte Token ist ungültig. Stellen Sie sicher, dass das Passwort dasselbe ist wie das zum Speichern des Tokens verwendete.", + "enter-oculus-token": "Ein Oculus-Token eingeben" }, "valid-btn": "Validieren" } diff --git a/assets/jsons/translations/en.json b/assets/jsons/translations/en.json index 02527bae..625c0405 100644 --- a/assets/jsons/translations/en.json +++ b/assets/jsons/translations/en.json @@ -707,12 +707,20 @@ "understood": "Understood" }, "enter-meta-token": { - "title": "Meta Token", + "title": "Oculus Token", "body": { - "need-token": "To download Beat Saber, your Meta login token is required.", - "how-obtain-token": "How do I obtain my Meta Token?", - "input-label": "Meta Token", - "token-is-invalid": "The Token is invalid." + "info-enter-token": "To download Beat Saber, your Oculus login token is required.", + "how-obtain-token": "How do I obtain my Oculus Token?", + "oculus-token": "Oculus Token", + "token-is-invalid": "The Token is invalid.", + "save-my-token": "Save my token", + "have-token-saved": "I already have a token saved", + "save-token-info": "This will save your token for easier reuse. You will need to create a password to encrypt your token for storage purposes. If you ever forget your password, you just need to provide your token again.", + "password": "Password", + "password-too-short": "Password too short", + "info-enter-password": "To download Beat Saber, your Oculus login token is required. Enter the password used to save your Oculus token.", + "info-disabled-btn-password": "The token decrypted with the provided password is invalid. Make sure the password is the same as the one used to save the token.", + "enter-oculus-token": "Enter an Oculus token" }, "valid-btn": "Validate" } diff --git a/assets/jsons/translations/es.json b/assets/jsons/translations/es.json index 865c54a5..67441fa6 100644 --- a/assets/jsons/translations/es.json +++ b/assets/jsons/translations/es.json @@ -706,12 +706,20 @@ "understood": "Entendido" }, "enter-meta-token": { - "title": "Token de Meta", + "title": "Token de Oculus", "body": { - "need-token": "Para descargar Beat Saber, se requiere su token de inicio de sesión de Meta.", - "how-obtain-token": "¿Cómo obtengo mi Token de Meta?", - "input-label": "Token de Meta", - "token-is-invalid": "El Token es inválido." + "info-enter-token": "Para descargar Beat Saber, se requiere tu token de inicio de sesión de Oculus.", + "how-obtain-token": "¿Cómo obtengo mi Token de Oculus?", + "oculus-token": "Token de Oculus", + "token-is-invalid": "El token es inválido.", + "save-my-token": "Guardar mi token", + "have-token-saved": "Ya tengo un token guardado", + "save-token-info": "Esto guardará tu token para reutilizarlo más fácilmente. Necesitarás crear una contraseña para encriptar tu token para su almacenamiento. Si alguna vez olvidas tu contraseña, solo necesitas proporcionar tu token nuevamente.", + "password": "Contraseña", + "password-too-short": "Contraseña demasiado corta", + "info-enter-password": "Para descargar Beat Saber, se requiere tu token de inicio de sesión de Oculus. Introduce la contraseña utilizada para guardar tu token de Oculus.", + "info-disabled-btn-password": "El token descifrado con la contraseña proporcionada es inválido. Asegúrate de que la contraseña sea la misma que la utilizada para guardar el token.", + "enter-oculus-token": "Introducir un token de Oculus" }, "valid-btn": "Validar" } diff --git a/assets/jsons/translations/fr.json b/assets/jsons/translations/fr.json index e60ef015..7631e256 100644 --- a/assets/jsons/translations/fr.json +++ b/assets/jsons/translations/fr.json @@ -703,12 +703,20 @@ "understood": "J'ai compris" }, "enter-meta-token": { - "title": "Token Meta", + "title": "Token Oculus", "body": { - "need-token": "Pour télécharger Beat Saber, votre token de connexion à Meta est nécessaire.", - "how-obtain-token": "Comment obtenir mon Token Meta ?", - "input-label": "Token Meta", - "token-is-invalid": "Le Token est invalide." + "info-enter-token": "Pour télécharger Beat Saber, votre token de connexion à Oculus est nécessaire.", + "how-obtain-token": "Comment obtenir mon Token Oculus ?", + "oculus-token": "Token Oculus", + "token-is-invalid": "Le Token est invalide.", + "save-my-token": "Sauvegarder mon token", + "have-token-saved": "J'ai déjà un token sauvegardé", + "save-token-info": "Ceci enregistrera votre token pour le réutiliser plus facilement. Vous devrez créer un mot de passe pour crypter votre token à des fins de stockage. Si jamais vous oubliez votre mot de passe, il vous suffit de fournir à nouveau votre token.", + "password": "Mot de passe", + "password-too-short": "Mot de passe trop court", + "info-enter-password": "Pour télécharger Beat Saber, votre token de connexion à Oculus est nécessaire. Entrez le mot de passe utilisé pour sauvegarder votre token Oculus.", + "info-disabled-btn-password": "Le token déchiffré à l'aide du mot de passe fourni est invalide. Assurez-vous que le mot de passe est le même que celui utilisé pour sauvegarder le token.", + "enter-oculus-token": "Entrer un token Oculus" }, "valid-btn": "Valider" } diff --git a/assets/jsons/translations/ja.json b/assets/jsons/translations/ja.json index 85393775..65132a6a 100644 --- a/assets/jsons/translations/ja.json +++ b/assets/jsons/translations/ja.json @@ -707,14 +707,22 @@ "understood": "分かった" }, "enter-meta-token": { - "title": "Metaトークン", + "title": "Oculusトークン", "body": { - "need-token": "Beat Saberをダウンロードするには、Metaのログイントークンが必要です。", - "how-obtain-token": "Metaトークンはどうやって入手すればいいですか?", - "input-label": "Metaトークン", - "token-is-invalid": "トークンが無効です。" + "info-enter-token": "Beat Saberをダウンロードするには、あなたのオキュラスログイントークンが必要です。", + "how-obtain-token": "オキュラストークンはどうやって取得するの?", + "oculus-token": "オキュラストークン", + "token-is-invalid": "トークンが無効です。", + "save-my-token": "私のトークンを保存する", + "have-token-saved": "すでにトークンを保存しています", + "save-token-info": "これにより、トークンを簡単に再利用するために保存します。保管のためにトークンを暗号化するパスワードを作成する必要があります。パスワードを忘れた場合は、トークンを再度提供するだけです。", + "password": "パスワード", + "password-too-short": "パスワードが短すぎます", + "info-enter-password": "Beat Saberをダウンロードするには、あなたのオキュラスログイントークンが必要です。オキュラストークンを保存するために使用したパスワードを入力してください。", + "info-disabled-btn-password": "提供されたパスワードで復号化されたトークンは無効です。トークンを保存するために使用されたパスワードと同じであることを確認してください。", + "enter-oculus-token": "オキュラストークンを入力する" }, - "valid-btn": "検証" + "valid-btn": "確認" } }, "maps": { diff --git a/assets/jsons/translations/ru.json b/assets/jsons/translations/ru.json index 93b8c0bf..f1e289e6 100644 --- a/assets/jsons/translations/ru.json +++ b/assets/jsons/translations/ru.json @@ -707,12 +707,20 @@ "understood": "Понял" }, "enter-meta-token": { - "title": "Мета Токен", + "title": "Токен Oculus", "body": { - "need-token": "Для загрузки Beat Saber требуется ваш токен входа в Meta.", - "how-obtain-token": "Как получить мой Мета Токен?", - "input-label": "Мета Токен", - "token-is-invalid": "Токен недействителен." + "info-enter-token": "Для загрузки Beat Saber требуется ваш токен входа в Oculus.", + "how-obtain-token": "Как получить мой токен Oculus?", + "oculus-token": "Токен Oculus", + "token-is-invalid": "Токен недействителен.", + "save-my-token": "Сохранить мой токен", + "have-token-saved": "У меня уже есть сохраненный токен", + "save-token-info": "Это сохранит ваш токен для удобства повторного использования. Вам необходимо создать пароль для шифрования вашего токена для хранения. Если вы забудете пароль, вам просто нужно будет снова предоставить свой токен.", + "password": "Пароль", + "password-too-short": "Слишком короткий пароль", + "info-enter-password": "Для загрузки Beat Saber требуется ваш токен входа в Oculus. Введите пароль, используемый для сохранения вашего токена Oculus.", + "info-disabled-btn-password": "Токен, расшифрованный с использованием предоставленного пароля, недействителен. Убедитесь, что пароль совпадает с тем, который использовался для сохранения токена.", + "enter-oculus-token": "Введите токен Oculus" }, "valid-btn": "Подтвердить" } diff --git a/assets/jsons/translations/zh-tw.json b/assets/jsons/translations/zh-tw.json index cca5aa27..cf2e71b2 100644 --- a/assets/jsons/translations/zh-tw.json +++ b/assets/jsons/translations/zh-tw.json @@ -708,12 +708,20 @@ "understood": "明白了" }, "enter-meta-token": { - "title": "Meta 令牌", + "title": "Oculus令牌", "body": { - "need-token": "要下載 BeatSaber,需要你的 Meta 登錄令牌。", - "how-obtain-token": "如何獲取我的 Meta 令牌?", - "input-label": "Meta 令牌", - "token-is-invalid": "令牌無效。" + "info-enter-token": "下載Beat Saber需要您的Oculus登錄令牌。", + "how-obtain-token": "我如何獲得我的Oculus令牌?", + "oculus-token": "Oculus令牌", + "token-is-invalid": "令牌無效。", + "save-my-token": "保存我的令牌", + "have-token-saved": "我已經保存了一個令牌", + "save-token-info": "這將保存您的令牌以便更容易地重新使用。您需要創建一個密碼來加密您的令牌以進行存儲。如果您忘記了密碼,只需再次提供您的令牌即可。", + "password": "密碼", + "password-too-short": "密碼太短", + "info-enter-password": "下載Beat Saber需要您的Oculus登錄令牌。請輸入用於保存您的Oculus令牌的密碼。", + "info-disabled-btn-password": "使用提供的密碼解密的令牌無效。確保密碼與保存令牌時使用的密碼相同。", + "enter-oculus-token": "輸入Oculus令牌" }, "valid-btn": "驗證" } diff --git a/assets/jsons/translations/zh.json b/assets/jsons/translations/zh.json index 8db38707..2e806fc0 100644 --- a/assets/jsons/translations/zh.json +++ b/assets/jsons/translations/zh.json @@ -708,12 +708,20 @@ "understood": "明白了" }, "enter-meta-token": { - "title": "Meta 令牌", + "title": "Oculus令牌", "body": { - "need-token": "要下载 BeatSaber,需要你的 Meta 登录令牌。", - "how-obtain-token": "如何获取我的 Meta 令牌?", - "input-label": "Meta 令牌", - "token-is-invalid": "令牌无效。" + "info-enter-token": "下载Beat Saber需要您的Oculus登录令牌。", + "how-obtain-token": "我如何获得我的Oculus令牌?", + "oculus-token": "Oculus令牌", + "token-is-invalid": "令牌无效。", + "save-my-token": "保存我的令牌", + "have-token-saved": "我已经保存了一个令牌", + "save-token-info": "这将保存您的令牌以便更容易地重新使用。您需要创建一个密码来加密您的令牌以进行存储。如果您忘记了密码,只需再次提供您的令牌即可。", + "password": "密码", + "password-too-short": "密码太短", + "info-enter-password": "下载Beat Saber需要您的Oculus登录令牌。请输入用于保存您的Oculus令牌的密码。", + "info-disabled-btn-password": "使用提供的密码解密的令牌无效。确保密码与保存令牌时使用的密码相同。", + "enter-oculus-token": "输入Oculus令牌" }, "valid-btn": "验证" } diff --git a/package-lock.json b/package-lock.json index 88acdeb7..d9494b8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,10 @@ "@electron/fuses": "^1.6.2", "@node-steam/vdf": "^2.2.0", "@tippyjs/react": "^4.2.6", + "@types/crypto-js": "^4.2.1", "archiver": "^6.0.1", "color": "^4.2.3", + "crypto-js": "^4.2.0", "dateformat": "^5.0.3", "dot-prop": "^8.0.2", "electron-debug": "^3.2.0", @@ -2524,6 +2526,11 @@ "@types/node": "*" } }, + "node_modules/@types/crypto-js": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.2.1.tgz", + "integrity": "sha512-FSPGd9+OcSok3RsM0UZ/9fcvMOXJ1ENE/ZbLfOPlBWj7BgXtEAM8VYfTtT760GiLbQIMoVozwVuisjvsVwqYWw==" + }, "node_modules/@types/dateformat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/dateformat/-/dateformat-5.0.0.tgz", @@ -5711,6 +5718,11 @@ "node": ">= 8" } }, + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" + }, "node_modules/css-color-names": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", @@ -21062,6 +21074,11 @@ "@types/node": "*" } }, + "@types/crypto-js": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.2.1.tgz", + "integrity": "sha512-FSPGd9+OcSok3RsM0UZ/9fcvMOXJ1ENE/ZbLfOPlBWj7BgXtEAM8VYfTtT760GiLbQIMoVozwVuisjvsVwqYWw==" + }, "@types/dateformat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/dateformat/-/dateformat-5.0.0.tgz", @@ -23585,6 +23602,11 @@ "which": "^2.0.1" } }, + "crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" + }, "css-color-names": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", diff --git a/package.json b/package.json index 6e1b815a..6ac26fbe 100644 --- a/package.json +++ b/package.json @@ -236,8 +236,10 @@ "@electron/fuses": "^1.6.2", "@node-steam/vdf": "^2.2.0", "@tippyjs/react": "^4.2.6", + "@types/crypto-js": "^4.2.1", "archiver": "^6.0.1", "color": "^4.2.3", + "crypto-js": "^4.2.0", "dateformat": "^5.0.3", "dot-prop": "^8.0.2", "electron-debug": "^3.2.0", diff --git a/src/main/services/bs-version-download/bs-oculus-downloader.service.ts b/src/main/services/bs-version-download/bs-oculus-downloader.service.ts index 7fc43a3b..3b974a0c 100644 --- a/src/main/services/bs-version-download/bs-oculus-downloader.service.ts +++ b/src/main/services/bs-version-download/bs-oculus-downloader.service.ts @@ -129,6 +129,7 @@ export class BsOculusDownloaderService { return tokenObs$.pipe( switchMap(token => { + isOculusTokenValid(token, log.info); // Log token validity if(!downloadInfo.isVerification){ return this.createDownloadVersion(downloadInfo.bsVersion).then(({version, dest}) => ({token, version, dest})) } diff --git a/src/renderer/components/modal/modal-types/bs-downgrade/enter-meta-token-modal.component.tsx b/src/renderer/components/modal/modal-types/bs-downgrade/enter-meta-token-modal.component.tsx index 796f05ef..f7c8be4f 100644 --- a/src/renderer/components/modal/modal-types/bs-downgrade/enter-meta-token-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/bs-downgrade/enter-meta-token-modal.component.tsx @@ -5,55 +5,203 @@ import BeatWaiting from "../../../../../../assets/images/apngs/beat-impatient.pn import { useTranslation } from "renderer/hooks/use-translation.hook"; import { useState } from "react"; import { isOculusTokenValid } from "shared/helpers/oculus.helpers"; +import crypto from "crypto-js"; +import { BsmCheckbox } from "renderer/components/shared/bsm-checkbox.component"; +import Tippy from "@tippyjs/react"; +import { tryit } from "shared/helpers/error.helpers"; import { logRenderError } from "renderer"; +import { useService } from "renderer/hooks/use-service.hook"; +import { ConfigurationService } from "renderer/services/configuration.service"; + +const OCULUS_TOKEN_STORAGE_KEY = "meta-token"; export const EnterMetaTokenModal: ModalComponent = ({resolver}) => { const t = useTranslation(); - const [token, setToken] = useState(""); - const [showToken, setShowToken] = useState(false); + const config = useService(ConfigurationService); - const submit = () => { + const [passwordView, setPasswordView] = useState(() => !!config.get(OCULUS_TOKEN_STORAGE_KEY)); + + const submit = (token: string) => { resolver({exitCode: ModalExitCode.COMPLETED, data: token}); } const cancel = () => { resolver({exitCode: ModalExitCode.CANCELED}); } - - const isTokenValid = (() => { - return isOculusTokenValid(token, logRenderError); - })(); return (

{t("modals.enter-meta-token.title")}

- + {passwordView ? ( + setPasswordView(() => false)}/> + ) : ( + setPasswordView(() => true)}/> + )} + + ); +} -

{t("modals.enter-meta-token.body.need-token")}

+const isPasswordValid = (password: string) => { + return password.length >= 8; +} - {t("modals.enter-meta-token.body.how-obtain-token")} - -
-
- - {!isTokenValid && token.length > 0 && ( - {t("modals.enter-meta-token.body.token-is-invalid")} - )} +const EnterPasswordView = ({onValid, onCancel, dontHaveToken}: {onValid: (token: string) => void, onCancel: () => void, dontHaveToken: () => void}) => { + + const t = useTranslation(); + + const config = useService(ConfigurationService); + + const [password, setPassword] = useState(""); + const [showPassword, setShowPassword] = useState(false); + + const getTokenFromStorage = () => { + const cryptedToken = config.get(OCULUS_TOKEN_STORAGE_KEY); + if(!cryptedToken) return null; + const { result: token, error } = tryit(() => crypto.AES.decrypt(cryptedToken, password).toString(crypto.enc.Utf8)); + + if(error){ + logRenderError(error, "Often indicate that the password is not the same as the one used to save the token."); + } + + return token; + } + + const isTokenValid = () => { + const token = getTokenFromStorage(); + return isOculusTokenValid(token); + } + + const valid = () => { + const token = getTokenFromStorage(); + onValid(token); + } + + return ( + <> +

{t("modals.enter-meta-token.body.info-enter-password")}

+ +
+
+
+ + {!isPasswordValid(password) && password.length > 0 && ( + {t("modals.enter-meta-token.body.password-too-short")} + )} +
+
+ setPassword(e.target.value)} value={password} type={showPassword ? "text" : "password"} name="password" id="password" placeholder={t("modals.enter-meta-token.body.password")} /> + setShowPassword(prev => !prev)} /> +
-
- setToken(e.target.value)} value={token} type={showToken ? "text" : "password"} name="meta_token" id="meta_token" placeholder="OCAStr43sdx2..." /> - setShowToken(prev => !prev)} /> + +
+ {t("modals.enter-meta-token.body.enter-oculus-token")}
- - + + +
+ +
+
- - + + ); + +} + +const EnterOculusTokenView = ({onValid, onCancel, alreadyHaveToken}: {onValid: (token: string) => void, onCancel: () => void, alreadyHaveToken: () => void}) => { + + const t = useTranslation(); + + const config = useService(ConfigurationService); + + const [token, setToken] = useState(""); + const [showToken, setShowToken] = useState(false); + const [stay, setStay] = useState(false); + const [password, setPassword] = useState(""); + const [showPassword, setShowPassword] = useState(false); + + const storeToken = (token: string, password: string) => { + const cryptedToken = crypto.AES.encrypt(token, password).toString(); + config.set(OCULUS_TOKEN_STORAGE_KEY, cryptedToken); + } + + const valid = () => { + + if(stay){ + storeToken(token, password); + } else { + config.delete(OCULUS_TOKEN_STORAGE_KEY); + } + + onValid(token); + } + + const isCryptedTokenPresent = () => { + return !!config.get(OCULUS_TOKEN_STORAGE_KEY); + } + + return ( + <> +

{t("modals.enter-meta-token.body.info-enter-token")}

+ {t("modals.enter-meta-token.body.how-obtain-token")} + +
+
+
+ + {!isOculusTokenValid(token) && token.length > 0 && ( + {t("modals.enter-meta-token.body.token-is-invalid")} + )} +
+
+ setToken(e.target.value)} value={token} type={showToken ? "text" : "password"} name="meta_token" id="meta_token" placeholder="FRLAStr43sdx2..." /> + setShowToken(prev => !prev)} /> +
+
+ + +
+ + {t("modals.enter-meta-token.body.save-my-token")} +
+
+ +
+
+
+ + {!isPasswordValid(password) && password.length > 0 && ( + {t("modals.enter-meta-token.body.password-too-short")} + )} +
+
+ setPassword(e.target.value)} value={password} type={showPassword ? "text" : "password"} name="password" id="password" placeholder={t("modals.enter-meta-token.body.password")} /> + setShowPassword(prev => !prev)} /> +
+
+
+ + {isCryptedTokenPresent() && ( +
+ {t("modals.enter-meta-token.body.have-token-saved")} +
+ )} +
+ +
+ + +
+ + + ); + } diff --git a/src/renderer/pages/settings-page.component.tsx b/src/renderer/pages/settings-page.component.tsx index bccd2bf6..7bf12f88 100644 --- a/src/renderer/pages/settings-page.component.tsx +++ b/src/renderer/pages/settings-page.component.tsx @@ -80,6 +80,7 @@ export function SettingsPage() { const themeSelected = useObservable(themeService.theme$, "os"); const languageSelected = useObservable(i18nService.currentLanguage$, i18nService.getFallbackLanguage()); const downloadStore = useObservable(bsDownloader.defaultStore$); + const [installationFolder, setInstallationFolder] = useState(null); const [showSupporters, setShowSupporters] = useState(false); const [mapDeepLinksEnabled, setMapDeepLinksEnabled] = useState(false); @@ -236,7 +237,7 @@ export function SettingsPage() { }, { id: 2, text: "Oculus Store (PC)", value: BsStore.OCULUS, icon: }, - { id: 0, text: t("pages.settings.steam-and-oculus.download-platform.always-ask"), value: undefined, }, + { id: 0, text: t("pages.settings.steam-and-oculus.download-platform.always-ask"), value: null, }, ]} selectedItemValue={downloadStore} onItemSelected={handleChangeBsStore}/> diff --git a/src/renderer/services/bs-version-download/bs-downloader.service.ts b/src/renderer/services/bs-version-download/bs-downloader.service.ts index 200a5df8..d8cc7b68 100644 --- a/src/renderer/services/bs-version-download/bs-downloader.service.ts +++ b/src/renderer/services/bs-version-download/bs-downloader.service.ts @@ -28,7 +28,7 @@ export class BsDownloaderService extends AbstractBsDownloaderService { private readonly oculusDownloader: OculusDownloaderService; private readonly versionManager: BSVersionManagerService; - private readonly SELECTED_STORE_TO_DOWNLOAD_KET = "selectedStoreToDownload"; + private readonly SELECTED_STORE_TO_DOWNLOAD_KEY = "selectedStoreToDownload"; private constructor(){ super(); @@ -55,11 +55,11 @@ export class BsDownloaderService extends AbstractBsDownloaderService { this._isVerifying$.next(false); } - public get defaultStore(): BsStore | undefined { return this.config.get(this.SELECTED_STORE_TO_DOWNLOAD_KET); } - public get defaultStore$(): Observable { return this.config.watch(this.SELECTED_STORE_TO_DOWNLOAD_KET); } + public get defaultStore(): BsStore | undefined { return this.config.get(this.SELECTED_STORE_TO_DOWNLOAD_KEY); } + public get defaultStore$(): Observable { return this.config.watch(this.SELECTED_STORE_TO_DOWNLOAD_KEY); } public setDefaultStore(store: BsStore|undefined): void { - this.config.set(this.SELECTED_STORE_TO_DOWNLOAD_KET, store); + this.config.set(this.SELECTED_STORE_TO_DOWNLOAD_KEY, store); } public async chooseStoreToDownloadFrom(): Promise { diff --git a/src/renderer/services/bs-version-download/oculus-downloader.service.ts b/src/renderer/services/bs-version-download/oculus-downloader.service.ts index ecd9b09c..590d1497 100644 --- a/src/renderer/services/bs-version-download/oculus-downloader.service.ts +++ b/src/renderer/services/bs-version-download/oculus-downloader.service.ts @@ -87,37 +87,39 @@ export class OculusDownloaderService extends AbstractBsDownloaderService impleme private async doDownloadBsVersion(bsVersion: BSVersion, isVerification: boolean): Promise { - let autoDownloadFailed = false; + const autoDownloadFailed = false; return (async () => { - const autoDownload = await lastValueFrom(this.tryAutoDownload({ bsVersion, isVerification })).then(() => true).catch((err: CustomError) => { - const doNotRestartCodes: string[] = [ - OculusDownloaderErrorCodes.ALREADY_DOWNLOADING, - OculusDownloaderErrorCodes.SOME_FILES_FAILED_TO_DOWNLOAD, - OculusDownloaderErrorCodes.VERIFY_INTEGRITY_FAILED, - OculusDownloaderErrorCodes.DOWNLOAD_CANCELLED - ]; - autoDownloadFailed = true; + // DISABLE FOR NOW, WILL MAYBE BE RE-ENABLED WHEN META AUTH IS FIXED - if(doNotRestartCodes.includes(err?.code)){ - return true; - } + // const autoDownload = await lastValueFrom(this.tryAutoDownload({ bsVersion, isVerification })).then(() => true).catch((err: CustomError) => { + // const doNotRestartCodes: string[] = [ + // OculusDownloaderErrorCodes.ALREADY_DOWNLOADING, + // OculusDownloaderErrorCodes.SOME_FILES_FAILED_TO_DOWNLOAD, + // OculusDownloaderErrorCodes.VERIFY_INTEGRITY_FAILED, + // OculusDownloaderErrorCodes.DOWNLOAD_CANCELLED + // ]; + // autoDownloadFailed = true; - return false; - }); + // if(doNotRestartCodes.includes(err?.code)){ + // return true; + // } + + // return false; + // }); - if(autoDownload){ return autoDownload; } + // if(autoDownload){ return autoDownload; } - const {exitCode, data} = await this.modals.openModal(LoginToMetaModal) + // const {exitCode, data} = await this.modals.openModal(LoginToMetaModal) - if(exitCode !== ModalExitCode.COMPLETED){ - return false - } + // if(exitCode !== ModalExitCode.COMPLETED){ + // return false + // } - if(data.method === MetaAuthMethod.META){ - return lastValueFrom(this.startDownloadBsVersion({ bsVersion, isVerification, stay: data.stay })).then(() => true); - } + // if(data.method === MetaAuthMethod.META){ + // return lastValueFrom(this.startDownloadBsVersion({ bsVersion, isVerification, stay: data.stay })).then(() => true); + // } const tokenRes = await this.modals.openModal(EnterMetaTokenModal); @@ -129,8 +131,6 @@ export class OculusDownloaderService extends AbstractBsDownloaderService impleme })().then(res => { - console.log("aaa", res); - if(autoDownloadFailed || !res){ return bsVersion; } diff --git a/src/renderer/services/configuration.service.ts b/src/renderer/services/configuration.service.ts index 81dc31a6..9a1a61c4 100644 --- a/src/renderer/services/configuration.service.ts +++ b/src/renderer/services/configuration.service.ts @@ -30,10 +30,14 @@ export class ConfigurationService { public get(key: string | DefaultConfigKey): Type { const rawValue = (window.sessionStorage.getItem(key) ?? window.localStorage.getItem(key)); const tryParse = tryit(() => JSON.parse(rawValue)); - if (!tryParse.result) { - return defaultConfiguration[key as DefaultConfigKey]; + + const res = (tryParse.error ? rawValue : tryParse.result) as Type; + + if(!res && Object.keys(defaultConfiguration).includes(key)){ + return defaultConfiguration[key as DefaultConfigKey] as Type; } - return (tryParse.result ?? rawValue) as Type; + + return res; } public set(key: string, value: unknown, persistant = true) { diff --git a/src/shared/helpers/oculus.helpers.ts b/src/shared/helpers/oculus.helpers.ts index 70fd416d..3176867c 100644 --- a/src/shared/helpers/oculus.helpers.ts +++ b/src/shared/helpers/oculus.helpers.ts @@ -1,6 +1,6 @@ export function isOculusTokenValid(token: string, logger?: (...args: unknown[]) => void): boolean{ - // Code taken from "https://github.com/ComputerElite/QuestAppVersionSwitcher" (TokenTools.cs) + // Part of code taken from "https://github.com/ComputerElite/QuestAppVersionSwitcher" (TokenTools.cs) logger?.("Checking if Oculus user token is valid"); @@ -12,12 +12,16 @@ export function isOculusTokenValid(token: string, logger?: (...args: unknown[]) logger?.("Token contains %. Token most likely comes from an uri and won't work"); return false; } - if(!token.startsWith("OC")){ - logger?.("Token does not start with OC."); + if(!token.startsWith("FRL")){ + logger?.("Tokens must start with 'FRL'."); return false; } if(token.includes("|")){ - logger?.("Token contains | which usually indicates an application token which is not valid for user tokens"); + logger?.("Token contains '|' which usually indicates an application token which is not valid for user tokens"); + return false; + } + if(token.includes(":")){ + logger?.("Token contains ':' wich can indicate that the user have copied the 'access_token' field with the token"); return false; } if(token.match(/OC\d{15}/)){ @@ -25,7 +29,7 @@ export function isOculusTokenValid(token: string, logger?: (...args: unknown[]) return false; } - logger?.("Oculus user token is valid"); + logger?.("Oculus user token is valid.", `token lenght : ${token.length}`); return true; From 1ba0b0beac54d5b7f57a6f33533a0bb2c32363c3 Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Tue, 26 Dec 2023 22:52:44 +0100 Subject: [PATCH 4/8] [chore] remove comments --- .../oculus-downloader.service.ts | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/src/renderer/services/bs-version-download/oculus-downloader.service.ts b/src/renderer/services/bs-version-download/oculus-downloader.service.ts index 590d1497..6bc8bca2 100644 --- a/src/renderer/services/bs-version-download/oculus-downloader.service.ts +++ b/src/renderer/services/bs-version-download/oculus-downloader.service.ts @@ -6,7 +6,6 @@ import { ProgressBarService } from "../progress-bar.service"; import { CustomError } from "shared/models/exceptions/custom-error.class"; import { NotificationService } from "../notification.service"; import { ModalExitCode, ModalService } from "../modale.service"; -import { LoginToMetaModal, MetaAuthMethod } from "renderer/components/modal/modal-types/bs-downgrade/login-to-meta-modal.component"; import { DownloaderServiceInterface } from "./bs-store-downloader.interface"; import { AbstractBsDownloaderService } from "./abstract-bs-downloader.service"; import { DownloadInfo } from "main/services/bs-version-download/bs-steam-downloader.service"; @@ -69,14 +68,6 @@ export class OculusDownloaderService extends AbstractBsDownloaderService impleme ); } - private tryAutoDownload(downloadInfo: DownloadInfo): Observable>{ - const ignoreCode = [MetaAuthErrorCodes.NO_META_AUTH_TOKEN, OculusDownloaderErrorCodes.DOWNLOAD_CANCELLED]; - return this.handleDownload( - this.ipc.sendV2>("bs-oculus-auto-download", { args: downloadInfo }), - ignoreCode - ); - } - private startDownloadBsVersion(downloadInfo: DownloadInfo): Observable>{ const ignoreCode = [MetaAuthErrorCodes.META_LOGIN_WINDOW_CLOSED_BY_USER, OculusDownloaderErrorCodes.DOWNLOAD_CANCELLED]; return this.handleDownload( @@ -91,36 +82,6 @@ export class OculusDownloaderService extends AbstractBsDownloaderService impleme return (async () => { - // DISABLE FOR NOW, WILL MAYBE BE RE-ENABLED WHEN META AUTH IS FIXED - - // const autoDownload = await lastValueFrom(this.tryAutoDownload({ bsVersion, isVerification })).then(() => true).catch((err: CustomError) => { - // const doNotRestartCodes: string[] = [ - // OculusDownloaderErrorCodes.ALREADY_DOWNLOADING, - // OculusDownloaderErrorCodes.SOME_FILES_FAILED_TO_DOWNLOAD, - // OculusDownloaderErrorCodes.VERIFY_INTEGRITY_FAILED, - // OculusDownloaderErrorCodes.DOWNLOAD_CANCELLED - // ]; - // autoDownloadFailed = true; - - // if(doNotRestartCodes.includes(err?.code)){ - // return true; - // } - - // return false; - // }); - - // if(autoDownload){ return autoDownload; } - - // const {exitCode, data} = await this.modals.openModal(LoginToMetaModal) - - // if(exitCode !== ModalExitCode.COMPLETED){ - // return false - // } - - // if(data.method === MetaAuthMethod.META){ - // return lastValueFrom(this.startDownloadBsVersion({ bsVersion, isVerification, stay: data.stay })).then(() => true); - // } - const tokenRes = await this.modals.openModal(EnterMetaTokenModal); if(tokenRes.exitCode !== ModalExitCode.COMPLETED){ From fb7f08ee2e2aeab73133fadd56775af9779decf7 Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Tue, 26 Dec 2023 22:56:44 +0100 Subject: [PATCH 5/8] [chore] move types of "crypto-js" to dev dependencies --- package-lock.json | 8 +++++--- package.json | 2 +- release/app/package-lock.json | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index d9494b8b..4cd548dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,6 @@ "@electron/fuses": "^1.6.2", "@node-steam/vdf": "^2.2.0", "@tippyjs/react": "^4.2.6", - "@types/crypto-js": "^4.2.1", "archiver": "^6.0.1", "color": "^4.2.3", "crypto-js": "^4.2.0", @@ -62,6 +61,7 @@ "@testing-library/react": "^13.3.0", "@types/archiver": "^5.3.1", "@types/color": "^3.0.3", + "@types/crypto-js": "^4.2.1", "@types/dateformat": "^5.0.0", "@types/jest": "^27.5.2", "@types/node": "17.0.23", @@ -2529,7 +2529,8 @@ "node_modules/@types/crypto-js": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.2.1.tgz", - "integrity": "sha512-FSPGd9+OcSok3RsM0UZ/9fcvMOXJ1ENE/ZbLfOPlBWj7BgXtEAM8VYfTtT760GiLbQIMoVozwVuisjvsVwqYWw==" + "integrity": "sha512-FSPGd9+OcSok3RsM0UZ/9fcvMOXJ1ENE/ZbLfOPlBWj7BgXtEAM8VYfTtT760GiLbQIMoVozwVuisjvsVwqYWw==", + "dev": true }, "node_modules/@types/dateformat": { "version": "5.0.0", @@ -21077,7 +21078,8 @@ "@types/crypto-js": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.2.1.tgz", - "integrity": "sha512-FSPGd9+OcSok3RsM0UZ/9fcvMOXJ1ENE/ZbLfOPlBWj7BgXtEAM8VYfTtT760GiLbQIMoVozwVuisjvsVwqYWw==" + "integrity": "sha512-FSPGd9+OcSok3RsM0UZ/9fcvMOXJ1ENE/ZbLfOPlBWj7BgXtEAM8VYfTtT760GiLbQIMoVozwVuisjvsVwqYWw==", + "dev": true }, "@types/dateformat": { "version": "5.0.0", diff --git a/package.json b/package.json index 6ac26fbe..10dfac8d 100644 --- a/package.json +++ b/package.json @@ -172,6 +172,7 @@ "@types/use-double-click": "^1.0.1", "@types/webpack-bundle-analyzer": "^4.4.2", "@types/webpack-env": "^1.18.0", + "@types/crypto-js": "^4.2.1", "@typescript-eslint/eslint-plugin": "^5.34.0", "@typescript-eslint/parser": "^5.34.0", "autoprefixer": "^10.4.8", @@ -236,7 +237,6 @@ "@electron/fuses": "^1.6.2", "@node-steam/vdf": "^2.2.0", "@tippyjs/react": "^4.2.6", - "@types/crypto-js": "^4.2.1", "archiver": "^6.0.1", "color": "^4.2.3", "crypto-js": "^4.2.0", diff --git a/release/app/package-lock.json b/release/app/package-lock.json index 2ae5ec12..a784f062 100644 --- a/release/app/package-lock.json +++ b/release/app/package-lock.json @@ -1,12 +1,12 @@ { "name": "bs-manager", - "version": "1.4.1", + "version": "1.4.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "bs-manager", - "version": "1.4.1", + "version": "1.4.2", "hasInstallScript": true, "license": "MIT", "dependencies": { From b97e03041aeec61ad6477d10978c4c2ed40262bd Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Tue, 26 Dec 2023 23:14:43 +0100 Subject: [PATCH 6/8] [chore] reduce code duplication --- .../enter-meta-token-modal.component.tsx | 62 ++++++++++--------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/src/renderer/components/modal/modal-types/bs-downgrade/enter-meta-token-modal.component.tsx b/src/renderer/components/modal/modal-types/bs-downgrade/enter-meta-token-modal.component.tsx index f7c8be4f..d18a694c 100644 --- a/src/renderer/components/modal/modal-types/bs-downgrade/enter-meta-token-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/bs-downgrade/enter-meta-token-modal.component.tsx @@ -44,10 +44,6 @@ export const EnterMetaTokenModal: ModalComponent = ({resolver}) => { ); } -const isPasswordValid = (password: string) => { - return password.length >= 8; -} - const EnterPasswordView = ({onValid, onCancel, dontHaveToken}: {onValid: (token: string) => void, onCancel: () => void, dontHaveToken: () => void}) => { const t = useTranslation(); @@ -55,7 +51,6 @@ const EnterPasswordView = ({onValid, onCancel, dontHaveToken}: {onValid: (token: const config = useService(ConfigurationService); const [password, setPassword] = useState(""); - const [showPassword, setShowPassword] = useState(false); const getTokenFromStorage = () => { const cryptedToken = config.get(OCULUS_TOKEN_STORAGE_KEY); @@ -63,7 +58,7 @@ const EnterPasswordView = ({onValid, onCancel, dontHaveToken}: {onValid: (token: const { result: token, error } = tryit(() => crypto.AES.decrypt(cryptedToken, password).toString(crypto.enc.Utf8)); if(error){ - logRenderError(error, "Often indicate that the password is not the same as the one used to save the token."); + logRenderError(error, "Often indicate that the password is not the same as the one used to save the token. This error can occur when the use is writing the password."); } return token; @@ -85,16 +80,7 @@ const EnterPasswordView = ({onValid, onCancel, dontHaveToken}: {onValid: (token:
-
- - {!isPasswordValid(password) && password.length > 0 && ( - {t("modals.enter-meta-token.body.password-too-short")} - )} -
-
- setPassword(e.target.value)} value={password} type={showPassword ? "text" : "password"} name="password" id="password" placeholder={t("modals.enter-meta-token.body.password")} /> - setShowPassword(prev => !prev)} /> -
+ setPassword(v.password)} value={password}/>
@@ -126,7 +112,7 @@ const EnterOculusTokenView = ({onValid, onCancel, alreadyHaveToken}: {onValid: ( const [showToken, setShowToken] = useState(false); const [stay, setStay] = useState(false); const [password, setPassword] = useState(""); - const [showPassword, setShowPassword] = useState(false); + const [passwordValid, setPasswordValid] = useState(false); const storeToken = (token: string, password: string) => { const cryptedToken = crypto.AES.encrypt(token, password).toString(); @@ -170,22 +156,13 @@ const EnterOculusTokenView = ({onValid, onCancel, alreadyHaveToken}: {onValid: (
- {t("modals.enter-meta-token.body.save-my-token")} + {t("modals.enter-meta-token.body.save-my-token")}
-
- - {!isPasswordValid(password) && password.length > 0 && ( - {t("modals.enter-meta-token.body.password-too-short")} - )} -
-
- setPassword(e.target.value)} value={password} type={showPassword ? "text" : "password"} name="password" id="password" placeholder={t("modals.enter-meta-token.body.password")} /> - setShowPassword(prev => !prev)} /> -
+ {setPassword(v.password); setPasswordValid(v.valid)}} value={password}/>
@@ -198,10 +175,37 @@ const EnterOculusTokenView = ({onValid, onCancel, alreadyHaveToken}: {onValid: (
- +
); } + +const PasswordInput = ({onChange, value}: {onChange: (value : {password: string, valid: boolean}) => void, value: string}) => { + + const t = useTranslation(); + + const [showPassword, setShowPassword] = useState(false); + + const isPasswordValid = (password: string) => { + return password.length >= 8; + } + + return ( + <> +
+ + {!isPasswordValid(value) && value.length > 0 && ( + {t("modals.enter-meta-token.body.password-too-short")} + )} +
+
+ onChange({password: e.target.value, valid: isPasswordValid(e.target.value)})} value={value} type={showPassword ? "text" : "password"} name="password" id="password" placeholder={t("modals.enter-meta-token.body.password")} /> + setShowPassword(prev => !prev)} /> +
+ + ) + +} From 7b22387fc563348c5435483078ba855beabaf569 Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Wed, 27 Dec 2023 00:40:32 +0100 Subject: [PATCH 7/8] [chore] add id in version's metadatas for future features --- src/main/services/bs-local-version.service.ts | 54 +++++++++---------- .../bs-oculus-downloader.service.ts | 6 +-- .../bs-steam-downloader.service.ts | 4 +- src/shared/bs-version.interface.ts | 1 + 4 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/main/services/bs-local-version.service.ts b/src/main/services/bs-local-version.service.ts index d58dbe05..eb33c388 100644 --- a/src/main/services/bs-local-version.service.ts +++ b/src/main/services/bs-local-version.service.ts @@ -18,6 +18,8 @@ import readline from "readline"; import { Observable, Subject, catchError, finalize, from, map, switchMap, throwError } from "rxjs"; import { BsStore } from "../../shared/models/bs-store.enum"; import { CustomError } from "../../shared/models/exceptions/custom-error.class"; +import crypto from "crypto"; + export class BSLocalVersionService { private static instance: BSLocalVersionService; @@ -119,7 +121,14 @@ export class BSLocalVersionService { folderVersion.ino = folderStats.ino; } - folderVersion.metadata = await this.getAllVersionMetadata(folderVersion, { store: BsStore.STEAM }); + + let metadata = await this.getAllVersionMetadata(folderVersion); + + // Will be removed in future version. It just to prepare future features + if(!metadata?.id){ + metadata = await this.initVersionMetadata(folderVersion, metadata ?? { store: BsStore.STEAM }); + } + folderVersion.metadata = metadata; const customVersion = this.getCustomVersions().find(customVersion => { return customVersion.BSVersion === folderVersion.BSVersion && customVersion.name === folderVersion.name; @@ -130,36 +139,27 @@ export class BSLocalVersionService { return folderVersion; } - public getAllVersionMetadata(version: BSVersion, defaultMetadata?: BSVersionMetadata): Promise{ + private async writeVersionMetadata(version: BSVersion, metadata: BSVersionMetadata): Promise{ + const versionPath = await this.getVersionPath(version); + const metadataPath = path.join(versionPath, this.METADATA_FILE); + return writeFile(metadataPath, JSON.stringify(metadata)); + } + + public initVersionMetadata(version: BSVersion, metadata: Omit): Promise{ + const firstMetadata = { id: crypto.randomUUID(), ...metadata }; + return this.writeVersionMetadata(version, firstMetadata).then(() => firstMetadata).catch(err => { + log.error("initVersionMetadata error", err); + return firstMetadata; + }); + } + + public getAllVersionMetadata(version: BSVersion): Promise{ return (async () => { const versionPath = await this.getVersionPath(version); const contents = await readFile(path.join(versionPath, this.METADATA_FILE), "utf-8"); return JSON.parse(contents); })().catch(e => { - log.warn("Not a critical error", e); - return {}; - }).then(metadata => ({...defaultMetadata, ...metadata})); - } - - public getVersionMetadata(version: BSVersion, key: K, defaultValue?: T): Promise{ - return (async () => { - const metadata = await this.getAllVersionMetadata(version); - return metadata?.[key]; - })().catch(e => { - log.warn("Not a critical error", e); - return null; - }).then(value => (value ?? defaultValue) as T); - } - - public setVersionMetadata(version: BSVersion, key: K, value: T): Promise{ - return (async () => { - const versionPath = await this.getVersionPath(version); - const metadataPath = path.join(versionPath, this.METADATA_FILE); - const metadata = await this.getAllVersionMetadata(version) ?? ({} as BSVersionMetadata); - metadata[key] = value; - await writeFile(metadataPath, JSON.stringify(metadata)); - })().catch(e => { - log.error(e); + log.warn("Error getAllVersionMetadata", e); }); } @@ -378,7 +378,7 @@ export class BSLocalVersionService { }), finalize(async () => { if(failed){ return; } - await this.setVersionMetadata(versionDest.version, "store", store); + await this.initVersionMetadata(versionDest.version, { store }); }) ); } diff --git a/src/main/services/bs-version-download/bs-oculus-downloader.service.ts b/src/main/services/bs-version-download/bs-oculus-downloader.service.ts index 3b974a0c..21820526 100644 --- a/src/main/services/bs-version-download/bs-oculus-downloader.service.ts +++ b/src/main/services/bs-version-download/bs-oculus-downloader.service.ts @@ -111,7 +111,7 @@ export class BsOculusDownloaderService { version: { ...version, ...(path.basename(dest) !== version.BSVersion && { name: path.basename(dest) }), - metadata: { store: BsStore.OCULUS } + metadata: { store: BsStore.OCULUS, id: "" } }, dest }; @@ -141,7 +141,7 @@ export class BsOculusDownloaderService { progress => ({...progress, data: version}) )); }), - finalize(() => downloadVersion && this.versions.setVersionMetadata(downloadVersion, "store", BsStore.OCULUS)), + finalize(() => downloadVersion && this.versions.initVersionMetadata(downloadVersion, { store: BsStore.OCULUS })), finalize(() => this.oculusDownloader.stopDownload()) ); } @@ -171,7 +171,7 @@ export class BsOculusDownloaderService { map(progress => ({...progress, data: version})), ); }), - finalize(() => downloadVersion && this.versions.setVersionMetadata(downloadVersion, "store", BsStore.OCULUS)), + finalize(() => downloadVersion && this.versions.initVersionMetadata(downloadVersion, { store: BsStore.OCULUS })), finalize(() => this.oculusDownloader.stopDownload()), ); } diff --git a/src/main/services/bs-version-download/bs-steam-downloader.service.ts b/src/main/services/bs-version-download/bs-steam-downloader.service.ts index a86c7639..2660b929 100644 --- a/src/main/services/bs-version-download/bs-steam-downloader.service.ts +++ b/src/main/services/bs-version-download/bs-steam-downloader.service.ts @@ -67,7 +67,7 @@ export class BsSteamDownloaderService { const downloadVersion: BSVersion = { ...downloadInfos.bsVersion, ...(path.basename(dest) !== downloadInfos.bsVersion.BSVersion && { name: path.basename(dest) }), - metadata: { store: BsStore.STEAM } + metadata: { store: BsStore.STEAM, id: "" } }; const depotDownloaderOptions: DepotDownloaderArgsOptions = { @@ -118,7 +118,7 @@ export class BsSteamDownloaderService { } return event; }), - finalize(() => this.localVersionService.setVersionMetadata(version, "store", BsStore.STEAM)) + finalize(() => this.localVersionService.initVersionMetadata(version, { store: BsStore.STEAM })) ).subscribe(sub); }).catch(err => sub.error({ diff --git a/src/shared/bs-version.interface.ts b/src/shared/bs-version.interface.ts index f6d84d51..4bd6edd3 100644 --- a/src/shared/bs-version.interface.ts +++ b/src/shared/bs-version.interface.ts @@ -21,6 +21,7 @@ export interface BSVersion extends PartialBSVersion { } export interface BSVersionMetadata { + id: string; store: BsStore; } From 07a353393b23b919f3a0973d565fc0f5507e11fb Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Wed, 27 Dec 2023 03:10:31 +0100 Subject: [PATCH 8/8] bumb to 1.4.3 --- release/app/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/app/package.json b/release/app/package.json index df0eb293..86a037ba 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "bs-manager", - "version": "1.4.2", + "version": "1.4.3", "description": "BSManager", "main": "./dist/main/main.js", "author": {