diff options
Diffstat (limited to 'src/utils/cloud.tsx')
-rw-r--r-- | src/utils/cloud.tsx | 124 |
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}`); +} |