diff --git a/api/src/auth/auth.controller.ts b/api/src/auth/auth.controller.ts index 3997e06..f85a698 100644 --- a/api/src/auth/auth.controller.ts +++ b/api/src/auth/auth.controller.ts @@ -58,6 +58,30 @@ export class AuthController { return { data: req.user } } + @ApiOperation({ summary: 'Update Profile' }) + @HttpCode(HttpStatus.OK) + @ApiBearerAuth() + @UseGuards(AuthGuard) + @Patch('/update-profile') + async updateProfile( + @Body() input: { name: string; phone: string }, + @Request() req, + ) { + return await this.authService.updateProfile(input, req.user) + } + + @ApiOperation({ summary: 'Change Password' }) + @HttpCode(HttpStatus.OK) + @ApiBearerAuth() + @UseGuards(AuthGuard) + @Post('/change-password') + async changePassword( + @Body() input: { oldPassword: string; newPassword: string }, + @Request() req, + ) { + return await this.authService.changePassword(input, req.user) + } + @UseGuards(AuthGuard) @ApiOperation({ summary: 'Generate Api Key' }) @ApiBearerAuth() diff --git a/api/src/auth/auth.dto.ts b/api/src/auth/auth.dto.ts index aee3372..c1ffc2e 100644 --- a/api/src/auth/auth.dto.ts +++ b/api/src/auth/auth.dto.ts @@ -8,7 +8,7 @@ export class RegisterInputDTO { email: string @ApiProperty({ type: String }) - primaryPhone?: string + phone?: string @ApiProperty({ type: String, required: true }) password: string diff --git a/api/src/auth/auth.service.ts b/api/src/auth/auth.service.ts index dad46c2..a77bff8 100644 --- a/api/src/auth/auth.service.ts +++ b/api/src/auth/auth.service.ts @@ -6,7 +6,7 @@ import { v4 as uuidv4 } from 'uuid' import { InjectModel } from '@nestjs/mongoose' import { ApiKey, ApiKeyDocument } from './schemas/api-key.schema' import { Model } from 'mongoose' -import { User } from '../users/schemas/user.schema' +import { User, UserDocument } from '../users/schemas/user.schema' import axios from 'axios' import { PasswordReset, @@ -197,6 +197,33 @@ export class AuthService { return { message: 'Password reset successfully' } } + async updateProfile( + input: { name: string; phone: string }, + user: UserDocument, + ) { + return this.usersService.updateProfile(input, user) + } + + async changePassword( + input: { oldPassword: string; newPassword: string }, + user: UserDocument, + ) { + const userToUpdate = await this.usersService.findOne({ _id: user._id }) + if (!userToUpdate) { + throw new HttpException({ error: 'User not found' }, HttpStatus.NOT_FOUND) + } + if (!(await bcrypt.compare(input.oldPassword, userToUpdate.password))) { + throw new HttpException( + { error: 'Invalid old password' }, + HttpStatus.BAD_REQUEST, + ) + } + + const hashedPassword = await bcrypt.hash(input.newPassword, 10) + userToUpdate.password = hashedPassword + await userToUpdate.save() + } + async generateApiKey(currentUser: User) { const apiKey = uuidv4() const hashedApiKey = await bcrypt.hash(apiKey, 10) @@ -249,7 +276,10 @@ export class AuthService { async revokeApiKey(apiKeyId: string) { const apiKey = await this.apiKeyModel.findById(apiKeyId) if (!apiKey) { - throw new HttpException({ error: 'Api key not found' }, HttpStatus.NOT_FOUND) + throw new HttpException( + { error: 'Api key not found' }, + HttpStatus.NOT_FOUND, + ) } apiKey.revokedAt = new Date() await apiKey.save() @@ -258,7 +288,10 @@ export class AuthService { async renameApiKey(apiKeyId: string, name: string) { const apiKey = await this.apiKeyModel.findById(apiKeyId) if (!apiKey) { - throw new HttpException({ error: 'Api key not found' }, HttpStatus.NOT_FOUND) + throw new HttpException( + { error: 'Api key not found' }, + HttpStatus.NOT_FOUND, + ) } apiKey.name = name await apiKey.save() diff --git a/api/src/users/schemas/user.schema.ts b/api/src/users/schemas/user.schema.ts index 2e4a62e..a0642e7 100644 --- a/api/src/users/schemas/user.schema.ts +++ b/api/src/users/schemas/user.schema.ts @@ -21,7 +21,7 @@ export class User { avatar?: string @Prop({ type: String, trim: true }) - primaryPhone: string + phone: string @Prop({ type: String }) password: string diff --git a/api/src/users/users.service.ts b/api/src/users/users.service.ts index 1e4f270..44cd71d 100644 --- a/api/src/users/users.service.ts +++ b/api/src/users/users.service.ts @@ -40,4 +40,23 @@ export class UsersService { }) return await newUser.save() } + + async updateProfile( + input: { name: string; phone: string }, + user: UserDocument, + ) { + const userToUpdate = await this.findOne({ _id: user._id }) + if (!userToUpdate) { + throw new HttpException({ error: 'User not found' }, HttpStatus.NOT_FOUND) + } + + if (input.name) { + userToUpdate.name = input.name + } + if (input.phone) { + userToUpdate.phone = input.phone + } + + return await userToUpdate.save() + } }