UI to prevent suspended users viewing the application
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import { Switch, Route, withRouter } from 'react-router-dom';
|
||||
import { Switch, Route, Redirect, withRouter } from 'react-router-dom';
|
||||
import type { Location } from 'react-router-dom';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import styled from 'styled-components';
|
||||
@ -17,6 +17,7 @@ import Sidebar from 'components/Sidebar';
|
||||
import SettingsSidebar from 'components/Sidebar/Settings';
|
||||
import Modals from 'components/Modals';
|
||||
import Toasts from 'components/Toasts';
|
||||
import ErrorSuspended from 'scenes/ErrorSuspended';
|
||||
|
||||
import AuthStore from 'stores/AuthStore';
|
||||
import UiStore from 'stores/UiStore';
|
||||
@ -66,11 +67,17 @@ class Layout extends React.Component {
|
||||
this.props.ui.setActiveModal('keyboard-shortcuts');
|
||||
}
|
||||
|
||||
renderSuspended() {
|
||||
return <ErrorSuspended />;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { auth, ui } = this.props;
|
||||
const { user, team } = auth;
|
||||
const showSidebar = auth.authenticated && user && team;
|
||||
|
||||
if (auth.isSuspended) return this.renderSuspended();
|
||||
|
||||
return (
|
||||
<Container column auto>
|
||||
<Helmet>
|
||||
|
24
app/scenes/ErrorSuspended/ErrorSuspended.js
Normal file
24
app/scenes/ErrorSuspended/ErrorSuspended.js
Normal file
@ -0,0 +1,24 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
|
||||
import CenteredContent from 'components/CenteredContent';
|
||||
import PageTitle from 'components/PageTitle';
|
||||
|
||||
const ErrorSuspended = () => (
|
||||
<CenteredContent>
|
||||
<PageTitle title="Your account has been suspended" />
|
||||
<h1>
|
||||
<span role="img" aria-label="Warning sign">
|
||||
⚠️
|
||||
</span>{' '}
|
||||
Your account has been suspended
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
Team admin has suspended your account. To re-activate your account, please
|
||||
reach out to them directly.
|
||||
</p>
|
||||
</CenteredContent>
|
||||
);
|
||||
|
||||
export default ErrorSuspended;
|
3
app/scenes/ErrorSuspended/index.js
Normal file
3
app/scenes/ErrorSuspended/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
// @flow
|
||||
import ErrorSuspended from './ErrorSuspended';
|
||||
export default ErrorSuspended;
|
@ -14,6 +14,7 @@ class AuthStore {
|
||||
@observable token: ?string;
|
||||
@observable oauthState: string;
|
||||
@observable isLoading: boolean = false;
|
||||
@observable isSuspended: boolean = false;
|
||||
|
||||
/* Computed */
|
||||
|
||||
@ -43,8 +44,9 @@ class AuthStore {
|
||||
this.team = res.data.team;
|
||||
});
|
||||
} catch (err) {
|
||||
// Failure to update user info is a non-fatal error.
|
||||
console.error(err);
|
||||
if (err.data.error === 'user_suspended') {
|
||||
this.isSuspended = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -75,7 +75,9 @@ export default function auth() {
|
||||
}
|
||||
}
|
||||
|
||||
if (user.isSuspended) throw new UserSuspendedError();
|
||||
if (user.isSuspended) {
|
||||
throw new UserSuspendedError();
|
||||
}
|
||||
|
||||
ctx.state.token = token;
|
||||
ctx.state.user = user;
|
||||
|
@ -22,7 +22,9 @@ export function AdminRequiredError(
|
||||
export function UserSuspendedError(
|
||||
message: string = 'Your access has been suspended by the team admin'
|
||||
) {
|
||||
return httpErrors(403, message, { id: 'user_suspended' });
|
||||
return httpErrors(403, message, {
|
||||
id: 'user_suspended',
|
||||
});
|
||||
}
|
||||
|
||||
export function InvalidRequestError(message: string = 'Request invalid') {
|
||||
|
@ -2,6 +2,10 @@ module.exports = {
|
||||
up: async (queryInterface, Sequelize) => {
|
||||
await queryInterface.addColumn('users', 'suspendedById', {
|
||||
type: Sequelize.UUID,
|
||||
allowNull: true,
|
||||
references: {
|
||||
model: 'users',
|
||||
},
|
||||
});
|
||||
await queryInterface.addColumn('users', 'suspendedAt', {
|
||||
type: Sequelize.DATE,
|
||||
|
@ -49,10 +49,6 @@ User.associate = models => {
|
||||
User.hasMany(models.ApiKey, { as: 'apiKeys' });
|
||||
User.hasMany(models.Document, { as: 'documents' });
|
||||
User.hasMany(models.View, { as: 'views' });
|
||||
User.belongsTo(models.User, {
|
||||
as: 'suspendedBy',
|
||||
foreignKey: 'suspendedById',
|
||||
});
|
||||
};
|
||||
|
||||
// Instance methods
|
||||
|
Reference in New Issue
Block a user