feat: create auth module sample
parent
64788600b2
commit
74319bddc2
|
@ -0,0 +1,10 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { AuthController } from './controllers/auth.controller';
|
||||
import { UserDataService } from './data/user.dataservice';
|
||||
import { AuthService } from './domain/services/auth.service';
|
||||
|
||||
@Module({
|
||||
providers: [AuthService, UserDataService],
|
||||
controllers: [AuthController],
|
||||
})
|
||||
export class AuthModule {}
|
|
@ -0,0 +1,3 @@
|
|||
export const JWT_SECRET =
|
||||
process.env.JWT_SECRET ?? 'B9A8Y92wZwbGBHOcUaHykeQ6mNNKeTFt';
|
||||
export const JWT_EXPIRED = process.env.JWT_EXPIRED ?? '12h';
|
|
@ -0,0 +1,32 @@
|
|||
import { Body, Controller, Get, Post } from '@nestjs/common';
|
||||
import { Unprotected } from 'src/core/guards';
|
||||
import { Pagination } from 'src/core/response';
|
||||
import { PaginationResponse } from 'src/core/response/domain/ok-response.interface';
|
||||
import { LoginRequest } from '../domain/entities/request.interface';
|
||||
import { User } from '../domain/entities/user.interface';
|
||||
import { AuthService } from '../domain/services/auth.service';
|
||||
|
||||
@Controller('auth')
|
||||
export class AuthController {
|
||||
constructor(private readonly service: AuthService) {}
|
||||
|
||||
@Unprotected()
|
||||
@Post()
|
||||
login(@Body() body: LoginRequest) {
|
||||
return this.service.createAccessToken(body);
|
||||
}
|
||||
|
||||
@Get()
|
||||
user() {
|
||||
return this.service.getUser();
|
||||
}
|
||||
|
||||
@Pagination()
|
||||
@Get('/all')
|
||||
async users(): Promise<PaginationResponse<User>> {
|
||||
return {
|
||||
data: await this.service.getUsers(),
|
||||
total: 101,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
import { LoginRequest } from '../domain/entities/request.interface';
|
||||
import { User } from '../domain/entities/user.interface';
|
||||
|
||||
const mockUsers: User[] = [
|
||||
{
|
||||
id: 1,
|
||||
name: 'John Doe',
|
||||
username: 'johndoe',
|
||||
password: 'password1',
|
||||
roles: ['admin'],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'Jane Doe',
|
||||
username: 'janedoe',
|
||||
password: 'password2',
|
||||
roles: ['user'],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'Jim Brown',
|
||||
username: 'jimbrown',
|
||||
password: 'password3',
|
||||
roles: ['user', 'admin'],
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: 'Jane Smith',
|
||||
username: 'janesmith',
|
||||
password: 'password4',
|
||||
roles: ['user'],
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: 'John Smith',
|
||||
username: 'johnsmith',
|
||||
password: 'password5',
|
||||
roles: ['admin'],
|
||||
},
|
||||
];
|
||||
|
||||
export class UserDataService {
|
||||
async login({ username, password }: LoginRequest): Promise<User | undefined> {
|
||||
const user = mockUsers.find((user) => {
|
||||
return user.username == username && user.password == password;
|
||||
});
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
async users(): Promise<User[]> {
|
||||
return mockUsers;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export interface LoginRequest {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
export interface User {
|
||||
id: number;
|
||||
name: string;
|
||||
username: string;
|
||||
password: string;
|
||||
roles: string[];
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { AuthService } from './auth.service';
|
||||
|
||||
describe('AuthService', () => {
|
||||
let service: AuthService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [AuthService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<AuthService>(AuthService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,37 @@
|
|||
import { Injectable, UnprocessableEntityException } from '@nestjs/common';
|
||||
import { SessionService, UserProvider, UsersSession } from 'src/core/sessions';
|
||||
import { UserDataService } from '../../data/user.dataservice';
|
||||
import { LoginRequest } from '../entities/request.interface';
|
||||
import { User } from '../entities/user.interface';
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
constructor(
|
||||
private readonly userDataService: UserDataService,
|
||||
private readonly session: SessionService,
|
||||
private readonly user: UserProvider,
|
||||
) {}
|
||||
async createAccessToken(payload: LoginRequest): Promise<string> {
|
||||
const user = await this.userDataService.login(payload);
|
||||
|
||||
if (!user)
|
||||
throw new UnprocessableEntityException(`Username or Password not match`);
|
||||
|
||||
const token = this.session.createAccessToken({
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
name: user.name,
|
||||
roles: user.roles,
|
||||
});
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
getUser(): UsersSession {
|
||||
return this.user.user;
|
||||
}
|
||||
|
||||
async getUsers(): Promise<User[]> {
|
||||
return this.userDataService.users();
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export * from './constants';
|
Loading…
Reference in New Issue