summaryrefslogtreecommitdiff
path: root/web/source/settings
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2023-10-05 16:06:19 +0200
committerLibravatar GitHub <noreply@github.com>2023-10-05 16:06:19 +0200
commitd173fcdfa3ad6f6aee721c8553f25f4db38fa302 (patch)
tree722cdaf93e090edcf83769ae763731008daf5fd3 /web/source/settings
parentupdates markdown parsing to reduce allocations in the same way as the plain t... (diff)
downloadgotosocial-d173fcdfa3ad6f6aee721c8553f25f4db38fa302.tar.xz
[chore] Convert some settings / admin panel JS to TypeScript (#2247)
* initial conversion of STUFF to typescript * more stuff * update babel deps, include commonjs transform * update bundler & eslint configuration * eslint --fix * upgrade deps * update docs, build stuff, peripheral stuff --------- Co-authored-by: f0x <f0x@cthu.lu>
Diffstat (limited to 'web/source/settings')
-rw-r--r--web/source/settings/admin/accounts/detail.jsx2
-rw-r--r--web/source/settings/admin/accounts/index.jsx2
-rw-r--r--web/source/settings/admin/actions/keys/expireremote.jsx2
-rw-r--r--web/source/settings/admin/actions/keys/index.jsx2
-rw-r--r--web/source/settings/admin/actions/media/cleanup.jsx2
-rw-r--r--web/source/settings/admin/actions/media/index.jsx2
-rw-r--r--web/source/settings/admin/emoji/category-select.jsx2
-rw-r--r--web/source/settings/admin/emoji/local/detail.js2
-rw-r--r--web/source/settings/admin/emoji/local/index.js2
-rw-r--r--web/source/settings/admin/emoji/local/new-emoji.js2
-rw-r--r--web/source/settings/admin/emoji/local/overview.js2
-rw-r--r--web/source/settings/admin/emoji/local/use-shortcode.js2
-rw-r--r--web/source/settings/admin/emoji/remote/index.js2
-rw-r--r--web/source/settings/admin/emoji/remote/parse-from-toot.js2
-rw-r--r--web/source/settings/admin/federation/detail.js2
-rw-r--r--web/source/settings/admin/federation/import-export/export-format-table.jsx2
-rw-r--r--web/source/settings/admin/federation/import-export/form.jsx2
-rw-r--r--web/source/settings/admin/federation/import-export/index.jsx2
-rw-r--r--web/source/settings/admin/federation/import-export/process.jsx2
-rw-r--r--web/source/settings/admin/federation/index.js2
-rw-r--r--web/source/settings/admin/federation/overview.js2
-rw-r--r--web/source/settings/admin/reports/detail.jsx2
-rw-r--r--web/source/settings/admin/reports/index.jsx2
-rw-r--r--web/source/settings/admin/reports/username.jsx2
-rw-r--r--web/source/settings/admin/settings/index.jsx2
-rw-r--r--web/source/settings/admin/settings/rules.jsx2
-rw-r--r--web/source/settings/components/authorization/index.tsx (renamed from web/source/settings/components/authorization/index.jsx)30
-rw-r--r--web/source/settings/components/authorization/login.tsx (renamed from web/source/settings/components/authorization/login.jsx)33
-rw-r--r--web/source/settings/components/back-button.jsx2
-rw-r--r--web/source/settings/components/check-list.jsx2
-rw-r--r--web/source/settings/components/combo-box.jsx2
-rw-r--r--web/source/settings/components/error.jsx2
-rw-r--r--web/source/settings/components/fake-profile.jsx2
-rw-r--r--web/source/settings/components/fake-toot.jsx2
-rw-r--r--web/source/settings/components/form/inputs.jsx2
-rw-r--r--web/source/settings/components/form/mutation-button.jsx2
-rw-r--r--web/source/settings/components/languages.jsx2
-rw-r--r--web/source/settings/components/loading.jsx2
-rw-r--r--web/source/settings/components/user-logout-card.jsx2
-rw-r--r--web/source/settings/index.js8
-rw-r--r--web/source/settings/lib/domain-block.js2
-rw-r--r--web/source/settings/lib/form/bool.jsx2
-rw-r--r--web/source/settings/lib/form/check-list.jsx2
-rw-r--r--web/source/settings/lib/form/combo-box.jsx2
-rw-r--r--web/source/settings/lib/form/context.jsx2
-rw-r--r--web/source/settings/lib/form/field-array.jsx2
-rw-r--r--web/source/settings/lib/form/file.jsx2
-rw-r--r--web/source/settings/lib/form/form-with-data.jsx2
-rw-r--r--web/source/settings/lib/form/get-form-mutations.js2
-rw-r--r--web/source/settings/lib/form/index.js2
-rw-r--r--web/source/settings/lib/form/radio.jsx2
-rw-r--r--web/source/settings/lib/form/submit.js2
-rw-r--r--web/source/settings/lib/form/text.jsx2
-rw-r--r--web/source/settings/lib/navigation/components.jsx2
-rw-r--r--web/source/settings/lib/navigation/index.js2
-rw-r--r--web/source/settings/lib/navigation/util.js2
-rw-r--r--web/source/settings/lib/query/admin/custom-emoji.js2
-rw-r--r--web/source/settings/lib/query/admin/import-export.js2
-rw-r--r--web/source/settings/lib/query/admin/index.js6
-rw-r--r--web/source/settings/lib/query/admin/reports.js2
-rw-r--r--web/source/settings/lib/query/base.js70
-rw-r--r--web/source/settings/lib/query/gts-api.ts149
-rw-r--r--web/source/settings/lib/query/index.js6
-rw-r--r--web/source/settings/lib/query/lib.js6
-rw-r--r--web/source/settings/lib/query/oauth.js160
-rw-r--r--web/source/settings/lib/query/oauth/index.ts204
-rw-r--r--web/source/settings/lib/query/user/index.ts (renamed from web/source/settings/lib/query/user.js)43
-rw-r--r--web/source/settings/redux/oauth.js44
-rw-r--r--web/source/settings/redux/oauth.ts89
-rw-r--r--web/source/settings/redux/store.ts (renamed from web/source/settings/redux/index.js)54
-rw-r--r--web/source/settings/user/profile.js2
-rw-r--r--web/source/settings/user/settings.js2
72 files changed, 542 insertions, 476 deletions
diff --git a/web/source/settings/admin/accounts/detail.jsx b/web/source/settings/admin/accounts/detail.jsx
index 189c07e8d..0e906cd1c 100644
--- a/web/source/settings/admin/accounts/detail.jsx
+++ b/web/source/settings/admin/accounts/detail.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { useRoute, Redirect } = require("wouter");
diff --git a/web/source/settings/admin/accounts/index.jsx b/web/source/settings/admin/accounts/index.jsx
index 1dea36fb5..c642d903e 100644
--- a/web/source/settings/admin/accounts/index.jsx
+++ b/web/source/settings/admin/accounts/index.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { Switch, Route, Link } = require("wouter");
diff --git a/web/source/settings/admin/actions/keys/expireremote.jsx b/web/source/settings/admin/actions/keys/expireremote.jsx
index b9045a7ed..172f65bc3 100644
--- a/web/source/settings/admin/actions/keys/expireremote.jsx
+++ b/web/source/settings/admin/actions/keys/expireremote.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const query = require("../../../lib/query");
diff --git a/web/source/settings/admin/actions/keys/index.jsx b/web/source/settings/admin/actions/keys/index.jsx
index b40835c12..f6a851e70 100644
--- a/web/source/settings/admin/actions/keys/index.jsx
+++ b/web/source/settings/admin/actions/keys/index.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const ExpireRemote = require("./expireremote");
diff --git a/web/source/settings/admin/actions/media/cleanup.jsx b/web/source/settings/admin/actions/media/cleanup.jsx
index 61ee15258..8b0e628f6 100644
--- a/web/source/settings/admin/actions/media/cleanup.jsx
+++ b/web/source/settings/admin/actions/media/cleanup.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const query = require("../../../lib/query");
diff --git a/web/source/settings/admin/actions/media/index.jsx b/web/source/settings/admin/actions/media/index.jsx
index c5167506a..c904eb047 100644
--- a/web/source/settings/admin/actions/media/index.jsx
+++ b/web/source/settings/admin/actions/media/index.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const Cleanup = require("./cleanup");
diff --git a/web/source/settings/admin/emoji/category-select.jsx b/web/source/settings/admin/emoji/category-select.jsx
index bc4c280d5..da2604602 100644
--- a/web/source/settings/admin/emoji/category-select.jsx
+++ b/web/source/settings/admin/emoji/category-select.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const splitFilterN = require("split-filter-n");
const syncpipe = require('syncpipe');
diff --git a/web/source/settings/admin/emoji/local/detail.js b/web/source/settings/admin/emoji/local/detail.js
index 6b583b0b9..daf7a2dac 100644
--- a/web/source/settings/admin/emoji/local/detail.js
+++ b/web/source/settings/admin/emoji/local/detail.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { useRoute, Link, Redirect } = require("wouter");
diff --git a/web/source/settings/admin/emoji/local/index.js b/web/source/settings/admin/emoji/local/index.js
index 56695094c..008bd7a61 100644
--- a/web/source/settings/admin/emoji/local/index.js
+++ b/web/source/settings/admin/emoji/local/index.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { Switch, Route } = require("wouter");
diff --git a/web/source/settings/admin/emoji/local/new-emoji.js b/web/source/settings/admin/emoji/local/new-emoji.js
index de796fe30..439d09e62 100644
--- a/web/source/settings/admin/emoji/local/new-emoji.js
+++ b/web/source/settings/admin/emoji/local/new-emoji.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const query = require("../../../lib/query");
diff --git a/web/source/settings/admin/emoji/local/overview.js b/web/source/settings/admin/emoji/local/overview.js
index e8d35ff54..38dc1feba 100644
--- a/web/source/settings/admin/emoji/local/overview.js
+++ b/web/source/settings/admin/emoji/local/overview.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { Link } = require("wouter");
const syncpipe = require("syncpipe");
diff --git a/web/source/settings/admin/emoji/local/use-shortcode.js b/web/source/settings/admin/emoji/local/use-shortcode.js
index c9c27cdf2..7e1bae0ad 100644
--- a/web/source/settings/admin/emoji/local/use-shortcode.js
+++ b/web/source/settings/admin/emoji/local/use-shortcode.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const query = require("../../../lib/query");
diff --git a/web/source/settings/admin/emoji/remote/index.js b/web/source/settings/admin/emoji/remote/index.js
index bf7113b49..e877efb89 100644
--- a/web/source/settings/admin/emoji/remote/index.js
+++ b/web/source/settings/admin/emoji/remote/index.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const ParseFromToot = require("./parse-from-toot");
diff --git a/web/source/settings/admin/emoji/remote/parse-from-toot.js b/web/source/settings/admin/emoji/remote/parse-from-toot.js
index 3bf5fdd90..e6438a4d2 100644
--- a/web/source/settings/admin/emoji/remote/parse-from-toot.js
+++ b/web/source/settings/admin/emoji/remote/parse-from-toot.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const query = require("../../../lib/query");
diff --git a/web/source/settings/admin/federation/detail.js b/web/source/settings/admin/federation/detail.js
index a3bbfcac1..7bdee66cf 100644
--- a/web/source/settings/admin/federation/detail.js
+++ b/web/source/settings/admin/federation/detail.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { useRoute, Redirect, useLocation } = require("wouter");
diff --git a/web/source/settings/admin/federation/import-export/export-format-table.jsx b/web/source/settings/admin/federation/import-export/export-format-table.jsx
index 062a169a4..7fcffa348 100644
--- a/web/source/settings/admin/federation/import-export/export-format-table.jsx
+++ b/web/source/settings/admin/federation/import-export/export-format-table.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
module.exports = function ExportFormatTable() {
diff --git a/web/source/settings/admin/federation/import-export/form.jsx b/web/source/settings/admin/federation/import-export/form.jsx
index a6967b8f0..2086739e3 100644
--- a/web/source/settings/admin/federation/import-export/form.jsx
+++ b/web/source/settings/admin/federation/import-export/form.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const query = require("../../../lib/query");
diff --git a/web/source/settings/admin/federation/import-export/index.jsx b/web/source/settings/admin/federation/import-export/index.jsx
index 7126b4e89..bff14b939 100644
--- a/web/source/settings/admin/federation/import-export/index.jsx
+++ b/web/source/settings/admin/federation/import-export/index.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { Switch, Route, Redirect, useLocation } = require("wouter");
diff --git a/web/source/settings/admin/federation/import-export/process.jsx b/web/source/settings/admin/federation/import-export/process.jsx
index b78dc8ed9..b39410605 100644
--- a/web/source/settings/admin/federation/import-export/process.jsx
+++ b/web/source/settings/admin/federation/import-export/process.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const query = require("../../../lib/query");
diff --git a/web/source/settings/admin/federation/index.js b/web/source/settings/admin/federation/index.js
index 081d34113..ec536c0be 100644
--- a/web/source/settings/admin/federation/index.js
+++ b/web/source/settings/admin/federation/index.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { Switch, Route } = require("wouter");
diff --git a/web/source/settings/admin/federation/overview.js b/web/source/settings/admin/federation/overview.js
index 626794455..c09289284 100644
--- a/web/source/settings/admin/federation/overview.js
+++ b/web/source/settings/admin/federation/overview.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { Link, useLocation } = require("wouter");
const { matchSorter } = require("match-sorter");
diff --git a/web/source/settings/admin/reports/detail.jsx b/web/source/settings/admin/reports/detail.jsx
index e85b345b0..6b85872c4 100644
--- a/web/source/settings/admin/reports/detail.jsx
+++ b/web/source/settings/admin/reports/detail.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { useRoute, Redirect } = require("wouter");
diff --git a/web/source/settings/admin/reports/index.jsx b/web/source/settings/admin/reports/index.jsx
index 62a71c3e3..2f7a09517 100644
--- a/web/source/settings/admin/reports/index.jsx
+++ b/web/source/settings/admin/reports/index.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { Link, Switch, Route } = require("wouter");
diff --git a/web/source/settings/admin/reports/username.jsx b/web/source/settings/admin/reports/username.jsx
index eca3570d8..9754c2dd5 100644
--- a/web/source/settings/admin/reports/username.jsx
+++ b/web/source/settings/admin/reports/username.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { Link } = require("wouter");
diff --git a/web/source/settings/admin/settings/index.jsx b/web/source/settings/admin/settings/index.jsx
index dab476433..5ea227fb1 100644
--- a/web/source/settings/admin/settings/index.jsx
+++ b/web/source/settings/admin/settings/index.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const query = require("../../lib/query");
diff --git a/web/source/settings/admin/settings/rules.jsx b/web/source/settings/admin/settings/rules.jsx
index 330bc07fd..7c78e6601 100644
--- a/web/source/settings/admin/settings/rules.jsx
+++ b/web/source/settings/admin/settings/rules.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { Switch, Route, Link, Redirect, useRoute } = require("wouter");
diff --git a/web/source/settings/components/authorization/index.jsx b/web/source/settings/components/authorization/index.tsx
index d38e160da..321bb03eb 100644
--- a/web/source/settings/components/authorization/index.jsx
+++ b/web/source/settings/components/authorization/index.tsx
@@ -17,23 +17,25 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
+import { useVerifyCredentialsQuery } from "../../lib/query/oauth";
+import { store } from "../../redux/store";
-const React = require("react");
-const Redux = require("react-redux");
+import React from "react";
-const query = require("../../lib/query");
+import Login from "./login";
+import Loading from "../loading";
+import { Error } from "../error";
-const Login = require("./login");
-const Loading = require("../loading");
-const { Error } = require("../error");
+export function Authorization({ App }) {
+ const { loginState, expectingRedirect } = store.getState().oauth;
+ const skip = (loginState == "none" || loginState == "logout" || expectingRedirect);
-module.exports = function Authorization({ App }) {
- const { loginState, expectingRedirect } = Redux.useSelector((state) => state.oauth);
-
- const { isLoading, isSuccess, data: account, error } = query.useVerifyCredentialsQuery(undefined, {
- skip: loginState == "none" || loginState == "logout" || expectingRedirect
- });
+ const {
+ isLoading,
+ isSuccess,
+ data: account,
+ error,
+ } = useVerifyCredentialsQuery(null, { skip: skip });
let showLogin = true;
let content = null;
@@ -73,4 +75,4 @@ module.exports = function Authorization({ App }) {
</section>
);
}
-}; \ No newline at end of file
+}
diff --git a/web/source/settings/components/authorization/login.jsx b/web/source/settings/components/authorization/login.tsx
index dbeb6c047..76bfccf43 100644
--- a/web/source/settings/components/authorization/login.jsx
+++ b/web/source/settings/components/authorization/login.tsx
@@ -17,18 +17,16 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
+import React from "react";
-const React = require("react");
+import { useAuthorizeFlowMutation } from "../../lib/query/oauth";
+import { useTextInput, useValue } from "../../lib/form";
+import useFormSubmit from "../../lib/form/submit";
+import { TextInput } from "../form/inputs";
+import MutationButton from "../form/mutation-button";
+import Loading from "../loading";
-const query = require("../../lib/query");
-const { useTextInput, useValue } = require("../../lib/form");
-const useFormSubmit = require("../../lib/form/submit");
-const { TextInput } = require("../form/inputs");
-const MutationButton = require("../form/mutation-button");
-const Loading = require("../loading");
-
-module.exports = function Login({ }) {
+export default function Login({ }) {
const form = {
instance: useTextInput("instance", {
defaultValue: window.location.origin
@@ -38,8 +36,11 @@ module.exports = function Login({ }) {
const [formSubmit, result] = useFormSubmit(
form,
- query.useAuthorizeFlowMutation(),
- { changedOnly: false }
+ useAuthorizeFlowMutation(),
+ {
+ changedOnly: false,
+ onFinish: undefined,
+ }
);
if (result.isLoading) {
@@ -63,7 +64,11 @@ module.exports = function Login({ }) {
label="Instance"
name="instance"
/>
- <MutationButton label="Login" result={result} />
+ <MutationButton
+ label="Login"
+ result={result}
+ disabled={false}
+ />
</form>
);
-}; \ No newline at end of file
+} \ No newline at end of file
diff --git a/web/source/settings/components/back-button.jsx b/web/source/settings/components/back-button.jsx
index 13a7a757b..05306e2ea 100644
--- a/web/source/settings/components/back-button.jsx
+++ b/web/source/settings/components/back-button.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { Link } = require("wouter");
diff --git a/web/source/settings/components/check-list.jsx b/web/source/settings/components/check-list.jsx
index 492e58e5f..de42a56a5 100644
--- a/web/source/settings/components/check-list.jsx
+++ b/web/source/settings/components/check-list.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
module.exports = function CheckList({ field, header = "All", EntryComponent, getExtraProps }) {
diff --git a/web/source/settings/components/combo-box.jsx b/web/source/settings/components/combo-box.jsx
index 030bd5c30..fc0133583 100644
--- a/web/source/settings/components/combo-box.jsx
+++ b/web/source/settings/components/combo-box.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const {
diff --git a/web/source/settings/components/error.jsx b/web/source/settings/components/error.jsx
index 283083481..3205cd5e3 100644
--- a/web/source/settings/components/error.jsx
+++ b/web/source/settings/components/error.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
function ErrorFallback({ error, resetErrorBoundary }) {
diff --git a/web/source/settings/components/fake-profile.jsx b/web/source/settings/components/fake-profile.jsx
index 04424a5ed..d1f28f36c 100644
--- a/web/source/settings/components/fake-profile.jsx
+++ b/web/source/settings/components/fake-profile.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
module.exports = function FakeProfile({ avatar, header, display_name, username, role }) {
diff --git a/web/source/settings/components/fake-toot.jsx b/web/source/settings/components/fake-toot.jsx
index b71831a95..7c2e40454 100644
--- a/web/source/settings/components/fake-toot.jsx
+++ b/web/source/settings/components/fake-toot.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const query = require("../lib/query");
diff --git a/web/source/settings/components/form/inputs.jsx b/web/source/settings/components/form/inputs.jsx
index 378879525..f7a6beeda 100644
--- a/web/source/settings/components/form/inputs.jsx
+++ b/web/source/settings/components/form/inputs.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
function TextInput({ label, field, ...inputProps }) {
diff --git a/web/source/settings/components/form/mutation-button.jsx b/web/source/settings/components/form/mutation-button.jsx
index 5f7218db4..0eaf33912 100644
--- a/web/source/settings/components/form/mutation-button.jsx
+++ b/web/source/settings/components/form/mutation-button.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { Error } = require("../error");
diff --git a/web/source/settings/components/languages.jsx b/web/source/settings/components/languages.jsx
index 51006098b..61c76e03a 100644
--- a/web/source/settings/components/languages.jsx
+++ b/web/source/settings/components/languages.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const langs = require("langs");
diff --git a/web/source/settings/components/loading.jsx b/web/source/settings/components/loading.jsx
index 27ba17499..c62c72a0a 100644
--- a/web/source/settings/components/loading.jsx
+++ b/web/source/settings/components/loading.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
module.exports = function Loading() {
diff --git a/web/source/settings/components/user-logout-card.jsx b/web/source/settings/components/user-logout-card.jsx
index 902d545bc..de77f0485 100644
--- a/web/source/settings/components/user-logout-card.jsx
+++ b/web/source/settings/components/user-logout-card.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const query = require("../lib/query");
diff --git a/web/source/settings/index.js b/web/source/settings/index.js
index 9758e89e6..bc3a925c2 100644
--- a/web/source/settings/index.js
+++ b/web/source/settings/index.js
@@ -17,17 +17,15 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const ReactDom = require("react-dom/client");
const { Provider } = require("react-redux");
const { PersistGate } = require("redux-persist/integration/react");
-const { store, persistor } = require("./redux");
+const { store, persistor } = require("./redux/store");
const { createNavigation, Menu, Item } = require("./lib/navigation");
-const AuthorizationGate = require("./components/authorization");
+const { Authorization } = require("./components/authorization");
const Loading = require("./components/loading");
const UserLogoutCard = require("./components/user-logout-card");
const { RoleContext } = require("./lib/navigation/util");
@@ -90,7 +88,7 @@ function Main() {
return (
<Provider store={store}>
<PersistGate loading={<section><Loading /></section>} persistor={persistor}>
- <AuthorizationGate App={App} />
+ <Authorization App={App} />
</PersistGate>
</Provider>
);
diff --git a/web/source/settings/lib/domain-block.js b/web/source/settings/lib/domain-block.js
index 98691d79d..e1cbd4c22 100644
--- a/web/source/settings/lib/domain-block.js
+++ b/web/source/settings/lib/domain-block.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const isValidDomain = require("is-valid-domain");
const psl = require("psl");
diff --git a/web/source/settings/lib/form/bool.jsx b/web/source/settings/lib/form/bool.jsx
index d7d916602..47a4bbd1b 100644
--- a/web/source/settings/lib/form/bool.jsx
+++ b/web/source/settings/lib/form/bool.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const _default = false;
diff --git a/web/source/settings/lib/form/check-list.jsx b/web/source/settings/lib/form/check-list.jsx
index fb1fdd32b..2f649dba6 100644
--- a/web/source/settings/lib/form/check-list.jsx
+++ b/web/source/settings/lib/form/check-list.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const syncpipe = require("syncpipe");
const { createSlice } = require("@reduxjs/toolkit");
diff --git a/web/source/settings/lib/form/combo-box.jsx b/web/source/settings/lib/form/combo-box.jsx
index 8506d72f0..985c262d8 100644
--- a/web/source/settings/lib/form/combo-box.jsx
+++ b/web/source/settings/lib/form/combo-box.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { useComboboxState } = require("ariakit/combobox");
diff --git a/web/source/settings/lib/form/context.jsx b/web/source/settings/lib/form/context.jsx
index b25bb11b7..1eb24a931 100644
--- a/web/source/settings/lib/form/context.jsx
+++ b/web/source/settings/lib/form/context.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const FormContext = React.createContext({});
diff --git a/web/source/settings/lib/form/field-array.jsx b/web/source/settings/lib/form/field-array.jsx
index beea0bc9b..f2d7bc7ce 100644
--- a/web/source/settings/lib/form/field-array.jsx
+++ b/web/source/settings/lib/form/field-array.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const getFormMutations = require("./get-form-mutations");
diff --git a/web/source/settings/lib/form/file.jsx b/web/source/settings/lib/form/file.jsx
index b28361c61..a9e96dc97 100644
--- a/web/source/settings/lib/form/file.jsx
+++ b/web/source/settings/lib/form/file.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const prettierBytes = require("prettier-bytes");
diff --git a/web/source/settings/lib/form/form-with-data.jsx b/web/source/settings/lib/form/form-with-data.jsx
index 73799da70..ef05c46c0 100644
--- a/web/source/settings/lib/form/form-with-data.jsx
+++ b/web/source/settings/lib/form/form-with-data.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { Error } = require("../../components/error");
diff --git a/web/source/settings/lib/form/get-form-mutations.js b/web/source/settings/lib/form/get-form-mutations.js
index 6bdc3e4cd..b0ae6e9b0 100644
--- a/web/source/settings/lib/form/get-form-mutations.js
+++ b/web/source/settings/lib/form/get-form-mutations.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const syncpipe = require("syncpipe");
module.exports = function getFormMutations(form, { changedOnly }) {
diff --git a/web/source/settings/lib/form/index.js b/web/source/settings/lib/form/index.js
index 3d5f5238b..99537ae7f 100644
--- a/web/source/settings/lib/form/index.js
+++ b/web/source/settings/lib/form/index.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const getByDot = require("get-by-dot").default;
diff --git a/web/source/settings/lib/form/radio.jsx b/web/source/settings/lib/form/radio.jsx
index c4bb77e7a..4bb061f4b 100644
--- a/web/source/settings/lib/form/radio.jsx
+++ b/web/source/settings/lib/form/radio.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const _default = "";
diff --git a/web/source/settings/lib/form/submit.js b/web/source/settings/lib/form/submit.js
index 2d1d42b3a..ab2945812 100644
--- a/web/source/settings/lib/form/submit.js
+++ b/web/source/settings/lib/form/submit.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const Promise = require("bluebird");
const React = require("react");
const getFormMutations = require("./get-form-mutations");
diff --git a/web/source/settings/lib/form/text.jsx b/web/source/settings/lib/form/text.jsx
index 0d7753bef..f9c096ac8 100644
--- a/web/source/settings/lib/form/text.jsx
+++ b/web/source/settings/lib/form/text.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const _default = "";
diff --git a/web/source/settings/lib/navigation/components.jsx b/web/source/settings/lib/navigation/components.jsx
index 365ebff89..64ed160b6 100644
--- a/web/source/settings/lib/navigation/components.jsx
+++ b/web/source/settings/lib/navigation/components.jsx
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { Link, Route, Redirect, Switch, useLocation, useRouter } = require("wouter");
const syncpipe = require("syncpipe");
diff --git a/web/source/settings/lib/navigation/index.js b/web/source/settings/lib/navigation/index.js
index c1331d0ec..2e8f062f4 100644
--- a/web/source/settings/lib/navigation/index.js
+++ b/web/source/settings/lib/navigation/index.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const { nanoid } = require("nanoid");
const { Redirect } = require("wouter");
diff --git a/web/source/settings/lib/navigation/util.js b/web/source/settings/lib/navigation/util.js
index f0b29d7a1..2c6c4968f 100644
--- a/web/source/settings/lib/navigation/util.js
+++ b/web/source/settings/lib/navigation/util.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const RoleContext = React.createContext([]);
const BaseUrlContext = React.createContext(null);
diff --git a/web/source/settings/lib/query/admin/custom-emoji.js b/web/source/settings/lib/query/admin/custom-emoji.js
index c84155efd..6e7c772a2 100644
--- a/web/source/settings/lib/query/admin/custom-emoji.js
+++ b/web/source/settings/lib/query/admin/custom-emoji.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const Promise = require("bluebird");
const { unwrapRes } = require("../lib");
diff --git a/web/source/settings/lib/query/admin/import-export.js b/web/source/settings/lib/query/admin/import-export.js
index 7c44d8280..9a04438c2 100644
--- a/web/source/settings/lib/query/admin/import-export.js
+++ b/web/source/settings/lib/query/admin/import-export.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const Promise = require("bluebird");
const fileDownload = require("js-file-download");
const csv = require("papaparse");
diff --git a/web/source/settings/lib/query/admin/index.js b/web/source/settings/lib/query/admin/index.js
index 7b46e6ba4..7a55389d3 100644
--- a/web/source/settings/lib/query/admin/index.js
+++ b/web/source/settings/lib/query/admin/index.js
@@ -17,15 +17,13 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const {
replaceCacheOnMutation,
removeFromCacheOnMutation,
domainListToObject,
idListToObject
} = require("../lib");
-const base = require("../base");
+const { gtsApi } = require("../gts-api");
const endpoints = (build) => ({
updateInstance: build.mutation({
@@ -164,4 +162,4 @@ const endpoints = (build) => ({
...require("./reports")(build)
});
-module.exports = base.injectEndpoints({ endpoints }); \ No newline at end of file
+module.exports = gtsApi.injectEndpoints({ endpoints }); \ No newline at end of file
diff --git a/web/source/settings/lib/query/admin/reports.js b/web/source/settings/lib/query/admin/reports.js
index 28940872c..1c45bb7bc 100644
--- a/web/source/settings/lib/query/admin/reports.js
+++ b/web/source/settings/lib/query/admin/reports.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
module.exports = (build) => ({
listReports: build.query({
query: (params = {}) => ({
diff --git a/web/source/settings/lib/query/base.js b/web/source/settings/lib/query/base.js
deleted file mode 100644
index ba02d4e07..000000000
--- a/web/source/settings/lib/query/base.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- GoToSocial
- Copyright (C) GoToSocial Authors admin@gotosocial.org
- SPDX-License-Identifier: AGPL-3.0-or-later
-
- 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 <http://www.gnu.org/licenses/>.
-*/
-
-"use strict";
-
-const { createApi, fetchBaseQuery } = require("@reduxjs/toolkit/query/react");
-const { serialize: serializeForm } = require("object-to-formdata");
-
-function instanceBasedQuery(args, api, extraOptions) {
- const state = api.getState();
- const { instance, token } = state.oauth;
-
- if (args.baseUrl == undefined) {
- args.baseUrl = instance;
- }
-
- if (args.discardEmpty) {
- if (args.body == undefined || Object.keys(args.body).length == 0) {
- return { data: null };
- }
- delete args.discardEmpty;
- }
-
- if (args.asForm) {
- delete args.asForm;
- args.body = serializeForm(args.body, {
- indices: true, // Array indices, for profile fields
- });
- }
-
- return fetchBaseQuery({
- baseUrl: args.baseUrl,
- prepareHeaders: (headers) => {
- if (token != undefined) {
- headers.set('Authorization', token);
- }
- headers.set("Accept", "application/json");
- return headers;
- },
- })(args, api, extraOptions);
-}
-
-module.exports = createApi({
- reducerPath: "api",
- baseQuery: instanceBasedQuery,
- tagTypes: ["Auth", "Emoji", "Reports", "Account", "InstanceRules"],
- endpoints: (build) => ({
- instance: build.query({
- query: () => ({
- url: `/api/v1/instance`
- })
- })
- })
-}); \ No newline at end of file
diff --git a/web/source/settings/lib/query/gts-api.ts b/web/source/settings/lib/query/gts-api.ts
new file mode 100644
index 000000000..9e043137c
--- /dev/null
+++ b/web/source/settings/lib/query/gts-api.ts
@@ -0,0 +1,149 @@
+/*
+ GoToSocial
+ Copyright (C) GoToSocial Authors admin@gotosocial.org
+ SPDX-License-Identifier: AGPL-3.0-or-later
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
+import type {
+ BaseQueryFn,
+ FetchArgs,
+ FetchBaseQueryError,
+} from '@reduxjs/toolkit/query/react';
+import { serialize as serializeForm } from "object-to-formdata";
+
+import type { RootState } from '../../redux/store';
+
+/**
+ * GTSFetchArgs extends standard FetchArgs used by
+ * RTK Query with a couple helpers of our own.
+ */
+export interface GTSFetchArgs extends FetchArgs {
+ /**
+ * If provided, will be used as base URL. Else,
+ * will fall back to authorized instance as baseUrl.
+ */
+ baseUrl?: string;
+ /**
+ * If true, and no args.body is set, or args.body is empty,
+ * then a null response will be returned from the API call.
+ */
+ discardEmpty?: boolean;
+ /**
+ * If true, then args.body will be serialized
+ * as FormData before submission.
+ */
+ asForm?: boolean;
+}
+
+/**
+ * gtsBaseQuery wraps the redux toolkit fetchBaseQuery with some helper functionality.
+ *
+ * For an explainer of what's happening in this function, see:
+ * - https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#customizing-queries-with-basequery
+ * - https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#constructing-a-dynamic-base-url-using-redux-state
+ *
+ * @param args
+ * @param api
+ * @param extraOptions
+ * @returns
+ */
+const gtsBaseQuery: BaseQueryFn<
+ string | GTSFetchArgs,
+ any,
+ FetchBaseQueryError
+> = async (args, api, extraOptions) => {
+ // Retrieve state at the moment
+ // this function was called.
+ const state = api.getState() as RootState;
+ const { instanceUrl, token } = state.oauth;
+
+ // Derive baseUrl dynamically.
+ let baseUrl: string;
+
+ // Check if simple string baseUrl provided
+ // as args, or if more complex args provided.
+ if (typeof args === "string") {
+ baseUrl = args;
+ } else {
+ if (args.baseUrl != undefined) {
+ baseUrl = args.baseUrl;
+ } else {
+ baseUrl = instanceUrl;
+ }
+
+ if (args.discardEmpty) {
+ if (args.body == undefined || Object.keys(args.body).length == 0) {
+ return { data: null };
+ }
+ }
+
+ if (args.asForm) {
+ args.body = serializeForm(args.body, {
+ // Array indices, for profile fields.
+ indices: true,
+ });
+ }
+
+ // Delete any of our extended arguments
+ // to avoid confusing fetchBaseQuery.
+ delete args.baseUrl;
+ delete args.discardEmpty;
+ delete args.asForm;
+ }
+
+ if (!baseUrl) {
+ return {
+ error: {
+ status: 400,
+ statusText: 'Bad Request',
+ data: {"error":"No baseUrl set for request"},
+ },
+ };
+ }
+
+ return fetchBaseQuery({
+ baseUrl: baseUrl,
+ prepareHeaders: (headers) => {
+ if (token != undefined) {
+ headers.set('Authorization', token);
+ }
+ headers.set("Accept", "application/json");
+ return headers;
+ },
+ })(args, api, extraOptions);
+};
+
+export const gtsApi = createApi({
+ reducerPath: "api",
+ baseQuery: gtsBaseQuery,
+ tagTypes: [
+ "Auth",
+ "Emoji",
+ "Reports",
+ "Account",
+ "InstanceRules",
+ ],
+ endpoints: (builder) => ({
+ instance: builder.query<any, void>({
+ query: () => ({
+ url: `/api/v1/instance`
+ })
+ })
+ })
+});
+
+export const { useInstanceQuery } = gtsApi;
diff --git a/web/source/settings/lib/query/index.js b/web/source/settings/lib/query/index.js
index dab896f80..aeaa4a1d7 100644
--- a/web/source/settings/lib/query/index.js
+++ b/web/source/settings/lib/query/index.js
@@ -17,11 +17,9 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
module.exports = {
- ...require("./base"),
+ ...require("./gts-api"),
...require("./oauth"),
...require("./user"),
...require("./admin")
-}; \ No newline at end of file
+};
diff --git a/web/source/settings/lib/query/lib.js b/web/source/settings/lib/query/lib.js
index 56ce05478..1025ca3a7 100644
--- a/web/source/settings/lib/query/lib.js
+++ b/web/source/settings/lib/query/lib.js
@@ -17,10 +17,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const syncpipe = require("syncpipe");
-const base = require("./base");
+const { gtsApi } = require("./gts-api");
module.exports = {
unwrapRes(res) {
@@ -70,7 +68,7 @@ function makeCacheMutation(action) {
return {
onQueryStarted: (_, { dispatch, queryFulfilled }) => {
queryFulfilled.then(({ data: newData }) => {
- dispatch(base.util.updateQueryData(queryName, arg, (draft) => {
+ dispatch(gtsApi.util.updateQueryData(queryName, arg, (draft) => {
if (findKey != undefined) {
key = findKey(draft, newData);
}
diff --git a/web/source/settings/lib/query/oauth.js b/web/source/settings/lib/query/oauth.js
deleted file mode 100644
index 7284ee856..000000000
--- a/web/source/settings/lib/query/oauth.js
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- GoToSocial
- Copyright (C) GoToSocial Authors admin@gotosocial.org
- SPDX-License-Identifier: AGPL-3.0-or-later
-
- 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 <http://www.gnu.org/licenses/>.
-*/
-
-"use strict";
-
-const Promise = require("bluebird");
-
-const base = require("./base");
-const { unwrapRes } = require("./lib");
-const oauth = require("../../redux/oauth").actions;
-
-function getSettingsURL() {
- /* needed in case the settings interface isn't hosted at /settings but
- some subpath like /gotosocial/settings. Other parts of the code don't
- take this into account yet so mostly future-proofing.
-
- Also drops anything past /settings/, because authorization urls that are too long
- get rejected by GTS.
- */
- let [pre, _past] = window.location.pathname.split("/settings");
- return `${window.location.origin}${pre}/settings`;
-}
-
-const SETTINGS_URL = getSettingsURL();
-
-const endpoints = (build) => ({
- verifyCredentials: build.query({
- providesTags: (_res, error) =>
- error == undefined
- ? ["Auth"]
- : [],
- queryFn: (_arg, api, _extraOpts, baseQuery) => {
- const state = api.getState();
-
- return Promise.try(() => {
- // Process callback code first, if available
- if (state.oauth.loginState == "callback") {
- let urlParams = new URLSearchParams(window.location.search);
- let code = urlParams.get("code");
-
- if (code == undefined) {
- throw {
- message: "Waiting for callback, but no ?code= provided in url."
- };
- } else {
- let app = state.oauth.registration;
-
- if (app == undefined || app.client_id == undefined) {
- throw {
- message: "No stored registration data, can't finish login flow."
- };
- }
-
- return baseQuery({
- method: "POST",
- url: "/oauth/token",
- body: {
- client_id: app.client_id,
- client_secret: app.client_secret,
- redirect_uri: SETTINGS_URL,
- grant_type: "authorization_code",
- code: code
- }
- }).then(unwrapRes).then((token) => {
- // remove ?code= from url
- window.history.replaceState({}, document.title, window.location.pathname);
- api.dispatch(oauth.setToken(token));
- });
- }
- }
- }).then(() => {
- return baseQuery({
- url: `/api/v1/accounts/verify_credentials`
- });
- }).catch((e) => {
- return { error: e };
- });
- }
- }),
- authorizeFlow: build.mutation({
- queryFn: (formData, api, _extraOpts, baseQuery) => {
- let instance;
- const state = api.getState();
-
- return Promise.try(() => {
- if (!formData.instance.startsWith("http")) {
- formData.instance = `https://${formData.instance}`;
- }
- instance = new URL(formData.instance).origin;
-
- const stored = state.oauth.instance;
- if (stored?.instance == instance && stored.registration) {
- return stored.registration;
- }
-
- return baseQuery({
- method: "POST",
- baseUrl: instance,
- url: "/api/v1/apps",
- body: {
- client_name: "GoToSocial Settings",
- scopes: formData.scopes,
- redirect_uris: SETTINGS_URL,
- website: SETTINGS_URL
- }
- }).then(unwrapRes).then((app) => {
- app.scopes = formData.scopes;
-
- api.dispatch(oauth.authorize({
- instance: instance,
- registration: app,
- loginState: "callback",
- expectingRedirect: true
- }));
-
- return app;
- });
- }).then((app) => {
- let url = new URL(instance);
- url.pathname = "/oauth/authorize";
- url.searchParams.set("client_id", app.client_id);
- url.searchParams.set("redirect_uri", SETTINGS_URL);
- url.searchParams.set("response_type", "code");
- url.searchParams.set("scope", app.scopes);
-
- let redirectURL = url.toString();
- window.location.assign(redirectURL);
-
- return { data: null };
- }).catch((e) => {
- return { error: e };
- });
- },
- }),
- logout: build.mutation({
- queryFn: (_arg, api) => {
- api.dispatch(oauth.remove());
- return { data: null };
- },
- invalidatesTags: ["Auth"]
- })
-});
-
-module.exports = base.injectEndpoints({ endpoints }); \ No newline at end of file
diff --git a/web/source/settings/lib/query/oauth/index.ts b/web/source/settings/lib/query/oauth/index.ts
new file mode 100644
index 000000000..9af2dd5fb
--- /dev/null
+++ b/web/source/settings/lib/query/oauth/index.ts
@@ -0,0 +1,204 @@
+/*
+ GoToSocial
+ Copyright (C) GoToSocial Authors admin@gotosocial.org
+ SPDX-License-Identifier: AGPL-3.0-or-later
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+import type { FetchBaseQueryError } from '@reduxjs/toolkit/query';
+
+import { gtsApi } from "../gts-api";
+import {
+ setToken as oauthSetToken,
+ remove as oauthRemove,
+ authorize as oauthAuthorize,
+} from "../../../redux/oauth";
+import { RootState } from '../../../redux/store';
+
+export interface OauthTokenRequestBody {
+ client_id: string;
+ client_secret: string;
+ redirect_uri: string;
+ grant_type: string;
+ code: string;
+}
+
+function getSettingsURL() {
+ /*
+ needed in case the settings interface isn't hosted at /settings but
+ some subpath like /gotosocial/settings. Other parts of the code don't
+ take this into account yet so mostly future-proofing.
+
+ Also drops anything past /settings/, because authorization urls that are too long
+ get rejected by GTS.
+ */
+ let [pre, _past] = window.location.pathname.split("/settings");
+ return `${window.location.origin}${pre}/settings`;
+}
+
+const SETTINGS_URL = (getSettingsURL());
+
+// Couple auth functions here require multiple requests as
+// part of an OAuth token 'flow'. To keep things simple for
+// callers of these query functions, the multiple requests
+// are chained within one query.
+//
+// https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#performing-multiple-requests-with-a-single-query
+const extended = gtsApi.injectEndpoints({
+ endpoints: (builder) => ({
+ verifyCredentials: builder.query<any, void>({
+ providesTags: (_res, error) =>
+ error == undefined ? ["Auth"] : [],
+ async queryFn(_arg, api, _extraOpts, fetchWithBQ) {
+ const state = api.getState() as RootState;
+ const oauthState = state.oauth;
+
+ // If we're not in the middle of an auth/callback,
+ // we may already have an auth token, so just
+ // return a standard verify_credentials query.
+ if (oauthState.loginState != 'callback') {
+ return fetchWithBQ({
+ url: `/api/v1/accounts/verify_credentials`
+ });
+ }
+
+ // We're in the middle of an auth/callback flow.
+ // Try to retrieve callback code from URL query.
+ let urlParams = new URLSearchParams(window.location.search);
+ let code = urlParams.get("code");
+ if (code == undefined) {
+ return {
+ error: {
+ status: 400,
+ statusText: 'Bad Request',
+ data: {"error":"Waiting for callback, but no ?code= provided in url."},
+ },
+ };
+ }
+
+ // Retrieve app with which the
+ // callback code was generated.
+ let app = oauthState.app;
+ if (app == undefined || app.client_id == undefined) {
+ return {
+ error: {
+ status: 400,
+ statusText: 'Bad Request',
+ data: {"error":"No stored app registration data, can't finish login flow."},
+ },
+ };
+ }
+
+ // Use the provided code and app
+ // secret to request an auth token.
+ const tokenReqBody: OauthTokenRequestBody = {
+ client_id: app.client_id,
+ client_secret: app.client_secret,
+ redirect_uri: SETTINGS_URL,
+ grant_type: "authorization_code",
+ code: code
+ };
+
+ const tokenResult = await fetchWithBQ({
+ method: "POST",
+ url: "/oauth/token",
+ body: tokenReqBody,
+ });
+ if (tokenResult.error) {
+ return { error: tokenResult.error as FetchBaseQueryError };
+ }
+
+ // Remove ?code= query param from
+ // url, we don't want it anymore.
+ window.history.replaceState({}, document.title, window.location.pathname);
+
+ // Store returned token in redux.
+ api.dispatch(oauthSetToken(tokenResult.data));
+
+ // We're now authed! So return
+ // standard verify_credentials query.
+ return fetchWithBQ({
+ url: `/api/v1/accounts/verify_credentials`
+ });
+ }
+ }),
+
+ authorizeFlow: builder.mutation({
+ async queryFn(formData, api, _extraOpts, fetchWithBQ) {
+ const state = api.getState() as RootState;
+ const oauthState = state.oauth;
+
+ let instanceUrl: string;
+ if (!formData.instance.startsWith("http")) {
+ formData.instance = `https://${formData.instance}`;
+ }
+
+ instanceUrl = new URL(formData.instance).origin;
+ if (oauthState?.instanceUrl == instanceUrl && oauthState.app) {
+ return { data: oauthState.app };
+ }
+
+ const appResult = await fetchWithBQ({
+ method: "POST",
+ baseUrl: instanceUrl,
+ url: "/api/v1/apps",
+ body: {
+ client_name: "GoToSocial Settings",
+ scopes: formData.scopes,
+ redirect_uris: SETTINGS_URL,
+ website: SETTINGS_URL
+ }
+ });
+ if (appResult.error) {
+ return { error: appResult.error as FetchBaseQueryError };
+ }
+
+ let app = appResult.data as any;
+
+ app.scopes = formData.scopes;
+ api.dispatch(oauthAuthorize({
+ instanceUrl: instanceUrl,
+ app: app,
+ loginState: "callback",
+ expectingRedirect: true
+ }));
+
+ let url = new URL(instanceUrl);
+ url.pathname = "/oauth/authorize";
+ url.searchParams.set("client_id", app.client_id);
+ url.searchParams.set("redirect_uri", SETTINGS_URL);
+ url.searchParams.set("response_type", "code");
+ url.searchParams.set("scope", app.scopes);
+
+ let redirectURL = url.toString();
+ window.location.assign(redirectURL);
+ return { data: null };
+ },
+ }),
+ logout: builder.mutation({
+ queryFn: (_arg, api) => {
+ api.dispatch(oauthRemove());
+ return { data: null };
+ },
+ invalidatesTags: ["Auth"]
+ })
+ })
+});
+
+export const {
+ useVerifyCredentialsQuery,
+ useAuthorizeFlowMutation,
+ useLogoutMutation,
+} = extended; \ No newline at end of file
diff --git a/web/source/settings/lib/query/user.js b/web/source/settings/lib/query/user/index.ts
index a88e16035..751e38e5b 100644
--- a/web/source/settings/lib/query/user.js
+++ b/web/source/settings/lib/query/user/index.ts
@@ -17,29 +17,32 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
+import { replaceCacheOnMutation } from "../lib";
+import { gtsApi } from "../gts-api";
-const { replaceCacheOnMutation } = require("./lib");
-const base = require("./base");
-
-const endpoints = (build) => ({
- updateCredentials: build.mutation({
- query: (formData) => ({
- method: "PATCH",
- url: `/api/v1/accounts/update_credentials`,
- asForm: true,
- body: formData,
- discardEmpty: true
+const extended = gtsApi.injectEndpoints({
+ endpoints: (builder) => ({
+ updateCredentials: builder.mutation({
+ query: (formData) => ({
+ method: "PATCH",
+ url: `/api/v1/accounts/update_credentials`,
+ asForm: true,
+ body: formData,
+ discardEmpty: true
+ }),
+ ...replaceCacheOnMutation("verifyCredentials")
}),
- ...replaceCacheOnMutation("verifyCredentials")
- }),
- passwordChange: build.mutation({
- query: (data) => ({
- method: "POST",
- url: `/api/v1/user/password_change`,
- body: data
+ passwordChange: builder.mutation({
+ query: (data) => ({
+ method: "POST",
+ url: `/api/v1/user/password_change`,
+ body: data
+ })
})
})
});
-module.exports = base.injectEndpoints({ endpoints }); \ No newline at end of file
+export const {
+ useUpdateCredentialsMutation,
+ usePasswordChangeMutation,
+} = extended;
diff --git a/web/source/settings/redux/oauth.js b/web/source/settings/redux/oauth.js
deleted file mode 100644
index ca0be15d0..000000000
--- a/web/source/settings/redux/oauth.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- GoToSocial
- Copyright (C) GoToSocial Authors admin@gotosocial.org
- SPDX-License-Identifier: AGPL-3.0-or-later
-
- 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 <http://www.gnu.org/licenses/>.
-*/
-
-"use strict";
-
-const { createSlice } = require("@reduxjs/toolkit");
-
-module.exports = createSlice({
- name: "oauth",
- initialState: {
- loginState: 'none',
- expectingRedirect: false
- },
- reducers: {
- authorize: (state, { payload }) => {
- return payload; // overrides state
- },
- setToken: (state, { payload }) => {
- state.token = `${payload.token_type} ${payload.access_token}`;
- state.loginState = "login";
- },
- remove: (state, { _payload }) => {
- delete state.token;
- delete state.registration;
- state.loginState = "logout";
- }
- }
-}); \ No newline at end of file
diff --git a/web/source/settings/redux/oauth.ts b/web/source/settings/redux/oauth.ts
new file mode 100644
index 000000000..1d6bf9bb1
--- /dev/null
+++ b/web/source/settings/redux/oauth.ts
@@ -0,0 +1,89 @@
+/*
+ GoToSocial
+ Copyright (C) GoToSocial Authors admin@gotosocial.org
+ SPDX-License-Identifier: AGPL-3.0-or-later
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+import { PayloadAction, createSlice } from "@reduxjs/toolkit";
+
+/**
+ * OAuthToken represents a response
+ * to an OAuth token request.
+ */
+export interface OAuthToken {
+ /**
+ * Most likely to be 'Bearer'
+ * but may be something else.
+ */
+ token_type: string;
+ /**
+ * The actual token. Can be passed in to
+ * authenticate further requests using the
+ * Authorization header and the token type.
+ */
+ access_token: string;
+}
+
+export interface OAuthApp {
+ client_id: string;
+ client_secret: string;
+}
+
+export interface OAuthState {
+ instanceUrl?: string;
+ loginState: "none" | "callback" | "login" | "logout";
+ expectingRedirect: boolean;
+ /**
+ * Token stored in easy-to-use format.
+ * Will look something like:
+ * "Authorization: Bearer BLAHBLAHBLAH"
+ */
+ token?: string;
+ app?: OAuthApp;
+}
+
+const initialState: OAuthState = {
+ loginState: 'none',
+ expectingRedirect: false,
+};
+
+export const oauthSlice = createSlice({
+ name: "oauth",
+ initialState: initialState,
+ reducers: {
+ authorize: (_state, action: PayloadAction<OAuthState>) => {
+ // Overrides state with payload.
+ return action.payload;
+ },
+ setToken: (state, action: PayloadAction<OAuthToken>) => {
+ // Mark us as logged in by storing token.
+ state.token = `${action.payload.token_type} ${action.payload.access_token}`;
+ state.loginState = "login";
+ },
+ remove: (state) => {
+ // Mark us as logged out by clearing auth.
+ delete state.token;
+ delete state.app;
+ state.loginState = "logout";
+ }
+ }
+});
+
+export const {
+ authorize,
+ setToken,
+ remove,
+} = oauthSlice.actions;
diff --git a/web/source/settings/redux/index.js b/web/source/settings/redux/store.ts
index fe367a672..0c1285187 100644
--- a/web/source/settings/redux/index.js
+++ b/web/source/settings/redux/store.ts
@@ -17,11 +17,9 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
-const { combineReducers } = require("redux");
-const { configureStore } = require("@reduxjs/toolkit");
-const {
+import { combineReducers } from "redux";
+import { configureStore } from "@reduxjs/toolkit";
+import {
persistStore,
persistReducer,
FLUSH,
@@ -30,14 +28,14 @@ const {
PERSIST,
PURGE,
REGISTER,
-} = require("redux-persist");
+} from "redux-persist";
-const query = require("../lib/query/base");
-const { Promise } = require("bluebird");
+import { oauthSlice } from "./oauth";
+import { gtsApi } from "../lib/query/gts-api";
const combinedReducers = combineReducers({
- oauth: require("./oauth").reducer,
- [query.reducerPath]: query.reducer
+ [gtsApi.reducerPath]: gtsApi.reducer,
+ oauth: oauthSlice.reducer,
});
const persistedReducer = persistReducer({
@@ -45,27 +43,41 @@ const persistedReducer = persistReducer({
storage: require("redux-persist/lib/storage").default,
stateReconciler: require("redux-persist/lib/stateReconciler/autoMergeLevel1").default,
whitelist: ["oauth"],
- migrate: (state) => {
- return Promise.try(() => {
- if (state?.oauth != undefined) {
- state.oauth.expectingRedirect = false;
- }
+ migrate: async (state) => {
+ if (state == undefined) {
return state;
- });
+ }
+
+ // This is a cheeky workaround for
+ // redux-persist being a stickler.
+ let anyState = state as any;
+ if (anyState?.oauth != undefined) {
+ anyState.oauth.expectingRedirect = false;
+ }
+
+ return anyState;
}
}, combinedReducers);
-const store = configureStore({
+export const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) => {
return getDefaultMiddleware({
serializableCheck: {
- ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER]
+ ignoredActions: [
+ FLUSH,
+ REHYDRATE,
+ PAUSE,
+ PERSIST,
+ PURGE,
+ REGISTER,
+ ]
}
- }).concat(query.middleware);
+ }).concat(gtsApi.middleware);
}
});
-const persistor = persistStore(store);
+export const persistor = persistStore(store);
-module.exports = { store, persistor }; \ No newline at end of file
+export type AppDispatch = typeof store.dispatch;
+export type RootState = ReturnType<typeof store.getState>;
diff --git a/web/source/settings/user/profile.js b/web/source/settings/user/profile.js
index dd600cafc..6c26bb406 100644
--- a/web/source/settings/user/profile.js
+++ b/web/source/settings/user/profile.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const query = require("../lib/query");
diff --git a/web/source/settings/user/settings.js b/web/source/settings/user/settings.js
index 68483f105..2a23a87e0 100644
--- a/web/source/settings/user/settings.js
+++ b/web/source/settings/user/settings.js
@@ -17,8 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-"use strict";
-
const React = require("react");
const query = require("../lib/query");