Conditional OAuth scopes
This commit is contained in:
parent
f848f6ace3
commit
39c95f7a00
3 changed files with 44 additions and 20 deletions
|
@ -17,6 +17,7 @@ import { getLoggedInAccount, parseBaseURL } from 'soapbox/utils/auth';
|
||||||
import { createApp } from 'soapbox/actions/apps';
|
import { createApp } from 'soapbox/actions/apps';
|
||||||
import { obtainOAuthToken, revokeOAuthToken } from 'soapbox/actions/oauth';
|
import { obtainOAuthToken, revokeOAuthToken } from 'soapbox/actions/oauth';
|
||||||
import sourceCode from 'soapbox/utils/code';
|
import sourceCode from 'soapbox/utils/code';
|
||||||
|
import { getFeatures } from 'soapbox/utils/features';
|
||||||
|
|
||||||
export const SWITCH_ACCOUNT = 'SWITCH_ACCOUNT';
|
export const SWITCH_ACCOUNT = 'SWITCH_ACCOUNT';
|
||||||
|
|
||||||
|
@ -36,6 +37,12 @@ export const messages = defineMessages({
|
||||||
|
|
||||||
const noOp = () => () => new Promise(f => f());
|
const noOp = () => () => new Promise(f => f());
|
||||||
|
|
||||||
|
const getScopes = state => {
|
||||||
|
const instance = state.get('instance');
|
||||||
|
const { scopes } = getFeatures(instance);
|
||||||
|
return scopes;
|
||||||
|
};
|
||||||
|
|
||||||
function createAppAndToken() {
|
function createAppAndToken() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
return dispatch(createAuthApp()).then(() => {
|
return dispatch(createAuthApp()).then(() => {
|
||||||
|
@ -49,7 +56,7 @@ function createAuthApp() {
|
||||||
const params = {
|
const params = {
|
||||||
client_name: sourceCode.displayName,
|
client_name: sourceCode.displayName,
|
||||||
redirect_uris: 'urn:ietf:wg:oauth:2.0:oob',
|
redirect_uris: 'urn:ietf:wg:oauth:2.0:oob',
|
||||||
scopes: 'read write follow push admin',
|
scopes: getScopes(getState()),
|
||||||
website: sourceCode.homepage,
|
website: sourceCode.homepage,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,6 +75,7 @@ function createAppToken() {
|
||||||
client_secret: app.get('client_secret'),
|
client_secret: app.get('client_secret'),
|
||||||
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
|
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
|
||||||
grant_type: 'client_credentials',
|
grant_type: 'client_credentials',
|
||||||
|
scope: getScopes(getState()),
|
||||||
};
|
};
|
||||||
|
|
||||||
return dispatch(obtainOAuthToken(params)).then(token => {
|
return dispatch(obtainOAuthToken(params)).then(token => {
|
||||||
|
@ -87,6 +95,7 @@ function createUserToken(username, password) {
|
||||||
grant_type: 'password',
|
grant_type: 'password',
|
||||||
username: username,
|
username: username,
|
||||||
password: password,
|
password: password,
|
||||||
|
scope: getScopes(getState()),
|
||||||
};
|
};
|
||||||
|
|
||||||
return dispatch(obtainOAuthToken(params))
|
return dispatch(obtainOAuthToken(params))
|
||||||
|
@ -107,6 +116,7 @@ export function refreshUserToken() {
|
||||||
refresh_token: refreshToken,
|
refresh_token: refreshToken,
|
||||||
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
|
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
|
||||||
grant_type: 'refresh_token',
|
grant_type: 'refresh_token',
|
||||||
|
scope: getScopes(getState()),
|
||||||
};
|
};
|
||||||
|
|
||||||
return dispatch(obtainOAuthToken(params))
|
return dispatch(obtainOAuthToken(params))
|
||||||
|
|
|
@ -6,23 +6,33 @@
|
||||||
* @see module:soapbox/actions/oauth
|
* @see module:soapbox/actions/oauth
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { baseClient } from '../api';
|
||||||
import { createApp } from 'soapbox/actions/apps';
|
import { createApp } from 'soapbox/actions/apps';
|
||||||
import { obtainOAuthToken } from 'soapbox/actions/oauth';
|
import { obtainOAuthToken } from 'soapbox/actions/oauth';
|
||||||
import { authLoggedIn, verifyCredentials } from 'soapbox/actions/auth';
|
import { authLoggedIn, verifyCredentials } from 'soapbox/actions/auth';
|
||||||
import { parseBaseURL } from 'soapbox/utils/auth';
|
import { parseBaseURL } from 'soapbox/utils/auth';
|
||||||
|
import { getFeatures } from 'soapbox/utils/features';
|
||||||
import sourceCode from 'soapbox/utils/code';
|
import sourceCode from 'soapbox/utils/code';
|
||||||
|
import { fromJS } from 'immutable';
|
||||||
|
|
||||||
const scope = 'read write follow push';
|
const fetchExternalInstance = baseURL => {
|
||||||
|
return baseClient(null, baseURL)
|
||||||
|
.get('/api/v1/instance')
|
||||||
|
.then(({ data: instance }) => fromJS(instance));
|
||||||
|
};
|
||||||
|
|
||||||
export function createAppAndRedirect(host) {
|
export function createAppAndRedirect(host) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const baseURL = parseBaseURL(host) || parseBaseURL(`https://${host}`);
|
const baseURL = parseBaseURL(host) || parseBaseURL(`https://${host}`);
|
||||||
|
|
||||||
|
return fetchExternalInstance(baseURL).then(instance => {
|
||||||
|
const { scopes } = getFeatures(instance);
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
client_name: sourceCode.displayName,
|
client_name: sourceCode.displayName,
|
||||||
redirect_uris: `${window.location.origin}/auth/external`,
|
redirect_uris: `${window.location.origin}/auth/external`,
|
||||||
website: sourceCode.homepage,
|
website: sourceCode.homepage,
|
||||||
scopes: scope,
|
scopes,
|
||||||
};
|
};
|
||||||
|
|
||||||
return dispatch(createApp(params, baseURL)).then(app => {
|
return dispatch(createApp(params, baseURL)).then(app => {
|
||||||
|
@ -32,14 +42,16 @@ export function createAppAndRedirect(host) {
|
||||||
client_id,
|
client_id,
|
||||||
redirect_uri,
|
redirect_uri,
|
||||||
response_type: 'code',
|
response_type: 'code',
|
||||||
scope,
|
scope: scopes,
|
||||||
});
|
});
|
||||||
|
|
||||||
localStorage.setItem('soapbox:external:app', JSON.stringify(app));
|
localStorage.setItem('soapbox:external:app', JSON.stringify(app));
|
||||||
localStorage.setItem('soapbox:external:baseurl', baseURL);
|
localStorage.setItem('soapbox:external:baseurl', baseURL);
|
||||||
|
localStorage.setItem('soapbox:external:scopes', scopes);
|
||||||
|
|
||||||
window.location.href = `${baseURL}/oauth/authorize?${query.toString()}`;
|
window.location.href = `${baseURL}/oauth/authorize?${query.toString()}`;
|
||||||
});
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +59,7 @@ export function loginWithCode(code) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const { client_id, client_secret, redirect_uri } = JSON.parse(localStorage.getItem('soapbox:external:app'));
|
const { client_id, client_secret, redirect_uri } = JSON.parse(localStorage.getItem('soapbox:external:app'));
|
||||||
const baseURL = localStorage.getItem('soapbox:external:baseurl');
|
const baseURL = localStorage.getItem('soapbox:external:baseurl');
|
||||||
|
const scope = localStorage.getItem('soapbox:external:scopes');
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
client_id,
|
client_id,
|
||||||
|
|
|
@ -17,6 +17,7 @@ export const getFeatures = createSelector([
|
||||||
importMutes: v.software === 'Pleroma' && gte(v.version, '2.2.0'),
|
importMutes: v.software === 'Pleroma' && gte(v.version, '2.2.0'),
|
||||||
emailList: f.includes('email_list'),
|
emailList: f.includes('email_list'),
|
||||||
chats: v.software === 'Pleroma' && gte(v.version, '2.1.0'),
|
chats: v.software === 'Pleroma' && gte(v.version, '2.1.0'),
|
||||||
|
scopes: v.software === 'Pleroma' ? 'read write follow push admin' : 'read write follow push',
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue