From 938328cd077d40b75e0834d56ff8d43ad035fd2b Mon Sep 17 00:00:00 2001 From: f0x52 Date: Thu, 29 Sep 2022 12:02:41 +0200 Subject: [frontend] Unified panels (#812) * settings panel restructuring * clean up old Gin handlers * colorscheme redesign, some other small css tweaks * basic router layout, error boundary * colorscheme redesign, some other small css tweaks * kebab-case consistency * superfluous padding on applist * remove unused consts * redux, whitespace changes.. * use .jsx extensions for components * login flow up till app registration * full redux oauth implementation, with basic error handling * split oauth api functions * oauth api revocation handling * basic profile change submission * move old dir * profile overview * fix keeping track of the wrong instance url (for different instance/api domains) * use redux state for profile form * delete old/index.js, old/basic.js, fully implemented * implement old/user/profile.js * implement password change * remove debug logging * support future api for removing files * customize profile css * remove unneeded wrapper components * restructure form fields * start on admin pages * admin panel settings * admin settings panel * remove old/admin files * add top-level redirect * refactor/cleanup forms * only do API checks on logged-in state * admin-status based routing * federation block routing * federation blocks * upgrade dependencies * react 18 changes * media cleanup * fix useEffect hooks * remove unused require * custom emoji base * emoji uploader * delete last old panel files * sidebar styling, remove unused page * refactor submit functions * fix sidebar boxshadow-border * fix old css variables * fix fake-toot avatar * fix non-square emoji * fix user settings redux keys * properly get admin account contact from instance response * Account.source default values * source.status_format key * mobile responsiveness * mobile element tweaks * proper redirect after removing block * add redirects for old setting panel urls * deletes * fix mobile overflow * clean up debug logging calls --- web/source/panels/lib/oauth.js | 227 ----------------------------------------- 1 file changed, 227 deletions(-) delete mode 100644 web/source/panels/lib/oauth.js (limited to 'web/source/panels/lib/oauth.js') diff --git a/web/source/panels/lib/oauth.js b/web/source/panels/lib/oauth.js deleted file mode 100644 index 3619dfa01..000000000 --- a/web/source/panels/lib/oauth.js +++ /dev/null @@ -1,227 +0,0 @@ -/* - GoToSocial - Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ - -"use strict"; - -const Promise = require("bluebird"); - -function getCurrentUrl() { - return window.location.origin + window.location.pathname; // strips ?query=string and #hash -} - -module.exports = function oauthClient(config, initState) { - /* config: - instance: instance domain (https://testingtesting123.xyz) - client_name: "GoToSocial Admin Panel" - scope: [] - website: - */ - - let state = initState; - if (initState == undefined) { - state = localStorage.getItem("oauth"); - if (state == undefined) { - state = { - config - }; - storeState(); - } else { - state = JSON.parse(state); - } - } - - function storeState() { - localStorage.setItem("oauth", JSON.stringify(state)); - } - - /* register app - /api/v1/apps - */ - function register() { - if (state.client_id != undefined) { - return true; // we already have a registration - } - let url = new URL(config.instance); - url.pathname = "/api/v1/apps"; - - return fetch(url.href, { - method: "POST", - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - client_name: config.client_name, - redirect_uris: getCurrentUrl(), - scopes: config.scope.join(" "), - website: getCurrentUrl() - }) - }).then((res) => { - if (res.status != 200) { - throw res; - } - return res.json(); - }).then((json) => { - state.client_id = json.client_id; - state.client_secret = json.client_secret; - storeState(); - }); - } - - /* authorize: - /oauth/authorize - ?client_id=CLIENT_ID - &redirect_uri=window.location.href - &response_type=code - &scope=admin - */ - function authorize() { - let url = new URL(config.instance); - url.pathname = "/oauth/authorize"; - url.searchParams.set("client_id", state.client_id); - url.searchParams.set("redirect_uri", getCurrentUrl()); - url.searchParams.set("response_type", "code"); - url.searchParams.set("scope", config.scope.join(" ")); - - window.location.assign(url.href); - } - - function callback() { - if (state.access_token != undefined) { - return; // we're already done :) - } - let params = (new URL(window.location)).searchParams; - - let token = params.get("code"); - if (token != null) { - console.log("got token callback:", token); - } - - return authorizeToken(token) - .catch((e) => { - console.log("Error processing oauth callback:", e); - logout(); // just to be sure - }); - } - - function authorizeToken(token) { - let url = new URL(config.instance); - url.pathname = "/oauth/token"; - return fetch(url.href, { - method: "POST", - headers: { - "Content-Type": "application/json" - }, - body: JSON.stringify({ - client_id: state.client_id, - client_secret: state.client_secret, - redirect_uri: getCurrentUrl(), - grant_type: "authorization_code", - code: token - }) - }).then((res) => { - if (res.status != 200) { - throw res; - } - return res.json(); - }).then((json) => { - state.access_token = json.access_token; - storeState(); - window.location = getCurrentUrl(); // clear ?token= - }); - } - - function isAuthorized() { - return (state.access_token != undefined); - } - - function apiRequest(path, method, data, type="json", accept="json") { - if (!isAuthorized()) { - throw new Error("Not Authenticated"); - } - let url = new URL(config.instance); - let [p, s] = path.split("?"); - url.pathname = p; - if (s != undefined) { - url.search = s; - } - let headers = { - "Authorization": `Bearer ${state.access_token}`, - "Accept": accept == "json" ? "application/json" : "*/*" - }; - let body = data; - if (type == "json" && body != undefined) { - headers["Content-Type"] = "application/json"; - body = JSON.stringify(data); - } - return fetch(url.href, { - method, - headers, - body - }).then((res) => { - return Promise.all([res.json(), res]); - }).then(([json, res]) => { - if (res.status != 200) { - if (json.error) { - throw new Error(json.error); - } else { - throw new Error(`${res.status}: ${res.statusText}`); - } - } else { - return json; - } - }).catch(e => { - if (e instanceof SyntaxError) { - throw new Error("Error: The GtS API returned a non-json error. This usually means a network problem, or an issue with your instance's reverse proxy configuration.", {cause: e}); - } else { - throw e; - } - }); - } - - function logout() { - let url = new URL(config.instance); - url.pathname = "/oauth/revoke"; - return fetch(url.href, { - method: "POST", - headers: { - "Content-Type": "application/json" - }, - body: JSON.stringify({ - client_id: state.client_id, - client_secret: state.client_secret, - token: state.access_token, - }) - }).then((res) => { - if (res.status != 200) { - // GoToSocial doesn't actually implement this route yet, - // so error is to be expected - return; - } - return res.json(); - }).catch(() => { - // see above - }).then(() => { - localStorage.removeItem("oauth"); - window.location = getCurrentUrl(); - }); - } - - return { - register, authorize, callback, isAuthorized, apiRequest, logout - }; -}; -- cgit v1.2.3