Add get profile route that supports gravatar

This commit is contained in:
2023-07-23 15:56:48 +09:00
parent 20eb62d19b
commit 04487c9b24
6 changed files with 69 additions and 18 deletions
+26 -14
View File
@@ -44,16 +44,16 @@ export class AuthController {
private settingsService: SettingsService,
) {}
@Get("login/google")
@Get('login/google')
@UseGuards(AuthGuard('google'))
googleLogin() { }
googleLogin() {}
@Get("logged/google")
@Get('logged/google')
@UseGuards(AuthGuard('google'))
async googleLoginCallbakc(@Req() req: any) {
let user = await this.usersService.user({googleID: req.user.googleID});
let user = await this.usersService.user({ googleID: req.user.googleID });
if (!user) {
user = await this.usersService.createUser(req.user)
user = await this.usersService.createUser(req.user);
await this.settingsService.createUserSetting(user.id);
}
return this.authService.login(user);
@@ -62,9 +62,9 @@ export class AuthController {
@Post('register')
async register(@Body() registerDto: RegisterDto): Promise<void> {
try {
const user = await this.usersService.createUser(registerDto)
const user = await this.usersService.createUser(registerDto);
await this.settingsService.createUserSetting(user.id);
} catch(e) {
} catch (e) {
console.error(e);
throw new BadRequestException();
}
@@ -86,6 +86,15 @@ export class AuthController {
return this.authService.login(user);
}
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
@ApiOkResponse({ description: 'The user profile picture' })
@ApiUnauthorizedResponse({ description: 'Invalid token' })
@Get('me/picture')
async getProfilePicture(@Request() req: any) {
return await this.usersService.getProfilePicture(req.user.id);
}
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
@ApiOkResponse({ description: 'Successfully logged in', type: User })
@@ -133,25 +142,28 @@ export class AuthController {
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
@ApiOkResponse({description: 'Successfully edited settings', type: Setting})
@ApiUnauthorizedResponse({description: 'Invalid token'})
@ApiOkResponse({ description: 'Successfully edited settings', type: Setting })
@ApiUnauthorizedResponse({ description: 'Invalid token' })
@Patch('me/settings')
udpateSettings(
@Request() req: any,
@Body() settingUserDto: UpdateSettingDto): Promise<Setting> {
@Body() settingUserDto: UpdateSettingDto,
): Promise<Setting> {
return this.settingsService.updateUserSettings({
where: { userId: +req.user.id},
where: { userId: +req.user.id },
data: settingUserDto,
});
}
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
@ApiOkResponse({description: 'Successfully edited settings', type: Setting})
@ApiUnauthorizedResponse({description: 'Invalid token'})
@ApiOkResponse({ description: 'Successfully edited settings', type: Setting })
@ApiUnauthorizedResponse({ description: 'Invalid token' })
@Get('me/settings')
async getSettings(@Request() req: any): Promise<Setting> {
const result = await this.settingsService.getUserSetting({ userId: +req.user.id });
const result = await this.settingsService.getUserSetting({
userId: +req.user.id,
});
if (!result) throw new NotFoundException();
return result;
}
+5
View File
@@ -20,4 +20,9 @@ export class UsersController {
if (!ret) throw new NotFoundException();
return ret;
}
@Get(':id/picture')
async getPicture(@Param('id') id: number) {
return await this.usersService.getProfilePicture(+id);
}
}
+28 -4
View File
@@ -1,8 +1,14 @@
import { Injectable } from '@nestjs/common';
import {
Injectable,
InternalServerErrorException,
NotFoundException,
StreamableFile,
} from '@nestjs/common';
import { User, Prisma } from '@prisma/client';
import { PrismaService } from 'src/prisma/prisma.service';
import * as bcrypt from 'bcryptjs';
import { randomUUID } from 'crypto';
import { createHash, randomUUID } from 'crypto';
import { createReadStream, existsSync } from 'fs';
@Injectable()
export class UsersService {
@@ -34,8 +40,7 @@ export class UsersService {
}
async createUser(data: Prisma.UserCreateInput): Promise<User> {
if (data.password)
data.password = await bcrypt.hash(data.password, 8);
if (data.password) data.password = await bcrypt.hash(data.password, 8);
return this.prisma.user.create({
data,
});
@@ -73,4 +78,23 @@ export class UsersService {
where,
});
}
async getProfilePicture(userId: number) {
const path = `/data/${userId}.png`;
if (existsSync(path)) {
const file = createReadStream(path);
return new StreamableFile(file);
}
// We could not find a profile icon locally, using gravatar instead.
const user = await this.user({ id: userId });
if (!user) throw new InternalServerErrorException();
const hash = createHash('md5')
.update(user.email.trim().toLowerCase())
.digest('hex');
const resp = await fetch(
`https://www.gravatar.com/avatar/${hash}.jpg?d=404`,
);
if (!resp.ok) throw new NotFoundException('No image found for user');
return resp.arrayBuffer();
}
}