This commit is contained in:
Bastian Wagner
2024-09-12 21:33:11 +02:00
parent 6abfdcb632
commit c00aad559d
36 changed files with 1118 additions and 397 deletions

View File

@@ -0,0 +1,26 @@
import {
Body,
Controller,
HttpException,
HttpStatus,
Post,
} from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthCodeDto } from 'src/model/dto';
import { User } from 'src/model/entitites';
@Controller('auth')
export class AuthController {
constructor(private authService: AuthService) {}
@Post('auth-code')
async registerOrLoginWithAuthCode(
@Body() authDto: AuthCodeDto,
): Promise<User> {
const user = await this.authService.registerOrLoginWithAuthCode(authDto);
if (user == null) {
throw new HttpException('forbidden', HttpStatus.FORBIDDEN);
}
return user;
}
}

View File

@@ -0,0 +1,26 @@
import { Module } from '@nestjs/common';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { DatabaseModule } from 'src/shared/database/database.module';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { HttpModule } from '@nestjs/axios';
import { JwtModule } from '@nestjs/jwt';
@Module({
controllers: [AuthController],
providers: [AuthService],
imports: [
DatabaseModule,
ConfigModule,
HttpModule,
JwtModule.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (config: ConfigService) => ({
secret: config.get('JWT_SECRET'),
signOptions: { expiresIn: config.get('JWT_EXPIRES_IN') },
}),
}),
],
})
export class AuthModule {}

View File

@@ -0,0 +1,106 @@
import { Injectable } from '@nestjs/common';
import { AuthCodeDto } from 'src/model/dto';
import { CreateUserDto } from 'src/model/dto/create-user.dto';
import { UserRepository } from 'src/model/repositories';
import { HttpService } from '@nestjs/axios';
import { ConfigService } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
import { IExternalAccessPayload, IPayload } from 'src/model/interface';
import { User } from 'src/model/entitites';
@Injectable()
export class AuthService {
constructor(
private userRepo: UserRepository,
private readonly http: HttpService,
private configService: ConfigService,
private jwt: JwtService,
) {}
register(register: CreateUserDto) {
return this.userRepo.createUser(register);
}
async registerOrLoginWithAuthCode(auth: AuthCodeDto): Promise<User> {
console.log(auth);
const body = this.createAuthCodeFormData(auth.code, 'authorization_code');
const url = this.configService.get('SSO_TOKEN_URL');
return new Promise<User>((resolve) => {
this.http.post(url, body).subscribe({
next: async (response) => {
const user = await this.saveExternalTokens(response.data as any);
this.generateTokens(user);
resolve(user);
},
error: () => {
resolve(null);
},
});
});
}
private async saveExternalTokens({
access_token,
refresh_token,
}: {
access_token: string;
refresh_token: string;
}): Promise<User> {
console.log(access_token, refresh_token);
const payload: IExternalAccessPayload = this.jwt.decode(access_token);
return new Promise<User>(async (resolve) => {
let user = await this.userRepo.findByUsername(payload.username);
if (!user) {
user = await this.userRepo.createUser({
username: payload.username,
externalId: payload.id,
});
}
user.firstName = payload.firstName;
user.lastName = payload.lastName;
user.external.accessToken = access_token;
user.external.refreshToken = refresh_token;
await this.userRepo.save(user);
resolve(user);
});
}
private generateTokens(user: User) {
const payload: IPayload = {
username: user.username,
id: user.id,
type: 'access',
};
const token = this.jwt.sign(payload);
user.accessToken = token;
const rPay: IPayload = {
username: user.username,
id: user.id,
type: 'refresh',
};
user.refreshToken = this.jwt.sign(rPay);
}
private createAuthCodeFormData(
code: string,
grant_type = 'authorization_code',
): FormData {
const bodyFormData = new FormData();
bodyFormData.append('client_id', this.configService.get('SSO_CLIENT_ID'));
bodyFormData.append(
'client_secret',
this.configService.get('SSO_CLIENT_SECRET'),
);
bodyFormData.append('code', code);
bodyFormData.append('grant_type', grant_type);
bodyFormData.append(
'redirect_uri',
this.configService.get('SSO_REDIRECT_URI'),
);
return bodyFormData;
}
}