Skip to content

Commit

Permalink
feat: implement signup
Browse files Browse the repository at this point in the history
implement signup for new user

#18
  • Loading branch information
seo-wo committed Dec 1, 2023
1 parent 264574f commit 0e0a149
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 56 deletions.
92 changes: 71 additions & 21 deletions src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import { Controller, Get, UseGuards, Req, Res, Logger } from '@nestjs/common';
import {
Controller,
Get,
Post,
UseGuards,
Req,
Res,
Body,
Logger,
} from '@nestjs/common';
import { Request, Response } from 'express';
import { AuthService } from './auth.service';
import { GoogleAuthGuard } from './google/google.guard';
import { User as AuthUser } from 'passport';
import { User } from 'src/user/entity/user.entity';
import { UserEntity } from 'src/user/entity/user.entity';
import { CreateUserDto } from 'src/user/dto/create-user.dto';
import { SignUpUserDto } from 'src/user/dto/signup-user.dto';

@Controller('auth')
export class AuthController {
private readonly logger = new Logger(AuthController.name);

constructor(private readonly authService: AuthService) {}

@Get('google')
Expand All @@ -20,29 +32,67 @@ export class AuthController {
@Req() req: Request & { user: AuthUser },
@Res() res: Response,
): Promise<void> {
this.logger.debug(`googleAuthRedirect`);
try {
const user = req.user;
this.logger.debug(`googleAuthRedirect [user: ${JSON.stringify(user)}]`);
const userEntity: { isNew: boolean; user: Partial<User> } =
await this.authService.findOrCreateUser(user);
const accessToken: string = await this.authService.generateToken(userEntity.user);
const refreshToken: string = await this.authService.generateRefreshToken(userEntity.user);
// res.cookie('access_token', accessToken, {
// httpOnly: true,
// secure: true,
// sameSite: 'none',
// // expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7),
// });
res.cookie('refresh_token', refreshToken, {
httpOnly: true,
secure: true,
sameSite: 'none',
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7),
});
res.redirect(`${process.env.FRONT_URL}/auth/callback/?token=${accessToken}`);
const user: AuthUser = req.user;
const findUser: Partial<UserEntity> =
await this.authService.findOneByEmail(user.email);
if (typeof findUser === 'undefined' || findUser === null) {
this.logger.debug(`new user [user: ${JSON.stringify(user)}]`);
res.cookie('google_token', user.accessToken, {
httpOnly: true,
secure: true,
sameSite: 'none',
});
res.redirect(`${process.env.FRONT_URL}/auth/signup`);
} else {
this.logger.debug(`existing user [user: ${JSON.stringify(user)}]`);
const accessToken: string =
await this.authService.generateToken(findUser);
const refreshToken: string =
await this.authService.generateRefreshToken(findUser);
this.setCookie(res, accessToken, refreshToken);
res.redirect(`${process.env.FRONT_URL}/auth/callback/`);
}
} catch (error) {
this.logger.error(`googleAuthRedirect [error: ${error.message}]`);
res.status(500).json({ message: error.message });
}
}

@Post('signup')
async signup(
@Req() req: Request,
@Res() res: Response,
@Body() body: SignUpUserDto,
) {
const user = req['user'];
const userInfo: CreateUserDto = {
email: user.email,
googleId: user.sub,
nickname: body.nickname,
slackId: body.slackId,
};
console.log('userInfo', userInfo);
const newUser = await this.authService.createUser(userInfo);
const accessToken = await this.authService.generateToken(newUser);
const refreshToken = await this.authService.generateRefreshToken(newUser);
this.setCookie(res, accessToken, refreshToken);
res.redirect(`${process.env.FRONT_URL}/auth/callback/`);
}

private setCookie(res: Response, accessToken: string, refreshToken: string) {
res.cookie('refresh_token', refreshToken, {
httpOnly: true,
secure: true,
sameSite: 'none',
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7),
});
res.cookie('access_token', accessToken, {
httpOnly: true,
secure: true,
sameSite: 'none',
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 1),
});
}
}
9 changes: 7 additions & 2 deletions src/auth/auth.module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Module } from '@nestjs/common';
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
Expand All @@ -8,6 +8,7 @@ import { JwtStrategy } from './jwt/jwt.strategy';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { UserModule } from 'src/user/user.module';
import { UserService } from 'src/user/user.service';
import { GoogleMiddleware } from './google/google.middleware';

@Module({
imports: [
Expand All @@ -32,4 +33,8 @@ import { UserService } from 'src/user/user.service';
controllers: [AuthController],
providers: [UserService, AuthService, GoogleStrategy, JwtStrategy],
})
export class AuthModule {}
export class AuthModule implements NestModule {
configure(consumer: MiddlewareConsumer): any {
consumer.apply(GoogleMiddleware).forRoutes('/auth/signup');
}
}
33 changes: 10 additions & 23 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { Injectable, Logger } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { ConfigService } from '@nestjs/config';
import { UserService } from 'src/user/user.service';
import { User } from 'src/user/entity/user.entity';
import { UserEntity } from 'src/user/entity/user.entity';
import { CreateUserDto } from 'src/user/dto/create-user.dto';

@Injectable()
export class AuthService {
Expand All @@ -13,38 +14,24 @@ export class AuthService {
private readonly userService: UserService,
) {}

async googleLogin(user: any): Promise<boolean> {
this.logger.debug(`googleLogin [user: ${JSON.stringify(user)}]`);
// const userId = user.sub;
const userEntity = await this.userService.findOneByEmail(user.email);
if (typeof userEntity === 'undefined' || userEntity === null) {
await this.userService.createUser(user);
return false;
}
return true;
async findOneByEmail(email: string): Promise<UserEntity | null> {
return this.userService.findOneByEmail(email);
}
async generateToken(user: Partial<User>): Promise<string> {

async generateToken(user: Partial<UserEntity>): Promise<string> {
const payload = { username: user.nickname, uid: user.id, role: user.role };
return this.jwtService.signAsync(payload);
}

async generateRefreshToken(user: Partial<User>): Promise<string> {
async generateRefreshToken(user: Partial<UserEntity>): Promise<string> {
const payload = { uid: user.id };
return this.jwtService.signAsync(payload, {
secret: this.configService.get<string>('jwt.refreshSecret'),
expiresIn: this.configService.get<string>('jwt.refreshExpiresIn'),
});
}
async findOrCreateUser(
user: any,
): Promise<{ isNew: boolean; user: Partial<User> }> {
let userEntity: Partial<User> = await this.userService.findOneByEmail(
user.email,
);
if (typeof userEntity === 'undefined' || userEntity === null) {
userEntity = await this.userService.createUser(user);
return { isNew: true, user: userEntity };
}
return { isNew: false, user: userEntity };

async createUser(user: CreateUserDto): Promise<Partial<UserEntity> | null> {
return this.userService.createUser(user);
}
}
13 changes: 3 additions & 10 deletions src/auth/google/google.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,17 @@ export class GoogleAuthGuard extends AuthGuard('google') {
constructor() {
super({});
}

async canActivate(context: ExecutionContext): Promise<boolean> {
let result: boolean = false;
if (context.getType() === 'http') {
this.logger.debug(
`canActivate [http, ${context.getArgs()[0].method} ${
context.getArgs()[0].url
}]`,
);
}
// const token = context
// .switchToHttp()
// .getRequest()
// .headers?.authorization?.split('Bearer ')[1];
const result: boolean = (await super.canActivate(context)) as boolean;
const request = context.switchToHttp().getRequest();
// await super.logIn(request);
this.logger.debug(
`canActivate success [request.user: ${JSON.stringify(request.user)}]`,
);
result = (await super.canActivate(context)) as boolean;
return result;
}
}

0 comments on commit 0e0a149

Please sign in to comment.