[CORL-523] Document GraphQL mutations for managing accounts (#2544)

* Create preliminary endpoint for updating user names via API

CORL-523

* Create preliminary endpoint for updating user emails via API

CORL-523

* Create preliminary endpoint for deleting users via the API

CORL-523

* Hook up the delete, update email, and update user name endpoints

CORL-523

* Update readme to include preliminary GDPR endpoint instructions

CORL-523

* Uncomment limiters on updateEmail endpoint

My mistake leaving these commented while testing, should not have been committed.

CORL-523

* Run DocToc on the README to generate table of contents

CORL-523

* feat: enhanced documentation on account management edges

* fix: prevent double delete of user account

* fix: swapped order of params

* Update README.md

* Update README.md

* fix: remove unknown field title

* fix: remove unknown field title on story
This commit is contained in:
Nick Funk
2019-09-10 20:16:40 +07:00
committed by Vinh
parent e86e9d2c68
commit f9e1bf144e
7 changed files with 530 additions and 211 deletions
@@ -28,12 +28,14 @@ import {
updateUsernameByID,
} from "coral-server/services/users";
import { invite } from "coral-server/services/users/auth/invite";
import { deleteUser } from "coral-server/services/users/delete";
import {
GQLBanUserInput,
GQLCancelAccountDeletionInput,
GQLCreateTokenInput,
GQLDeactivateTokenInput,
GQLDeleteUserAccountInput,
GQLIgnoreUserInput,
GQLInviteUsersInput,
GQLRemoveUserBanInput,
@@ -135,6 +137,15 @@ export const Users = (ctx: TenantContext) => ({
),
{ "input.password": [ERROR_CODES.PASSWORD_INCORRECT] }
),
deleteAccount: async (
input: GQLDeleteUserAccountInput
): Promise<Readonly<User> | null> => {
if (input.userID === ctx.user!.id) {
throw new Error("cannot delete self immediately");
}
return deleteUser(ctx.mongo, input.userID, ctx.tenant.id, ctx.now);
},
cancelAccountDeletion: async (
input: GQLCancelAccountDeletionInput
): Promise<Readonly<User> | null> =>
@@ -209,4 +209,8 @@ export const Mutation: Required<GQLMutationTypeResolver<void>> = {
user: await ctx.mutators.Users.cancelAccountDeletion(input),
clientMutationId: input.clientMutationId,
}),
deleteUserAccount: async (source, { input }, ctx) => ({
user: await ctx.mutators.Users.deleteAccount(input),
clientMutationId: input.clientMutationId,
}),
};
@@ -4363,6 +4363,34 @@ type RequestAccountDeletionPayload {
clientMutationId: String!
}
##################
# deleteUserAccount
##################
input DeleteUserAccountInput {
"""
userID is the ID of the User being deleted.
"""
userID: ID!
"""
clientMutationId is required for Relay support.
"""
clientMutationId: String!
}
type DeleteUserAccountPayload {
"""
user is the User that was deleted.
"""
user: User
"""
clientMutationId is required for Relay support.
"""
clientMutationId: String!
}
##################
# cancelAccountDeletion
##################
@@ -5052,13 +5080,20 @@ type Mutation {
input: RequestAccountDeletionInput!
): RequestAccountDeletionPayload! @auth
"""
deleteUserAccount will delete the target user now.
"""
deleteUserAccount(input: DeleteUserAccountInput!): DeleteUserAccountPayload!
@auth(roles: [ADMIN])
"""
cancelAccountDeletion allows the current logged in User to cancel the
request to delete their account
"""
cancelAccountDeletion(
input: CancelAccountDeletionInput!
): CancelAccountDeletionPayload! @auth(permit: [SUSPENDED, BANNED, PENDING_DELETION])
): CancelAccountDeletionPayload!
@auth(permit: [SUSPENDED, BANNED, PENDING_DELETION])
"""
createToken allows an administrator to create a Token based on the current