convert project from microservices to rest apis

This commit is contained in:
faris Aljohari
2024-03-10 12:49:51 +03:00
parent b3179a5c1f
commit c5537b3230
72 changed files with 155 additions and 384 deletions

View File

@ -1,22 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
describe('AuthController', () => {
let authController: AuthController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AuthController],
providers: [AuthService],
}).compile();
authController = app.get<AuthController>(AuthController);
});
describe('root', () => {
it('should return "Hello World!"', () => {
expect(authController.getHello()).toBe('Hello World!');
});
});
});

View File

@ -1,12 +0,0 @@
import { Controller, Get } from '@nestjs/common';
import { AuthService } from './auth.service';
@Controller()
export class AuthController {
constructor(private readonly authService: AuthService) {}
@Get()
getHello(): string {
return this.authService.getHello();
}
}

View File

@ -1,18 +0,0 @@
import { Module } from '@nestjs/common';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { ConfigModule } from '@nestjs/config';
import config from './config';
import { AuthenticationModule } from './modules/authentication/authentication.module';
import { AuthenticationController } from './modules/authentication/controllers/authentication.controller';
@Module({
imports: [
ConfigModule.forRoot({
load: config,
}),
AuthenticationModule,
],
controllers: [AuthController,AuthenticationController],
providers: [AuthService],
})
export class AuthModule {}

View File

@ -1,8 +0,0 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class AuthService {
getHello(): string {
return 'Hello World!';
}
}

View File

@ -1,4 +0,0 @@
import AuthConfig from './auth.config';
import AppConfig from './app.config'
export default [AuthConfig,AppConfig];

View File

@ -1,11 +0,0 @@
import { registerAs } from '@nestjs/config';
export default registerAs(
'jwt',
(): Record<string, any> => ({
secret: process.env.JWT_SECRET,
expire_time: process.env.JWT_EXPIRE_TIME,
secret_refresh: process.env.JWT_SECRET_REFRESH,
expire_refresh: process.env.JWT_EXPIRE_TIME_REFRESH,
})
);

View File

@ -1,4 +0,0 @@
export * from './user-auth.dto'
export * from './user-login.dto'
export * from './user-otp.dto'
export * from './user-password.dto'

View File

@ -1,24 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AuthModule } from './../src/auth.module';
describe('AuthController (e2e)', () => {
let app: INestApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AuthModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('/ (GET)', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
});

View File

@ -1,9 +0,0 @@
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": ".",
"testEnvironment": "node",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
}

View File

@ -1,9 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"declaration": false,
"outDir": "../../dist/apps/auth"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
}

View File

@ -1,12 +0,0 @@
import { Controller, Get } from '@nestjs/common';
import { AppService } from './backend.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get('healthcheck')
getHello(): string {
return this.appService.healthcheck();
}
}

View File

@ -1,20 +0,0 @@
import { Module } from '@nestjs/common';
import { AppController } from './backend.controller';
import { AppService } from './backend.service';
import { UserModule } from './modules/user/user.module';
import { ConfigModule } from '@nestjs/config';
import config from './config';
import { CommonModule } from '@app/common';
@Module({
imports: [
ConfigModule.forRoot({
load: config,
}),
UserModule,
CommonModule,
],
controllers: [AppController],
providers: [AppService],
})
export class BackendModule {}

View File

@ -1,8 +0,0 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
healthcheck(): string {
return 'Healthcheck!';
}
}

View File

@ -1,9 +0,0 @@
export default () => ({
DB_HOST: process.env.AZURE_POSTGRESQL_HOST,
DB_PORT: process.env.AZURE_POSTGRESQL_PORT,
DB_USER: process.env.AZURE_POSTGRESQL_USER,
DB_PASSWORD: process.env.AZURE_POSTGRESQL_PASSWORD,
DB_NAME: process.env.AZURE_POSTGRESQL_DATABASE,
DB_SYNC: process.env.AZURE_POSTGRESQL_SYNC,
DB_SSL: process.env.AZURE_POSTGRESQL_SSL,
});

View File

@ -1,10 +0,0 @@
import { registerAs } from '@nestjs/config';
export default registerAs(
'auth-config',
(): Record<string, any> => ({
//DEVICE_ID: process.env.DEVICE_ID,
ACCESS_KEY: process.env.ACCESS_KEY,
SECRET_KEY: process.env.SECRET_KEY,
}),
);

View File

@ -1,4 +0,0 @@
import AuthConfig from './auth.config';
import AppConfig from './app.config'
import JwtConfig from './jwt.config'
export default [AuthConfig,AppConfig,JwtConfig];

View File

@ -1,36 +0,0 @@
import { NestFactory } from '@nestjs/core';
import { BackendModule } from './backend.module';
import rateLimit from 'express-rate-limit';
import helmet from 'helmet';
import { ValidationPipe } from '@nestjs/common';
async function bootstrap() {
const app = await NestFactory.create(BackendModule);
// Enable 'trust proxy' setting
app.use((req, res, next) => {
app.getHttpAdapter().getInstance().set('trust proxy', 1);
next();
});
app.enableCors();
app.use(
rateLimit({
windowMs: 5 * 60 * 1000, // 5 minutes
max: 500, // limit each IP to 500 requests per windowMs
}),
);
app.use(
helmet({
contentSecurityPolicy: false,
}),
);
app.useGlobalPipes(new ValidationPipe());
await app.listen(4000);
}
console.log('Starting backend at port 7000...');
bootstrap();

View File

@ -1 +0,0 @@
export * from './user.controller'

View File

@ -1 +0,0 @@
export * from './user.list.dto'

View File

@ -1 +0,0 @@
export * from './user.service'

View File

@ -1,9 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"declaration": false,
"outDir": "../../dist/apps/backend"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
}

View File

@ -22,7 +22,7 @@ import { UserRepository } from '../modules/user/repositories';
}), }),
HelperModule, HelperModule,
], ],
providers: [JwtStrategy, UserSessionRepository,AuthService,UserRepository], providers: [JwtStrategy, UserSessionRepository, AuthService, UserRepository],
exports: [AuthService], exports: [AuthService],
}) })
export class AuthModule {} export class AuthModule {}

View File

@ -1,9 +1,9 @@
import { BadRequestException, Injectable } from '@nestjs/common'; import { BadRequestException, Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt'; import { JwtService } from '@nestjs/jwt';
import { HelperHashService } from '../../helper/services'; import { HelperHashService } from '../../helper/services';
import { UserRepository } from '@app/common/modules/user/repositories'; import { UserRepository } from '../../../../common/src/modules/user/repositories';
import { UserSessionRepository } from '@app/common/modules/session/repositories/session.repository'; import { UserSessionRepository } from '../../../../common/src/modules/session/repositories/session.repository';
import { UserSessionEntity } from '@app/common/modules/session/entities'; import { UserSessionEntity } from '../../../../common/src/modules/session/entities';
@Injectable() @Injectable()
export class AuthService { export class AuthService {

View File

@ -2,7 +2,7 @@ import { ConfigService } from '@nestjs/config';
import { ExtractJwt, Strategy } from 'passport-jwt'; import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport'; import { PassportStrategy } from '@nestjs/passport';
import { BadRequestException, Injectable } from '@nestjs/common'; import { BadRequestException, Injectable } from '@nestjs/common';
import { UserSessionRepository } from '@app/common/modules/session/repositories/session.repository'; import { UserSessionRepository } from '../../../src/modules/session/repositories/session.repository';
import { AuthInterface } from '../interfaces/auth.interface'; import { AuthInterface } from '../interfaces/auth.interface';
@Injectable() @Injectable()

View File

@ -8,8 +8,8 @@ import config from './config';
import { EmailService } from './util/email.service'; import { EmailService } from './util/email.service';
@Module({ @Module({
providers: [CommonService,EmailService], providers: [CommonService, EmailService],
exports: [CommonService, HelperModule, AuthModule,EmailService], exports: [CommonService, HelperModule, AuthModule, EmailService],
imports: [ imports: [
ConfigModule.forRoot({ ConfigModule.forRoot({
load: config, load: config,

View File

@ -5,7 +5,7 @@ export default registerAs(
(): Record<string, any> => ({ (): Record<string, any> => ({
SMTP_HOST: process.env.SMTP_HOST, SMTP_HOST: process.env.SMTP_HOST,
SMTP_PORT: parseInt(process.env.SMTP_PORT), SMTP_PORT: parseInt(process.env.SMTP_PORT),
SMTP_SECURE: process.env.SMTP_SECURE === 'true', SMTP_SECURE: process.env.SMTP_SECURE === 'true',
SMTP_USER: process.env.SMTP_USER, SMTP_USER: process.env.SMTP_USER,
SMTP_PASSWORD: process.env.SMTP_PASSWORD, SMTP_PASSWORD: process.env.SMTP_PASSWORD,
}), }),

View File

@ -19,7 +19,7 @@ import { UserOtpEntity } from '../modules/user-otp/entities';
username: configService.get('DB_USER'), username: configService.get('DB_USER'),
password: configService.get('DB_PASSWORD'), password: configService.get('DB_PASSWORD'),
database: configService.get('DB_NAME'), database: configService.get('DB_NAME'),
entities: [UserEntity, UserSessionEntity,UserOtpEntity], entities: [UserEntity, UserSessionEntity, UserOtpEntity],
namingStrategy: new SnakeNamingStrategy(), namingStrategy: new SnakeNamingStrategy(),
synchronize: Boolean(JSON.parse(configService.get('DB_SYNC'))), synchronize: Boolean(JSON.parse(configService.get('DB_SYNC'))),
logging: true, logging: true,
@ -32,7 +32,6 @@ import { UserOtpEntity } from '../modules/user-otp/entities';
}, },
continuationLocalStorage: true, continuationLocalStorage: true,
ssl: Boolean(JSON.parse(configService.get('DB_SSL'))), ssl: Boolean(JSON.parse(configService.get('DB_SSL'))),
}), }),
}), }),
], ],

View File

@ -32,7 +32,6 @@ export class SnakeNamingStrategy
firstTableName: string, firstTableName: string,
secondTableName: string, secondTableName: string,
firstPropertyName: any, firstPropertyName: any,
_secondPropertyName: string,
): string { ): string {
return snakeCase( return snakeCase(
firstTableName + firstTableName +

View File

@ -2,7 +2,7 @@ import { UnauthorizedException } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport'; import { AuthGuard } from '@nestjs/passport';
export class JwtAuthGuard extends AuthGuard('jwt') { export class JwtAuthGuard extends AuthGuard('jwt') {
handleRequest(err, user, info) { handleRequest(err, user) {
if (err || !user) { if (err || !user) {
throw err || new UnauthorizedException(); throw err || new UnauthorizedException();
} }

View File

@ -1 +1 @@
export * from './helper.hash.service' export * from './helper.hash.service';

View File

@ -1 +1 @@
export * from './abstract.dto' export * from './abstract.dto';

View File

@ -8,11 +8,11 @@ import {
} from 'typeorm'; } from 'typeorm';
import { AbstractDto } from '../dtos'; import { AbstractDto } from '../dtos';
import { Constructor } from '@app/common/util/types'; import { Constructor } from '../../../../../common/src/util/types';
export abstract class AbstractEntity< export abstract class AbstractEntity<
T extends AbstractDto = AbstractDto, T extends AbstractDto = AbstractDto,
O = never O = never,
> { > {
@PrimaryGeneratedColumn('increment') @PrimaryGeneratedColumn('increment')
@Exclude() @Exclude()
@ -38,7 +38,7 @@ export abstract class AbstractEntity<
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!dtoClass) { if (!dtoClass) {
throw new Error( throw new Error(
`You need to use @UseDto on class (${this.constructor.name}) be able to call toDto function` `You need to use @UseDto on class (${this.constructor.name}) be able to call toDto function`,
); );
} }

View File

@ -22,5 +22,4 @@ export class SessionDto {
@IsBoolean() @IsBoolean()
@IsNotEmpty() @IsNotEmpty()
public isLoggedOut: boolean; public isLoggedOut: boolean;
} }

View File

@ -1 +1 @@
export * from './session.entity' export * from './session.entity';

View File

@ -5,7 +5,7 @@ import { SessionDto } from '../dtos/session.dto';
@Entity({ name: 'userSession' }) @Entity({ name: 'userSession' })
export class UserSessionEntity extends AbstractEntity<SessionDto> { export class UserSessionEntity extends AbstractEntity<SessionDto> {
@Column({ @Column({
type: 'uuid', type: 'uuid',
default: () => 'gen_random_uuid()', default: () => 'gen_random_uuid()',
nullable: false, nullable: false,
}) })

View File

@ -1 +1 @@
export * from './user-otp.dto' export * from './user-otp.dto';

View File

@ -4,7 +4,7 @@ export class UserOtpDto {
@IsString() @IsString()
@IsNotEmpty() @IsNotEmpty()
public uuid: string; public uuid: string;
@IsString() @IsString()
@IsNotEmpty() @IsNotEmpty()
public email: string; public email: string;

View File

@ -1 +1 @@
export * from './user-otp.entity' export * from './user-otp.entity';

View File

@ -1,13 +1,13 @@
import { Column, Entity } from 'typeorm'; import { Column, Entity } from 'typeorm';
import { AbstractEntity } from '../../abstract/entities/abstract.entity'; import { AbstractEntity } from '../../abstract/entities/abstract.entity';
import { UserOtpDto } from '../dtos'; import { UserOtpDto } from '../dtos';
import { OtpType } from '@app/common/constants/otp-type.enum'; import { OtpType } from '../../../../src/constants/otp-type.enum';
@Entity({ name: 'user-otp' }) @Entity({ name: 'user-otp' })
export class UserOtpEntity extends AbstractEntity<UserOtpDto> { export class UserOtpEntity extends AbstractEntity<UserOtpDto> {
@Column({ @Column({
type: 'uuid', type: 'uuid',
default: () => 'gen_random_uuid()', default: () => 'gen_random_uuid()',
nullable: false, nullable: false,
}) })
public uuid: string; public uuid: string;

View File

@ -5,7 +5,7 @@ import { AbstractEntity } from '../../abstract/entities/abstract.entity';
@Entity({ name: 'user' }) @Entity({ name: 'user' })
export class UserEntity extends AbstractEntity<UserDto> { export class UserEntity extends AbstractEntity<UserDto> {
@Column({ @Column({
type: 'uuid', type: 'uuid',
default: () => 'gen_random_uuid()', // Use gen_random_uuid() for default value default: () => 'gen_random_uuid()', // Use gen_random_uuid() for default value
nullable: false, nullable: false,
}) })

View File

@ -1,4 +1,4 @@
import { SetMetadata } from '@nestjs/common'; import { SetMetadata } from '@nestjs/common';
export const ResponseMessage = (message: string) => export const ResponseMessage = (message: string) =>
SetMetadata('response_message', message); SetMetadata('response_message', message);

View File

@ -1,5 +1,5 @@
export interface Response<T> { export interface Response<T> {
statusCode: number; statusCode: number;
message: string; message: string;
data?: T; data?: T;
} }

View File

@ -1,46 +1,45 @@
export type Constructor<T, Arguments extends unknown[] = undefined[]> = new ( export type Constructor<T, Arguments extends unknown[] = undefined[]> = new (
...arguments_: Arguments ...arguments_: Arguments
) => T; ) => T;
export type Plain<T> = T; export type Plain<T> = T;
export type Optional<T> = T | undefined; export type Optional<T> = T | undefined;
export type Nullable<T> = T | null; export type Nullable<T> = T | null;
export type PathImpl<T, Key extends keyof T> = Key extends string export type PathImpl<T, Key extends keyof T> = Key extends string
? T[Key] extends Record<string, any> ? T[Key] extends Record<string, any>
? ?
| `${Key}.${PathImpl<T[Key], Exclude<keyof T[Key], keyof any[]>> & | `${Key}.${PathImpl<T[Key], Exclude<keyof T[Key], keyof any[]>> &
string}` string}`
| `${Key}.${Exclude<keyof T[Key], keyof any[]> & string}` | `${Key}.${Exclude<keyof T[Key], keyof any[]> & string}`
: never
: never;
export type PathImpl2<T> = PathImpl<T, keyof T> | keyof T;
export type Path<T> = keyof T extends string
? PathImpl2<T> extends string | keyof T
? PathImpl2<T>
: keyof T
: never;
export type PathValue<
T,
P extends Path<T>,
> = P extends `${infer Key}.${infer Rest}`
? Key extends keyof T
? Rest extends Path<T[Key]>
? PathValue<T[Key], Rest>
: never : never
: never; : never
: P extends keyof T
export type PathImpl2<T> = PathImpl<T, keyof T> | keyof T;
export type Path<T> = keyof T extends string
? PathImpl2<T> extends string | keyof T
? PathImpl2<T>
: keyof T
: never;
export type PathValue<
T,
P extends Path<T>
> = P extends `${infer Key}.${infer Rest}`
? Key extends keyof T
? Rest extends Path<T[Key]>
? PathValue<T[Key], Rest>
: never
: never
: P extends keyof T
? T[P] ? T[P]
: never; : never;
export type KeyOfType<Entity, U> = { export type KeyOfType<Entity, U> = {
[P in keyof Required<Entity>]: Required<Entity>[P] extends U [P in keyof Required<Entity>]: Required<Entity>[P] extends U
? P ? P
: Required<Entity>[P] extends U[] : Required<Entity>[P] extends U[]
? P ? P
: never; : never;
}[keyof Entity]; }[keyof Entity];

View File

@ -3,7 +3,7 @@ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
export function setupSwaggerAuthentication(app: INestApplication): void { export function setupSwaggerAuthentication(app: INestApplication): void {
const options = new DocumentBuilder() const options = new DocumentBuilder()
.setTitle('Authentication-Service') .setTitle('APIs Documentation')
.addBearerAuth({ .addBearerAuth({
type: 'http', type: 'http',
scheme: 'bearer', scheme: 'bearer',
@ -13,7 +13,7 @@ export function setupSwaggerAuthentication(app: INestApplication): void {
.build(); .build();
const document = SwaggerModule.createDocument(app, options); const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup('api/authentication/documentation', app, document, { SwaggerModule.setup('api', app, document, {
swaggerOptions: { swaggerOptions: {
persistAuthorization: true, persistAuthorization: true,
}, },

View File

@ -1,41 +1,19 @@
{ {
"$schema": "https://json.schemastore.org/nest-cli", "$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics", "collection": "@nestjs/schematics",
"sourceRoot": "apps/backend/src", "sourceRoot": "src",
"compilerOptions": { "compilerOptions": {
"deleteOutDir": true, "deleteOutDir": true,
"webpack": true, "webpack": true,
"tsConfigPath": "apps/backend/tsconfig.app.json" "tsConfigPath": "tsconfig.build.json"
}, },
"monorepo": true, "common": {
"root": "apps/backend", "type": "library",
"projects": { "root": "libs/common",
"backend": { "entryFile": "index",
"type": "application", "sourceRoot": "libs/common/src",
"root": "apps/backend", "compilerOptions": {
"entryFile": "main", "tsConfigPath": "libs/common/tsconfig.lib.json"
"sourceRoot": "apps/backend/src",
"compilerOptions": {
"tsConfigPath": "apps/backend/tsconfig.app.json"
}
},
"auth": {
"type": "application",
"root": "apps/auth",
"entryFile": "main",
"sourceRoot": "apps/auth/src",
"compilerOptions": {
"tsConfigPath": "apps/auth/tsconfig.app.json"
}
},
"common": {
"type": "library",
"root": "libs/common",
"entryFile": "index",
"sourceRoot": "libs/common/src",
"compilerOptions": {
"tsConfigPath": "libs/common/tsconfig.lib.json"
}
} }
} }
} }

View File

@ -10,19 +10,14 @@
"format": "prettier --write \"apps/**/*.ts\" \"libs/**/*.ts\"", "format": "prettier --write \"apps/**/*.ts\" \"libs/**/*.ts\"",
"start": "npx nest start", "start": "npx nest start",
"start:dev": "npx nest start --watch", "start:dev": "npx nest start --watch",
"backend:dev": "npx nest start backend --watch",
"auth:dev": "npx nest start auth --watch",
"start:debug": "npx nest start --debug --watch", "start:debug": "npx nest start --debug --watch",
"start:prod": "node dist/apps/backend/main", "start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest", "test": "jest",
"test:watch": "jest --watch", "test:watch": "jest --watch",
"test:cov": "jest --coverage", "test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./apps/backend/test/jest-e2e.json", "test:e2e": "jest --config ./apps/backend/test/jest-e2e.json"
"start:auth": "npx nest start auth",
"start:backend": "npx nest start backend",
"start:all": "concurrently \"npm run start:auth\" \"npm run start:backend\""
}, },
"dependencies": { "dependencies": {
"@nestjs/common": "^10.0.0", "@nestjs/common": "^10.0.0",

17
src/app.module.ts Normal file
View File

@ -0,0 +1,17 @@
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import config from './config';
import { AuthenticationModule } from './auth/auth.module';
import { AuthenticationController } from './auth/controllers/authentication.controller';
import { UserModule } from './users/user.module';
@Module({
imports: [
ConfigModule.forRoot({
load: config,
}),
AuthenticationModule,
UserModule,
],
controllers: [AuthenticationController],
})
export class AuthModule {}

View File

@ -2,13 +2,13 @@ import { Module } from '@nestjs/common';
import { AuthenticationController } from './controllers/authentication.controller'; import { AuthenticationController } from './controllers/authentication.controller';
import { AuthenticationService } from './services/authentication.service'; import { AuthenticationService } from './services/authentication.service';
import { ConfigModule } from '@nestjs/config'; import { ConfigModule } from '@nestjs/config';
import { UserRepositoryModule } from '@app/common/modules/user/user.repository.module'; import { UserRepositoryModule } from '../../libs/common/src/modules/user/user.repository.module';
import { CommonModule } from '@app/common'; import { CommonModule } from '../../libs/common/src';
import { UserAuthController } from './controllers'; import { UserAuthController } from './controllers';
import { UserAuthService } from './services'; import { UserAuthService } from './services';
import { UserRepository } from '@app/common/modules/user/repositories'; import { UserRepository } from '../../libs/common/src/modules/user/repositories';
import { UserSessionRepository } from '@app/common/modules/session/repositories/session.repository'; import { UserSessionRepository } from '../../libs/common/src/modules/session/repositories/session.repository';
import { UserOtpRepository } from '@app/common/modules/user-otp/repositories/user-otp.repository'; import { UserOtpRepository } from '../../libs/common/src/modules/user-otp/repositories/user-otp.repository';
@Module({ @Module({
imports: [ConfigModule, UserRepositoryModule, CommonModule], imports: [ConfigModule, UserRepositoryModule, CommonModule],

View File

@ -10,9 +10,9 @@ import {
import { UserAuthService } from '../services/user-auth.service'; import { UserAuthService } from '../services/user-auth.service';
import { UserSignUpDto } from '../dtos/user-auth.dto'; import { UserSignUpDto } from '../dtos/user-auth.dto';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { ResponseMessage } from '@app/common/response/response.decorator'; import { ResponseMessage } from '../../../libs/common/src/response/response.decorator';
import { UserLoginDto } from '../dtos/user-login.dto'; import { UserLoginDto } from '../dtos/user-login.dto';
import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard'; import { JwtAuthGuard } from '../../../libs/common/src/guards/jwt.auth.guard';
import { ForgetPasswordDto, UserOtpDto, VerifyOtpDto } from '../dtos'; import { ForgetPasswordDto, UserOtpDto, VerifyOtpDto } from '../dtos';
@Controller({ @Controller({

4
src/auth/dtos/index.ts Normal file
View File

@ -0,0 +1,4 @@
export * from './user-auth.dto';
export * from './user-login.dto';
export * from './user-otp.dto';
export * from './user-password.dto';

View File

@ -3,32 +3,32 @@ import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
export class UserSignUpDto { export class UserSignUpDto {
@ApiProperty({ @ApiProperty({
description:'email', description: 'email',
required:true required: true,
}) })
@IsEmail() @IsEmail()
@IsNotEmpty() @IsNotEmpty()
public email: string; public email: string;
@ApiProperty({ @ApiProperty({
description:'password', description: 'password',
required:true required: true,
}) })
@IsString() @IsString()
@IsNotEmpty() @IsNotEmpty()
public password: string; public password: string;
@ApiProperty({ @ApiProperty({
description:'first name', description: 'first name',
required:true required: true,
}) })
@IsString() @IsString()
@IsNotEmpty() @IsNotEmpty()
public firstName: string; public firstName: string;
@ApiProperty({ @ApiProperty({
description:'last name', description: 'last name',
required:true required: true,
}) })
@IsString() @IsString()
@IsNotEmpty() @IsNotEmpty()

View File

@ -1,4 +1,4 @@
import { OtpType } from '@app/common/constants/otp-type.enum'; import { OtpType } from '../../../libs/common/src/constants/otp-type.enum';
import { ApiProperty } from '@nestjs/swagger'; import { ApiProperty } from '@nestjs/swagger';
import { IsEmail, IsEnum, IsNotEmpty, IsString } from 'class-validator'; import { IsEmail, IsEnum, IsNotEmpty, IsString } from 'class-validator';

View File

@ -89,7 +89,6 @@ export class AuthenticationService {
async getRequestSign( async getRequestSign(
path: string, path: string,
method: string, method: string,
headers: { [k: string]: string } = {},
query: { [k: string]: any } = {}, query: { [k: string]: any } = {},
body: { [k: string]: any } = {}, body: { [k: string]: any } = {},
) { ) {

View File

@ -1,19 +1,19 @@
import { UserRepository } from '@app/common/modules/user/repositories'; import { UserRepository } from '../../../libs/common/src/modules/user/repositories';
import { import {
BadRequestException, BadRequestException,
Injectable, Injectable,
UnauthorizedException, UnauthorizedException,
} from '@nestjs/common'; } from '@nestjs/common';
import { UserSignUpDto } from '../dtos/user-auth.dto'; import { UserSignUpDto } from '../dtos/user-auth.dto';
import { HelperHashService } from '@app/common/helper/services'; import { HelperHashService } from '../../../libs/common/src/helper/services';
import { UserLoginDto } from '../dtos/user-login.dto'; import { UserLoginDto } from '../dtos/user-login.dto';
import { AuthService } from '@app/common/auth/services/auth.service'; import { AuthService } from '../../../libs/common/src/auth/services/auth.service';
import { UserSessionRepository } from '@app/common/modules/session/repositories/session.repository'; import { UserSessionRepository } from '../../../libs/common/src/modules/session/repositories/session.repository';
import { UserOtpRepository } from '@app/common/modules/user-otp/repositories/user-otp.repository'; import { UserOtpRepository } from '../../../libs/common/src/modules/user-otp/repositories/user-otp.repository';
import { ForgetPasswordDto, UserOtpDto, VerifyOtpDto } from '../dtos'; import { ForgetPasswordDto, UserOtpDto, VerifyOtpDto } from '../dtos';
import { EmailService } from '@app/common/util/email.service'; import { EmailService } from '../../../libs/common/src/util/email.service';
import { OtpType } from '@app/common/constants/otp-type.enum'; import { OtpType } from '../../../libs/common/src/constants/otp-type.enum';
import { UserEntity } from '@app/common/modules/user/entities/user.entity'; import { UserEntity } from '../../../libs/common/src/modules/user/entities/user.entity';
import { ILoginResponse } from '../constants/login.response.constant'; import { ILoginResponse } from '../constants/login.response.constant';
@Injectable() @Injectable()

4
src/config/index.ts Normal file
View File

@ -0,0 +1,4 @@
import AuthConfig from './auth.config';
import AppConfig from './app.config';
export default [AuthConfig, AppConfig];

View File

@ -7,5 +7,5 @@ export default registerAs(
expire_time: process.env.JWT_EXPIRE_TIME, expire_time: process.env.JWT_EXPIRE_TIME,
secret_refresh: process.env.JWT_SECRET_REFRESH, secret_refresh: process.env.JWT_SECRET_REFRESH,
expire_refresh: process.env.JWT_EXPIRE_TIME_REFRESH, expire_refresh: process.env.JWT_EXPIRE_TIME_REFRESH,
}) }),
); );

View File

@ -1,8 +1,8 @@
import { NestFactory } from '@nestjs/core'; import { NestFactory } from '@nestjs/core';
import { AuthModule } from './auth.module'; import { AuthModule } from './app.module';
import rateLimit from 'express-rate-limit'; import rateLimit from 'express-rate-limit';
import helmet from 'helmet'; import helmet from 'helmet';
import { setupSwaggerAuthentication } from '@app/common/util/user-auth.swagger.utils'; import { setupSwaggerAuthentication } from '../libs/common/src/util/user-auth.swagger.utils';
import { ValidationPipe } from '@nestjs/common'; import { ValidationPipe } from '@nestjs/common';
async function bootstrap() { async function bootstrap() {
@ -13,7 +13,7 @@ async function bootstrap() {
app.getHttpAdapter().getInstance().set('trust proxy', 1); app.getHttpAdapter().getInstance().set('trust proxy', 1);
next(); next();
}); });
app.enableCors(); app.enableCors();
app.use( app.use(
@ -30,11 +30,10 @@ async function bootstrap() {
); );
setupSwaggerAuthentication(app); setupSwaggerAuthentication(app);
app.useGlobalPipes(new ValidationPipe());
app.useGlobalPipes(new ValidationPipe());
await app.listen(4001); await app.listen(4001);
} }
console.log('Starting auth at port 7001...'); console.log('Starting auth at port 4001...');
bootstrap(); bootstrap();

View File

@ -0,0 +1 @@
export * from './user.controller';

View File

@ -1,7 +1,8 @@
import { Controller, Get, Query } from '@nestjs/common'; import { Controller, Get, Query, UseGuards } from '@nestjs/common';
import { UserService } from '../services/user.service'; import { UserService } from '../services/user.service';
import { UserListDto } from '../dtos/user.list.dto'; import { UserListDto } from '../dtos/user.list.dto';
import { ApiTags } from '@nestjs/swagger'; import { ApiTags, ApiBearerAuth } from '@nestjs/swagger';
import { JwtAuthGuard } from '../../../libs/common/src/guards/jwt.auth.guard';
@ApiTags('User Module') @ApiTags('User Module')
@Controller({ @Controller({
@ -11,6 +12,8 @@ import { ApiTags } from '@nestjs/swagger';
export class UserController { export class UserController {
constructor(private readonly userService: UserService) {} constructor(private readonly userService: UserService) {}
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Get('list') @Get('list')
async userList(@Query() userListDto: UserListDto) { async userList(@Query() userListDto: UserListDto) {
try { try {

1
src/users/dtos/index.ts Normal file
View File

@ -0,0 +1 @@
export * from './user.list.dto';

View File

@ -1,15 +1,20 @@
import { IsNotEmpty, IsNumber, IsOptional, IsString } from 'class-validator'; import {
IsNotEmpty,
IsNumberString,
IsOptional,
IsString,
} from 'class-validator';
export class UserListDto { export class UserListDto {
@IsString() @IsString()
@IsOptional() @IsOptional()
schema: string; schema: string;
@IsNumber() @IsNumberString()
@IsNotEmpty() @IsNotEmpty()
page_no: number; page_no: number;
@IsNumber() @IsNumberString()
@IsNotEmpty() @IsNotEmpty()
page_size: number; page_size: number;
@ -17,11 +22,11 @@ export class UserListDto {
@IsOptional() @IsOptional()
username: string; username: string;
@IsNumber() @IsNumberString()
@IsOptional() @IsOptional()
start_time: number; start_time: number;
@IsNumber() @IsNumberString()
@IsOptional() @IsOptional()
end_time: number; end_time: number;
} }

View File

@ -0,0 +1 @@
export * from './user.service';