mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
[feature] add function to get user oculus token + other small changes
This commit is contained in:
@@ -20,6 +20,8 @@ import { APP_NAME } from "./constants";
|
||||
import { BSLauncherService } from "./services/bs-launcher.service";
|
||||
import { IpcRequest } from "shared/models/ipc";
|
||||
import { LivShortcut } from "./services/liv/liv-shortcut.service";
|
||||
import { BsOculusDownloaderService } from "./services/bs-oculus-downloader.service";
|
||||
import { BSVersion } from "shared/bs-version.interface";
|
||||
|
||||
const isDebug = process.env.NODE_ENV === "development" || process.env.DEBUG_PROD === "true";
|
||||
|
||||
@@ -58,6 +60,8 @@ const createWindow = async (window: AppWindow = "launcher.html") => {
|
||||
await installExtensions();
|
||||
}
|
||||
WindowManagerService.getInstance().openWindow(window);
|
||||
|
||||
BsOculusDownloaderService.getInstance().downloadVersion({} as BSVersion).then(console.log).catch(console.error);
|
||||
};
|
||||
|
||||
const initServicesMustBeInitialized = () => {
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
import { BSVersion } from "../../shared/bs-version.interface";
|
||||
import { WindowManagerService } from "./window-manager.service";
|
||||
import { minToMs } from "../../shared/helpers/time.helpers";
|
||||
import log from "electron-log";
|
||||
|
||||
export class BsOculusDownloaderService {
|
||||
|
||||
private static instance: BsOculusDownloaderService;
|
||||
|
||||
public static getInstance(): BsOculusDownloaderService {
|
||||
if (!BsOculusDownloaderService.instance) {
|
||||
BsOculusDownloaderService.instance = new BsOculusDownloaderService();
|
||||
}
|
||||
|
||||
return BsOculusDownloaderService.instance;
|
||||
}
|
||||
|
||||
private readonly windows: WindowManagerService;
|
||||
|
||||
private constructor() {
|
||||
this.windows = WindowManagerService.getInstance();
|
||||
}
|
||||
|
||||
private isUserTokenValid(token: string): boolean{
|
||||
|
||||
// Code take from "https://github.com/ComputerElite/QuestAppVersionSwitcher" (TokenTools.cs)
|
||||
|
||||
log.info("Checking if Oculus user token is valid");
|
||||
|
||||
if(!token){
|
||||
log.info("Oculus user token is empty");
|
||||
return false;
|
||||
}
|
||||
if(token.includes("%")){
|
||||
log.info("Token contains %. Token most likely comes from an uri and won't work");
|
||||
return false;
|
||||
}
|
||||
if(!token.startsWith("OC")){
|
||||
log.info("Token does not start with OC.");
|
||||
return false;
|
||||
}
|
||||
if(token.includes("|")){
|
||||
log.info("Token contains | which usually indicates an application token which is not valid for user tokens");
|
||||
return false;
|
||||
}
|
||||
if(token.match(/OC[0-9]{15}/)){
|
||||
log.info("Token matches /OC[0-9}{15}/ which usually indicates a changed oculus store token");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public async getUserToken(): Promise<string>{
|
||||
const redirectUrl = "https://developer.oculus.com/manage/";
|
||||
const loginUrl = `https://auth.oculus.com/login/?redirect_uri=${encodeURIComponent(redirectUrl)}`;
|
||||
const window = await this.windows.openWindow(loginUrl, { frame: true });
|
||||
|
||||
let timout: NodeJS.Timeout;
|
||||
|
||||
const promise = new Promise<string>((resolve, reject) => {
|
||||
timout = setTimeout(() => {
|
||||
reject(new Error("Trying to get Oculus user token timed out"));
|
||||
window.close();
|
||||
}, minToMs(5));
|
||||
|
||||
window.webContents.on("did-navigate", async (_, url) => {
|
||||
if(!url.startsWith(redirectUrl)){ return; }
|
||||
|
||||
const token = (await window.webContents.session.cookies.get({ name: "oc_www_at" })).at(0)?.value;
|
||||
|
||||
if(!this.isUserTokenValid(token)){
|
||||
return;
|
||||
}
|
||||
|
||||
resolve(token);
|
||||
});
|
||||
|
||||
window.on("closed", () => {
|
||||
reject(new Error("Oculus login window closed by user"));
|
||||
});
|
||||
}).finally(() => {
|
||||
if(!window.isDestroyed() && window.isClosable()){
|
||||
window.close();
|
||||
}
|
||||
clearTimeout(timout);
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
public downloadVersion(version: BSVersion){
|
||||
return this.getUserToken();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { app, BrowserWindow, BrowserWindowConstructorOptions, shell } from "electron";
|
||||
import { app, BrowserWindow, BrowserWindowConstructorOptions, shell, WebContents } from "electron";
|
||||
import { resolveHtmlPath } from "../util";
|
||||
import { UtilsService } from "./utils.service";
|
||||
import { AppWindow } from "shared/models/window-manager/app-window.model";
|
||||
@@ -10,6 +10,7 @@ export class WindowManagerService {
|
||||
private static instance: WindowManagerService;
|
||||
|
||||
private readonly PRELOAD_PATH = app.isPackaged ? path.join(__dirname, "preload.js") : path.join(__dirname, "../../../.erb/dll/preload.js");
|
||||
private readonly IS_DEBUG = process.env.NODE_ENV === "development" || process.env.DEBUG_PROD === "true"
|
||||
|
||||
private readonly utilsService: UtilsService = UtilsService.getInstance();
|
||||
|
||||
@@ -28,10 +29,10 @@ export class WindowManagerService {
|
||||
show: false,
|
||||
frame: false,
|
||||
titleBarOverlay: false,
|
||||
webPreferences: { preload: this.PRELOAD_PATH, webSecurity: false },
|
||||
webPreferences: { preload: this.PRELOAD_PATH, webSecurity: !this.IS_DEBUG },
|
||||
};
|
||||
|
||||
private readonly windows: Map<AppWindow, BrowserWindow> = new Map<AppWindow, BrowserWindow>();
|
||||
private readonly windows = new Map<string, BrowserWindow>();
|
||||
|
||||
public static getInstance(): WindowManagerService {
|
||||
if (!WindowManagerService.instance) {
|
||||
@@ -42,8 +43,7 @@ export class WindowManagerService {
|
||||
|
||||
private constructor() {}
|
||||
|
||||
public openWindow(windowType: AppWindow, options?: BrowserWindowConstructorOptions): Promise<BrowserWindow> {
|
||||
const window = new BrowserWindow({ ...this.appWindowsOptions[windowType], ...this.baseWindowOption, ...options });
|
||||
private handleNewWindow(url: AppWindow, window: BrowserWindow){
|
||||
|
||||
window.webContents.setWindowOpenHandler(({ url }) => {
|
||||
if(isValidUrl(url)){
|
||||
@@ -51,12 +51,13 @@ export class WindowManagerService {
|
||||
}
|
||||
|
||||
return { action: "deny"}
|
||||
})
|
||||
});
|
||||
|
||||
const promise = window.loadURL(resolveHtmlPath(windowType));
|
||||
window.removeMenu();
|
||||
window.setMenu(null);
|
||||
|
||||
const promise = window.loadURL(isValidUrl(url) ? url : resolveHtmlPath(url));
|
||||
|
||||
window.once("ready-to-show", () => {
|
||||
if (!window) {
|
||||
throw new Error('"window" is not defined');
|
||||
@@ -65,18 +66,24 @@ export class WindowManagerService {
|
||||
});
|
||||
|
||||
window.once("closed", () => {
|
||||
this.windows.delete(windowType);
|
||||
this.windows.delete(url);
|
||||
if (!this.windows.size) {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
this.windows.set(windowType, window);
|
||||
this.utilsService.setMainWindows(this.windows);
|
||||
this.windows.set(url, window);
|
||||
this.utilsService.setMainWindows(this.windows as Map<AppWindow, BrowserWindow>); // TODO : remove
|
||||
|
||||
|
||||
return promise.then(() => window);
|
||||
}
|
||||
|
||||
public openWindow(windowType: AppWindow, options?: BrowserWindowConstructorOptions): Promise<BrowserWindow> {
|
||||
const window = new BrowserWindow({ ...(this.appWindowsOptions[windowType] ?? {}), ...this.baseWindowOption, ...options });
|
||||
return this.handleNewWindow(windowType, window);
|
||||
}
|
||||
|
||||
public closeAllWindows(except?: AppWindow) {
|
||||
this.windows.forEach((window, key) => {
|
||||
if (key === except) {
|
||||
@@ -96,7 +103,7 @@ export class WindowManagerService {
|
||||
return this.windows.get(window);
|
||||
}
|
||||
|
||||
public getAppWindowFromWebContents(sender: Electron.WebContents): AppWindow {
|
||||
public getAppWindowFromWebContents(sender: WebContents): AppWindow {
|
||||
return Array.from(this.windows.entries()).find(([, value]) => value.webContents.id === sender.id)[0];
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { MutableRefObject, useEffect, useRef, useState } from "react";
|
||||
import { MAP_TYPES } from "renderer/partials/maps/map-tags/map-types";
|
||||
import { MAP_STYLES } from "renderer/partials/maps/map-tags/map-styles";
|
||||
import { BsmCheckbox } from "../shared/bsm-checkbox.component";
|
||||
import { minToS } from "renderer/helpers/time-utils";
|
||||
import { minToS } from "shared/helpers/time.helpers";
|
||||
import dateFormat from "dateformat";
|
||||
import { BsmRange } from "../shared/bsm-range.component";
|
||||
import { useTranslation } from "renderer/hooks/use-translation.hook";
|
||||
|
||||
@@ -5,6 +5,10 @@ export function minToS(minutes: number): number {
|
||||
return minutes * SECONDS_IN_MINUTE;
|
||||
}
|
||||
|
||||
export function minToMs(minutes: number): number {
|
||||
return minToS(minutes) * 1000;
|
||||
}
|
||||
|
||||
export function hourToMin(hours: number): number {
|
||||
return hours * MINUTES_IN_HOUR;
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
export type AppWindow = "index.html" | "launcher.html" | "oneclick-download-map.html" | "oneclick-download-playlist.html" | "oneclick-download-model.html" | "shortcut-launch.html";
|
||||
export type AppWindow = "index.html" | "launcher.html" | "oneclick-download-map.html" | "oneclick-download-playlist.html" | "oneclick-download-model.html" | "shortcut-launch.html" | string;
|
||||
|
||||
Reference in New Issue
Block a user