added suspending admin email to error screen

This commit is contained in:
Jori Lallo 2018-03-06 23:38:52 -08:00
parent e9e4538436
commit f5c1ddf8b9
7 changed files with 37 additions and 22 deletions

View File

@ -1,24 +1,29 @@
// @flow
import React from 'react';
import { inject, observer } from 'mobx-react';
import CenteredContent from 'components/CenteredContent';
import PageTitle from 'components/PageTitle';
import AuthStore from 'stores/AuthStore';
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>
const ErrorSuspended = observer(({ auth }: { auth: AuthStore }) => {
return (
<CenteredContent>
<PageTitle title="Your account has been suspended" />
<h1>
<span role="img" aria-label="Warning sign">
</span>{' '}
Your account has been suspended
</h1>
<p>
A team admin has suspended your account. To re-activate your account,
please reach out to them directly.
</p>
</CenteredContent>
);
<p>
A team admin (<strong>{auth.suspendedContactEmail}</strong>) has
suspended your account. To re-activate your account, please reach out to
them directly.
</p>
</CenteredContent>
);
});
export default ErrorSuspended;
export default inject('auth')(ErrorSuspended);

View File

@ -15,6 +15,7 @@ class AuthStore {
@observable oauthState: string;
@observable isLoading: boolean = false;
@observable isSuspended: boolean = false;
@observable suspendedContactEmail: ?string;
/* Computed */
@ -46,6 +47,7 @@ class AuthStore {
} catch (err) {
if (err.data.error === 'user_suspended') {
this.isSuspended = true;
this.suspendedContactEmail = err.data.adminEmail;
}
}
};

View File

@ -29,6 +29,7 @@ api.use(async (ctx, next) => {
} catch (err) {
ctx.status = err.status || 500;
let message = err.message || err.name;
let error;
if (err instanceof Sequelize.ValidationError) {
// super basic form error handling
@ -40,18 +41,21 @@ api.use(async (ctx, next) => {
if (message.match('Authorization error')) {
ctx.status = 403;
error = 'authorization_error';
}
if (ctx.status === 500) {
message = 'Internal Server Error';
error = 'internal_server_error';
ctx.app.emit('error', err, ctx);
}
ctx.body = {
ok: false,
error: _.snakeCase(err.id || err.message),
error: _.snakeCase(err.id || error),
status: err.status,
message,
adminEmail: err.adminEmail ? err.adminEmail : undefined,
};
}
});

View File

@ -76,7 +76,8 @@ export default function auth() {
}
if (user.isSuspended) {
throw new UserSuspendedError();
const suspendingAdmin = await User.findById(user.suspendedById);
throw new UserSuspendedError({ adminEmail: suspendingAdmin.email });
}
ctx.state.token = token;

View File

@ -159,8 +159,10 @@ describe('Authentication middleware', async () => {
it('should return an error for suspended users', async () => {
const state = {};
const admin = await buildUser({});
const user = await buildUser({
suspendedAt: new Date(),
suspendedById: admin.id,
});
const authMiddleware = auth();
@ -179,6 +181,7 @@ describe('Authentication middleware', async () => {
expect(e.message).toEqual(
'Your access has been suspended by the team admin'
);
expect(e.adminEmail).toEqual(admin.email);
}
});
});

View File

@ -19,11 +19,10 @@ export function AdminRequiredError(
return httpErrors(403, message, { id: 'admin_required' });
}
export function UserSuspendedError(
message: string = 'Your access has been suspended by the team admin'
) {
return httpErrors(403, message, {
export function UserSuspendedError({ adminEmail }: { adminEmail: string }) {
return httpErrors(403, 'Your access has been suspended by the team admin', {
id: 'user_suspended',
adminEmail,
});
}

View File

@ -29,6 +29,7 @@ const User = sequelize.define(
slackData: DataTypes.JSONB,
jwtSecret: encryptedFields.vault('jwtSecret'),
suspendedAt: DataTypes.DATE,
suspendedById: DataTypes.UUID,
},
{
getterMethods: {