kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
SecurityForm: Display OAuth tokens
rodzic
8fd5a3cd35
commit
db1ad3e16f
|
@ -23,6 +23,10 @@ export const CHANGE_PASSWORD_REQUEST = 'CHANGE_PASSWORD_REQUEST';
|
||||||
export const CHANGE_PASSWORD_SUCCESS = 'CHANGE_PASSWORD_SUCCESS';
|
export const CHANGE_PASSWORD_SUCCESS = 'CHANGE_PASSWORD_SUCCESS';
|
||||||
export const CHANGE_PASSWORD_FAIL = 'CHANGE_PASSWORD_FAIL';
|
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());
|
const noOp = () => () => new Promise(f => f());
|
||||||
|
|
||||||
function createAppAndToken() {
|
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) {
|
export function authAppCreated(app) {
|
||||||
return {
|
return {
|
||||||
type: AUTH_APP_CREATED,
|
type: AUTH_APP_CREATED,
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { connect } from 'react-redux';
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import Column from '../ui/components/column';
|
import Column from '../ui/components/column';
|
||||||
import {
|
import {
|
||||||
SimpleForm,
|
SimpleForm,
|
||||||
|
@ -10,7 +11,11 @@ import {
|
||||||
FieldsGroup,
|
FieldsGroup,
|
||||||
TextInput,
|
TextInput,
|
||||||
} from 'soapbox/features/forms';
|
} 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';
|
import { showAlert } from 'soapbox/actions/alerts';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
@ -37,6 +42,7 @@ class SecurityForm extends ImmutablePureComponent {
|
||||||
<Column icon='lock' heading={intl.formatMessage(messages.heading)} backBtnSlim>
|
<Column icon='lock' heading={intl.formatMessage(messages.heading)} backBtnSlim>
|
||||||
<ChangeEmailForm />
|
<ChangeEmailForm />
|
||||||
<ChangePasswordForm />
|
<ChangePasswordForm />
|
||||||
|
<AuthTokenList />
|
||||||
</Column>
|
</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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -3,12 +3,14 @@ import {
|
||||||
AUTH_LOGGED_IN,
|
AUTH_LOGGED_IN,
|
||||||
AUTH_APP_AUTHORIZED,
|
AUTH_APP_AUTHORIZED,
|
||||||
AUTH_LOGGED_OUT,
|
AUTH_LOGGED_OUT,
|
||||||
|
FETCH_TOKENS_SUCCESS,
|
||||||
} from '../actions/auth';
|
} from '../actions/auth';
|
||||||
import { Map as ImmutableMap } from 'immutable';
|
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
|
||||||
|
|
||||||
const initialState = ImmutableMap({
|
const initialState = ImmutableMap({
|
||||||
app: ImmutableMap(JSON.parse(localStorage.getItem('soapbox:auth:app'))),
|
app: ImmutableMap(JSON.parse(localStorage.getItem('soapbox:auth:app'))),
|
||||||
user: ImmutableMap(JSON.parse(localStorage.getItem('soapbox:auth:user'))),
|
user: ImmutableMap(JSON.parse(localStorage.getItem('soapbox:auth:user'))),
|
||||||
|
tokens: ImmutableList(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function auth(state = initialState, action) {
|
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));
|
return state.set('user', ImmutableMap(action.user));
|
||||||
case AUTH_LOGGED_OUT:
|
case AUTH_LOGGED_OUT:
|
||||||
localStorage.removeItem('soapbox:auth:user');
|
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:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue