-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
/
user.resolver.ts
117 lines (107 loc) · 3.24 KB
/
user.resolver.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { Resolver, Query, Mutation, Args, Subscription } from '@nestjs/graphql';
import { SessionType, User } from './user.model';
import { UseGuards } from '@nestjs/common';
import { GqlAuthGuard } from '../guards/gql-auth.guard';
import { GqlUser } from '../decorators/gql-user.decorator';
import { UserService } from './user.service';
import { throwErr } from 'src/utils';
import * as E from 'fp-ts/lib/Either';
import * as TE from 'fp-ts/TaskEither';
import { pipe } from 'fp-ts/function';
import { PubSubService } from 'src/pubsub/pubsub.service';
import { AuthUser } from 'src/types/AuthUser';
import { GqlThrottlerGuard } from 'src/guards/gql-throttler.guard';
import { SkipThrottle } from '@nestjs/throttler';
@UseGuards(GqlThrottlerGuard)
@Resolver(() => User)
export class UserResolver {
constructor(
private readonly userService: UserService,
private readonly pubsub: PubSubService,
) {}
@Query(() => User, {
description:
"Gives details of the user executing this query (pass Authorization 'Bearer' header)",
})
@UseGuards(GqlAuthGuard)
me(@GqlUser() user: AuthUser) {
return this.userService.convertDbUserToUser(user);
}
/* Mutations */
@Mutation(() => User, {
description: 'Update user sessions',
})
@UseGuards(GqlAuthGuard)
async updateUserSessions(
@GqlUser() user: AuthUser,
@Args({
name: 'currentSession',
description: 'JSON string of the saved REST/GQL session',
})
currentSession: string,
@Args({
name: 'sessionType',
description: 'Type of the session',
type: () => SessionType,
})
sessionType: SessionType,
): Promise<User> {
const updatedUser = await this.userService.updateUserSessions(
user,
currentSession,
sessionType,
);
if (E.isLeft(updatedUser)) throwErr(updatedUser.left);
return updatedUser.right;
}
@Mutation(() => User, {
description: 'Update a users display name',
})
@UseGuards(GqlAuthGuard)
async updateDisplayName(
@GqlUser() user: AuthUser,
@Args({
name: 'updatedDisplayName',
description: 'New name of user',
type: () => String,
})
updatedDisplayName: string,
) {
const updatedUser = await this.userService.updateUserDisplayName(
user.uid,
updatedDisplayName,
);
if (E.isLeft(updatedUser)) throwErr(updatedUser.left);
return updatedUser.right;
}
@Mutation(() => Boolean, {
description: 'Delete an user account',
})
@UseGuards(GqlAuthGuard)
deleteUser(@GqlUser() user: AuthUser): Promise<boolean> {
return pipe(
this.userService.deleteUserByUID(user),
TE.map(() => true),
TE.mapLeft((message) => message.toString()),
TE.getOrElse(throwErr),
)();
}
/* Subscriptions */
@Subscription(() => User, {
description: 'Listen for user updates',
resolve: (value) => value,
})
@SkipThrottle()
@UseGuards(GqlAuthGuard)
userUpdated(@GqlUser() user: User) {
return this.pubsub.asyncIterator(`user/${user.uid}/updated`);
}
@Subscription(() => User, {
description: 'Listen for user deletion',
resolve: (value) => value,
})
@UseGuards(GqlAuthGuard)
userDeleted(@GqlUser() user: User): AsyncIterator<User> {
return this.pubsub.asyncIterator(`user/${user.uid}/deleted`);
}
}