Skip to content

Commit

Permalink
Auth check issue (#114)
Browse files Browse the repository at this point in the history
* Logout on auth fail, issue #110, #80
Fix notifications stuck on top of each other, move to center

* Bump version
  • Loading branch information
hidden4003 authored Oct 25, 2017
1 parent 056e70c commit b6c9c00
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 37 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jmmserver-webui",
"version": "0.3.3-dev5",
"version": "0.3.3-dev6",
"private": true,
"engines": {
"node": ">=6",
Expand Down
4 changes: 2 additions & 2 deletions src/components/AlertContainer.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.alertContainer {
z-index: 100;
position: fixed;
top: 50px;
top: 20px;
width: 50%;
left: 25%;
left: 35%;
}
19 changes: 14 additions & 5 deletions src/components/Buttons/AutoRefreshSwitch.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import PropTypes from 'prop-types';
import React from 'react';
import { connect } from 'react-redux';
import cx from 'classnames';
import store from '../../core/store';
import { setAutoupdate } from '../../core/legacy-actions';

class AutoRefreshSwitch extends React.Component {
static propTypes = {
enabled: PropTypes.bool.isRequired,
autoUpdate: PropTypes.bool.isRequired,
};

constructor(props) {
Expand All @@ -15,14 +16,14 @@ class AutoRefreshSwitch extends React.Component {
}

handleClick() {
const newState = !this.props.enabled;
const newState = !this.props.autoUpdate;
store.dispatch(setAutoupdate(newState));
}

render() {
const { enabled } = this.props;
const { autoUpdate } = this.props;
return (
<li className={cx('notification', enabled ? 'enabled' : null)}>
<li className={cx('notification', autoUpdate ? 'enabled' : null)}>
<a className="dropdown-toggle" onClick={this.handleClick}>
<i className="fa fa-check-square" />
</a>
Expand All @@ -31,4 +32,12 @@ class AutoRefreshSwitch extends React.Component {
}
}

export default AutoRefreshSwitch;
function mapStateToProps(state) {
const { autoUpdate } = state;

return {
autoUpdate,
};
}

export default connect(mapStateToProps)(AutoRefreshSwitch);
16 changes: 6 additions & 10 deletions src/components/Layout/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,14 @@ class Header extends React.Component {
countHasher: PropTypes.number,
countGeneral: PropTypes.number,
countImages: PropTypes.number,
autoUpdate: PropTypes.bool,
sidebarToggle: PropTypes.bool,
updateAvailable: PropTypes.bool,
webuiVersionUpdate: PropTypes.object,
username: PropTypes.string,
};

render() {
const { countHasher, countGeneral, countImages, autoUpdate, sidebarToggle, updateAvailable,
webuiVersionUpdate, username } = this.props;
const { countHasher, countGeneral, countImages, sidebarToggle, updateAvailable,
webuiVersionUpdate } = this.props;
return (
<header className="header white-bg">
<SidebarToggle enabled={sidebarToggle} />
Expand All @@ -41,30 +39,28 @@ class Header extends React.Component {
<div className="nav notifications pull-right">
<ul className="nav">
<Notifications />
<AutoRefreshSwitch enabled={autoUpdate} />
<AutoRefreshSwitch />
</ul>
</div>
<UserDropdown user={username} />
<UserDropdown />
</header>
);
}
}

function mapStateToProps(state) {
const { queueStatus, autoUpdate, sidebarToggle, updateAvailable,
webuiVersionUpdate, apiSession, settings } = state;
const { queueStatus, sidebarToggle, updateAvailable,
webuiVersionUpdate, settings } = state;
const items = queueStatus.items || {};

return {
countHasher: items.hash ? items.hash.count : null,
countGeneral: items.general ? items.general.count : null,
countImages: items.image ? items.image.count : null,
autoUpdate,
sidebarToggle,
updateAvailable: updateAvailable.status,
updateChannel: settings.other.updateChannel,
webuiVersionUpdate,
username: apiSession.username,
};
}

Expand Down
4 changes: 2 additions & 2 deletions src/components/Notification.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.notify {
position: fixed;
min-width: 350px;
max-width: 450px;
background-color: #fff;
Expand All @@ -10,6 +9,8 @@
border: 1px solid #dedede;
box-shadow: rgba(0, 0, 0, 0.0980392) 0 2px 4px;
z-index: 999;
position: relative;
margin-bottom: 10px;
}

.notify .notify-icon {
Expand All @@ -34,7 +35,6 @@
}

.notify .notify-text {
float: left;
padding: 10px 15px;
margin-left: 50px;
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Notification.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Notification extends React.Component {
render() {
const { text, type } = this.props;
return (
<div className={cx(s.notify, s[type], s['notify-top-right'])} style={{ top: '20px' }}>
<div className={cx(s.notify, s[type])}>
<a className={s['notify-close-btn']} />
<div className={s['notify-icon']}>
<div className={s['notify-icon-inner']} style={{ marginTop: '-9px' }}>
Expand Down
32 changes: 20 additions & 12 deletions src/components/UserDropdown/UserDropdown.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,18 @@ import PropTypes from 'prop-types';
import React from 'react';
import cx from 'classnames';
import { Dropdown, MenuItem } from 'react-bootstrap';
import store from '../../core/store';
import history from '../../core/history';
import { Logout } from '../../core/actions';
import { connect } from 'react-redux';
import s from './UserDropdown.css';
import Events from '../../core/events';

class UserDropdown extends React.Component {
static propTypes = {
user: PropTypes.string,
logout: PropTypes.func,
};

// TODO: Move this to saga
static handleLogout() {
store.dispatch(Logout());
history.push({ pathname: '/' });
}

render() {
const { user } = this.props;
const { user, logout } = this.props;
return (
<div className={cx('nav notifications pull-right', s['user-dropdown'])}>
<Dropdown bsStyle="white" title="User" className="pull-right" id="user">
Expand All @@ -28,12 +22,26 @@ class UserDropdown extends React.Component {
<MenuItem eventKey="1"><i className="fa fa-user" />Profile</MenuItem>
<MenuItem divider />
<MenuItem eventKey="2"><i className="fa fa-key" />Change password</MenuItem>
<MenuItem onClick={UserDropdown.handleLogout} eventKey="3"><i className="fa fa-sign-out" />Logout</MenuItem>
<MenuItem onClick={logout} eventKey="3"><i className="fa fa-sign-out" />Logout</MenuItem>
</Dropdown.Menu>
</Dropdown>
</div>
);
}
}

export default UserDropdown;
function mapStateToProps(state) {
const { apiSession } = state;

return {
username: apiSession.username,
};
}

function mapDispatchToProps(dispatch) {
return {
logout: () => { dispatch(Events.LOGOUT); },
};
}

export default connect(mapStateToProps, mapDispatchToProps)(UserDropdown);
13 changes: 11 additions & 2 deletions src/core/api.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'isomorphic-fetch';
import store from './store';
import Events from './events';
import { setAutoupdate } from './legacy-actions';

function apiCallPost(apiAction, apiParams, apiKey) {
return fetch(`/api${apiAction}`, {
Expand Down Expand Up @@ -29,6 +31,11 @@ function apiCall(apiAction, apiParams, type = 'GET') {

return fetch.then((response) => {
if (response.status !== 200) {
if (response.status === 401) {
// FIXME: make a better fix
store.dispatch({ type: Events.LOGOUT });
setAutoupdate(false);
}
return Promise.reject(`Network error: ${apiAction} ${response.status}: ${response.statusText}`);
}
return Promise.resolve(response);
Expand Down Expand Up @@ -73,8 +80,10 @@ function jsonApiCall(apiAction, apiParams, type) {
function jsonApiResponse(apiAction, apiParams, type) {
return jsonApiCall(apiAction, apiParams, type)
.then((json) => {
if (json.code && json.code !== 200) {
return { error: true, code: json.code, message: json.message || 'No error message given.' };
if (json.code) {
if (json.code !== 200) {
return { error: true, code: json.code, message: json.message || 'No error message given.' };
}
}
return { data: json };
})
Expand Down
1 change: 1 addition & 0 deletions src/core/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ export default {
FIRSTRUN_TEST_ANIDB: 'EVENT_FIRSTRUN_TEST_ANIDB',
FIRSTRUN_GET_USER: 'EVENT_FIRSTRUN_GET_USER',
FIRSTRUN_SET_USER: 'EVENT_FIRSTRUN_SET_USER',
LOGOUT: 'EVENT_LOGOUT',
};
2 changes: 1 addition & 1 deletion src/core/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const fetching = handleAction(SET_FETCHING, (state, action) => {
}, {});

const rootReducer = combineReducers({
routerReducer,
router: routerReducer,
globalAlert,
apiSession,
autoUpdate,
Expand Down
9 changes: 8 additions & 1 deletion src/core/sagas/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import { delay } from 'redux-saga';
import { put, takeEvery, call, select } from 'redux-saga/effects';
import { without } from 'lodash/array';
import { forEach } from 'lodash';
import { push } from 'react-router-redux';
import * as Ajv from 'ajv';
import Api from '../api';
import Events from '../events';
import Dashboard from './dashboard';
import {
QUEUE_GLOBAL_ALERT,
SHOW_GLOBAL_ALERT,
GLOBAL_ALERT, SET_FETCHING,
GLOBAL_ALERT, SET_FETCHING, Logout,
} from '../actions';
import { GET_DELTA } from '../actions/logs/Delta';
import { SET_CONTENTS, APPEND_CONTENTS } from '../actions/logs/Contents';
Expand Down Expand Up @@ -438,6 +439,11 @@ function* firstrunGetDatabaseSqlserverinstance() {
}
}

function* logout() {
yield put(Logout());
yield put(push({ pathname: '/' }));
}

export default function* rootSaga() {
yield [
takeEvery(QUEUE_GLOBAL_ALERT, queueGlobalAlert),
Expand Down Expand Up @@ -470,5 +476,6 @@ export default function* rootSaga() {
takeEvery(Events.FIRSTRUN_TEST_ANIDB, firstrunTestAnidb),
takeEvery(Events.FIRSTRUN_GET_USER, firstrunGetDefaultuser),
takeEvery(Events.FIRSTRUN_SET_USER, firstrunSetDefaultuser),
takeEvery(Events.LOGOUT, logout),
];
}

0 comments on commit b6c9c00

Please sign in to comment.