Skip to content

Commit b0b52f4

Browse files
authored
Merge pull request #716 from Zagrios/chore/reimplement-login-with-meta
[chore] reimplement login with meta
2 parents 8eec1fe + cda8a8a commit b0b52f4

File tree

18 files changed

+187
-75
lines changed

18 files changed

+187
-75
lines changed

assets/jsons/translations/de.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@
364364
"UNABLE_TO_GET_MANIFEST": "Unmöglich, das für den Download erforderliche Manifest zu erhalten.",
365365
"VERIFY_INTEGRITY_FAILED": "Beim Überprüfen der Dateien ist ein Fehler aufgetreten.",
366366
"SOME_FILES_FAILED_TO_DOWNLOAD": "Einige Dateien konnten nicht heruntergeladen werden.",
367-
"OCULUS_LOGIN_TIMED_OUT": "Es hat zu lange gedauert, das Anmelde-Token abzurufen.",
368-
"OCULUS_LOGIN_WINDOW_CLOSED_BY_USER": "Das Meta-Anmeldefenster wurde geschlossen.",
367+
"META_LOGIN_TIMED_OUT": "Es hat zu lange gedauert, das Anmelde-Token abzurufen.",
368+
"META_LOGIN_WINDOW_CLOSED_BY_USER": "Das Meta-Anmeldefenster wurde geschlossen.",
369369
"NO_META_AUTH_TOKEN": "Unmöglich, das für den Download erforderliche Meta-Anmelde-Token zu erhalten.",
370370
"UNKNOWN_ERROR": "Ein unbekannter Fehler ist aufgetreten."
371371
}

assets/jsons/translations/en.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@
364364
"UNABLE_TO_GET_MANIFEST": "Unable to obtain the manifest required for download.",
365365
"VERIFY_INTEGRITY_FAILED": "An error occurred during file verification.",
366366
"SOME_FILES_FAILED_TO_DOWNLOAD": "Some files failed to download.",
367-
"OCULUS_LOGIN_TIMED_OUT": "The login token took too long to retrieve.",
368-
"OCULUS_LOGIN_WINDOW_CLOSED_BY_USER": "The Meta login window was closed.",
367+
"META_LOGIN_TIMED_OUT": "The login token took too long to retrieve.",
368+
"META_LOGIN_WINDOW_CLOSED_BY_USER": "The Meta login window was closed.",
369369
"NO_META_AUTH_TOKEN": "Unable to retrieve the Meta login token required for download.",
370370
"UNKNOWN_ERROR": "An unknown error occurred."
371371
}

assets/jsons/translations/es.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@
364364
"UNABLE_TO_GET_MANIFEST": "Imposible obtener el manifiesto necesario para la descarga.",
365365
"VERIFY_INTEGRITY_FAILED": "Se produjo un error durante la verificación de archivos.",
366366
"SOME_FILES_FAILED_TO_DOWNLOAD": "Algunos archivos no pudieron ser descargados.",
367-
"OCULUS_LOGIN_TIMED_OUT": "El token de inicio de sesión tardó demasiado en recuperarse.",
368-
"OCULUS_LOGIN_WINDOW_CLOSED_BY_USER": "La ventana de inicio de sesión de Meta fue cerrada.",
367+
"META_LOGIN_TIMED_OUT": "El token de inicio de sesión tardó demasiado en recuperarse.",
368+
"META_LOGIN_WINDOW_CLOSED_BY_USER": "La ventana de inicio de sesión de Meta fue cerrada.",
369369
"NO_META_AUTH_TOKEN": "Imposible recuperar el token de inicio de sesión de Meta necesario para la descarga.",
370370
"UNKNOWN_ERROR": "Se produjo un error desconocido."
371371
}

assets/jsons/translations/fr.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@
364364
"UNABLE_TO_GET_MANIFEST": "Impossible d'obtenir le manifest nécessaire au téléchargement.",
365365
"VERIFY_INTEGRITY_FAILED": "Une erreur c'est produite lors de la vérification des fichiers.",
366366
"SOME_FILES_FAILED_TO_DOWNLOAD": "Certains fichiers n'ont pas pu être téléchargés.",
367-
"OCULUS_LOGIN_TIMED_OUT": "Le Token de connexion à mis trop de temps à être récupéré.",
368-
"OCULUS_LOGIN_WINDOW_CLOSED_BY_USER": "La fenêtre de connexion à Meta a été fermée.",
367+
"META_LOGIN_TIMED_OUT": "Le Token de connexion à mis trop de temps à être récupéré.",
368+
"META_LOGIN_WINDOW_CLOSED_BY_USER": "La fenêtre de connexion à Meta a été fermée.",
369369
"NO_META_AUTH_TOKEN": "Impossible de récupérer le token de connexion à Meta nécessaire au téléchargement.",
370370
"UNKNOWN_ERROR": "Une erreur inconnue s'est produite."
371371
}

assets/jsons/translations/ja.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@
364364
"UNABLE_TO_GET_MANIFEST": "ダウンロードに必要なマニフェストを取得できません。",
365365
"VERIFY_INTEGRITY_FAILED": "ファイルの検証中にエラーが発生しました。",
366366
"SOME_FILES_FAILED_TO_DOWNLOAD": "一部のファイルのダウンロードに失敗しました。",
367-
"OCULUS_LOGIN_TIMED_OUT": "ログイントークンの取得に時間がかかりすぎました。",
368-
"OCULUS_LOGIN_WINDOW_CLOSED_BY_USER": "メタ・ログイン・ウィンドウが閉じられた。",
367+
"META_LOGIN_TIMED_OUT": "ログイントークンの取得に時間がかかりすぎました。",
368+
"META_LOGIN_WINDOW_CLOSED_BY_USER": "メタ・ログイン・ウィンドウが閉じられた。",
369369
"NO_META_AUTH_TOKEN": "ダウンロードに必要な Meta ログイン トークンを取得できません。",
370370
"UNKNOWN_ERROR": "不明なエラーが発生しました。"
371371
}

assets/jsons/translations/ko.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@
364364
"UNABLE_TO_GET_MANIFEST": "다운로드에 필요한 매니페스트를 가져올 수 없습니다.",
365365
"VERIFY_INTEGRITY_FAILED": "파일 검증 중 오류가 발생했습니다.",
366366
"SOME_FILES_FAILED_TO_DOWNLOAD": "일부 파일을 다운로드하지 못했습니다.",
367-
"OCULUS_LOGIN_TIMED_OUT": "로그인 토큰을 얻는 데 시간이 너무 오래 걸렸습니다.",
368-
"OCULUS_LOGIN_WINDOW_CLOSED_BY_USER": "Meta 로그인 창이 닫혔습니다.",
367+
"META_LOGIN_TIMED_OUT": "로그인 토큰을 얻는 데 시간이 너무 오래 걸렸습니다.",
368+
"META_LOGIN_WINDOW_CLOSED_BY_USER": "Meta 로그인 창이 닫혔습니다.",
369369
"NO_META_AUTH_TOKEN": "다운로드에 필요한 Meta 로그인 토큰을 얻을 수 없습니다.",
370370
"UNKNOWN_ERROR": "알 수 없는 오류가 발생했습니다."
371371
}

assets/jsons/translations/ru.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@
364364
"UNABLE_TO_GET_MANIFEST": "Невозможно получить манифест, необходимый для загрузки.",
365365
"VERIFY_INTEGRITY_FAILED": "При проверке файлов произошла ошибка.",
366366
"SOME_FILES_FAILED_TO_DOWNLOAD": "Некоторые файлы не удалось загрузить.",
367-
"OCULUS_LOGIN_TIMED_OUT": "Получение токена входа заняло слишком много времени.",
368-
"OCULUS_LOGIN_WINDOW_CLOSED_BY_USER": "Окно входа в Meta было закрыто.",
367+
"META_LOGIN_TIMED_OUT": "Получение токена входа заняло слишком много времени.",
368+
"META_LOGIN_WINDOW_CLOSED_BY_USER": "Окно входа в Meta было закрыто.",
369369
"NO_META_AUTH_TOKEN": "Невозможно получить токен входа в Meta, необходимый для загрузки.",
370370
"UNKNOWN_ERROR": "Произошла неизвестная ошибка."
371371
}

assets/jsons/translations/zh-tw.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@
364364
"UNABLE_TO_GET_MANIFEST": "無法獲取下載所需的清單。",
365365
"VERIFY_INTEGRITY_FAILED": "文件驗證過程中發生錯誤。",
366366
"SOME_FILES_FAILED_TO_DOWNLOAD": "一些文件下載失敗。",
367-
"OCULUS_LOGIN_TIMED_OUT": "獲取登錄令牌用時過長。",
368-
"OCULUS_LOGIN_WINDOW_CLOSED_BY_USER": "Meta 登錄窗口被關閉。",
367+
"META_LOGIN_TIMED_OUT": "獲取登錄令牌用時過長。",
368+
"META_LOGIN_WINDOW_CLOSED_BY_USER": "Meta 登錄窗口被關閉。",
369369
"NO_META_AUTH_TOKEN": "無法獲取下載所需的 Meta 登錄令牌。",
370370
"UNKNOWN_ERROR": "發生未知錯誤。"
371371
}

assets/jsons/translations/zh.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@
364364
"UNABLE_TO_GET_MANIFEST": "无法获取下载所需的清单。",
365365
"VERIFY_INTEGRITY_FAILED": "文件验证过程中发生错误。",
366366
"SOME_FILES_FAILED_TO_DOWNLOAD": "一些文件下载失败。",
367-
"OCULUS_LOGIN_TIMED_OUT": "获取登录令牌用时过长。",
368-
"OCULUS_LOGIN_WINDOW_CLOSED_BY_USER": "Meta 登录窗口被关闭。",
367+
"META_LOGIN_TIMED_OUT": "获取登录令牌用时过长。",
368+
"META_LOGIN_WINDOW_CLOSED_BY_USER": "Meta 登录窗口被关闭。",
369369
"NO_META_AUTH_TOKEN": "无法获取下载所需的 Meta 登录令牌。",
370370
"UNKNOWN_ERROR": "发生未知错误。"
371371
}

src/main/ipcs/bs-version-download/bs-download-ipcs.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { BsOculusDownloaderService } from "../../services/bs-version-download/bs-oculus-downloader.service";
22
import { BsSteamDownloaderService } from "../../services/bs-version-download/bs-steam-downloader.service";
33
import { IpcService } from "../../services/ipc.service";
4-
import { of } from "rxjs";
4+
import { from, of } from "rxjs";
55
import { BSLocalVersionService } from "../../services/bs-local-version.service";
66

77
const ipc = IpcService.getInstance();
@@ -42,14 +42,29 @@ ipc.on("send-input-bs-download", (args, reply) => {
4242

4343
// #region Oculus
4444

45-
ipc.on("bs-oculus-download", async (args, reply) => {
45+
ipc.on("bs-oculus-download", (args, reply) => {
4646
const oculusDownloader = BsOculusDownloaderService.getInstance();
4747
reply(oculusDownloader.downloadVersion(args));
4848
});
4949

50-
ipc.on("bs-oculus-stop-download", async (_, reply) => {
50+
ipc.on("bs-oculus-stop-download", (_, reply) => {
5151
const oculusDownloader = BsOculusDownloaderService.getInstance();
5252
reply(of(oculusDownloader.stopDownload()));
5353
});
5454

55+
ipc.on("login-with-meta", (stay, reply) => {
56+
const oculusDownloader = BsOculusDownloaderService.getInstance();
57+
reply(from(oculusDownloader.getUserTokenFromMetaAuth(stay)));
58+
});
59+
60+
ipc.on("delete-meta-session", (_, reply) => {
61+
const oculusDownloader = BsOculusDownloaderService.getInstance();
62+
reply(from(oculusDownloader.clearAuthToken()));
63+
});
64+
65+
ipc.on("meta-session-exists", (_, reply) => {
66+
const oculusDownloader = BsOculusDownloaderService.getInstance();
67+
reply(from(oculusDownloader.metaSessionExists()));
68+
});
69+
5570
// #endregion

src/main/main.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,3 +264,11 @@ function deleteOlestLogs(): void{
264264
}
265265
});
266266
}
267+
268+
export function addFilterStringLog(filter: string): void {
269+
filterStrings.add(filter);
270+
}
271+
272+
export function addFilterPatternLog(filter: RegExp): void {
273+
filterPatterns.add(filter);
274+
}

src/main/services/bs-version-download/bs-oculus-downloader.service.ts

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ import path from "path";
88
import { DownloadInfo } from "./bs-steam-downloader.service";
99
import { BsStore } from "../../../shared/models/bs-store.enum";
1010
import { isOculusTokenValid } from "../../../shared/helpers/oculus.helpers";
11+
import { CustomError } from "shared/models/exceptions/custom-error.class";
12+
import { minToMs } from "shared/helpers/time.helpers";
13+
import { session } from "electron";
14+
import { WindowManagerService } from "../window-manager.service";
15+
import { addFilterStringLog } from "../../main";
16+
import { MetaAuthErrorCodes } from "shared/models/bs-version-download/oculus-download.model";
1117

1218
export class BsOculusDownloaderService {
1319

@@ -23,13 +29,63 @@ export class BsOculusDownloaderService {
2329

2430
private readonly oculusDownloader: OculusDownloader;
2531
private readonly versions: BSLocalVersionService;
32+
private readonly windows: WindowManagerService;
2633

2734
private constructor() {
2835
this.versions = BSLocalVersionService.getInstance();
29-
36+
this.windows = WindowManagerService.getInstance();
3037
this.oculusDownloader = new OculusDownloader();
3138
}
3239

40+
public async getUserTokenFromMetaAuth(keepToken: boolean): Promise<string>{
41+
42+
const loginUrl = "https://secure.oculus.com";
43+
const redirectUrl = `${loginUrl}/my/profile`;
44+
const window = await this.windows.openWindow(loginUrl, { frame: true, width: 650, height: 800 });
45+
46+
let timout: NodeJS.Timeout;
47+
48+
return new Promise<string>((resolve, reject) => {
49+
timout = setTimeout(() => {
50+
reject(new CustomError("Trying to get Oculus user token timed out", MetaAuthErrorCodes.META_LOGIN_TIMED_OUT));
51+
window.close();
52+
}, minToMs(10));
53+
54+
const tryExtractToken = async () => {
55+
log.info("Meta auth window navigated to", new URL(window.webContents.getURL()).origin + new URL(window.webContents.getURL()).pathname); // Dot not log full url for privacy reasons
56+
if(!window.webContents.getURL()?.startsWith(redirectUrl)){ return; }
57+
58+
const token = (await window.webContents.session.cookies.get({ name: "oc_ac_at" })).at(0)?.value;
59+
60+
if(!isOculusTokenValid(token, log.info)){
61+
return;
62+
}
63+
64+
addFilterStringLog(token);
65+
resolve(token);
66+
}
67+
68+
window.webContents.on("did-stop-loading", tryExtractToken);
69+
window.webContents.on("did-navigate", tryExtractToken);
70+
window.webContents.on("did-navigate-in-page", tryExtractToken);
71+
72+
window.on("closed", () => {
73+
reject(new CustomError("Oculus login window closed by user", MetaAuthErrorCodes.META_LOGIN_WINDOW_CLOSED_BY_USER));
74+
});
75+
}).finally(() => {
76+
77+
clearTimeout(timout);
78+
79+
if(!keepToken){
80+
this.clearAuthToken();
81+
}
82+
83+
if(!window.isDestroyed() && window.isClosable()){
84+
window.close();
85+
}
86+
});
87+
}
88+
3389
private async createDownloadVersion(version: BSVersion): Promise<{version: BSVersion, dest: string}>{
3490
const dest = await ensurePathNotAlreadyExist(await this.versions.getVersionPath(version));
3591
return {
@@ -46,7 +102,7 @@ export class BsOculusDownloaderService {
46102
this.oculusDownloader.stopDownload();
47103
}
48104

49-
public downloadVersion(downloadInfo: DownloadInfo): Observable<Progression<BSVersion>>{
105+
public downloadVersion(downloadInfo: OculusDownloadInfo): Observable<Progression<BSVersion>>{
50106

51107
let downloadVersion: BSVersion
52108

@@ -69,9 +125,16 @@ export class BsOculusDownloaderService {
69125
);
70126
}
71127

128+
public clearAuthToken(): Promise<void>{
129+
return session.defaultSession.clearStorageData({ storages: ["cookies"], origin: ".oculus.com" })
130+
}
131+
132+
public metaSessionExists(): Promise<boolean>{
133+
return session.defaultSession.cookies.get({ domain: ".oculus.com" }).then(cookies => cookies.length > 0);
134+
}
135+
72136
}
73137

74-
export interface OculusDownloadInfo {
75-
version: BSVersion;
76-
stay?: boolean;
138+
export interface OculusDownloadInfo extends DownloadInfo {
139+
token: string;
77140
}

src/main/services/bs-version-download/bs-steam-downloader.service.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ export interface DownloadInfo {
147147
bsVersion: BSVersion;
148148
isVerification?: boolean;
149149
stay?: boolean;
150-
token?: string;
151150
}
152151

153152
export interface DownloadSteamInfo extends DownloadInfo {

src/renderer/components/modal/modal-types/bs-downgrade/login-to-meta-modal.component.tsx

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,52 @@
1-
import { ModalComponent, ModalExitCode } from "../../../../services/modale.service";
2-
import { useState } from "react";
1+
import { ModalComponent, ModalExitCode, ModalService } from "../../../../services/modale.service";
2+
import { MouseEventHandler, useState } from "react";
33
import { BsmButton } from "renderer/components/shared/bsm-button.component";
4-
import { useTranslation } from "renderer/hooks/use-translation.hook";
4+
import { useTranslationV2 } from "renderer/hooks/use-translation.hook";
55
import { MetaIcon } from "renderer/components/svgs/icons/meta-icon.component";
66
import { BsmCheckbox } from "renderer/components/shared/bsm-checkbox.component";
77
import Tippy from "@tippyjs/react";
8+
import { useService } from "renderer/hooks/use-service.hook";
9+
import { IpcService } from "renderer/services/ipc.service";
10+
import { lastValueFrom } from "rxjs";
11+
import { EnterMetaTokenModal } from "./enter-meta-token-modal.component";
12+
import { CustomError } from "shared/models/exceptions/custom-error.class";
13+
import { MetaAuthErrorCodes } from "shared/models/bs-version-download/oculus-download.model";
14+
import { NotificationService } from "renderer/services/notification.service";
815

9-
type ReturnType = { method: MetaAuthMethod.META, stay: boolean } | { method: MetaAuthMethod.MANUAL };
16+
export const LoginToMetaModal: ModalComponent<string> = ({ resolver }) => {
1017

11-
export const LoginToMetaModal: ModalComponent<ReturnType> = ({ resolver }) => {
18+
const { text: t } = useTranslationV2();
1219

13-
const t = useTranslation();
20+
const ipc = useService(IpcService);
21+
const modal = useService(ModalService);
22+
const notifications = useService(NotificationService);
1423

15-
const [stay, setStay] = useState(false);
24+
const [stay, setStay] = useState(true);
25+
const [authWindowOpen, setAuthWindowOpen] = useState(false);
1626

17-
const submit = () => {
18-
resolver({ exitCode: ModalExitCode.COMPLETED, data: { method: MetaAuthMethod.META, stay } });
19-
};
27+
const handleLoginWithMeta = () => {
28+
setAuthWindowOpen(() => true);
29+
lastValueFrom(ipc.sendV2("login-with-meta", stay)).then(token => {
30+
resolver({ exitCode: ModalExitCode.COMPLETED, data: token });
31+
}).catch((e: CustomError) => {
32+
if(e.code === MetaAuthErrorCodes.META_LOGIN_WINDOW_CLOSED_BY_USER){
33+
return;
34+
}
2035

21-
const enterTokenManually = () => {
22-
resolver({ exitCode: ModalExitCode.COMPLETED, data: { method: MetaAuthMethod.MANUAL } });
36+
if(e.code){
37+
notifications.notifyError({title: "notifications.types.error", desc: `notifications.bs-download.oculus-download.errors.msg.${e.code}`});
38+
}
39+
40+
resolver({ exitCode: ModalExitCode.CANCELED });
41+
}).finally(() => {
42+
setAuthWindowOpen(() => false);
43+
})
44+
}
45+
46+
const handleEnterTokenManually: MouseEventHandler<HTMLButtonElement> = async (e) => {
47+
e.preventDefault();
48+
const res = await modal.openModal(EnterMetaTokenModal);
49+
resolver(res);
2350
}
2451

2552
return (
@@ -38,17 +65,12 @@ export const LoginToMetaModal: ModalComponent<ReturnType> = ({ resolver }) => {
3865
<span>{t("modals.connect-to-meta.stay")}</span>
3966
</div>
4067

41-
<BsmButton className="rounded-md flex justify-center items-center transition-all h-10 w-full" typeColor="primary" text="modals.connect-to-meta.connect-to-meta" withBar={false} onClick={submit}/>
68+
<BsmButton className="rounded-md flex justify-center items-center transition-all h-10 w-full" typeColor="primary" text="modals.connect-to-meta.connect-to-meta" withBar={false} onClick={handleLoginWithMeta} disabled={authWindowOpen}/>
4269

4370
<Tippy className="!bg-neutral-900" arrow={false} content={t("modals.connect-to-meta.body.enter-token-manually-tooltip")} >
44-
<p className="text-sm italic underline text-center -translate-y-1 leading-3 cursor-pointer" onClick={enterTokenManually}>{t("modals.connect-to-meta.body.enter-token-manually")}</p>
71+
<button className="text-sm italic underline text-center -translate-y-1 leading-3 cursor-pointer" onClick={handleEnterTokenManually}>{t("modals.connect-to-meta.body.enter-token-manually")}</button>
4572
</Tippy>
46-
73+
4774
</form>
4875
);
4976
};
50-
51-
export enum MetaAuthMethod {
52-
MANUAL = "manual",
53-
META = "meta"
54-
}

0 commit comments

Comments
 (0)