From a79cf1bd000da84111ac839cfada1f8d867211fd Mon Sep 17 00:00:00 2001 From: RaindropsSys Date: Fri, 29 Mar 2024 22:05:24 +0100 Subject: Updated 7 files and added 4 files (automated) --- .gitignore | 4 +- client/assets/icons2/questions.svg | 1 + client/dom/new.html | 8 ++- client/fragments/home.html | 9 ++- client/fragments/questions.html | 57 +++++++++++++++++ client/fragments/settings/experiments.html | 2 +- client/main.js | 11 +++- client/src/platforms.js | 99 ++++++++++++++++++++++++++++++ client/src/plugin.js | 4 ++ client/src/spyglass.js | 21 +++++-- server/platforms.js | 75 ++++++++++++++++++++++ 11 files changed, 279 insertions(+), 12 deletions(-) create mode 100644 client/assets/icons2/questions.svg create mode 100644 client/fragments/questions.html create mode 100644 client/src/platforms.js create mode 100644 server/platforms.js diff --git a/.gitignore b/.gitignore index 637cb9f..59fcf91 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,6 @@ debug build bot/tokens.json vpn/keys.json -vpn/requests.json \ No newline at end of file +vpn/requests.json +server/data +server/secrets.json diff --git a/client/assets/icons2/questions.svg b/client/assets/icons2/questions.svg new file mode 100644 index 0000000..ebe64e3 --- /dev/null +++ b/client/assets/icons2/questions.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/dom/new.html b/client/dom/new.html index 22a9988..76d478c 100644 --- a/client/dom/new.html +++ b/client/dom/new.html @@ -11,6 +11,7 @@ Chatroom + + + +
+
+

Chatroom Questions

+

Ask any question here, and get an instant, reliable and trustworthy answer from the internet.

+ +
+ +
+
+
+
Enter a question and press Enter to see an answer here.
+ + +
+
+ + + + diff --git a/client/fragments/settings/experiments.html b/client/fragments/settings/experiments.html index cb344ed..e5dcb02 100644 --- a/client/fragments/settings/experiments.html +++ b/client/fragments/settings/experiments.html @@ -55,7 +55,7 @@ } }, { - name: "m2spyglassdialogbehavior", + name: "m2spyglassdialogbehavior2", treatments: { "false": "Treatment 1: Display Spyglass dialog in M2", "true": "Treatment 2: Hide Spyglass dialog in M2" diff --git a/client/main.js b/client/main.js index c2f40cf..77d67f5 100755 --- a/client/main.js +++ b/client/main.js @@ -2,8 +2,8 @@ const buildNumber = "main"; // --- >FINAL< @BUILDNUMBER@ >FINAL< --- // -const version_stable = "2.8.2-LTS"; -const version_beta = "3.0.0-DP.2-rv1"; +const version_stable = "2.8.3-LTS"; +const version_beta = "3.0.0-DP.3"; let version = version_stable; const { desktopCapturer, protocol, app, BrowserWindow, webContents, globalShortcut, nativeTheme, ipcMain, session, dialog, Menu } = require('electron'); @@ -429,6 +429,13 @@ ipcMain.handle('reload', (_) => { }); }); +ipcMain.handle('platforms', (_, req) => { + return new Promise(async (res) => { + if (!global.mainWindow) return; + res(await global.mainWindow.webContents.executeJavaScript("platformsRequest(JSON.parse(atob(\"" + Buffer.from(JSON.stringify(req)).toString("base64") + "\")));")); + }); +}); + ipcMain.on('menu', (_, params) => { console.log(params); diff --git a/client/src/platforms.js b/client/src/platforms.js new file mode 100644 index 0000000..31c5c5c --- /dev/null +++ b/client/src/platforms.js @@ -0,0 +1,99 @@ +const PLATFORMS_SERVER = "wss://school.equestria.dev/platforms"; + +let PLATFORMS_STATE = false; +let PLATFORMS_INITIALIZED = false; +let PLATFORMS_SOCKET = null; +const PLATFORMS_CALLBACKS = {}; + +function platformsSend(d) { + return PLATFORMS_SOCKET.send(JSON.stringify(d)); +} + +function startPlatforms() { + PLATFORMS_INITIALIZED = true; + PLATFORMS_SOCKET = new WebSocket(PLATFORMS_SERVER); + + PLATFORMS_SOCKET.onmessage = (e) => { + let data; + try { + data = JSON.parse(e.data) + } catch (e) { + console.error("Platforms", e); + } + if (!data) return; + + console.log("Platforms", data); + + if (data.state) { + switch (data.state) { + case "NEEDS_AUTHENTICATION": + let authInterval = setInterval(async () => { + try { + if (await tabs.filter(i => i.small)[1].webview.children[1].executeJavaScript("!!document.getElementsByClassName('mx_ConfirmSessionLockTheftView_body')[0]")) { + await tabs.filter(i => i.small)[1].webview.children[1].executeJavaScript("document.querySelector('.mx_ConfirmSessionLockTheftView_body .mx_AccessibleButton.mx_AccessibleButton_hasKind.mx_AccessibleButton_kind_primary').click()") + } + + let token = await tabs.filter(i => i.small)[1].webview.children[1].executeJavaScript("matrixChat.stores.client.http.opts.accessToken"); + clearInterval(authInterval); + + platformsSend({ + state: "AUTHENTICATION_RESPONSE", + token: token + }); + } catch (e) { + console.error(e); + } + }, 50); + + break; + + case "AUTHENTICATION_OK": + PLATFORMS_STATE = true; + break; + + case "REQUEST_RESPONSE": + console.log(data); + + if (data.data._id && PLATFORMS_CALLBACKS[data.data._id]) { + PLATFORMS_CALLBACKS[data.data._id](data); + } + break; + } + } + } + + PLATFORMS_SOCKET.onopen = (e) => { + console.log("Platforms", e); + } + + PLATFORMS_SOCKET.onerror = (e) => { + console.log("Platforms", e); + + PLATFORMS_SOCKET.close(); + clearInterval(window.spyglassInterval); + } + + PLATFORMS_SOCKET.onclose = (e) => { + console.log("Platforms", e); + + PLATFORMS_SOCKET = false; + + setTimeout(() => { + startPlatforms(); + }, 1000); + } +} + +function platformsRequest(req) { + return new Promise((res, rej) => { + let id = crypto.randomUUID(); + req["_id"] = id; + + PLATFORMS_CALLBACKS[id] = (data) => { + res(data.data); + delete PLATFORMS_CALLBACKS[id]; + } + + platformsSend(req); + }); +} diff --git a/client/src/plugin.js b/client/src/plugin.js index 7324672..8ff022f 100644 --- a/client/src/plugin.js +++ b/client/src/plugin.js @@ -17,6 +17,10 @@ const crObj = { reloadHost: async () => { if (location.protocol !== "file:") throw new Error("reloadHost is only available from local pages."); return await ipcRenderer.invoke("reload"); + }, + executePlatformsRequest: async (req) => { + if (location.protocol !== "file:") throw new Error("reloadHost is only available from local pages."); + return await ipcRenderer.invoke("platforms", req); } }; diff --git a/client/src/spyglass.js b/client/src/spyglass.js index bff90af..e719d44 100644 --- a/client/src/spyglass.js +++ b/client/src/spyglass.js @@ -38,13 +38,13 @@ if ((process.env.USERDNSDOMAIN && process.env.USERDNSDOMAIN.endsWith(".AC-ORLEAN function startSpyglass() { SPYGLASS_INITIALIZED = true; - if (localStorage.getItem("cr3-trial-m2spyglassdialogbehavior") === "true") { + if (localStorage.getItem("cr3-trial-m2spyglassdialogbehavior2") === "true") { SPYGLASS_INITIALIZED = false; } if (window.bootstrap) { if (!modal) modal = new bootstrap.Modal(document.getElementById("loading-modal")); - if (localStorage.getItem("cr3-trial-m2spyglassdialogbehavior") !== "true") modal.show(); + if (localStorage.getItem("cr3-trial-m2spyglassdialogbehavior2") !== "true") modal.show(); } SPYGLASS_SOCKET = new WebSocket(SPYGLASS_SERVER); @@ -65,11 +65,22 @@ if ((process.env.USERDNSDOMAIN && process.env.USERDNSDOMAIN.endsWith(".AC-ORLEAN case "NEEDS_AUTHENTICATION": let authInterval = setInterval(async () => { try { - if (await tabs.filter(i => i.small)[0].webview.children[1].executeJavaScript("!!document.getElementsByClassName('mx_ConfirmSessionLockTheftView_body')[0]")) { - await tabs.filter(i => i.small)[0].webview.children[1].executeJavaScript("document.querySelector('.mx_ConfirmSessionLockTheftView_body .mx_AccessibleButton.mx_AccessibleButton_hasKind.mx_AccessibleButton_kind_primary').click()") + let token; + + if (!window.isNewUI) { + if (await tabs.filter(i => i.small)[0].webview.children[1].executeJavaScript("!!document.getElementsByClassName('mx_ConfirmSessionLockTheftView_body')[0]")) { + await tabs.filter(i => i.small)[0].webview.children[1].executeJavaScript("document.querySelector('.mx_ConfirmSessionLockTheftView_body .mx_AccessibleButton.mx_AccessibleButton_hasKind.mx_AccessibleButton_kind_primary').click()") + } + + token = await tabs.filter(i => i.small)[0].webview.children[1].executeJavaScript("matrixChat.stores.client.http.opts.accessToken"); + } else { + if (await tabs.filter(i => i.small)[1].webview.children[1].executeJavaScript("!!document.getElementsByClassName('mx_ConfirmSessionLockTheftView_body')[0]")) { + await tabs.filter(i => i.small)[1].webview.children[1].executeJavaScript("document.querySelector('.mx_ConfirmSessionLockTheftView_body .mx_AccessibleButton.mx_AccessibleButton_hasKind.mx_AccessibleButton_kind_primary').click()") + } + + token = await tabs.filter(i => i.small)[1].webview.children[1].executeJavaScript("matrixChat.stores.client.http.opts.accessToken"); } - let token = await tabs.filter(i => i.small)[0].webview.children[1].executeJavaScript("matrixChat.stores.client.http.opts.accessToken"); clearInterval(authInterval); spyglassSend({ diff --git a/server/platforms.js b/server/platforms.js new file mode 100644 index 0000000..01773ed --- /dev/null +++ b/server/platforms.js @@ -0,0 +1,75 @@ +const secrets = require('./secrets.json'); +const WebSocketServer = require('ws').WebSocketServer; +const wss = new WebSocketServer({ port: 19219 }); + +async function processRequest(ws, data) { + if (data.method === "wolfram") { + let query = "https://api.wolframalpha.com/v1/simple?appid=" + secrets.wolfram + "&i=" + encodeURIComponent(data.query ?? ""); + + ws.send({ + state: "REQUEST_RESPONSE", + data: { + _id: data._id ?? null, + data: Buffer.from(await (await fetch(query)).arrayBuffer()).toString("base64") + } + }); + + return; + } + + ws.send({ + state: "REQUEST_RESPONSE", + data: null + }); +} + +wss.on('connection', function connection(ws) { + ws.authenticated = false; + ws.token = null; + ws.auth = null; + + ws._send = ws.send; + ws.send = (d) => { + return ws._send(JSON.stringify(d)); + } + + ws.on('error', console.error); + + ws.on('message', async (_data) => { + try { + let data = JSON.parse(_data); + + if (data.state) { + switch (data.state) { + case "AUTHENTICATION_RESPONSE": + if (data.token) { + let userInfo = (await (await fetch("https://school.equestria.dev/_matrix/client/v3/account/whoami", { headers: { 'Authorization': 'Bearer ' + data.token } })).json()); + console.log(userInfo); + + if (userInfo['user_id']) { + ws.auth = userInfo; + ws.token = data.token; + ws.authenticated = true; + + ws.send({ + state: "AUTHENTICATION_OK" + }); + } else { + ws.close(); + } + } + break; + } + } + + if (!ws.authenticated) ws.close(); + if (!data.state || data.state !== "AUTHENTICATION_RESPONSE") processRequest(ws, data); + } catch (e) { + console.error(e); + } + }); + + ws.send({ + state: "NEEDS_AUTHENTICATION" + }); +}); -- cgit