Add get profile route that supports gravatar
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ services:
|
||||
volumes:
|
||||
- ./back:/app
|
||||
- ./assets:/assets
|
||||
- data:/data
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
@@ -54,3 +55,6 @@ services:
|
||||
- "back"
|
||||
env_file:
|
||||
- .env
|
||||
|
||||
volumes:
|
||||
data:
|
||||
|
||||
@@ -10,6 +10,7 @@ services:
|
||||
- .env
|
||||
volumes:
|
||||
- ./assets:/assets
|
||||
- data:/data
|
||||
scorometer:
|
||||
image: ghcr.io/chroma-case/scorometer:main
|
||||
ports:
|
||||
@@ -43,3 +44,6 @@ services:
|
||||
- "back"
|
||||
env_file:
|
||||
- .env
|
||||
|
||||
volumes:
|
||||
data:
|
||||
|
||||
@@ -10,6 +10,7 @@ services:
|
||||
- .env
|
||||
volumes:
|
||||
- ./assets:/assets
|
||||
- data:/data
|
||||
scorometer:
|
||||
build: ./scorometer
|
||||
ports:
|
||||
@@ -52,3 +53,4 @@ services:
|
||||
|
||||
volumes:
|
||||
db:
|
||||
data:
|
||||
|
||||
Reference in New Issue
Block a user