feat: change auth concept
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
d597734467
commit
f4cf5178b8
|
@ -79,6 +79,7 @@ import { SupersetModule } from './modules/configuration/superset/superset.module
|
||||||
import { GateScanModule } from './modules/gates/gate.module';
|
import { GateScanModule } from './modules/gates/gate.module';
|
||||||
import { UserLoginModel } from './modules/user-related/user/data/models/user-login.model';
|
import { UserLoginModel } from './modules/user-related/user/data/models/user-login.model';
|
||||||
import { LogUserLoginModel } from './modules/configuration/log/data/models/log-user-login.model';
|
import { LogUserLoginModel } from './modules/configuration/log/data/models/log-user-login.model';
|
||||||
|
import { AuthService } from './core/guards/domain/services/auth.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -189,6 +190,7 @@ import { LogUserLoginModel } from './modules/configuration/log/data/models/log-u
|
||||||
],
|
],
|
||||||
controllers: [],
|
controllers: [],
|
||||||
providers: [
|
providers: [
|
||||||
|
AuthService,
|
||||||
PrivilegeService,
|
PrivilegeService,
|
||||||
/**
|
/**
|
||||||
* By default all request from client will protect by JWT
|
* By default all request from client will protect by JWT
|
||||||
|
|
|
@ -7,10 +7,10 @@ import {
|
||||||
UnauthorizedException,
|
UnauthorizedException,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { Reflector } from '@nestjs/core';
|
import { Reflector } from '@nestjs/core';
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { SessionService, UsersSession } from 'src/core/sessions';
|
import { SessionService, UsersSession } from 'src/core/sessions';
|
||||||
import { UNPROTECTED_URL } from '../constants';
|
import { UNPROTECTED_URL } from '../constants';
|
||||||
import { PrivilegeService } from './services/privilege.service';
|
import { PrivilegeService } from './services/privilege.service';
|
||||||
|
import { AuthService } from './services/auth.service';
|
||||||
|
|
||||||
@Injectable({ scope: Scope.REQUEST })
|
@Injectable({ scope: Scope.REQUEST })
|
||||||
export class JWTGuard implements CanActivate {
|
export class JWTGuard implements CanActivate {
|
||||||
|
@ -18,14 +18,13 @@ export class JWTGuard implements CanActivate {
|
||||||
protected readonly session: SessionService,
|
protected readonly session: SessionService,
|
||||||
protected readonly reflector: Reflector,
|
protected readonly reflector: Reflector,
|
||||||
protected readonly privilege: PrivilegeService,
|
protected readonly privilege: PrivilegeService,
|
||||||
|
protected readonly authService: AuthService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
protected isPublic = false;
|
protected isPublic = false;
|
||||||
protected userSession: UsersSession;
|
protected userSession: UsersSession;
|
||||||
|
|
||||||
canActivate(
|
async canActivate(context: ExecutionContext) {
|
||||||
context: ExecutionContext,
|
|
||||||
): boolean | Promise<boolean> | Observable<boolean> {
|
|
||||||
/**
|
/**
|
||||||
* Check if access url is protected or not
|
* Check if access url is protected or not
|
||||||
* By default `isUnprotected` equals `false`
|
* By default `isUnprotected` equals `false`
|
||||||
|
@ -61,9 +60,29 @@ export class JWTGuard implements CanActivate {
|
||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
this.userSession = this.session.verifyToken(token);
|
this.userSession = this.session.verifyToken(token);
|
||||||
|
await this.authService.verifyRegisteredLoginToken(token);
|
||||||
|
|
||||||
Logger.log(`Access from ${this.userSession.name}`, 'AuthGuard');
|
Logger.log(`Access from ${this.userSession.name}`, 'AuthGuard');
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
const expiredError = error.message;
|
||||||
|
if (expiredError === 'jwt expired') {
|
||||||
|
const [, body] = token.split('.');
|
||||||
|
const bodyToken = JSON.parse(atob(body));
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
role: bodyToken.role,
|
||||||
|
user_id: bodyToken.id,
|
||||||
|
username: bodyToken.username,
|
||||||
|
user_privilege_id: bodyToken.user_privilege_id,
|
||||||
|
item_id: bodyToken.item_id,
|
||||||
|
item_name: bodyToken.item_name,
|
||||||
|
source: bodyToken.source,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.authService.logoutUser(user, token);
|
||||||
|
}
|
||||||
|
|
||||||
throw new UnauthorizedException({
|
throw new UnauthorizedException({
|
||||||
code: 10001,
|
code: 10001,
|
||||||
message:
|
message:
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { MAIN_MENU } from '../constants';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RolesGuard extends JWTGuard {
|
export class RolesGuard extends JWTGuard {
|
||||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||||
super.canActivate(context);
|
await super.canActivate(context);
|
||||||
|
|
||||||
// jika endpoint tersebut bukan public, maka lakukan check lanjutan
|
// jika endpoint tersebut bukan public, maka lakukan check lanjutan
|
||||||
if (!this.isPublic) {
|
if (!this.isPublic) {
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
import {
|
||||||
|
HttpStatus,
|
||||||
|
Injectable,
|
||||||
|
Scope,
|
||||||
|
UnauthorizedException,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { InjectDataSource } from '@nestjs/typeorm';
|
||||||
|
import {
|
||||||
|
CONNECTION_NAME,
|
||||||
|
OPERATION,
|
||||||
|
} from 'src/core/strings/constants/base.constants';
|
||||||
|
import { DataSource } from 'typeorm';
|
||||||
|
import { UserRole } from 'src/modules/user-related/user/constants';
|
||||||
|
import { UserModel } from 'src/modules/user-related/user/data/models/user.model';
|
||||||
|
import { AppSource, LogUserType } from 'src/core/helpers/constant';
|
||||||
|
import { EventBus } from '@nestjs/cqrs';
|
||||||
|
import { LogUserLoginEvent } from 'src/modules/configuration/log/domain/entities/log-user-login.event';
|
||||||
|
import { UserLoginModel } from 'src/modules/user-related/user/data/models/user-login.model';
|
||||||
|
|
||||||
|
interface UserEntity {
|
||||||
|
user_id: string;
|
||||||
|
username: string;
|
||||||
|
role: UserRole;
|
||||||
|
user_privilege_id: string;
|
||||||
|
item_id: string;
|
||||||
|
item_name: string;
|
||||||
|
source: AppSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable({ scope: Scope.REQUEST })
|
||||||
|
export class AuthService {
|
||||||
|
constructor(
|
||||||
|
@InjectDataSource(CONNECTION_NAME.DEFAULT)
|
||||||
|
protected readonly dataSource: DataSource,
|
||||||
|
|
||||||
|
private eventBus: EventBus,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
get repository() {
|
||||||
|
return this.dataSource.getRepository(UserLoginModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
async logoutUser(user: UserEntity, token: string) {
|
||||||
|
await this.repository.delete({ login_token: token });
|
||||||
|
|
||||||
|
const userLogout = {
|
||||||
|
type: LogUserType.logout,
|
||||||
|
created_at: new Date().getTime(),
|
||||||
|
name: user.username,
|
||||||
|
user_privilege_id: user.user_privilege_id,
|
||||||
|
...user,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.eventBus.publish(
|
||||||
|
new LogUserLoginEvent({
|
||||||
|
id: user.user_id,
|
||||||
|
old: null,
|
||||||
|
data: userLogout,
|
||||||
|
user: userLogout as any,
|
||||||
|
description: 'Logout',
|
||||||
|
module: UserModel.name,
|
||||||
|
op: OPERATION.UPDATE,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async verifyRegisteredLoginToken(token: string) {
|
||||||
|
const data = await this.repository.findOneBy({ login_token: token });
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
throw new UnauthorizedException({
|
||||||
|
statusCode: HttpStatus.UNAUTHORIZED,
|
||||||
|
message: `Invalid token`,
|
||||||
|
error: 'Unauthorized',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,3 +2,10 @@ export enum LogUserType {
|
||||||
login = 'login',
|
login = 'login',
|
||||||
logout = 'logout',
|
logout = 'logout',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum AppSource {
|
||||||
|
POS_ADMIN = 'POS_ADMIN',
|
||||||
|
POS_COUNTER = 'POS_COUNTER',
|
||||||
|
QUEUE_ADMIN = 'QUEUE_ADMIN',
|
||||||
|
QUEUE_CUSTOMER = 'QUEUE_CUSTOMER',
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
import { AppSource } from 'src/core/helpers/constant';
|
||||||
import { UserRole } from 'src/modules/user-related/user/constants';
|
import { UserRole } from 'src/modules/user-related/user/constants';
|
||||||
|
|
||||||
export interface UsersSession {
|
export interface UsersSession {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
role: UserRole;
|
role: UserRole;
|
||||||
|
source?: AppSource;
|
||||||
user_privilege_id: string;
|
user_privilege_id: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,4 +23,9 @@ export class UserProvider {
|
||||||
const [, token] = this.request.headers['authorization'].split(' ');
|
const [, token] = this.request.headers['authorization'].split(' ');
|
||||||
return this.session.verifyToken(token);
|
return this.session.verifyToken(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get token(): string {
|
||||||
|
const [, token] = this.request.headers['authorization'].split(' ');
|
||||||
|
return token;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class ChangeUserLoginRelation1726642119207
|
||||||
|
implements MigrationInterface
|
||||||
|
{
|
||||||
|
name = 'ChangeUserLoginRelation1726642119207';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "refresh_token"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "users_login" DROP CONSTRAINT "FK_2a80a213b51423ce5b8211f0584"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "users_login" DROP CONSTRAINT "REL_2a80a213b51423ce5b8211f058"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "users_login" ADD CONSTRAINT "FK_2a80a213b51423ce5b8211f0584" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "users_login" DROP CONSTRAINT "FK_2a80a213b51423ce5b8211f0584"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "users_login" ADD CONSTRAINT "REL_2a80a213b51423ce5b8211f058" UNIQUE ("user_id")`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "users_login" ADD CONSTRAINT "FK_2a80a213b51423ce5b8211f0584" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "users" ADD "refresh_token" character varying`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class AddColumnSourceAtUserLogin1726642499135
|
||||||
|
implements MigrationInterface
|
||||||
|
{
|
||||||
|
name = 'AddColumnSourceAtUserLogin1726642499135';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."users_login_role_enum" AS ENUM('superadmin', 'staff', 'tenant', 'queue_admin')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "users_login" ADD "role" "public"."users_login_role_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."users_login_source_enum" AS ENUM('POS_ADMIN', 'POS_COUNTER', 'QUEUE_ADMIN', 'QUEUE_CUSTOMER')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "users_login" ADD "source" "public"."users_login_source_enum"`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "users_login" DROP COLUMN "source"`);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."users_login_source_enum"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "users_login" DROP COLUMN "role"`);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."users_login_role_enum"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class AddSourceOnLogLogin1726647442006 implements MigrationInterface {
|
||||||
|
name = 'AddSourceOnLogLogin1726647442006';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."log_users_login_source_enum" AS ENUM('POS_ADMIN', 'POS_COUNTER', 'QUEUE_ADMIN', 'QUEUE_CUSTOMER')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "log_users_login" ADD "source" "public"."log_users_login_source_enum"`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "log_users_login" DROP COLUMN "source"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."log_users_login_source_enum"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,10 +19,14 @@ export class AuthAdminQueueOrchestrator {
|
||||||
return this.loginManager.getResult();
|
return this.loginManager.getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
async logout(id?: string): Promise<any> {
|
async logout(userId?: string): Promise<any> {
|
||||||
if (id) this.logoutManager.setData({ id });
|
if (userId) this.logoutManager.setData({ user_id: userId });
|
||||||
this.logoutManager.setService(this.serviceData, TABLE_NAME.USER);
|
this.logoutManager.setService(this.serviceData, TABLE_NAME.USER);
|
||||||
await this.logoutManager.execute();
|
await this.logoutManager.execute();
|
||||||
return this.logoutManager.getResult();
|
return this.logoutManager.getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async forceLogout(token): Promise<any> {
|
||||||
|
return this.serviceData.forceLogout(token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,4 +24,8 @@ export class AuthOrchestrator {
|
||||||
await this.logoutManager.execute();
|
await this.logoutManager.execute();
|
||||||
return this.logoutManager.getResult();
|
return this.logoutManager.getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async forceLogout(token): Promise<any> {
|
||||||
|
return this.serviceData.forceLogout(token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,9 @@ import { UserModel } from 'src/modules/user-related/user/data/models/user.model'
|
||||||
import { UserEntity } from 'src/modules/user-related/user/domain/entities/user.entity';
|
import { UserEntity } from 'src/modules/user-related/user/domain/entities/user.entity';
|
||||||
import { In } from 'typeorm';
|
import { In } from 'typeorm';
|
||||||
import { UserRole } from 'src/modules/user-related/user/constants';
|
import { UserRole } from 'src/modules/user-related/user/constants';
|
||||||
import { LogUserType } from 'src/core/helpers/constant';
|
import { AppSource, LogUserType } from 'src/core/helpers/constant';
|
||||||
import { LogUserLoginEvent } from 'src/modules/configuration/log/domain/entities/log-user-login.event';
|
import { LogUserLoginEvent } from 'src/modules/configuration/log/domain/entities/log-user-login.event';
|
||||||
|
import { UserLoginEntity } from 'src/modules/user-related/user/domain/entities/user-login.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LoginAdminQueueManager extends BaseCustomManager<UserEntity> {
|
export class LoginAdminQueueManager extends BaseCustomManager<UserEntity> {
|
||||||
|
@ -62,13 +63,19 @@ export class LoginAdminQueueManager extends BaseCustomManager<UserEntity> {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.userLogin.user_login) {
|
const hasLoginAsQueue = this.userLogin?.user_login?.find(
|
||||||
|
(item) => item.source === AppSource.QUEUE_ADMIN,
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(hasLoginAsQueue, userLoginItem);
|
||||||
|
|
||||||
|
if (hasLoginAsQueue && hasLoginAsQueue?.item_id !== this.data.item_id) {
|
||||||
throw new UnauthorizedException({
|
throw new UnauthorizedException({
|
||||||
statusCode: HttpStatus.UNAUTHORIZED,
|
statusCode: HttpStatus.UNAUTHORIZED,
|
||||||
message: `Akun anda sudah login di perangkat lain.`,
|
message: `Akun anda sudah login di item "${hasLoginAsQueue?.item_name}"`,
|
||||||
error: 'Unauthorized',
|
error: 'Unauthorized',
|
||||||
});
|
});
|
||||||
} else if (itemLogin) {
|
} else if (itemLogin && itemLogin.user_id !== this.userLogin.id) {
|
||||||
throw new UnauthorizedException({
|
throw new UnauthorizedException({
|
||||||
statusCode: HttpStatus.UNAUTHORIZED,
|
statusCode: HttpStatus.UNAUTHORIZED,
|
||||||
message: `"${userLoginItem.name}" masih login sebagai admin antrian `,
|
message: `"${userLoginItem.name}" masih login sebagai admin antrian `,
|
||||||
|
@ -85,32 +92,28 @@ export class LoginAdminQueueManager extends BaseCustomManager<UserEntity> {
|
||||||
user_privilege_id: this.userLogin.user_privilege_id,
|
user_privilege_id: this.userLogin.user_privilege_id,
|
||||||
item_id: this.data.item_id,
|
item_id: this.data.item_id,
|
||||||
item_name: this.data.item_name,
|
item_name: this.data.item_name,
|
||||||
|
source: AppSource.QUEUE_ADMIN,
|
||||||
};
|
};
|
||||||
|
|
||||||
Logger.debug('Sign Token Admin Queue', 'LoginAdminQueueManager');
|
Logger.debug('Sign Token Admin Queue', 'LoginAdminQueueManager');
|
||||||
this.token = this.session.createAccessToken(tokenData);
|
this.token = this.session.createAccessToken(tokenData);
|
||||||
|
|
||||||
Logger.debug('refreshToken Admin Queue', 'LoginAdminQueueManager');
|
Logger.debug('Save Login Token', 'LoginManager');
|
||||||
const refreshToken = this.session.createAccessToken(tokenData);
|
const userLoginData: UserLoginEntity = {
|
||||||
|
user_id: this.userLogin.id,
|
||||||
Logger.debug('Update Refresh Token Admin Queue', 'LoginAdminQueueManager');
|
login_token: this.token,
|
||||||
|
login_date: new Date().getTime(),
|
||||||
|
source: AppSource.QUEUE_ADMIN,
|
||||||
|
role: this.userLogin.role,
|
||||||
|
item_id: this.data.item_id,
|
||||||
|
item_name: this.data.item_name,
|
||||||
|
};
|
||||||
|
if (hasLoginAsQueue?.item_id === this.data.item_id) {
|
||||||
|
Object.assign(userLoginData, { id: hasLoginAsQueue.id });
|
||||||
|
}
|
||||||
// Update refresh token
|
// Update refresh token
|
||||||
await this.dataService.update(
|
await this.dataService.saveUserLogin(userLoginData);
|
||||||
this.queryRunner,
|
|
||||||
this.entityTarget,
|
|
||||||
{ id: this.userLogin.id },
|
|
||||||
{
|
|
||||||
refresh_token: refreshToken,
|
|
||||||
user_login: {
|
|
||||||
user_id: this.userLogin.id,
|
|
||||||
login_token: this.token,
|
|
||||||
login_date: new Date().getTime(),
|
|
||||||
item_id: this.data.item_id,
|
|
||||||
item_name: this.data.item_name,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
await this.publishEvents();
|
await this.publishEvents();
|
||||||
|
|
||||||
Logger.debug('Process Login Admin Queue Done', 'LoginAdminQueueManager');
|
Logger.debug('Process Login Admin Queue Done', 'LoginAdminQueueManager');
|
||||||
|
@ -149,6 +152,7 @@ export class LoginAdminQueueManager extends BaseCustomManager<UserEntity> {
|
||||||
created_at: new Date().getTime(),
|
created_at: new Date().getTime(),
|
||||||
item_id: this.data.item_id,
|
item_id: this.data.item_id,
|
||||||
item_name: this.data.item_name,
|
item_name: this.data.item_name,
|
||||||
|
source: AppSource.QUEUE_ADMIN,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { LogUserType } from 'src/core/helpers/constant';
|
import { AppSource, LogUserType } from 'src/core/helpers/constant';
|
||||||
import { BaseCustomManager } from 'src/core/modules/domain/usecase/managers/base-custom.manager';
|
import { BaseCustomManager } from 'src/core/modules/domain/usecase/managers/base-custom.manager';
|
||||||
import { EventTopics } from 'src/core/strings/constants/interface.constants';
|
import { EventTopics } from 'src/core/strings/constants/interface.constants';
|
||||||
import { LogUserLoginEvent } from 'src/modules/configuration/log/domain/entities/log-user-login.event';
|
import { LogUserLoginEvent } from 'src/modules/configuration/log/domain/entities/log-user-login.event';
|
||||||
|
@ -17,21 +17,17 @@ export class LogoutAdminQueueManager extends BaseCustomManager<UserEntity> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async process(): Promise<void> {
|
async process(): Promise<void> {
|
||||||
const id = this.data?.id ?? this.user.id;
|
const id = this.data?.user_id ?? this.user.id;
|
||||||
|
|
||||||
this.userLogin = await this.dataService.getOneByOptions({
|
this.userLogin = await this.dataService.getOneByOptions({
|
||||||
where: { id },
|
where: { id },
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.dataService.update(
|
await this.dataService.removeUserLogin({
|
||||||
this.queryRunner,
|
user_id: id,
|
||||||
this.entityTarget,
|
source: AppSource.QUEUE_ADMIN,
|
||||||
{ id: this.userLogin.id },
|
});
|
||||||
{
|
|
||||||
refresh_token: null,
|
|
||||||
user_login: null,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
await this.publishEvents();
|
await this.publishEvents();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -58,6 +54,7 @@ export class LogoutAdminQueueManager extends BaseCustomManager<UserEntity> {
|
||||||
user_id: this.userLogin.id,
|
user_id: this.userLogin.id,
|
||||||
username: this.userLogin.name,
|
username: this.userLogin.name,
|
||||||
created_at: new Date().getTime(),
|
created_at: new Date().getTime(),
|
||||||
|
source: AppSource.QUEUE_ADMIN,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -14,8 +14,9 @@ import { UserModel } from 'src/modules/user-related/user/data/models/user.model'
|
||||||
import { UserEntity } from 'src/modules/user-related/user/domain/entities/user.entity';
|
import { UserEntity } from 'src/modules/user-related/user/domain/entities/user.entity';
|
||||||
import { Not } from 'typeorm';
|
import { Not } from 'typeorm';
|
||||||
import { UserRole } from 'src/modules/user-related/user/constants';
|
import { UserRole } from 'src/modules/user-related/user/constants';
|
||||||
import { LogUserType } from 'src/core/helpers/constant';
|
import { AppSource, LogUserType } from 'src/core/helpers/constant';
|
||||||
import { LogUserLoginEvent } from 'src/modules/configuration/log/domain/entities/log-user-login.event';
|
import { LogUserLoginEvent } from 'src/modules/configuration/log/domain/entities/log-user-login.event';
|
||||||
|
import { UserLoginEntity } from 'src/modules/user-related/user/domain/entities/user-login.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LoginManager extends BaseCustomManager<UserEntity> {
|
export class LoginManager extends BaseCustomManager<UserEntity> {
|
||||||
|
@ -62,24 +63,25 @@ export class LoginManager extends BaseCustomManager<UserEntity> {
|
||||||
username: this.userLogin.username,
|
username: this.userLogin.username,
|
||||||
role: this.userLogin.role,
|
role: this.userLogin.role,
|
||||||
user_privilege_id: this.userLogin.user_privilege_id,
|
user_privilege_id: this.userLogin.user_privilege_id,
|
||||||
|
source: AppSource.POS_ADMIN,
|
||||||
};
|
};
|
||||||
|
|
||||||
Logger.debug('Sign Token', 'LoginManager');
|
Logger.debug('Sign Token', 'LoginManager');
|
||||||
this.token = this.session.createAccessToken(tokenData);
|
this.token = this.session.createAccessToken(tokenData);
|
||||||
|
|
||||||
Logger.debug('refreshToken', 'LoginManager');
|
Logger.debug('Save Login Token', 'LoginManager');
|
||||||
const refreshToken = this.session.createAccessToken(tokenData);
|
const userLoginData: UserLoginEntity = {
|
||||||
|
user_id: this.userLogin.id,
|
||||||
|
login_token: this.token,
|
||||||
|
login_date: new Date().getTime(),
|
||||||
|
source: AppSource.POS_ADMIN,
|
||||||
|
role: this.userLogin.role,
|
||||||
|
item_id: null,
|
||||||
|
item_name: null,
|
||||||
|
};
|
||||||
|
|
||||||
Logger.debug('Update Refresh Token', 'LoginManager');
|
|
||||||
// Update refresh token
|
// Update refresh token
|
||||||
await this.dataService.update(
|
await this.dataService.saveUserLogin(userLoginData);
|
||||||
this.queryRunner,
|
|
||||||
this.entityTarget,
|
|
||||||
{ id: this.userLogin.id },
|
|
||||||
{
|
|
||||||
refresh_token: refreshToken,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
await this.publishEvents();
|
await this.publishEvents();
|
||||||
Logger.debug('Process Login Done', 'LoginManager');
|
Logger.debug('Process Login Done', 'LoginManager');
|
||||||
|
@ -131,6 +133,7 @@ export class LoginManager extends BaseCustomManager<UserEntity> {
|
||||||
user_id: this.userLogin.id,
|
user_id: this.userLogin.id,
|
||||||
username: this.userLogin.username,
|
username: this.userLogin.username,
|
||||||
created_at: new Date().getTime(),
|
created_at: new Date().getTime(),
|
||||||
|
source: AppSource.POS_ADMIN,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { BaseCustomManager } from 'src/core/modules/domain/usecase/managers/base
|
||||||
import { EventTopics } from 'src/core/strings/constants/interface.constants';
|
import { EventTopics } from 'src/core/strings/constants/interface.constants';
|
||||||
import { UserModel } from 'src/modules/user-related/user/data/models/user.model';
|
import { UserModel } from 'src/modules/user-related/user/data/models/user.model';
|
||||||
import { UserEntity } from 'src/modules/user-related/user/domain/entities/user.entity';
|
import { UserEntity } from 'src/modules/user-related/user/domain/entities/user.entity';
|
||||||
import { LogUserType } from 'src/core/helpers/constant';
|
import { AppSource, LogUserType } from 'src/core/helpers/constant';
|
||||||
import { LogUserLoginEvent } from 'src/modules/configuration/log/domain/entities/log-user-login.event';
|
import { LogUserLoginEvent } from 'src/modules/configuration/log/domain/entities/log-user-login.event';
|
||||||
|
|
||||||
export class LogoutManager extends BaseCustomManager<UserEntity> {
|
export class LogoutManager extends BaseCustomManager<UserEntity> {
|
||||||
|
@ -15,15 +15,11 @@ export class LogoutManager extends BaseCustomManager<UserEntity> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async process(): Promise<void> {
|
async process(): Promise<void> {
|
||||||
await this.dataService.update(
|
await this.dataService.removeUserLogin({
|
||||||
this.queryRunner,
|
user_id: this.user.id,
|
||||||
this.entityTarget,
|
login_token: this.userProvider.token,
|
||||||
{ id: this.user.id },
|
source: AppSource.POS_ADMIN,
|
||||||
{
|
});
|
||||||
refresh_token: null,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
await this.publishEvents();
|
await this.publishEvents();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -50,6 +46,7 @@ export class LogoutManager extends BaseCustomManager<UserEntity> {
|
||||||
user_id: this.user.id,
|
user_id: this.user.id,
|
||||||
username: this.user.name,
|
username: this.user.name,
|
||||||
created_at: new Date().getTime(),
|
created_at: new Date().getTime(),
|
||||||
|
source: AppSource.POS_ADMIN,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Body, Controller, Delete, Param, Post, Put } from '@nestjs/common';
|
import { Body, Controller, Delete, Param, Post, Put } from '@nestjs/common';
|
||||||
import { ExcludePrivilege, Public } from 'src/core/guards';
|
import { ExcludePrivilege, Public } from 'src/core/guards';
|
||||||
import { ApiBearerAuth } from '@nestjs/swagger';
|
import { ApiBearerAuth } from '@nestjs/swagger';
|
||||||
import { LoginQueueDto } from './dto/login.dto';
|
import { ForceLogoutDto, LoginQueueDto } from './dto/login.dto';
|
||||||
import { AuthAdminQueueOrchestrator } from '../domain/auth-admin-queue.orchestrator';
|
import { AuthAdminQueueOrchestrator } from '../domain/auth-admin-queue.orchestrator';
|
||||||
|
|
||||||
@Controller('v1/auth/queue')
|
@Controller('v1/auth/queue')
|
||||||
|
@ -18,12 +18,18 @@ export class AuthAdminQueueController {
|
||||||
@Public(false)
|
@Public(false)
|
||||||
@ExcludePrivilege()
|
@ExcludePrivilege()
|
||||||
@Delete('logout')
|
@Delete('logout')
|
||||||
async logoout() {
|
async logout() {
|
||||||
return await this.orchestrator.logout();
|
return await this.orchestrator.logout();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Put(':id/logout')
|
@Put(':user_id/logout')
|
||||||
async logoutQueueAdmin(@Param('id') dataId: string) {
|
async logoutQueueAdmin(@Param('user_id') userId: string) {
|
||||||
return await this.orchestrator.logout(dataId);
|
return await this.orchestrator.logout(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('force-logout')
|
||||||
|
@Public(true)
|
||||||
|
async forceLogout(@Body() body: ForceLogoutDto) {
|
||||||
|
return await this.orchestrator.forceLogout(body.token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Body, Controller, Delete, Post } from '@nestjs/common';
|
||||||
import { ExcludePrivilege, Public } from 'src/core/guards';
|
import { ExcludePrivilege, Public } from 'src/core/guards';
|
||||||
import { AuthOrchestrator } from '../domain/auth.orchestrator';
|
import { AuthOrchestrator } from '../domain/auth.orchestrator';
|
||||||
import { ApiBearerAuth } from '@nestjs/swagger';
|
import { ApiBearerAuth } from '@nestjs/swagger';
|
||||||
import { LoginDto } from './dto/login.dto';
|
import { ForceLogoutDto, LoginDto } from './dto/login.dto';
|
||||||
|
|
||||||
@Controller('v1/auth')
|
@Controller('v1/auth')
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
|
@ -18,7 +18,13 @@ export class AuthController {
|
||||||
@Public(false)
|
@Public(false)
|
||||||
@ExcludePrivilege()
|
@ExcludePrivilege()
|
||||||
@Delete('logout')
|
@Delete('logout')
|
||||||
async logoout() {
|
async logout() {
|
||||||
return await this.orchestrator.logout();
|
return await this.orchestrator.logout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post('force-logout')
|
||||||
|
@Public(true)
|
||||||
|
async forceLogout(@Body() body: ForceLogoutDto) {
|
||||||
|
return await this.orchestrator.forceLogout(body.token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,3 +29,9 @@ export class LoginQueueDto implements LoginRequest {
|
||||||
@IsString()
|
@IsString()
|
||||||
item_name: string;
|
item_name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ForceLogoutDto {
|
||||||
|
@ApiProperty({ required: true })
|
||||||
|
@IsString()
|
||||||
|
token: string;
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Column, Entity } from 'typeorm';
|
||||||
import { BaseCoreModel } from 'src/core/modules/data/model/base-core.model';
|
import { BaseCoreModel } from 'src/core/modules/data/model/base-core.model';
|
||||||
import { LogUserLoginEntity } from '../../domain/entities/log-user-login.entity';
|
import { LogUserLoginEntity } from '../../domain/entities/log-user-login.entity';
|
||||||
import { UserRole } from '../../../../user-related/user/constants';
|
import { UserRole } from '../../../../user-related/user/constants';
|
||||||
import { LogUserType } from 'src/core/helpers/constant';
|
import { AppSource, LogUserType } from 'src/core/helpers/constant';
|
||||||
|
|
||||||
@Entity(TABLE_NAME.LOG_USER_LOGIN)
|
@Entity(TABLE_NAME.LOG_USER_LOGIN)
|
||||||
export class LogUserLoginModel
|
export class LogUserLoginModel
|
||||||
|
@ -31,4 +31,7 @@ export class LogUserLoginModel
|
||||||
|
|
||||||
@Column({ type: 'bigint', nullable: true })
|
@Column({ type: 'bigint', nullable: true })
|
||||||
created_at: number;
|
created_at: number;
|
||||||
|
|
||||||
|
@Column({ type: 'enum', enum: AppSource, nullable: true })
|
||||||
|
source: AppSource;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,4 @@ export class TenantDto extends BaseStatusDto implements UserEntity {
|
||||||
|
|
||||||
@Exclude()
|
@Exclude()
|
||||||
role: UserRole;
|
role: UserRole;
|
||||||
|
|
||||||
@Exclude()
|
|
||||||
refresh_token: string;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,4 @@ export class UpdatePasswordTenantDto
|
||||||
|
|
||||||
@Exclude()
|
@Exclude()
|
||||||
role: UserRole;
|
role: UserRole;
|
||||||
|
|
||||||
@Exclude()
|
|
||||||
refresh_token: string;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,4 @@ export class UpdateTenantDto extends BaseStatusDto implements UserEntity {
|
||||||
|
|
||||||
@Exclude()
|
@Exclude()
|
||||||
role: UserRole;
|
role: UserRole;
|
||||||
|
|
||||||
@Exclude()
|
|
||||||
refresh_token: string;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
|
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
|
||||||
import { UserEntity } from '../../domain/entities/user.entity';
|
import { UserEntity } from '../../domain/entities/user.entity';
|
||||||
import { Column, Entity, JoinColumn, OneToOne } from 'typeorm';
|
import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from 'typeorm';
|
||||||
import { UserLoginEntity } from '../../domain/entities/user-login.entity';
|
import { UserLoginEntity } from '../../domain/entities/user-login.entity';
|
||||||
import { UserModel } from './user.model';
|
import { UserModel } from './user.model';
|
||||||
import { BaseCoreModel } from 'src/core/modules/data/model/base-core.model';
|
import { BaseCoreModel } from 'src/core/modules/data/model/base-core.model';
|
||||||
|
import { UserRole } from '../../constants';
|
||||||
|
import { AppSource } from 'src/core/helpers/constant';
|
||||||
|
|
||||||
@Entity(TABLE_NAME.USER_LOGIN)
|
@Entity(TABLE_NAME.USER_LOGIN)
|
||||||
export class UserLoginModel
|
export class UserLoginModel
|
||||||
|
@ -25,7 +27,13 @@ export class UserLoginModel
|
||||||
@Column({ type: 'varchar', nullable: true })
|
@Column({ type: 'varchar', nullable: true })
|
||||||
item_name: string;
|
item_name: string;
|
||||||
|
|
||||||
@OneToOne(() => UserModel, (model) => model.user_login, {
|
@Column({ type: 'enum', enum: UserRole, nullable: true })
|
||||||
|
role: UserRole;
|
||||||
|
|
||||||
|
@Column({ type: 'enum', enum: AppSource, nullable: true })
|
||||||
|
source: AppSource;
|
||||||
|
|
||||||
|
@ManyToOne(() => UserModel, (model) => model.user_login, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
onUpdate: 'CASCADE',
|
onUpdate: 'CASCADE',
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
|
|
@ -19,9 +19,6 @@ export class UserModel
|
||||||
extends BaseStatusModel<UserEntity>
|
extends BaseStatusModel<UserEntity>
|
||||||
implements UserEntity
|
implements UserEntity
|
||||||
{
|
{
|
||||||
@Column('varchar', { name: 'refresh_token', nullable: true })
|
|
||||||
refresh_token: string;
|
|
||||||
|
|
||||||
@Column('varchar', { name: 'name', nullable: true })
|
@Column('varchar', { name: 'name', nullable: true })
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
|
@ -58,7 +55,7 @@ export class UserModel
|
||||||
items: ItemModel[];
|
items: ItemModel[];
|
||||||
|
|
||||||
// relasi ke user login for admin queue
|
// relasi ke user login for admin queue
|
||||||
@OneToOne(() => UserLoginModel, (model) => model.user, {
|
@OneToMany(() => UserLoginModel, (model) => model.user, {
|
||||||
cascade: true,
|
cascade: true,
|
||||||
})
|
})
|
||||||
user_login: UserLoginModel;
|
user_login: UserLoginModel;
|
||||||
|
|
|
@ -3,9 +3,16 @@ import { BaseDataService } from 'src/core/modules/data/service/base-data.service
|
||||||
import { UserEntity } from '../../domain/entities/user.entity';
|
import { UserEntity } from '../../domain/entities/user.entity';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { UserModel } from '../models/user.model';
|
import { UserModel } from '../models/user.model';
|
||||||
import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants';
|
import {
|
||||||
|
CONNECTION_NAME,
|
||||||
|
OPERATION,
|
||||||
|
} from 'src/core/strings/constants/base.constants';
|
||||||
import { IsNull, Not, Repository } from 'typeorm';
|
import { IsNull, Not, Repository } from 'typeorm';
|
||||||
import { UserLoginModel } from '../models/user-login.model';
|
import { UserLoginModel } from '../models/user-login.model';
|
||||||
|
import { UserLoginEntity } from '../../domain/entities/user-login.entity';
|
||||||
|
import { LogUserType } from 'src/core/helpers/constant';
|
||||||
|
import { EventBus } from '@nestjs/cqrs';
|
||||||
|
import { LogUserLoginEvent } from 'src/modules/configuration/log/domain/entities/log-user-login.event';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserDataService extends BaseDataService<UserEntity> {
|
export class UserDataService extends BaseDataService<UserEntity> {
|
||||||
|
@ -15,6 +22,8 @@ export class UserDataService extends BaseDataService<UserEntity> {
|
||||||
|
|
||||||
@InjectRepository(UserLoginModel, CONNECTION_NAME.DEFAULT)
|
@InjectRepository(UserLoginModel, CONNECTION_NAME.DEFAULT)
|
||||||
private repoLoginUser: Repository<UserLoginModel>,
|
private repoLoginUser: Repository<UserLoginModel>,
|
||||||
|
|
||||||
|
private eventBus: EventBus,
|
||||||
) {
|
) {
|
||||||
super(repo);
|
super(repo);
|
||||||
}
|
}
|
||||||
|
@ -24,4 +33,55 @@ export class UserDataService extends BaseDataService<UserEntity> {
|
||||||
where: { item_id: itemId, user_id: Not(IsNull()) },
|
where: { item_id: itemId, user_id: Not(IsNull()) },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async saveUserLogin(userLogin: UserLoginEntity) {
|
||||||
|
return this.repoLoginUser.save(userLogin);
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeUserLogin(userLogin: Partial<UserLoginEntity>) {
|
||||||
|
return this.repoLoginUser.delete(userLogin);
|
||||||
|
}
|
||||||
|
|
||||||
|
async forceLogout(token: string) {
|
||||||
|
const data = await this.repoLoginUser.findOneBy({ login_token: token });
|
||||||
|
|
||||||
|
if (data) return;
|
||||||
|
else {
|
||||||
|
await this.repoLoginUser.delete({ login_token: token });
|
||||||
|
|
||||||
|
const [, body] = token.split('.');
|
||||||
|
const bodyToken = JSON.parse(atob(body));
|
||||||
|
const user = {
|
||||||
|
role: bodyToken.role,
|
||||||
|
user_id: bodyToken.id,
|
||||||
|
username: bodyToken.username,
|
||||||
|
user_privilege_id: bodyToken.user_privilege_id,
|
||||||
|
item_id: bodyToken.item_id,
|
||||||
|
item_name: bodyToken.item_name,
|
||||||
|
source: bodyToken.source,
|
||||||
|
};
|
||||||
|
|
||||||
|
const userLogout = {
|
||||||
|
type: LogUserType.logout,
|
||||||
|
created_at: new Date().getTime(),
|
||||||
|
name: user.username,
|
||||||
|
user_privilege_id: user.user_privilege_id,
|
||||||
|
...user,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.eventBus.publish(
|
||||||
|
new LogUserLoginEvent({
|
||||||
|
id: user.user_id,
|
||||||
|
old: null,
|
||||||
|
data: userLogout,
|
||||||
|
user: userLogout as any,
|
||||||
|
description: 'Logout',
|
||||||
|
module: UserModel.name,
|
||||||
|
op: OPERATION.UPDATE,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
import { BaseCoreEntity } from 'src/core/modules/domain/entities/base-core.entity';
|
import { BaseCoreEntity } from 'src/core/modules/domain/entities/base-core.entity';
|
||||||
|
import { UserRole } from '../../constants';
|
||||||
|
import { AppSource } from 'src/core/helpers/constant';
|
||||||
|
|
||||||
export interface UserLoginEntity extends BaseCoreEntity {
|
export interface UserLoginEntity extends BaseCoreEntity {
|
||||||
login_date: number;
|
login_date: number;
|
||||||
login_token: string;
|
login_token: string;
|
||||||
|
user_id: string;
|
||||||
item_id: string;
|
item_id: string;
|
||||||
item_name: string;
|
item_name: string;
|
||||||
|
role: UserRole;
|
||||||
|
source: AppSource;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ export interface UserEntity extends BaseStatusEntity {
|
||||||
username: string;
|
username: string;
|
||||||
password: string;
|
password: string;
|
||||||
role: UserRole;
|
role: UserRole;
|
||||||
refresh_token: string;
|
|
||||||
|
|
||||||
// tenant data
|
// tenant data
|
||||||
share_margin: number;
|
share_margin: number;
|
||||||
|
|
|
@ -54,6 +54,7 @@ export class IndexUserManager extends BaseIndexManager<UserEntity> {
|
||||||
'user_login.login_date',
|
'user_login.login_date',
|
||||||
'user_login.item_id',
|
'user_login.item_id',
|
||||||
'user_login.item_name',
|
'user_login.item_name',
|
||||||
|
'user_login.source',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,4 @@ export class UpdatePasswordUserDto extends BaseStatusDto implements UserEntity {
|
||||||
|
|
||||||
@Exclude()
|
@Exclude()
|
||||||
role: UserRole;
|
role: UserRole;
|
||||||
|
|
||||||
@Exclude()
|
|
||||||
refresh_token: string;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,4 @@ export class UpdateUserDto extends BaseStatusDto implements UserEntity {
|
||||||
|
|
||||||
@Exclude()
|
@Exclude()
|
||||||
password: string;
|
password: string;
|
||||||
|
|
||||||
@Exclude()
|
|
||||||
refresh_token: string;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,4 @@ export class UserDto extends BaseStatusDto implements UserEntity {
|
||||||
|
|
||||||
@Exclude()
|
@Exclude()
|
||||||
email: string;
|
email: string;
|
||||||
|
|
||||||
@Exclude()
|
|
||||||
refresh_token: string;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue