-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathuser.resolver.ts
127 lines (112 loc) · 3.37 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
118
119
120
121
122
123
124
125
126
127
import {
Args,
Field,
Mutation,
ObjectType,
Query,
Resolver,
} from '@nestjs/graphql';
import { User } from './user.model';
import { UserService } from './user.service';
import { RegisterUserInput } from './dto/register-user.input';
import { LoginUserInput } from './dto/login-user.input';
import { AuthService } from 'src/auth/auth.service';
import {
GetAuthToken,
GetUserIdFromToken,
} from 'src/decorator/get-auth-token.decorator';
import { Logger } from '@nestjs/common';
import { EmailConfirmationResponse } from 'src/auth/auth.resolver';
import { ResendEmailInput } from './dto/resend-email.input';
import { FileUpload, GraphQLUpload } from 'graphql-upload-minimal';
@ObjectType()
class LoginResponse {
@Field()
accessToken: string;
@Field()
refreshToken: string;
}
@ObjectType()
class AvatarUploadResponse {
@Field()
success: boolean;
@Field()
avatarUrl: string;
}
@Resolver(() => User)
export class UserResolver {
constructor(
private readonly userService: UserService,
private readonly authService: AuthService,
) {}
// @Mutation(() => EmailConfirmationResponse)
// async resendConfirmationEmail(
// @Args('input') resendInput: ResendConfirmationInput,
// ): Promise<EmailConfirmationResponse> {
// return this.authService.resendVerificationEmail(resendInput.email);
// }
@Mutation(() => EmailConfirmationResponse)
async resendConfirmationEmail(
@Args('input') input: ResendEmailInput,
): Promise<EmailConfirmationResponse> {
return this.authService.resendVerificationEmail(input.email);
}
@Mutation(() => User)
async registerUser(
@Args('input') registerUserInput: RegisterUserInput,
): Promise<User> {
if (registerUserInput.password.length < 6) {
throw new Error('Password must be at least 6 characters');
}
return this.authService.register(registerUserInput);
}
@Mutation(() => LoginResponse)
async login(
@Args('input') loginUserInput: LoginUserInput,
): Promise<LoginResponse> {
return this.authService.login(loginUserInput);
}
@Query(() => Boolean)
async logout(@GetAuthToken() token: string): Promise<boolean> {
return this.authService.logout(token);
}
@Query(() => User)
async me(@GetUserIdFromToken() id: string): Promise<User> {
Logger.log('me id:', id);
return this.userService.getUser(id);
}
/**
* Upload a new avatar for the authenticated user
* Uses validateAndBufferFile to ensure the image meets requirements
*/
@Mutation(() => AvatarUploadResponse)
async uploadAvatar(
@GetUserIdFromToken() userId: string,
@Args('file', { type: () => GraphQLUpload }) file: Promise<FileUpload>,
): Promise<AvatarUploadResponse> {
try {
const updatedUser = await this.userService.updateAvatar(userId, file);
return {
success: true,
avatarUrl: updatedUser.avatarUrl,
};
} catch (error) {
// Log the error
Logger.error(
`Avatar upload failed: ${error.message}`,
error.stack,
'UserResolver',
);
// Rethrow the exception to be handled by the GraphQL error handler
throw error;
}
}
/**
* Get the avatar URL for a user
*/
@Query(() => String, { nullable: true })
async getUserAvatar(@Args('userId') userId: string): Promise<string | null> {
const user = await this.userService.getUser(userId);
return user ? user.avatarUrl : null;
}
}