SecurityForm: Revoke OAuth token
This commit is contained in:
parent
db1ad3e16f
commit
35d5e7d649
3 changed files with 31 additions and 2 deletions
|
@ -27,6 +27,10 @@ export const FETCH_TOKENS_REQUEST = 'FETCH_TOKENS_REQUEST';
|
|||
export const FETCH_TOKENS_SUCCESS = 'FETCH_TOKENS_SUCCESS';
|
||||
export const FETCH_TOKENS_FAIL = 'FETCH_TOKENS_FAIL';
|
||||
|
||||
export const REVOKE_TOKEN_REQUEST = 'REVOKE_TOKEN_REQUEST';
|
||||
export const REVOKE_TOKEN_SUCCESS = 'REVOKE_TOKEN_SUCCESS';
|
||||
export const REVOKE_TOKEN_FAIL = 'REVOKE_TOKEN_FAIL';
|
||||
|
||||
const noOp = () => () => new Promise(f => f());
|
||||
|
||||
function createAppAndToken() {
|
||||
|
@ -204,6 +208,17 @@ export function fetchOAuthTokens() {
|
|||
};
|
||||
}
|
||||
|
||||
export function revokeOAuthToken(id) {
|
||||
return (dispatch, getState) => {
|
||||
dispatch({ type: REVOKE_TOKEN_REQUEST, id });
|
||||
return api(getState).delete(`/api/oauth_tokens/${id}`).then(response => {
|
||||
dispatch({ type: REVOKE_TOKEN_SUCCESS, id });
|
||||
}).catch(error => {
|
||||
dispatch({ type: REVOKE_TOKEN_FAIL, id });
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function authAppCreated(app) {
|
||||
return {
|
||||
type: AUTH_APP_CREATED,
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
changeEmail,
|
||||
changePassword,
|
||||
fetchOAuthTokens,
|
||||
revokeOAuthToken,
|
||||
} from 'soapbox/actions/auth';
|
||||
import { showAlert } from 'soapbox/actions/alerts';
|
||||
|
||||
|
@ -210,6 +211,12 @@ class AuthTokenList extends ImmutablePureComponent {
|
|||
tokens: ImmutablePropTypes.list,
|
||||
}
|
||||
|
||||
handleRevoke = id => {
|
||||
return e => {
|
||||
this.props.dispatch(revokeOAuthToken(id));
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(fetchOAuthTokens());
|
||||
}
|
||||
|
@ -221,9 +228,12 @@ class AuthTokenList extends ImmutablePureComponent {
|
|||
{this.props.tokens.map((token, i) => (
|
||||
<div key={i} className='authtoken'>
|
||||
<div>{token.get('app_name')}</div>
|
||||
<div>{token.get('id')}</div>
|
||||
<div>{token.get('valid_until')}</div>
|
||||
<div><button>Revoke</button></div>
|
||||
<div>
|
||||
<button onClick={this.handleRevoke(token.get('id'))}>
|
||||
Revoke
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</SimpleForm>
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
AUTH_APP_AUTHORIZED,
|
||||
AUTH_LOGGED_OUT,
|
||||
FETCH_TOKENS_SUCCESS,
|
||||
REVOKE_TOKEN_SUCCESS,
|
||||
} from '../actions/auth';
|
||||
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
|
||||
|
||||
|
@ -30,6 +31,9 @@ export default function auth(state = initialState, action) {
|
|||
return state.set('user', ImmutableMap());
|
||||
case FETCH_TOKENS_SUCCESS:
|
||||
return state.set('tokens', fromJS(action.tokens));
|
||||
case REVOKE_TOKEN_SUCCESS:
|
||||
const idx = state.get('tokens').findIndex(t => t.get('id') === action.id);
|
||||
return state.deleteIn(['tokens', idx]);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue