mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-04 07:32:24 -06:00 
			
		
		
		
	
		
			
	
	
		
			124 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			124 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
									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 <http://www.gnu.org/licenses/>.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								"use strict";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const Promise = require("bluebird");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const { OAUTHError, AuthenticationError } = require("../errors");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const oauth = require("../../redux/reducers/oauth").actions;
							 | 
						||
| 
								 | 
							
								const temporary = require("../../redux/reducers/temporary").actions;
							 | 
						||
| 
								 | 
							
								const admin = require("../../redux/reducers/admin").actions;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = function oauthAPI({ apiCall, getCurrentUrl }) {
							 | 
						||
| 
								 | 
							
									return {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										register: function register(scopes = []) {
							 | 
						||
| 
								 | 
							
											return function (dispatch, _getState) {
							 | 
						||
| 
								 | 
							
												return Promise.try(() => {
							 | 
						||
| 
								 | 
							
													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));
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
											};
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										authorize: function authorize() {
							 | 
						||
| 
								 | 
							
											return function (dispatch, getState) {
							 | 
						||
| 
								 | 
							
												let state = getState();
							 | 
						||
| 
								 | 
							
												let reg = state.oauth.registration;
							 | 
						||
| 
								 | 
							
												let base = new URL(state.oauth.instance);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												base.pathname = "/oauth/authorize";
							 | 
						||
| 
								 | 
							
												base.searchParams.set("client_id", reg.client_id);
							 | 
						||
| 
								 | 
							
												base.searchParams.set("redirect_uri", getCurrentUrl());
							 | 
						||
| 
								 | 
							
												base.searchParams.set("response_type", "code");
							 | 
						||
| 
								 | 
							
												base.searchParams.set("scope", reg.scopes.join(" "));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												dispatch(oauth.setLoginState("callback"));
							 | 
						||
| 
								 | 
							
												dispatch(temporary.setStatus("Redirecting to instance login..."));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												// send user to instance's login flow
							 | 
						||
| 
								 | 
							
												window.location.assign(base.href);
							 | 
						||
| 
								 | 
							
											};
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										tokenize: function tokenize(code) {
							 | 
						||
| 
								 | 
							
											return function (dispatch, getState) {
							 | 
						||
| 
								 | 
							
												let reg = getState().oauth.registration;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												return Promise.try(() => {
							 | 
						||
| 
								 | 
							
													if (reg == undefined || reg.client_id == undefined) {
							 | 
						||
| 
								 | 
							
														throw new OAUTHError("Callback code present, but no client registration is available from localStorage. \nNote: localStorage is unavailable in Private Browsing.");
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													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) => {
							 | 
						||
| 
								 | 
							
													window.history.replaceState({}, document.title, window.location.pathname);
							 | 
						||
| 
								 | 
							
													return dispatch(oauth.login(json));
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
											};
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										checkIfAdmin: function checkIfAdmin() {
							 | 
						||
| 
								 | 
							
											return function (dispatch, getState) {
							 | 
						||
| 
								 | 
							
												const state = getState();
							 | 
						||
| 
								 | 
							
												let stored = state.oauth.isAdmin;
							 | 
						||
| 
								 | 
							
												if (stored != undefined) {
							 | 
						||
| 
								 | 
							
													return stored;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												// newer GoToSocial version will include a `role` in the Account data, check that first
							 | 
						||
| 
								 | 
							
												// TODO: check account data for admin status				
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												// no role info, try fetching an admin-only route and see if we get an error
							 | 
						||
| 
								 | 
							
												return Promise.try(() => {
							 | 
						||
| 
								 | 
							
													return dispatch(apiCall("GET", "/api/v1/admin/domain_blocks"));
							 | 
						||
| 
								 | 
							
												}).then((data) => {
							 | 
						||
| 
								 | 
							
													return Promise.all([
							 | 
						||
| 
								 | 
							
														dispatch(oauth.setAdmin(true)),
							 | 
						||
| 
								 | 
							
														dispatch(admin.setBlockedInstances(data))
							 | 
						||
| 
								 | 
							
													]);
							 | 
						||
| 
								 | 
							
												}).catch(AuthenticationError, () => {
							 | 
						||
| 
								 | 
							
													return dispatch(oauth.setAdmin(false));
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
											};
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										logout: function logout() {
							 | 
						||
| 
								 | 
							
											return function (dispatch, _getState) {
							 | 
						||
| 
								 | 
							
												// TODO: GoToSocial does not have a logout API route yet
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												return dispatch(oauth.remove());
							 | 
						||
| 
								 | 
							
											};
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								};
							 |