[CORL-156] Manage user suspension status (#2419)

* wire up suspension modal

* show user suspended callout on stream

* prevent comment actions for suspended users

* set default to 3 hour suspension

* add message field to suspension

* allow custom message for suspension

* show suspend success modal

* fix type errors

* remove unused code

* update styles

* fix fixture for streams

* add suspension ui tests

* fix types

* remove warnings?

* remove snapshot

* fix merge conflicts

* allow custom email message when banning users

* fix typo

* correct message type

* use final-form in suspend modal

* refactor suspend modal to use final-form

* refactor ban modal to use final-form

* refactor userStatusChangeContainer to use useCallback

* feat: improve translated form

* fix: addressed issue caused by i18n refactor

* update getMessage to accept arguments, remove format method

* translate suspend info

* change hour format

* make message a mandatory input for suspend and ban user

* fix types in user table

* Revert "fix types in user table"

This reverts commit d396e90b88bb1bd354c5cdbdd72b6d8f1ab72929.

* fix types for user table

* fix: small review tweaks
This commit is contained in:
Tessa Thornton
2019-08-02 21:16:21 +00:00
committed by Wyatt Johnson
parent 4e548e8fbf
commit 5df2de6afc
42 changed files with 1511 additions and 276 deletions
@@ -133,6 +133,7 @@ export const Users = (ctx: TenantContext) => ({
ctx.tenant,
ctx.user!,
input.userID,
input.message,
ctx.now
),
suspend: async (input: GQLSuspendUserInput) =>
@@ -143,6 +144,7 @@ export const Users = (ctx: TenantContext) => ({
ctx.user!,
input.userID,
input.timeout,
input.message,
ctx.now
),
removeBan: async (input: GQLRemoveUserBanInput) =>
@@ -13,4 +13,5 @@ export const BanStatusHistory: Required<
return null;
},
createdAt: ({ createdAt }) => createdAt,
message: ({ message }) => message,
};
@@ -23,4 +23,5 @@ export const SuspensionStatusHistory: Required<
return null;
},
modifiedAt: ({ modifiedAt }) => modifiedAt,
message: ({ message }) => message,
};
@@ -1301,6 +1301,11 @@ type BanStatusHistory {
createdAt is the time that the given User was banned.
"""
createdAt: Time!
"""
message is sent to banned user via email.
"""
message: String!
}
"""
@@ -1375,6 +1380,11 @@ type SuspensionStatusHistory {
then the suspension has not been cancelled/edited.
"""
modifiedAt: Time
"""
message is sent to suspended user via email.
"""
message: String!
}
"""
@@ -4225,6 +4235,11 @@ input BanUserInput {
clientMutationId is required for Relay support.
"""
clientMutationId: String!
"""
message is sent to banned user via email.
"""
message: String!
}
type BanUserPayload {
@@ -4259,6 +4274,11 @@ input SuspendUserInput {
clientMutationId is required for Relay support.
"""
clientMutationId: String!
"""
message is sent to suspended user via email.
"""
message: String!
}
type SuspendUserPayload {
+4 -10
View File
@@ -10,11 +10,9 @@ email-notification-template-forgotPassword =
email-subject-forgotPassword = Password Reset Request
email-notification-template-ban =
Hello { $username },<br/><br/>
Someone with access to your account has violated our community guidelines.
As a result, your account has been banned. You will no longer be able to
comment, react or report comments. if you think this has been done in error,
please contact our community team at <a data-l10n-name="organizationContactEmail" >{ $organizationContactEmail }</a>.
{ $customMessage }<br /><br />
if you think this has been done in error, please contact our community team
at <a data-l10n-name="organizationContactEmail" >{ $organizationContactEmail }</a>.
email-subject-ban = Your account has been banned
@@ -27,11 +25,7 @@ email-notification-template-passwordChange =
email-subject-passwordChange = Your password has been changed
email-notification-template-suspend =
Hello { $username },<br/><br/>
In accordance with { $organizationName }'s community guidelines, your
account has been temporarily suspended. During the suspension, you will be
unable to comment, flag or engage with fellow commenters. Please rejoin the
conversation { $until }.<br/><br/>
{ $customMessage }<br/><br/>
If you think this has been done in error, please contact our community team
at <a data-l10n-name="organizationContactEmail" >{ $organizationContactEmail }</a>.
+13
View File
@@ -142,6 +142,11 @@ export interface SuspensionStatusHistory {
* was edited at.
*/
modifiedAt?: Date;
/**
* message is the email message content sent to the user.
*/
message: string;
}
/**
@@ -180,6 +185,8 @@ export interface BanStatusHistory {
* createdAt is the time that the given ban was added.
*/
createdAt: Date;
message?: string;
}
/**
@@ -1128,6 +1135,7 @@ async function retrieveConnection(
* @param tenantID the Tenant's ID where the User exists
* @param id the ID of the user being banned
* @param createdBy the ID of the user banning the above mentioned user
* @param message message to banned user
* @param now the current date
*/
export async function banUser(
@@ -1135,6 +1143,7 @@ export async function banUser(
tenantID: string,
id: string,
createdBy: string,
message?: string,
now = new Date()
) {
// Create the new ban.
@@ -1143,6 +1152,7 @@ export async function banUser(
active: true,
createdBy,
createdAt: now,
message,
};
// Try to update the user if the user isn't already banned.
@@ -1267,6 +1277,7 @@ export async function removeUserBan(
* @param id the ID of the user being suspended
* @param createdBy the ID of the user banning the above mentioned user
* @param from the range of time that the user is being banned for
* @param message the message sent to suspended user in email
* @param now the current date
*/
export async function suspendUser(
@@ -1275,6 +1286,7 @@ export async function suspendUser(
id: string,
createdBy: string,
finish: Date,
message: string,
now = new Date()
) {
// Create the new suspension.
@@ -1286,6 +1298,7 @@ export async function suspendUser(
},
createdBy,
createdAt: now,
message,
};
// Try to update the user if the user isn't already suspended.
@@ -24,6 +24,7 @@ export type BanTemplate = UserNotificationContext<
{
username: string;
organizationContactEmail: string;
customMessage?: string;
}
>;
@@ -33,6 +34,7 @@ export type SuspendTemplate = UserNotificationContext<
username: string;
until: string;
organizationContactEmail: string;
customMessage?: string;
}
>;
@@ -2,10 +2,12 @@
{% block content %}
Hello {{ context.username }},<br/><br/>
In accordance with {{ context.organizationName }}'s community guidelines, your
account has been temporarily suspended. During the suspension, you will be
unable to comment, flag or engage with fellow commenters. Please rejoin the
conversation {{ context.until }}.<br/><br/>
If you think this has been done in error, please contact our community team
at <a data-l10n-name="organizationContactEmail" href="mailto:{{ context.organizationContactEmail }}">{{ context.organizationContactEmail }}</a>.
If you think this has been done in error, please contact our community team at
<a data-l10n-name="organizationContactEmail" href="mailto:{{ context.organizationContactEmail }}">{{ context.organizationContactEmail }}</a>.
{% endblock %}
+8 -1
View File
@@ -447,6 +447,7 @@ export async function updateAvatar(
* @param tenant Tenant where the User will be banned on
* @param user the User that is banning the User
* @param userID the ID of the User being banned
* @param message message to banned user
* @param now the current time that the ban took effect
*/
export async function ban(
@@ -455,6 +456,7 @@ export async function ban(
tenant: Tenant,
banner: User,
userID: string,
message: string,
now = new Date()
) {
// Get the user being banned to check to see if the user already has an
@@ -471,7 +473,7 @@ export async function ban(
}
// Ban the user.
const user = await banUser(mongo, tenant.id, userID, banner.id, now);
const user = await banUser(mongo, tenant.id, userID, banner.id, message, now);
// If the user has an email address associated with their account, send them
// a ban notification email.
@@ -490,6 +492,7 @@ export async function ban(
organizationName: tenant.organization.name,
organizationURL: tenant.organization.url,
organizationContactEmail: tenant.organization.contactEmail,
customMessage: (message || "").replace(/\n/g, "<br />"),
},
},
});
@@ -506,6 +509,7 @@ export async function ban(
* @param user the User that is suspending the User
* @param userID the ID of the user being suspended
* @param timeout the duration in seconds that the user will suspended for
* @param message message to suspended user
* @param now the current time that the suspension will take effect
*/
export async function suspend(
@@ -515,6 +519,7 @@ export async function suspend(
user: User,
userID: string,
timeout: number,
message: string,
now = new Date()
) {
// Convert the timeout to the until time.
@@ -542,6 +547,7 @@ export async function suspend(
userID,
user.id,
finishDateTime.toJSDate(),
message,
now
);
@@ -563,6 +569,7 @@ export async function suspend(
organizationName: tenant.organization.name,
organizationURL: tenant.organization.url,
organizationContactEmail: tenant.organization.contactEmail,
customMessage: (message || "").replace(/\n/g, "<br />"),
},
},
});