Skip to content

Commit

Permalink
Merge pull request #506 from project-violet/discrod-auth
Browse files Browse the repository at this point in the history
Discord oauth2 login
  • Loading branch information
violet-dev authored Sep 8, 2024
2 parents 2a7aa41 + 1d39f6a commit 691e1ce
Show file tree
Hide file tree
Showing 13 changed files with 258 additions and 7 deletions.
117 changes: 117 additions & 0 deletions violet-server/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions violet-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"joi": "^17.11.0",
"mysql2": "^3.11.0",
"nest-winston": "^1.9.4",
"passport-discord": "^0.1.4",
"passport-jwt": "^4.0.1",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.1",
Expand Down
18 changes: 18 additions & 0 deletions violet-server/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { Request, Response } from 'express';
import { ResLoginUser } from './dtos/res-login-user.dto';
import { plainToClass } from 'class-transformer';
import { HmacAuthGuard } from './guards/hmac.guard';
import { DiscordAuthGuard } from './guards/discord.guard';

@ApiTags('auth')
@Controller('auth')
Expand Down Expand Up @@ -104,4 +105,21 @@ export class AuthController {
res.clearCookie('refresh-expires');
res.send();
}

@Get('discord')
@Post('discord')
@UseGuards(DiscordAuthGuard)
@ApiOperation({ summary: 'Login From Discord' })
logInDiscord() {
return { ok: true };
}

@Get('discord/redirect')
@UseGuards(DiscordAuthGuard)
@UseGuards(AccessTokenGuard)
@ApiOperation({ summary: 'Redirect discord oauth2' })
@Redirect('violet://discord-login')
async redirect(@CurrentUser() currentUser: User) {
return await this.authService.updateDiscordInfo(currentUser);
}
}
2 changes: 2 additions & 0 deletions violet-server/src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { AccessTokenStrategy } from './jwt/access-token.strategy';
import { RefreshTokenStrategy } from './jwt/refresh-token.strategy';
import { UserModule } from 'src/user/user.module';
import { JwtModule } from '@nestjs/jwt';
import { DiscordStrategy } from './discord/discord.strategy';

@Module({
imports: [JwtModule.register({}), UserModule],
Expand All @@ -14,6 +15,7 @@ import { JwtModule } from '@nestjs/jwt';
UserRepository,
AccessTokenStrategy,
RefreshTokenStrategy,
DiscordStrategy,
],
controllers: [AuthController],
})
Expand Down
23 changes: 22 additions & 1 deletion violet-server/src/auth/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { BadRequestException, HttpException, Injectable } from '@nestjs/common';
import {
BadRequestException,
HttpException,
Injectable,
Logger,
} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
import { UserRegisterDTO } from 'src/user/dtos/user-register.dto';
import { UserRepository } from 'src/user/user.repository';
import { ResLoginUser } from './dtos/res-login-user.dto';
import { Tokens } from './jwt/jwt.token';
import { User } from 'src/user/entity/user.entity';

@Injectable()
export class AuthService {
Expand Down Expand Up @@ -95,4 +101,19 @@ export class AuthService {
async deleteRefreshToken(userAppId: string) {
await this.userRepository.update({ userAppId }, { refreshToken: null });
}

async updateDiscordInfo(
user: User,
): Promise<{ ok: boolean; error?: string }> {
try {
const { userAppId, discordId, avatar } = user;
await this.userRepository.update({ userAppId }, { discordId, avatar });

return { ok: true };
} catch (e) {
Logger.error(e);

return { ok: false, error: e };
}
}
}
28 changes: 28 additions & 0 deletions violet-server/src/auth/discord/discord.strategy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { Profile, Strategy } from 'passport-discord';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';

@Injectable()
export class DiscordStrategy extends PassportStrategy(Strategy, 'discord') {
constructor(private readonly configService: ConfigService) {
super({
clientID: configService.get<string>('DISCORD_CLIENT_ID'),
clientSecret: configService.get<string>('DISCORD_CLIENT_SECRET'),
callbackURL: 'http://localhost:3000/api/v2/auth/discord/redirect',
scope: ['identify'],
});
}

async validate(accessToken: string, refreshToken: string, profile: Profile) {
try {
const { id: discordId, avatar } = profile;
return {
discordId: discordId,
avatar: avatar,
};
} catch (error) {
throw new UnauthorizedException(error);
}
}
}
26 changes: 26 additions & 0 deletions violet-server/src/auth/guards/discord.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {
ExecutionContext,
Injectable,
UnauthorizedException,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class DiscordAuthGuard extends AuthGuard('discord') {
constructor() {
super({
property: 'discord',
});
}

async canActivate(context: ExecutionContext) {
return (await super.canActivate(context)) as boolean;
}

handleRequest(err: any, user: any) {
if (err || !user) {
throw err || new UnauthorizedException('Retry login');
}
return user;
}
}
1 change: 0 additions & 1 deletion violet-server/src/auth/jwt/access-token.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export class AccessTokenStrategy extends PassportStrategy(

async validate(req: Request, payload: JwtPayload) {
try {
console.log('validate');
const user = await this.userRepository.findOneBy({
userAppId: payload.userAppId,
});
Expand Down
1 change: 1 addition & 0 deletions violet-server/src/auth/jwt/jwt.payload.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export class JwtPayload {
userAppId: string;
discordId?: string;
id: string;
refreshToken?: string;
}
Loading

0 comments on commit 691e1ce

Please sign in to comment.