SecurityForm: Display OAuth tokens

merge-requests/45/head
Alex Gleason 2020-06-05 15:43:03 -05:00
rodzic 8fd5a3cd35
commit db1ad3e16f
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 7211D1F99744FBB7
3 zmienionych plików z 62 dodań i 3 usunięć

Wyświetl plik

@ -23,6 +23,10 @@ export const CHANGE_PASSWORD_REQUEST = 'CHANGE_PASSWORD_REQUEST';
export const CHANGE_PASSWORD_SUCCESS = 'CHANGE_PASSWORD_SUCCESS';
export const CHANGE_PASSWORD_FAIL = 'CHANGE_PASSWORD_FAIL';
export const FETCH_TOKENS_REQUEST = 'FETCH_TOKENS_REQUEST';
export const FETCH_TOKENS_SUCCESS = 'FETCH_TOKENS_SUCCESS';
export const FETCH_TOKENS_FAIL = 'FETCH_TOKENS_FAIL';
const noOp = () => () => new Promise(f => f());
function createAppAndToken() {
@ -189,6 +193,17 @@ export function changePassword(oldPassword, newPassword, confirmation) {
};
}
export function fetchOAuthTokens() {
return (dispatch, getState) => {
dispatch({ type: FETCH_TOKENS_REQUEST });
return api(getState).get('/api/oauth_tokens.json').then(response => {
dispatch({ type: FETCH_TOKENS_SUCCESS, tokens: response.data });
}).catch(error => {
dispatch({ type: FETCH_TOKENS_FAIL });
});
};
}
export function authAppCreated(app) {
return {
type: AUTH_APP_CREATED,

Wyświetl plik

@ -3,6 +3,7 @@ import { connect } from 'react-redux';
import { defineMessages, injectIntl } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import Column from '../ui/components/column';
import {
SimpleForm,
@ -10,7 +11,11 @@ import {
FieldsGroup,
TextInput,
} from 'soapbox/features/forms';
import { changeEmail, changePassword } from 'soapbox/actions/auth';
import {
changeEmail,
changePassword,
fetchOAuthTokens,
} from 'soapbox/actions/auth';
import { showAlert } from 'soapbox/actions/alerts';
const messages = defineMessages({
@ -37,6 +42,7 @@ class SecurityForm extends ImmutablePureComponent {
<Column icon='lock' heading={intl.formatMessage(messages.heading)} backBtnSlim>
<ChangeEmailForm />
<ChangePasswordForm />
<AuthTokenList />
</Column>
);
}
@ -191,3 +197,37 @@ class ChangePasswordForm extends ImmutablePureComponent {
}
}
const mapStateToProps = state => ({
tokens: state.getIn(['auth', 'tokens']),
});
@connect(mapStateToProps)
@injectIntl
class AuthTokenList extends ImmutablePureComponent {
static propTypes = {
tokens: ImmutablePropTypes.list,
}
componentDidMount() {
this.props.dispatch(fetchOAuthTokens());
}
render() {
if (this.props.tokens.isEmpty()) return null;
return (
<SimpleForm>
{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>
))}
</SimpleForm>
);
}
}

Wyświetl plik

@ -3,12 +3,14 @@ import {
AUTH_LOGGED_IN,
AUTH_APP_AUTHORIZED,
AUTH_LOGGED_OUT,
FETCH_TOKENS_SUCCESS,
} from '../actions/auth';
import { Map as ImmutableMap } from 'immutable';
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
const initialState = ImmutableMap({
app: ImmutableMap(JSON.parse(localStorage.getItem('soapbox:auth:app'))),
user: ImmutableMap(JSON.parse(localStorage.getItem('soapbox:auth:user'))),
tokens: ImmutableList(),
});
export default function auth(state = initialState, action) {
@ -25,7 +27,9 @@ export default function auth(state = initialState, action) {
return state.set('user', ImmutableMap(action.user));
case AUTH_LOGGED_OUT:
localStorage.removeItem('soapbox:auth:user');
return state.setIn(['user'], ImmutableMap());
return state.set('user', ImmutableMap());
case FETCH_TOKENS_SUCCESS:
return state.set('tokens', fromJS(action.tokens));
default:
return state;
}