auth
This commit is contained in:
26
api/src/modules/auth/auth.controller.ts
Normal file
26
api/src/modules/auth/auth.controller.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
26
api/src/modules/auth/auth.module.ts
Normal file
26
api/src/modules/auth/auth.module.ts
Normal 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 {}
|
||||
106
api/src/modules/auth/auth.service.ts
Normal file
106
api/src/modules/auth/auth.service.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user