mirror of
https://github.com/wassname/talk.git
synced 2026-08-07 11:29:44 +08:00
[next] User Mutations (#2133)
* feat: added support for Token's * feat: added mutations - updateUserUsername - updateUserDisplayName - updateUserAvatar - updateUserEmail - updateUserRole * lint: removed old commented out code * fix: linting
This commit is contained in:
@@ -5,6 +5,7 @@ import CommonContext from "talk-server/graph/common/context";
|
||||
import { Tenant } from "talk-server/models/tenant";
|
||||
import { User } from "talk-server/models/user";
|
||||
import { TaskQueue } from "talk-server/queue";
|
||||
import { JWTSigningConfig } from "talk-server/services/jwt";
|
||||
import { AugmentedRedis } from "talk-server/services/redis";
|
||||
import TenantCache from "talk-server/services/tenant/cache";
|
||||
import { Request } from "talk-server/types/express";
|
||||
@@ -19,6 +20,7 @@ export interface TenantContextOptions {
|
||||
tenantCache: TenantCache;
|
||||
queue: TaskQueue;
|
||||
config: Config;
|
||||
signingConfig?: JWTSigningConfig;
|
||||
req?: Request;
|
||||
user?: User;
|
||||
}
|
||||
@@ -26,12 +28,13 @@ export interface TenantContextOptions {
|
||||
export default class TenantContext extends CommonContext {
|
||||
public readonly tenant: Tenant;
|
||||
public readonly tenantCache: TenantCache;
|
||||
public readonly user?: User;
|
||||
public readonly mongo: Db;
|
||||
public readonly redis: AugmentedRedis;
|
||||
public readonly queue: TaskQueue;
|
||||
public readonly loaders: ReturnType<typeof loaders>;
|
||||
public readonly mutators: ReturnType<typeof mutators>;
|
||||
public readonly user?: User;
|
||||
public readonly signingConfig?: JWTSigningConfig;
|
||||
|
||||
constructor({
|
||||
req,
|
||||
@@ -42,6 +45,7 @@ export default class TenantContext extends CommonContext {
|
||||
config,
|
||||
tenantCache,
|
||||
queue,
|
||||
signingConfig,
|
||||
}: TenantContextOptions) {
|
||||
super({ user, req, config });
|
||||
|
||||
@@ -51,6 +55,7 @@ export default class TenantContext extends CommonContext {
|
||||
this.mongo = mongo;
|
||||
this.redis = redis;
|
||||
this.queue = queue;
|
||||
this.signingConfig = signingConfig;
|
||||
this.loaders = loaders(this);
|
||||
this.mutators = mutators(this);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { GraphQLSchema } from "graphql";
|
||||
// import { graphqlBatchHTTPWrapper } from "react-relay-network-layer";
|
||||
|
||||
import { graphqlBatchMiddleware } from "talk-server/app/middleware/graphqlBatch";
|
||||
import { Config } from "talk-server/config";
|
||||
|
||||
@@ -1,16 +1,30 @@
|
||||
import TenantContext from "talk-server/graph/tenant/context";
|
||||
import * as user from "talk-server/models/user";
|
||||
import {
|
||||
createToken,
|
||||
deactivateToken,
|
||||
setEmail,
|
||||
setPassword,
|
||||
setUsername,
|
||||
updateAvatar,
|
||||
updateDisplayName,
|
||||
updateEmail,
|
||||
updatePassword,
|
||||
updateRole,
|
||||
updateUsername,
|
||||
} from "talk-server/services/users";
|
||||
import {
|
||||
GQLCreateTokenInput,
|
||||
GQLDeactivateTokenInput,
|
||||
GQLSetEmailInput,
|
||||
GQLSetPasswordInput,
|
||||
GQLSetUsernameInput,
|
||||
GQLUpdatePasswordInput,
|
||||
GQLUpdateUserAvatarInput,
|
||||
GQLUpdateUserDisplayNameInput,
|
||||
GQLUpdateUserEmailInput,
|
||||
GQLUpdateUserRoleInput,
|
||||
GQLUpdateUserUsernameInput,
|
||||
} from "../schema/__generated__/types";
|
||||
|
||||
export const User = (ctx: TenantContext) => ({
|
||||
@@ -30,4 +44,25 @@ export const User = (ctx: TenantContext) => ({
|
||||
input: GQLUpdatePasswordInput
|
||||
): Promise<Readonly<user.User> | null> =>
|
||||
updatePassword(ctx.mongo, ctx.tenant, ctx.user!, input.password),
|
||||
createToken: async (input: GQLCreateTokenInput) =>
|
||||
createToken(
|
||||
ctx.mongo,
|
||||
ctx.tenant,
|
||||
// NOTE: (wyattjoh) this will error if not provided.
|
||||
ctx.signingConfig!,
|
||||
ctx.user!,
|
||||
input.name
|
||||
),
|
||||
deactivateToken: async (input: GQLDeactivateTokenInput) =>
|
||||
deactivateToken(ctx.mongo, ctx.tenant, ctx.user!, input.id),
|
||||
updateUserUsername: async (input: GQLUpdateUserUsernameInput) =>
|
||||
updateUsername(ctx.mongo, ctx.tenant, input.userID, input.username),
|
||||
updateUserDisplayName: async (input: GQLUpdateUserDisplayNameInput) =>
|
||||
updateDisplayName(ctx.mongo, ctx.tenant, input.userID, input.displayName),
|
||||
updateUserEmail: async (input: GQLUpdateUserEmailInput) =>
|
||||
updateEmail(ctx.mongo, ctx.tenant, input.userID, input.email),
|
||||
updateUserAvatar: async (input: GQLUpdateUserAvatarInput) =>
|
||||
updateAvatar(ctx.mongo, ctx.tenant, input.userID, input.avatar),
|
||||
updateUserRole: async (input: GQLUpdateUserRoleInput) =>
|
||||
updateRole(ctx.mongo, ctx.tenant, input.userID, input.role),
|
||||
});
|
||||
|
||||
@@ -97,4 +97,32 @@ export const Mutation: Required<GQLMutationTypeResolver<void>> = {
|
||||
user: await ctx.mutators.User.updatePassword(input),
|
||||
clientMutationId: input.clientMutationId,
|
||||
}),
|
||||
createToken: async (source, { input }, ctx) => ({
|
||||
...(await ctx.mutators.User.createToken(input)),
|
||||
clientMutationId: input.clientMutationId,
|
||||
}),
|
||||
deactivateToken: async (source, { input }, ctx) => ({
|
||||
...(await ctx.mutators.User.deactivateToken(input)),
|
||||
clientMutationId: input.clientMutationId,
|
||||
}),
|
||||
updateUserUsername: async (source, { input }, ctx) => ({
|
||||
user: await ctx.mutators.User.updateUserUsername(input),
|
||||
clientMutationId: input.clientMutationId,
|
||||
}),
|
||||
updateUserDisplayName: async (source, { input }, ctx) => ({
|
||||
user: await ctx.mutators.User.updateUserDisplayName(input),
|
||||
clientMutationId: input.clientMutationId,
|
||||
}),
|
||||
updateUserEmail: async (source, { input }, ctx) => ({
|
||||
user: await ctx.mutators.User.updateUserEmail(input),
|
||||
clientMutationId: input.clientMutationId,
|
||||
}),
|
||||
updateUserAvatar: async (source, { input }, ctx) => ({
|
||||
user: await ctx.mutators.User.updateUserAvatar(input),
|
||||
clientMutationId: input.clientMutationId,
|
||||
}),
|
||||
updateUserRole: async (source, { input }, ctx) => ({
|
||||
user: await ctx.mutators.User.updateUserRole(input),
|
||||
clientMutationId: input.clientMutationId,
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -984,41 +984,6 @@ enum USER_ROLE {
|
||||
ADMIN
|
||||
}
|
||||
|
||||
enum USER_USERNAME_STATUS {
|
||||
"""
|
||||
UNSET is used when the username can be changed, and does not necessarily
|
||||
require moderator action to become active. This can be used when the user
|
||||
signs up with a social login and has the option of setting their own
|
||||
username.
|
||||
"""
|
||||
UNSET
|
||||
|
||||
"""
|
||||
SET is used when the username has been set for the first time, but cannot
|
||||
change without the username being rejected by a moderator and that moderator
|
||||
agreeing that the username should be allowed to change.
|
||||
"""
|
||||
SET
|
||||
|
||||
"""
|
||||
APPROVED is used when the username was changed, and subsequently approved by
|
||||
said moderator.
|
||||
"""
|
||||
APPROVED
|
||||
|
||||
"""
|
||||
REJECTED is used when the username was changed, and subsequently rejected by
|
||||
said moderator.
|
||||
"""
|
||||
REJECTED
|
||||
|
||||
"""
|
||||
CHANGED is used after a user has changed their username after it was
|
||||
rejected.
|
||||
"""
|
||||
CHANGED
|
||||
}
|
||||
|
||||
type LocalProfile {
|
||||
id: String!
|
||||
}
|
||||
@@ -1047,6 +1012,12 @@ union Profile =
|
||||
| FacebookProfile
|
||||
| GoogleProfile
|
||||
|
||||
type Token {
|
||||
id: ID!
|
||||
name: String!
|
||||
createdAt: Time!
|
||||
}
|
||||
|
||||
"""
|
||||
User is someone that leaves Comments, and logs in.
|
||||
"""
|
||||
@@ -1108,6 +1079,11 @@ type User {
|
||||
first: Int = 10
|
||||
after: Cursor
|
||||
): CommentModerationActionConnection! @auth(role: [MODERATOR, ADMIN])
|
||||
|
||||
"""
|
||||
tokens lists the access tokens associated with the account.
|
||||
"""
|
||||
tokens: [Token!]! @auth(role: [ADMIN], userIDField: "id")
|
||||
}
|
||||
|
||||
################################################################################
|
||||
@@ -2943,6 +2919,244 @@ type UpdatePasswordPayload {
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
##################
|
||||
# createToken
|
||||
##################
|
||||
|
||||
input CreateTokenInput {
|
||||
"""
|
||||
name is the desired name for the Token.
|
||||
"""
|
||||
name: String!
|
||||
|
||||
"""
|
||||
clientMutationId is required for Relay support.
|
||||
"""
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
type CreateTokenPayload {
|
||||
"""
|
||||
user is the possibly modified User.
|
||||
"""
|
||||
user: User!
|
||||
|
||||
"""
|
||||
token is the Token that was created.
|
||||
"""
|
||||
token: Token!
|
||||
|
||||
"""
|
||||
signedToken is the signed Token associated with the account.
|
||||
"""
|
||||
signedToken: String!
|
||||
|
||||
"""
|
||||
clientMutationId is required for Relay support.
|
||||
"""
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
##################
|
||||
# deactivateToken
|
||||
##################
|
||||
|
||||
input DeactivateTokenInput {
|
||||
"""
|
||||
id is the ID of the Token that should be deactivated.
|
||||
"""
|
||||
id: ID!
|
||||
|
||||
"""
|
||||
clientMutationId is required for Relay support.
|
||||
"""
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
type DeactivateTokenPayload {
|
||||
"""
|
||||
user is the possibly modified User.
|
||||
"""
|
||||
user: User!
|
||||
|
||||
"""
|
||||
token is the Token that was deleted.
|
||||
"""
|
||||
token: Token
|
||||
|
||||
"""
|
||||
clientMutationId is required for Relay support.
|
||||
"""
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
##################
|
||||
# updateUserUsername
|
||||
##################
|
||||
|
||||
input UpdateUserUsernameInput {
|
||||
"""
|
||||
userID is the ID of the User that should have their username updated.
|
||||
"""
|
||||
userID: ID!
|
||||
|
||||
"""
|
||||
username is the desired username to set for the User.
|
||||
"""
|
||||
username: String!
|
||||
|
||||
"""
|
||||
clientMutationId is required for Relay support.
|
||||
"""
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
type UpdateUserUsernamePayload {
|
||||
"""
|
||||
user is the possibly modified User.
|
||||
"""
|
||||
user: User!
|
||||
|
||||
"""
|
||||
clientMutationId is required for Relay support.
|
||||
"""
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
##################
|
||||
# updateUserDisplayName
|
||||
##################
|
||||
|
||||
input UpdateUserDisplayNameInput {
|
||||
"""
|
||||
userID is the ID of the User that should have their display name updated.
|
||||
"""
|
||||
userID: ID!
|
||||
|
||||
"""
|
||||
displayName is the desired display name to set for the User. If set to `null`
|
||||
or not provided, it will be unset.
|
||||
"""
|
||||
displayName: String
|
||||
|
||||
"""
|
||||
clientMutationId is required for Relay support.
|
||||
"""
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
type UpdateUserDisplayNamePayload {
|
||||
"""
|
||||
user is the possibly modified User.
|
||||
"""
|
||||
user: User!
|
||||
|
||||
"""
|
||||
clientMutationId is required for Relay support.
|
||||
"""
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
##################
|
||||
# updateUserEmail
|
||||
##################
|
||||
|
||||
input UpdateUserEmailInput {
|
||||
"""
|
||||
userID is the ID of the User that should have their email address updated.
|
||||
"""
|
||||
userID: ID!
|
||||
|
||||
"""
|
||||
email is the email address to set for the User.
|
||||
"""
|
||||
email: String!
|
||||
|
||||
"""
|
||||
clientMutationId is required for Relay support.
|
||||
"""
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
type UpdateUserEmailPayload {
|
||||
"""
|
||||
user is the possibly modified User.
|
||||
"""
|
||||
user: User!
|
||||
|
||||
"""
|
||||
clientMutationId is required for Relay support.
|
||||
"""
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
##################
|
||||
# updateUserAvatar
|
||||
##################
|
||||
|
||||
input UpdateUserAvatarInput {
|
||||
"""
|
||||
userID is the ID of the User that should have their avatar updated.
|
||||
"""
|
||||
userID: ID!
|
||||
|
||||
"""
|
||||
avatar is the URL to the avatar to set for the User. If set to `null` or not
|
||||
provided, it will be unset.
|
||||
"""
|
||||
avatar: String
|
||||
|
||||
"""
|
||||
clientMutationId is required for Relay support.
|
||||
"""
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
type UpdateUserAvatarPayload {
|
||||
"""
|
||||
user is the possibly modified User.
|
||||
"""
|
||||
user: User!
|
||||
|
||||
"""
|
||||
clientMutationId is required for Relay support.
|
||||
"""
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
##################
|
||||
# updateUserRole
|
||||
##################
|
||||
|
||||
input UpdateUserRoleInput {
|
||||
"""
|
||||
userID is the ID of the User that should have their avatar updated.
|
||||
"""
|
||||
userID: ID!
|
||||
|
||||
"""
|
||||
role is the `USER_ROLE` that the User should be set to.
|
||||
"""
|
||||
role: USER_ROLE!
|
||||
|
||||
"""
|
||||
clientMutationId is required for Relay support.
|
||||
"""
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
type UpdateUserRolePayload {
|
||||
"""
|
||||
user is the possibly modified User.
|
||||
"""
|
||||
user: User!
|
||||
|
||||
"""
|
||||
clientMutationId is required for Relay support.
|
||||
"""
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
##################
|
||||
## Mutation
|
||||
##################
|
||||
@@ -3085,12 +3299,54 @@ type Mutation {
|
||||
they already have one associated with them.
|
||||
"""
|
||||
updatePassword(input: UpdatePasswordInput!): UpdatePasswordPayload @auth
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## Subscriptions
|
||||
################################################################################
|
||||
"""
|
||||
createToken allows an administrator to create a Token based on the current
|
||||
logged in User.
|
||||
"""
|
||||
createToken(input: CreateTokenInput!): CreateTokenPayload!
|
||||
@auth(roles: [ADMIN])
|
||||
|
||||
type Subscription {
|
||||
commentCreated(storyID: ID!): Comment
|
||||
"""
|
||||
deactivateToken will deactivate the current logged in User's Token based on
|
||||
the input.
|
||||
"""
|
||||
deactivateToken(input: DeactivateTokenInput!): DeactivateTokenPayload!
|
||||
@auth(roles: [ADMIN])
|
||||
|
||||
"""
|
||||
updateUserUsername allows administrators to update a given User's username to
|
||||
the one provided.
|
||||
"""
|
||||
updateUserUsername(
|
||||
input: UpdateUserUsernameInput!
|
||||
): UpdateUserUsernamePayload! @auth(roles: [ADMIN])
|
||||
|
||||
"""
|
||||
updateUserDisplayName allows administrators to update a given User's display
|
||||
name to the one provided.
|
||||
"""
|
||||
updateUserDisplayName(
|
||||
input: UpdateUserDisplayNameInput!
|
||||
): UpdateUserDisplayNamePayload @auth(roles: [ADMIN])
|
||||
|
||||
"""
|
||||
updateUserEmail allows administrators to update a given User's email address
|
||||
to the one provided.
|
||||
"""
|
||||
updateUserEmail(input: UpdateUserEmailInput!): UpdateUserEmailPayload!
|
||||
@auth(roles: [ADMIN])
|
||||
|
||||
"""
|
||||
updateUserAvatar allows administrators to update a given User's avatar to the
|
||||
one provided.
|
||||
"""
|
||||
updateUserAvatar(input: UpdateUserAvatarInput!): UpdateUserAvatarPayload!
|
||||
@auth(roles: [ADMIN])
|
||||
|
||||
"""
|
||||
updateUserRole will update a given User's role.
|
||||
"""
|
||||
updateUserRole(input: UpdateUserRoleInput!): UpdateUserRolePayload!
|
||||
@auth(roles: [ADMIN])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user