diff --git a/web/source/settings-panel/index.js b/web/source/settings-panel/index.js
index 906163eb9..d59dc7237 100644
--- a/web/source/settings-panel/index.js
+++ b/web/source/settings-panel/index.js
@@ -79,7 +79,7 @@ function App() {
}).then(() => {
// Check currently stored auth token for validity if available
if (loginState == "callback" || loginState == "login") {
- return dispatch(api.oauth.verify());
+ return dispatch(api.user.fetchAccount());
}
}).then(() => {
setTokenChecked(true);
diff --git a/web/source/settings-panel/lib/api/index.js b/web/source/settings-panel/lib/api/index.js
index f6e826e49..840cbca10 100644
--- a/web/source/settings-panel/lib/api/index.js
+++ b/web/source/settings-panel/lib/api/index.js
@@ -22,51 +22,58 @@ const Promise = require("bluebird");
const { APIError } = require("../errors");
const { setInstanceInfo } = require("../../redux/reducers/instances").actions;
+const oauth = require("../../redux/reducers/oauth").actions;
-function apiCall(state, method, route, payload) {
- let base = state.oauth.instance;
- let auth = state.oauth.token;
- console.log(method, base, route, auth);
-
- return Promise.try(() => {
- let url = new URL(base);
- url.pathname = route;
- let body;
-
- if (payload != undefined) {
- body = JSON.stringify(payload);
- }
-
- let headers = {
- "Accept": "application/json",
- "Content-Type": "application/json"
- };
-
- if (auth != undefined) {
- headers["Authorization"] = auth;
- }
-
- return fetch(url.toString(), {
- method,
- headers,
- body
+function apiCall(method, route, payload) {
+ return function (dispatch, getState) {
+ const state = getState();
+ let base = state.oauth.instance;
+ let auth = state.oauth.token;
+ console.log(method, base, route, "auth:", auth != undefined);
+
+ return Promise.try(() => {
+ let url = new URL(base);
+ url.pathname = route;
+ let body;
+
+ if (payload != undefined) {
+ body = JSON.stringify(payload);
+ }
+
+ let headers = {
+ "Accept": "application/json",
+ "Content-Type": "application/json"
+ };
+
+ if (auth != undefined) {
+ headers["Authorization"] = auth;
+ }
+
+ return fetch(url.toString(), {
+ method,
+ headers,
+ body
+ });
+ }).then((res) => {
+ // try parse json even with error
+ let json = res.json().catch((e) => {
+ throw new APIError(`JSON parsing error: ${e.message}`);
+ });
+
+ return Promise.all([res, json]);
+ }).then(([res, json]) => {
+ if (!res.ok) {
+ if (auth != undefined && res.status == 401) {
+ // stored access token is invalid
+ dispatch(oauth.remove());
+ throw new APIError("Stored OAUTH login was no longer valid, please log in again.");
+ }
+ throw new APIError(json.error, {json});
+ } else {
+ return json;
+ }
});
- }).then((res) => {
- let ok = res.ok;
-
- // try parse json even with error
- let json = res.json().catch((e) => {
- throw new APIError(`JSON parsing error: ${e.message}`);
- });
-
- return Promise.all([ok, json]);
- }).then(([ok, json]) => {
- if (!ok) {
- throw new APIError(json.error, {json});
- } else {
- return json;
- }
- });
+ };
}
function getCurrentUrl() {
@@ -88,7 +95,7 @@ function fetchInstance(domain) {
oauth: {instance: domain}
};
- return apiCall(fakeState, "GET", "/api/v1/instance");
+ return apiCall("GET", "/api/v1/instance")(dispatch, () => fakeState);
}).then((json) => {
if (json && json.uri) { // TODO: validate instance json more?
dispatch(setInstanceInfo([json.uri, json]));
@@ -102,5 +109,6 @@ module.exports = {
instance: {
fetch: fetchInstance
},
- oauth: require("./oauth")({apiCall, getCurrentUrl})
+ oauth: require("./oauth")({apiCall, getCurrentUrl}),
+ user: require("./user")({apiCall})
};
\ No newline at end of file
diff --git a/web/source/settings-panel/lib/api/oauth.js b/web/source/settings-panel/lib/api/oauth.js
index 0fbf236d7..1b985e7bd 100644
--- a/web/source/settings-panel/lib/api/oauth.js
+++ b/web/source/settings-panel/lib/api/oauth.js
@@ -24,19 +24,20 @@ const { OAUTHError } = require("../errors");
const oauth = require("../../redux/reducers/oauth").actions;
const temporary = require("../../redux/reducers/temporary").actions;
+const user = require("../../redux/reducers/user").actions;
module.exports = function oauthAPI({apiCall, getCurrentUrl}) {
return {
register: function register(scopes = []) {
- return function (dispatch, getState) {
+ return function (dispatch, _getState) {
return Promise.try(() => {
- return apiCall(getState(), "POST", "/api/v1/apps", {
+ return dispatch(apiCall("POST", "/api/v1/apps", {
client_name: "GoToSocial Settings",
scopes: scopes.join(" "),
redirect_uris: getCurrentUrl(),
website: getCurrentUrl()
- });
+ }));
}).then((json) => {
json.scopes = scopes;
dispatch(oauth.setRegistration(json));
@@ -73,13 +74,13 @@ module.exports = function oauthAPI({apiCall, getCurrentUrl}) {
throw new OAUTHError("Callback code present, but no client registration is available from localStorage. \nNote: localStorage is unavailable in Private Browsing.");
}
- return apiCall(getState(), "POST", "/oauth/token", {
+ return dispatch(apiCall("POST", "/oauth/token", {
client_id: reg.client_id,
client_secret: reg.client_secret,
redirect_uri: getCurrentUrl(),
grant_type: "authorization_code",
code: code
- });
+ }));
}).then((json) => {
console.log(json);
window.history.replaceState({}, document.title, window.location.pathname);
@@ -88,20 +89,6 @@ module.exports = function oauthAPI({apiCall, getCurrentUrl}) {
};
},
- verify: function verify() {
- return function (dispatch, getState) {
- console.log(getState());
- return Promise.try(() => {
- return apiCall(getState(), "GET", "/api/v1/accounts/verify_credentials");
- }).then((account) => {
- console.log(account);
- }).catch((e) => {
- dispatch(oauth.remove());
- throw e;
- });
- };
- },
-
logout: function logout() {
return function (dispatch, _getState) {
// TODO: GoToSocial does not have a logout API route yet
diff --git a/web/source/settings-panel/lib/api/user.js b/web/source/settings-panel/lib/api/user.js
new file mode 100644
index 000000000..e0a9f7dda
--- /dev/null
+++ b/web/source/settings-panel/lib/api/user.js
@@ -0,0 +1,37 @@
+/*
+ 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");
+
+const user = require("../../redux/reducers/user").actions;
+
+module.exports = function({apiCall}) {
+ return {
+ fetchAccount: function fetchAccount() {
+ return function (dispatch, _getState) {
+ return Promise.try(() => {
+ return dispatch(apiCall("GET", "/api/v1/accounts/verify_credentials"));
+ }).then((account) => {
+ return dispatch(user.setAccount(account));
+ });
+ };
+ }
+ };
+};
\ No newline at end of file
diff --git a/web/source/settings-panel/lib/generate-views.js b/web/source/settings-panel/lib/generate-views.js
index 24822a735..2e825c63a 100644
--- a/web/source/settings-panel/lib/generate-views.js
+++ b/web/source/settings-panel/lib/generate-views.js
@@ -48,7 +48,6 @@ module.exports = function generateViews(struct) {
firstRoute = `${base}/${urlSafe(name)}`;
}
- console.log(name, ViewComponent);
routes.push((
{}}>
diff --git a/web/source/settings-panel/redux/index.js b/web/source/settings-panel/redux/index.js
index 33e9e5044..ab2694223 100644
--- a/web/source/settings-panel/redux/index.js
+++ b/web/source/settings-panel/redux/index.js
@@ -35,6 +35,7 @@ const combinedReducers = combineReducers({
oauth: require("./reducers/oauth").reducer,
instances: require("./reducers/instances").reducer,
temporary: require("./reducers/temporary").reducer,
+ user: require("./reducers/user").reducer,
});
const persistedReducer = persistReducer(persistConfig, combinedReducers);
diff --git a/web/source/settings-panel/redux/reducers/user.js b/web/source/settings-panel/redux/reducers/user.js
new file mode 100644
index 000000000..480751290
--- /dev/null
+++ b/web/source/settings-panel/redux/reducers/user.js
@@ -0,0 +1,32 @@
+/*
+ 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 {createSlice} = require("@reduxjs/toolkit");
+
+module.exports = createSlice({
+ name: "user",
+ initialState: {
+ },
+ reducers: {
+ setAccount: (state, {payload}) => {
+ state.account = payload;
+ }
+ }
+});
\ No newline at end of file
diff --git a/web/source/settings-panel/user/index.js b/web/source/settings-panel/user/index.js
index 7e95beb6b..9c207365b 100644
--- a/web/source/settings-panel/user/index.js
+++ b/web/source/settings-panel/user/index.js
@@ -20,26 +20,9 @@
const Promise = require("bluebird");
const React = require("react");
-const { Route, Switch } = require("wouter");
-
-module.exports = function UserPanel({oauth, routes}) {
- // const [account, setAccount] = React.useState({});
- // const [errorMsg, setError] = React.useState("");
- // const [statusMsg, setStatus] = React.useState("Fetching user info");
-
- // React.useEffect(() => {
- // Promise.try(() => {
- // return oauth.apiRequest("/api/v1/accounts/verify_credentials", "GET");
- // }).then((json) => {
- // setAccount(json);
- // }).catch((e) => {
- // setError(e.message);
- // setStatus("");
- // });
- // }, [oauth, setAccount, setError, setStatus]);
-
- // throw new Error("test");
+const { Switch } = require("wouter");
+module.exports = function UserPanel({routes}) {
return (
{routes}
diff --git a/web/source/settings-panel/user/profile.js b/web/source/settings-panel/user/profile.js
index 8ca8e3176..3d0a16b4e 100644
--- a/web/source/settings-panel/user/profile.js
+++ b/web/source/settings-panel/user/profile.js
@@ -20,11 +20,14 @@
const Promise = require("bluebird");
const React = require("react");
+const Redux = require("react-redux");
const { useErrorHandler } = require("react-error-boundary");
const Submit = require("../components/submit");
-module.exports = function UserProfile({account, oauth}) {
+module.exports = function UserProfile() {
+ const account = Redux.useSelector(state => state.user.account);
+
const [errorMsg, setError] = React.useState("");
const [statusMsg, setStatus] = React.useState("");