added suspending admin email to error screen
This commit is contained in:
@ -1,10 +1,13 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { inject, observer } from 'mobx-react';
|
||||||
|
|
||||||
import CenteredContent from 'components/CenteredContent';
|
import CenteredContent from 'components/CenteredContent';
|
||||||
import PageTitle from 'components/PageTitle';
|
import PageTitle from 'components/PageTitle';
|
||||||
|
import AuthStore from 'stores/AuthStore';
|
||||||
|
|
||||||
const ErrorSuspended = () => (
|
const ErrorSuspended = observer(({ auth }: { auth: AuthStore }) => {
|
||||||
|
return (
|
||||||
<CenteredContent>
|
<CenteredContent>
|
||||||
<PageTitle title="Your account has been suspended" />
|
<PageTitle title="Your account has been suspended" />
|
||||||
<h1>
|
<h1>
|
||||||
@ -15,10 +18,12 @@ const ErrorSuspended = () => (
|
|||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
A team admin has suspended your account. To re-activate your account,
|
A team admin (<strong>{auth.suspendedContactEmail}</strong>) has
|
||||||
please reach out to them directly.
|
suspended your account. To re-activate your account, please reach out to
|
||||||
|
them directly.
|
||||||
</p>
|
</p>
|
||||||
</CenteredContent>
|
</CenteredContent>
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
|
||||||
export default ErrorSuspended;
|
export default inject('auth')(ErrorSuspended);
|
||||||
|
@ -15,6 +15,7 @@ class AuthStore {
|
|||||||
@observable oauthState: string;
|
@observable oauthState: string;
|
||||||
@observable isLoading: boolean = false;
|
@observable isLoading: boolean = false;
|
||||||
@observable isSuspended: boolean = false;
|
@observable isSuspended: boolean = false;
|
||||||
|
@observable suspendedContactEmail: ?string;
|
||||||
|
|
||||||
/* Computed */
|
/* Computed */
|
||||||
|
|
||||||
@ -46,6 +47,7 @@ class AuthStore {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.data.error === 'user_suspended') {
|
if (err.data.error === 'user_suspended') {
|
||||||
this.isSuspended = true;
|
this.isSuspended = true;
|
||||||
|
this.suspendedContactEmail = err.data.adminEmail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -29,6 +29,7 @@ api.use(async (ctx, next) => {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
ctx.status = err.status || 500;
|
ctx.status = err.status || 500;
|
||||||
let message = err.message || err.name;
|
let message = err.message || err.name;
|
||||||
|
let error;
|
||||||
|
|
||||||
if (err instanceof Sequelize.ValidationError) {
|
if (err instanceof Sequelize.ValidationError) {
|
||||||
// super basic form error handling
|
// super basic form error handling
|
||||||
@ -40,18 +41,21 @@ api.use(async (ctx, next) => {
|
|||||||
|
|
||||||
if (message.match('Authorization error')) {
|
if (message.match('Authorization error')) {
|
||||||
ctx.status = 403;
|
ctx.status = 403;
|
||||||
|
error = 'authorization_error';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.status === 500) {
|
if (ctx.status === 500) {
|
||||||
message = 'Internal Server Error';
|
message = 'Internal Server Error';
|
||||||
|
error = 'internal_server_error';
|
||||||
ctx.app.emit('error', err, ctx);
|
ctx.app.emit('error', err, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
ok: false,
|
ok: false,
|
||||||
error: _.snakeCase(err.id || err.message),
|
error: _.snakeCase(err.id || error),
|
||||||
status: err.status,
|
status: err.status,
|
||||||
message,
|
message,
|
||||||
|
adminEmail: err.adminEmail ? err.adminEmail : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -76,7 +76,8 @@ export default function auth() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (user.isSuspended) {
|
if (user.isSuspended) {
|
||||||
throw new UserSuspendedError();
|
const suspendingAdmin = await User.findById(user.suspendedById);
|
||||||
|
throw new UserSuspendedError({ adminEmail: suspendingAdmin.email });
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.state.token = token;
|
ctx.state.token = token;
|
||||||
|
@ -159,8 +159,10 @@ describe('Authentication middleware', async () => {
|
|||||||
|
|
||||||
it('should return an error for suspended users', async () => {
|
it('should return an error for suspended users', async () => {
|
||||||
const state = {};
|
const state = {};
|
||||||
|
const admin = await buildUser({});
|
||||||
const user = await buildUser({
|
const user = await buildUser({
|
||||||
suspendedAt: new Date(),
|
suspendedAt: new Date(),
|
||||||
|
suspendedById: admin.id,
|
||||||
});
|
});
|
||||||
const authMiddleware = auth();
|
const authMiddleware = auth();
|
||||||
|
|
||||||
@ -179,6 +181,7 @@ describe('Authentication middleware', async () => {
|
|||||||
expect(e.message).toEqual(
|
expect(e.message).toEqual(
|
||||||
'Your access has been suspended by the team admin'
|
'Your access has been suspended by the team admin'
|
||||||
);
|
);
|
||||||
|
expect(e.adminEmail).toEqual(admin.email);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -19,11 +19,10 @@ export function AdminRequiredError(
|
|||||||
return httpErrors(403, message, { id: 'admin_required' });
|
return httpErrors(403, message, { id: 'admin_required' });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function UserSuspendedError(
|
export function UserSuspendedError({ adminEmail }: { adminEmail: string }) {
|
||||||
message: string = 'Your access has been suspended by the team admin'
|
return httpErrors(403, 'Your access has been suspended by the team admin', {
|
||||||
) {
|
|
||||||
return httpErrors(403, message, {
|
|
||||||
id: 'user_suspended',
|
id: 'user_suspended',
|
||||||
|
adminEmail,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ const User = sequelize.define(
|
|||||||
slackData: DataTypes.JSONB,
|
slackData: DataTypes.JSONB,
|
||||||
jwtSecret: encryptedFields.vault('jwtSecret'),
|
jwtSecret: encryptedFields.vault('jwtSecret'),
|
||||||
suspendedAt: DataTypes.DATE,
|
suspendedAt: DataTypes.DATE,
|
||||||
|
suspendedById: DataTypes.UUID,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
getterMethods: {
|
getterMethods: {
|
||||||
|
Reference in New Issue
Block a user