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