aboutsummaryrefslogtreecommitdiff
path: root/src/utils/cloud.tsx
diff options
context:
space:
mode:
authorLewis Crichton <lewi@lewisakura.moe>2023-04-07 01:27:18 +0100
committerGitHub <noreply@github.com>2023-04-07 02:27:18 +0200
commit97f8d4d5154d566568fc475d6aaba5db07399b2b (patch)
treefeafd22c26bdfc37a2d787e60f52bec94e777636 /src/utils/cloud.tsx
parent2672dea8e361e8216b9459ac5dac97d36a47e412 (diff)
downloadVencord-97f8d4d5154d566568fc475d6aaba5db07399b2b.tar.gz
Vencord-97f8d4d5154d566568fc475d6aaba5db07399b2b.tar.bz2
Vencord-97f8d4d5154d566568fc475d6aaba5db07399b2b.zip
feat: Cloud settings sync (#505)
Co-authored-by: Ven <vendicated@riseup.net>
Diffstat (limited to 'src/utils/cloud.tsx')
-rw-r--r--src/utils/cloud.tsx124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/utils/cloud.tsx b/src/utils/cloud.tsx
new file mode 100644
index 0000000..b31091f
--- /dev/null
+++ b/src/utils/cloud.tsx
@@ -0,0 +1,124 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2023 Vendicated and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+import * as DataStore from "@api/DataStore";
+import { showNotification } from "@api/Notifications";
+import { Settings } from "@api/settings";
+import { findByProps } from "@webpack";
+import { UserStore } from "@webpack/common";
+
+import Logger from "./Logger";
+import { openModal } from "./modal";
+
+export const cloudLogger = new Logger("Cloud", "#39b7e0");
+export const getCloudUrl = () => new URL(Settings.cloud.url);
+
+export async function getAuthorization() {
+ const secrets = await DataStore.get<Record<string, string>>("Vencord_cloudSecret") ?? {};
+ return secrets[getCloudUrl().origin];
+}
+
+async function setAuthorization(secret: string) {
+ await DataStore.update<Record<string, string>>("Vencord_cloudSecret", secrets => {
+ secrets ??= {};
+ secrets[getCloudUrl().origin] = secret;
+ return secrets;
+ });
+}
+
+export async function deauthorizeCloud() {
+ await DataStore.update<Record<string, string>>("Vencord_cloudSecret", secrets => {
+ secrets ??= {};
+ delete secrets[getCloudUrl().origin];
+ return secrets;
+ });
+}
+
+export async function authorizeCloud() {
+ if (await getAuthorization() !== undefined) {
+ Settings.cloud.authenticated = true;
+ return;
+ }
+
+ try {
+ const oauthConfiguration = await fetch(new URL("/v1/oauth/settings", getCloudUrl()));
+ var { clientId, redirectUri } = await oauthConfiguration.json();
+ } catch {
+ showNotification({
+ title: "Cloud Integration",
+ body: "Setup failed (couldn't retrieve OAuth configuration)."
+ });
+ Settings.cloud.authenticated = false;
+ return;
+ }
+
+ const { OAuth2AuthorizeModal } = findByProps("OAuth2AuthorizeModal");
+
+ openModal((props: any) => <OAuth2AuthorizeModal
+ {...props}
+ scopes={["identify"]}
+ responseType="code"
+ redirectUri={redirectUri}
+ permissions={0n}
+ clientId={clientId}
+ cancelCompletesFlow={false}
+ callback={async (callbackUrl: string) => {
+ if (!callbackUrl) {
+ Settings.cloud.authenticated = false;
+ return;
+ }
+
+ try {
+ const res = await fetch(callbackUrl, {
+ headers: new Headers({ Accept: "application/json" })
+ });
+ const { secret } = await res.json();
+ if (secret) {
+ cloudLogger.info("Authorized with secret");
+ await setAuthorization(secret);
+ showNotification({
+ title: "Cloud Integration",
+ body: "Cloud integrations enabled!"
+ });
+ Settings.cloud.authenticated = true;
+ } else {
+ showNotification({
+ title: "Cloud Integration",
+ body: "Setup failed (no secret returned?)."
+ });
+ Settings.cloud.authenticated = false;
+ }
+ } catch (e: any) {
+ cloudLogger.error("Failed to authorize", e);
+ showNotification({
+ title: "Cloud Integration",
+ body: `Setup failed (${e.toString()}).`
+ });
+ Settings.cloud.authenticated = false;
+ }
+ }
+ }
+ />);
+}
+
+export async function getCloudAuth() {
+ const userId = UserStore.getCurrentUser().id;
+ const secret = await getAuthorization();
+
+ return window.btoa(`${secret}:${userId}`);
+}