Skip to content

Commit

Permalink
feature: staff service
Browse files Browse the repository at this point in the history
resolves: #33
  • Loading branch information
alvinmarshall committed Oct 8, 2020
1 parent 4aca3f6 commit fb2794e
Show file tree
Hide file tree
Showing 48 changed files with 820 additions and 529 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"@nestjs/passport": "^7.1.0",
"@nestjs/platform-express": "^7.0.0",
"@nestjs/typeorm": "^7.1.0",
"bcryptjs": "^2.4.3",
"class-transformer": "^0.3.1",
"class-validator": "^0.12.2",
"date-fns": "^2.16.1",
Expand All @@ -52,6 +53,7 @@
"@nestjs/cli": "^7.0.0",
"@nestjs/schematics": "^7.0.0",
"@nestjs/testing": "^7.0.0",
"@types/bcryptjs": "^2.4.2",
"@types/express": "^4.17.3",
"@types/jest": "25.2.3",
"@types/node": "^13.9.1",
Expand Down
17 changes: 13 additions & 4 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,26 @@ import { AppService } from './app.service';
import { AuthModule } from './auth/auth.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TypeOrmConfig } from './libs';
import { StaffModule } from './staff/staff.module';
import { NoticeModule } from './module/notice/notice.module';
import { NoticeMessageModule } from './module/notice-message/notice-message.module';
import { FeesModule } from './module/fees/fees.module';
import { StudentModule } from './module/student/student.module';
import { StudentModule } from './module/student/student.module';
import { AttendanceModule } from './module/attendance/attendance.module';
import { StaffModule } from './module/staff/staff.module';


@Module({
imports: [AuthModule, TypeOrmModule.forRoot(TypeOrmConfig), StaffModule, NoticeModule, NoticeMessageModule, FeesModule,StudentModule, AttendanceModule],
imports: [
AuthModule,
TypeOrmModule.forRoot(TypeOrmConfig),
StaffModule,
NoticeModule,
NoticeMessageModule,
FeesModule,
StudentModule,
AttendanceModule
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
export class AppModule { }
2 changes: 1 addition & 1 deletion src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { PassportModule } from '@nestjs/passport';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { StaffRepository } from '../staff/staff.repository';
import { JwtPassportStrategy } from './jwt.passport.strategy';
import { AdminRepository } from '../admin/admin.repository';
import { TokenService } from './token/token.service';
import { TokenRepository } from './token/token.repository';
import { StudentRepository } from '../module/student/repository';
import { StaffRepository } from '../module/staff/repository';

@Module({
imports: [
Expand Down
21 changes: 13 additions & 8 deletions src/auth/auth.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { Test, TestingModule } from '@nestjs/testing';
import { AuthService } from './auth.service';
import { CredentialDto, UserEntity, LoginResponse } from './model/auth.model';
import { UnauthorizedException, BadRequestException } from '@nestjs/common';
import { StaffRepository } from '../staff/staff.repository';
import { AdminRepository } from '../admin/admin.repository';
import { TokenService } from './token/token.service';
import { RefreshTokenDto, TokenType } from './token/model/token.model';
import { AuthType } from '../libs';
import { StudentRepository } from '../module/student/repository';
import { StaffRepository } from '../module/staff/repository';

const mockRepository = () => ({
getStudentWithCredential: jest.fn(),
Expand All @@ -22,8 +22,8 @@ const mockTokenService = () => ({

describe('AuthService', () => {
let service: AuthService;
let studenRepository;
let staffRepository;
let studenRepository: StudentRepository;
let staffRepository: StaffRepository;
let adminRepository;
let tokenService;

Expand All @@ -34,13 +34,13 @@ describe('AuthService', () => {
};

const studentData = {
preStudentUsername: 'any_username',
esPreadmissionid: 1,
username: 'any_username',
id: 1,
};

const staffData = {
stUsername: 'any_username',
esStaffid: 1,
username: 'any_username',
id: 1,
};

const adminData = {
Expand All @@ -57,7 +57,7 @@ describe('AuthService', () => {
const loginPayload: LoginResponse = {
accessToken: 'any_token',
refreshToken: 'any_refresh',
tokenType:TokenType['Bearer']
tokenType: TokenType['Bearer']
};

const refreshTokenDto: RefreshTokenDto = {
Expand All @@ -84,6 +84,7 @@ describe('AuthService', () => {
tokenService.generateAccessToken.mockResolvedValue(loginPayload);
});


it('should throw an error as user type not found', () => {
const cred = Object.assign({}, credential);
cred.type = AuthType['unknown'];
Expand All @@ -98,6 +99,7 @@ describe('AuthService', () => {
studentPayload.type = AuthType.STUDENT;

it('should return access token for auth user', async () => {
//@ts-ignore
studenRepository.getStudentWithCredential.mockResolvedValue(mockData);

const result = await service.authenticate(studentCredential);
Expand All @@ -108,6 +110,7 @@ describe('AuthService', () => {
});

it('should throw unAuthorize error with invalid credentials', async () => {
//@ts-ignore
studenRepository.getStudentWithCredential.mockResolvedValue(null);
expect(service.authenticate(studentCredential)).rejects.toThrow(
UnauthorizedException,
Expand All @@ -123,6 +126,7 @@ describe('AuthService', () => {
staffPayload.type = AuthType.STAFF;

it('should return staff payload', async () => {
//@ts-ignore
staffRepository.getStaffWithCredential.mockResolvedValue(mockData);
const result = await service.authenticate(staffCredential);
expect(staffRepository.getStaffWithCredential).toHaveBeenCalledWith(
Expand All @@ -132,6 +136,7 @@ describe('AuthService', () => {
});

it('should throw unAuthorize error with invalid credentials', async () => {
//@ts-ignore
staffRepository.getStaffWithCredential.mockResolvedValue(null);
expect(service.authenticate(staffCredential)).rejects.toThrow(
UnauthorizedException,
Expand Down
15 changes: 8 additions & 7 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import {
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { CredentialDto, UserEntity, LoginResponse } from './model/auth.model';
import { StaffRepository } from '../staff/staff.repository';
import { AdminRepository } from '../admin/admin.repository';
import { TokenService } from './token/token.service';
import { RefreshTokenDto } from './token/model/token.model';
import { AuthType } from '../libs';
import { StudentRepository } from '../module/student/repository';
import { StaffRepository } from '../module/staff/repository';

/**
* Auth service
Expand All @@ -29,7 +29,7 @@ export class AuthService {
@InjectRepository(StaffRepository) private staffRepository: StaffRepository,
@InjectRepository(AdminRepository) private adminRepository: AdminRepository,
private tokenService: TokenService,
) {}
) { }

/**
* authenticate
Expand Down Expand Up @@ -92,7 +92,7 @@ export class AuthService {
credential,
);

if (!student) throw new UnauthorizedException('invalid credentials');
if (!student) throw new UnauthorizedException();

const payload: UserEntity = {
username: student.username,
Expand All @@ -113,12 +113,13 @@ export class AuthService {
const { type } = credential;
const staff = await this.staffRepository.getStaffWithCredential(credential);

if (!staff) throw new UnauthorizedException('invalid credentials');
if (!staff) throw new UnauthorizedException();

const payload: UserEntity = {
username: staff.stUsername,
id: staff.esStaffid,
username: staff.username,
id: staff.id,
type,
departmentId: staff.departmentId
};
return payload;
}
Expand All @@ -134,7 +135,7 @@ export class AuthService {
const { type } = credential;
const admin = await this.adminRepository.getAdminWithCredential(credential);

if (!admin) throw new UnauthorizedException('invalid credentials');
if (!admin) throw new UnauthorizedException();

const payload: UserEntity = {
username: admin.adminUsername,
Expand Down
26 changes: 13 additions & 13 deletions src/auth/jwt.passport.strategy.spec.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import { Test } from '@nestjs/testing';
import { JwtPassportStrategy } from './jwt.passport.strategy';
import { StaffRepository } from '../staff/staff.repository';
import { AdminRepository } from '../admin/admin.repository';
import { UserEntity } from './model/auth.model';
import { UnauthorizedException } from '@nestjs/common';
import { AuthType } from '../libs';
import { StudentRepository } from '../module/student/repository';
import { StaffRepository } from '../module/staff/repository';

const mockRepository = () => ({
getStudentById: jest.fn(),
getStaffWithPayload: jest.fn(),
getStaffById: jest.fn(),
getAdminWithPayload: jest.fn(),
});

const studentData = {
preStudentUsername: 'any_username',
esPreadmissionid: 1,
username: 'any_username',
id: 1,
};

const staffData = {
stUsername: 'any_username',
esStaffid: 1,
username: 'any_username',
id: 1,
};

const adminData = {
Expand All @@ -36,9 +36,9 @@ const payload: UserEntity = {
};
describe('JWtPassportStrategy', () => {
let jwtService: JwtPassportStrategy;
let studentRepository:StudentRepository;
let staffRepository;
let adminRepository;
let studentRepository: StudentRepository;
let staffRepository: StaffRepository
let adminRepository

beforeEach(async () => {
const module = await Test.createTestingModule({
Expand Down Expand Up @@ -77,15 +77,14 @@ describe('JWtPassportStrategy', () => {
const staffPayload = Object.assign({}, payload);
staffPayload.type = AuthType.STAFF;
const actual: UserEntity = staffPayload;

staffRepository.getStaffWithPayload.mockResolvedValue(staffData);
//@ts-ignore
staffRepository.getStaffById.mockResolvedValue(staffData);
const expected = await jwtService.validate(staffPayload);
expect(expected).toEqual(actual);
});

it('should get user entity with type admin', async () => {
const actual: UserEntity = payload;

adminRepository.getAdminWithPayload.mockResolvedValue(adminData);
const expected = await jwtService.validate(payload);
expect(expected).toEqual(actual);
Expand All @@ -112,7 +111,8 @@ describe('JWtPassportStrategy', () => {
it('should throw an error if staff is not found', async () => {
const staffPayload = Object.assign({}, payload);
staffPayload.type = AuthType.STAFF;
staffRepository.getStaffWithPayload.mockResolvedValue(null);
//@ts-ignore
staffRepository.getStaffById.mockResolvedValue(null);
expect(jwtService.validate(staffPayload)).rejects.toThrow(
UnauthorizedException,
);
Expand Down
5 changes: 3 additions & 2 deletions src/auth/jwt.passport.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { UserEntity } from './model/auth.model';
import { InjectRepository } from '@nestjs/typeorm';
import { StaffRepository } from '../staff/staff.repository';
import { AdminRepository } from '../admin/admin.repository';
import { UnauthorizedException, Injectable } from '@nestjs/common';
import { AuthType } from '../libs';
import { StudentRepository } from '../module/student/repository';
import { StaffRepository } from '../module/staff/repository';

@Injectable()
export class JwtPassportStrategy extends PassportStrategy(Strategy) {
Expand Down Expand Up @@ -34,14 +34,15 @@ export class JwtPassportStrategy extends PassportStrategy(Strategy) {
if (payload.type === AuthType.STUDENT) return this.getStudent(payload);
throw new Error(`type: '${payload.type}' not implemented`);
}

private async getAdmin(user: UserEntity) {
const admin = await this.adminRepository.getAdminWithPayload(user);
if (!admin) return null;
return user;
}

private async getStaff(user: UserEntity): Promise<UserEntity> {
const staff = await this.staffRepository.getStaffWithPayload(user);
const staff = await this.staffRepository.getStaffById(user.id);
if (!staff) return null;
return user;
}
Expand Down
5 changes: 3 additions & 2 deletions src/auth/model/auth.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { AuthType } from '../../libs';
export class CredentialDto {
@IsString()
username: string;

@IsString()
password: string;

Expand All @@ -21,7 +21,8 @@ export class UserEntity {
id: number;
username: string;
type: AuthType;
school?:number
school?: number;
departmentId?: number;
}

/**
Expand Down
Loading

0 comments on commit fb2794e

Please sign in to comment.