mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-11-27 00:14:54 +00:00
Merge pull request #91 from SyncrowIOT/SP-431-be-add-authorizer-and-authorizer-date-columns
Sp 431 be add authorizer and authorizer date columns
This commit is contained in:
@ -18,6 +18,7 @@ import { UserNotificationEntity } from '../modules/user/entities';
|
|||||||
import { DeviceNotificationEntity } from '../modules/device/entities';
|
import { DeviceNotificationEntity } from '../modules/device/entities';
|
||||||
import { RegionEntity } from '../modules/region/entities';
|
import { RegionEntity } from '../modules/region/entities';
|
||||||
import { TimeZoneEntity } from '../modules/timezone/entities';
|
import { TimeZoneEntity } from '../modules/timezone/entities';
|
||||||
|
import { VisitorPasswordEntity } from '../modules/visitor-password/entities';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@ -50,6 +51,7 @@ import { TimeZoneEntity } from '../modules/timezone/entities';
|
|||||||
DeviceNotificationEntity,
|
DeviceNotificationEntity,
|
||||||
RegionEntity,
|
RegionEntity,
|
||||||
TimeZoneEntity,
|
TimeZoneEntity,
|
||||||
|
VisitorPasswordEntity,
|
||||||
],
|
],
|
||||||
namingStrategy: new SnakeNamingStrategy(),
|
namingStrategy: new SnakeNamingStrategy(),
|
||||||
synchronize: Boolean(JSON.parse(configService.get('DB_SYNC'))),
|
synchronize: Boolean(JSON.parse(configService.get('DB_SYNC'))),
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import { TimeZoneEntity } from '../../timezone/entities';
|
|||||||
import { OtpType } from '../../../../src/constants/otp-type.enum';
|
import { OtpType } from '../../../../src/constants/otp-type.enum';
|
||||||
import { RoleTypeEntity } from '../../role-type/entities';
|
import { RoleTypeEntity } from '../../role-type/entities';
|
||||||
import { SpaceEntity } from '../../space/entities';
|
import { SpaceEntity } from '../../space/entities';
|
||||||
|
import { VisitorPasswordEntity } from '../../visitor-password/entities';
|
||||||
|
|
||||||
@Entity({ name: 'user' })
|
@Entity({ name: 'user' })
|
||||||
export class UserEntity extends AbstractEntity<UserDto> {
|
export class UserEntity extends AbstractEntity<UserDto> {
|
||||||
@ -109,6 +110,11 @@ export class UserEntity extends AbstractEntity<UserDto> {
|
|||||||
nullable: true,
|
nullable: true,
|
||||||
})
|
})
|
||||||
timezone: TimeZoneEntity;
|
timezone: TimeZoneEntity;
|
||||||
|
@OneToMany(
|
||||||
|
() => VisitorPasswordEntity,
|
||||||
|
(visitorPassword) => visitorPassword.user,
|
||||||
|
)
|
||||||
|
public visitorPasswords: VisitorPasswordEntity[];
|
||||||
constructor(partial: Partial<UserEntity>) {
|
constructor(partial: Partial<UserEntity>) {
|
||||||
super();
|
super();
|
||||||
Object.assign(this, partial);
|
Object.assign(this, partial);
|
||||||
|
|||||||
1
libs/common/src/modules/visitor-password/dtos/index.ts
Normal file
1
libs/common/src/modules/visitor-password/dtos/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './visitor-password.dto';
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
import { IsNotEmpty, IsString } from 'class-validator';
|
||||||
|
|
||||||
|
export class VisitorPasswordDto {
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
public uuid: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
public authorizerUuid: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
public passwordTuyaUuid: string;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
export * from './visitor-password.entity';
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
import { Column, Entity, ManyToOne, JoinColumn, Index } from 'typeorm';
|
||||||
|
import { VisitorPasswordDto } from '../dtos';
|
||||||
|
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
||||||
|
import { UserEntity } from '../../user/entities/user.entity';
|
||||||
|
|
||||||
|
@Entity({ name: 'visitor-password' })
|
||||||
|
@Index('IDX_PASSWORD_TUYA_UUID', ['passwordTuyaUuid'])
|
||||||
|
export class VisitorPasswordEntity extends AbstractEntity<VisitorPasswordDto> {
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
unique: true,
|
||||||
|
})
|
||||||
|
public passwordTuyaUuid: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => UserEntity, (user) => user.visitorPasswords, {
|
||||||
|
nullable: false,
|
||||||
|
})
|
||||||
|
@JoinColumn({ name: 'authorizer_uuid' })
|
||||||
|
public user: UserEntity;
|
||||||
|
|
||||||
|
constructor(partial: Partial<VisitorPasswordEntity>) {
|
||||||
|
super();
|
||||||
|
Object.assign(this, partial);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
export * from './visitor-password.repository';
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import { DataSource, Repository } from 'typeorm';
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { VisitorPasswordEntity } from '../entities/visitor-password.entity';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class VisitorPasswordRepository extends Repository<VisitorPasswordEntity> {
|
||||||
|
constructor(private dataSource: DataSource) {
|
||||||
|
super(VisitorPasswordEntity, dataSource.createEntityManager());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { VisitorPasswordEntity } from './entities/visitor-password.entity';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
providers: [],
|
||||||
|
exports: [],
|
||||||
|
controllers: [],
|
||||||
|
imports: [TypeOrmModule.forFeature([VisitorPasswordEntity])],
|
||||||
|
})
|
||||||
|
export class VisitorPasswordRepositoryModule {}
|
||||||
@ -5,10 +5,24 @@ import { ConfigModule } from '@nestjs/config';
|
|||||||
import { DeviceRepositoryModule } from '@app/common/modules/device';
|
import { DeviceRepositoryModule } from '@app/common/modules/device';
|
||||||
import { DeviceRepository } from '@app/common/modules/device/repositories';
|
import { DeviceRepository } from '@app/common/modules/device/repositories';
|
||||||
import { PasswordEncryptionService } from './services/encryption.services';
|
import { PasswordEncryptionService } from './services/encryption.services';
|
||||||
|
import { VisitorPasswordRepository } from '@app/common/modules/visitor-password/repositories';
|
||||||
|
import { DeviceService } from 'src/device/services';
|
||||||
|
import { ProductRepository } from '@app/common/modules/product/repositories';
|
||||||
|
import { DeviceStatusFirebaseService } from '@app/common/firebase/devices-status/services/devices-status.service';
|
||||||
|
import { SpaceRepository } from '@app/common/modules/space/repositories';
|
||||||
@Module({
|
@Module({
|
||||||
imports: [ConfigModule, DeviceRepositoryModule],
|
imports: [ConfigModule, DeviceRepositoryModule],
|
||||||
controllers: [DoorLockController],
|
controllers: [DoorLockController],
|
||||||
providers: [DoorLockService, PasswordEncryptionService, DeviceRepository],
|
providers: [
|
||||||
|
DoorLockService,
|
||||||
|
PasswordEncryptionService,
|
||||||
|
DeviceRepository,
|
||||||
|
VisitorPasswordRepository,
|
||||||
|
DeviceService,
|
||||||
|
ProductRepository,
|
||||||
|
DeviceStatusFirebaseService,
|
||||||
|
SpaceRepository,
|
||||||
|
],
|
||||||
exports: [DoorLockService],
|
exports: [DoorLockService],
|
||||||
})
|
})
|
||||||
export class DoorLockModule {}
|
export class DoorLockModule {}
|
||||||
|
|||||||
@ -22,6 +22,8 @@ import { AddDoorLockOfflineTempMultipleTimeDto } from '../dtos/add.offline-temp.
|
|||||||
import { convertKeysToCamelCase } from '@app/common/helper/camelCaseConverter';
|
import { convertKeysToCamelCase } from '@app/common/helper/camelCaseConverter';
|
||||||
import { UpdateDoorLockOfflineTempDto } from '../dtos/update.offline-temp.dto';
|
import { UpdateDoorLockOfflineTempDto } from '../dtos/update.offline-temp.dto';
|
||||||
import { defaultDoorLockPass } from '@app/common/constants/default.door-lock-pass';
|
import { defaultDoorLockPass } from '@app/common/constants/default.door-lock-pass';
|
||||||
|
import { VisitorPasswordRepository } from '@app/common/modules/visitor-password/repositories';
|
||||||
|
import { DeviceService } from 'src/device/services';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DoorLockService {
|
export class DoorLockService {
|
||||||
@ -29,7 +31,9 @@ export class DoorLockService {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly configService: ConfigService,
|
private readonly configService: ConfigService,
|
||||||
private readonly deviceRepository: DeviceRepository,
|
private readonly deviceRepository: DeviceRepository,
|
||||||
|
private readonly deviceService: DeviceService,
|
||||||
private readonly passwordEncryptionService: PasswordEncryptionService,
|
private readonly passwordEncryptionService: PasswordEncryptionService,
|
||||||
|
private readonly visitorPasswordRepository: VisitorPasswordRepository,
|
||||||
) {
|
) {
|
||||||
const accessKey = this.configService.get<string>('auth-config.ACCESS_KEY');
|
const accessKey = this.configService.get<string>('auth-config.ACCESS_KEY');
|
||||||
const secretKey = this.configService.get<string>('auth-config.SECRET_KEY');
|
const secretKey = this.configService.get<string>('auth-config.SECRET_KEY');
|
||||||
@ -105,6 +109,10 @@ export class DoorLockService {
|
|||||||
HttpStatus.BAD_REQUEST,
|
HttpStatus.BAD_REQUEST,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const deviceTuyaDetails =
|
||||||
|
await this.deviceService.getDeviceDetailsByDeviceIdTuya(
|
||||||
|
deviceDetails.deviceTuyaUuid,
|
||||||
|
);
|
||||||
const passwords = await this.getTemporaryOfflinePasswordsTuya(
|
const passwords = await this.getTemporaryOfflinePasswordsTuya(
|
||||||
deviceDetails.deviceTuyaUuid,
|
deviceDetails.deviceTuyaUuid,
|
||||||
'multiple',
|
'multiple',
|
||||||
@ -115,23 +123,37 @@ export class DoorLockService {
|
|||||||
}
|
}
|
||||||
if (passwords.result.records.length > 0) {
|
if (passwords.result.records.length > 0) {
|
||||||
return fromVisitor
|
return fromVisitor
|
||||||
? convertKeysToCamelCase(passwords.result.records).map((password) => {
|
? Promise.all(
|
||||||
const timestampInSeconds = Math.floor(Date.now() / 1000);
|
convertKeysToCamelCase(passwords.result.records).map(
|
||||||
return {
|
async (password) => {
|
||||||
passwordId: `${password.pwdId}`,
|
const passwordFromDB = await this.getVisitorPasswordFromDB(
|
||||||
invalidTime: `${password.gmtExpired}`,
|
password.pwdId,
|
||||||
effectiveTime: `${password.gmtStart}`,
|
);
|
||||||
passwordCreated: `${password.gmtCreate}`,
|
const timestampInSeconds = Math.floor(Date.now() / 1000);
|
||||||
createdTime: password.pwdName,
|
return {
|
||||||
passwordType: 'OFFLINE_MULTIPLE',
|
passwordId: `${password.pwdId}`,
|
||||||
deviceUuid: doorLockUuid,
|
invalidTime: `${password.gmtExpired}`,
|
||||||
passwordStatus: isExpired
|
effectiveTime: `${password.gmtStart}`,
|
||||||
? 'EXPIRED'
|
passwordCreated: `${password.gmtCreate}`,
|
||||||
: timestampInSeconds > password.effectiveTime
|
createdTime: password.pwdName,
|
||||||
? 'EFFECTIVE'
|
passwordType: 'OFFLINE_MULTIPLE',
|
||||||
: 'TO_BE_EFFECTIVE',
|
deviceUuid: doorLockUuid,
|
||||||
};
|
deviceName: deviceTuyaDetails.name,
|
||||||
})
|
passwordStatus: isExpired
|
||||||
|
? 'EXPIRED'
|
||||||
|
: timestampInSeconds > password.effectiveTime
|
||||||
|
? 'EFFECTIVE'
|
||||||
|
: 'TO_BE_EFFECTIVE',
|
||||||
|
authorizerEmail: passwordFromDB
|
||||||
|
? passwordFromDB.user.email
|
||||||
|
: 'OTHER',
|
||||||
|
authorizerDate: passwordFromDB
|
||||||
|
? `${Math.floor(new Date(passwordFromDB.createdAt).getTime() / 1000)}`
|
||||||
|
: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
: convertKeysToCamelCase(passwords.result.records);
|
: convertKeysToCamelCase(passwords.result.records);
|
||||||
}
|
}
|
||||||
return passwords;
|
return passwords;
|
||||||
@ -158,6 +180,10 @@ export class DoorLockService {
|
|||||||
HttpStatus.BAD_REQUEST,
|
HttpStatus.BAD_REQUEST,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const deviceTuyaDetails =
|
||||||
|
await this.deviceService.getDeviceDetailsByDeviceIdTuya(
|
||||||
|
deviceDetails.deviceTuyaUuid,
|
||||||
|
);
|
||||||
const passwords = await this.getTemporaryOfflinePasswordsTuya(
|
const passwords = await this.getTemporaryOfflinePasswordsTuya(
|
||||||
deviceDetails.deviceTuyaUuid,
|
deviceDetails.deviceTuyaUuid,
|
||||||
'once',
|
'once',
|
||||||
@ -168,23 +194,38 @@ export class DoorLockService {
|
|||||||
}
|
}
|
||||||
if (passwords.result.records.length > 0) {
|
if (passwords.result.records.length > 0) {
|
||||||
return fromVisitor
|
return fromVisitor
|
||||||
? convertKeysToCamelCase(passwords.result.records).map((password) => {
|
? Promise.all(
|
||||||
const timestampInSeconds = Math.floor(Date.now() / 1000);
|
convertKeysToCamelCase(passwords.result.records).map(
|
||||||
return {
|
async (password) => {
|
||||||
passwordId: `${password.pwdId}`,
|
const passwordFromDB = await this.getVisitorPasswordFromDB(
|
||||||
invalidTime: `${password.gmtExpired}`,
|
password.pwdId,
|
||||||
effectiveTime: `${password.gmtStart}`,
|
);
|
||||||
createdTime: `${password.gmtCreate}`,
|
|
||||||
passwordName: password.pwdName,
|
const timestampInSeconds = Math.floor(Date.now() / 1000);
|
||||||
passwordType: 'OFFLINE_ONETIME',
|
return {
|
||||||
deviceUuid: doorLockUuid,
|
passwordId: `${password.pwdId}`,
|
||||||
passwordStatus: isExpired
|
invalidTime: `${password.gmtExpired}`,
|
||||||
? 'EXPIRED'
|
effectiveTime: `${password.gmtStart}`,
|
||||||
: timestampInSeconds > password.gmtStart
|
createdTime: `${password.gmtCreate}`,
|
||||||
? 'EFFECTIVE'
|
passwordName: password.pwdName,
|
||||||
: 'TO_BE_EFFECTIVE',
|
passwordType: 'OFFLINE_ONETIME',
|
||||||
};
|
deviceUuid: doorLockUuid,
|
||||||
})
|
deviceName: deviceTuyaDetails.name,
|
||||||
|
passwordStatus: isExpired
|
||||||
|
? 'EXPIRED'
|
||||||
|
: timestampInSeconds > password.gmtStart
|
||||||
|
? 'EFFECTIVE'
|
||||||
|
: 'TO_BE_EFFECTIVE',
|
||||||
|
authorizerEmail: passwordFromDB
|
||||||
|
? passwordFromDB.user.email
|
||||||
|
: 'OTHER',
|
||||||
|
authorizerDate: passwordFromDB
|
||||||
|
? `${Math.floor(new Date(passwordFromDB.createdAt).getTime() / 1000)}`
|
||||||
|
: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
: convertKeysToCamelCase(passwords.result.records);
|
: convertKeysToCamelCase(passwords.result.records);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,6 +253,10 @@ export class DoorLockService {
|
|||||||
HttpStatus.BAD_REQUEST,
|
HttpStatus.BAD_REQUEST,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const deviceTuyaDetails =
|
||||||
|
await this.deviceService.getDeviceDetailsByDeviceIdTuya(
|
||||||
|
deviceDetails.deviceTuyaUuid,
|
||||||
|
);
|
||||||
const passwords = await this.getOnlineTemporaryPasswordsMultipleTuya(
|
const passwords = await this.getOnlineTemporaryPasswordsMultipleTuya(
|
||||||
deviceDetails.deviceTuyaUuid,
|
deviceDetails.deviceTuyaUuid,
|
||||||
isExpired,
|
isExpired,
|
||||||
@ -240,24 +285,36 @@ export class DoorLockService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return fromVisitor
|
return fromVisitor
|
||||||
? convertKeysToCamelCase(passwordFiltered).map((password) => {
|
? Promise.all(
|
||||||
const timestampInSeconds = Math.floor(Date.now() / 1000);
|
convertKeysToCamelCase(passwordFiltered).map(async (password) => {
|
||||||
return {
|
const passwordFromDB = await this.getVisitorPasswordFromDB(
|
||||||
passwordId: `${password.id}`,
|
password.id,
|
||||||
invalidTime: `${password.invalidTime}`,
|
);
|
||||||
effectiveTime: `${password.effectiveTime}`,
|
const timestampInSeconds = Math.floor(Date.now() / 1000);
|
||||||
createdTime: '',
|
return {
|
||||||
scheduleList: password?.scheduleList,
|
passwordId: `${password.id}`,
|
||||||
passwordName: password.name,
|
invalidTime: `${password.invalidTime}`,
|
||||||
passwordType: 'ONLINE_MULTIPLE',
|
effectiveTime: `${password.effectiveTime}`,
|
||||||
deviceUuid: doorLockUuid,
|
createdTime: '',
|
||||||
passwordStatus: isExpired
|
scheduleList: password?.scheduleList,
|
||||||
? 'EXPIRED'
|
passwordName: password.name,
|
||||||
: timestampInSeconds > password.effectiveTime
|
passwordType: 'ONLINE_MULTIPLE',
|
||||||
? 'EFFECTIVE'
|
deviceUuid: doorLockUuid,
|
||||||
: 'TO_BE_EFFECTIVE',
|
deviceName: deviceTuyaDetails.name,
|
||||||
};
|
passwordStatus: isExpired
|
||||||
})
|
? 'EXPIRED'
|
||||||
|
: timestampInSeconds > password.effectiveTime
|
||||||
|
? 'EFFECTIVE'
|
||||||
|
: 'TO_BE_EFFECTIVE',
|
||||||
|
authorizerEmail: passwordFromDB
|
||||||
|
? passwordFromDB.user.email
|
||||||
|
: 'OTHER',
|
||||||
|
authorizerDate: passwordFromDB
|
||||||
|
? `${Math.floor(new Date(passwordFromDB.createdAt).getTime() / 1000)}`
|
||||||
|
: '',
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
)
|
||||||
: convertKeysToCamelCase(passwordFiltered);
|
: convertKeysToCamelCase(passwordFiltered);
|
||||||
}
|
}
|
||||||
if (fromVisitor) {
|
if (fromVisitor) {
|
||||||
@ -271,12 +328,34 @@ export class DoorLockService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async getVisitorPasswordFromDB(passwordId: string) {
|
||||||
|
try {
|
||||||
|
return await this.visitorPasswordRepository.findOne({
|
||||||
|
where: {
|
||||||
|
passwordTuyaUuid: passwordId,
|
||||||
|
},
|
||||||
|
relations: ['user'],
|
||||||
|
select: {
|
||||||
|
user: {
|
||||||
|
email: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpException(
|
||||||
|
error.message || 'Error retrieving visitor password from database',
|
||||||
|
error.status || HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async getOnlineTemporaryPasswordsOneTime(
|
async getOnlineTemporaryPasswordsOneTime(
|
||||||
doorLockUuid: string,
|
doorLockUuid: string,
|
||||||
fromVisitor?: boolean,
|
fromVisitor?: boolean,
|
||||||
isExpired?: boolean,
|
isExpired?: boolean,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
// Retrieve device details
|
||||||
const deviceDetails = await this.getDeviceByDeviceUuid(doorLockUuid);
|
const deviceDetails = await this.getDeviceByDeviceUuid(doorLockUuid);
|
||||||
|
|
||||||
if (!deviceDetails || !deviceDetails.deviceTuyaUuid) {
|
if (!deviceDetails || !deviceDetails.deviceTuyaUuid) {
|
||||||
@ -287,11 +366,17 @@ export class DoorLockService {
|
|||||||
HttpStatus.BAD_REQUEST,
|
HttpStatus.BAD_REQUEST,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const deviceTuyaDetails =
|
||||||
|
await this.deviceService.getDeviceDetailsByDeviceIdTuya(
|
||||||
|
deviceDetails.deviceTuyaUuid,
|
||||||
|
);
|
||||||
|
// Get online temporary passwords
|
||||||
const passwords = await this.getOnlineTemporaryPasswordsMultipleTuya(
|
const passwords = await this.getOnlineTemporaryPasswordsMultipleTuya(
|
||||||
deviceDetails.deviceTuyaUuid,
|
deviceDetails.deviceTuyaUuid,
|
||||||
isExpired,
|
isExpired,
|
||||||
);
|
);
|
||||||
if (passwords.result?.length > 0) {
|
if (passwords.result?.length > 0) {
|
||||||
|
// Filter and map the passwords
|
||||||
const passwordFiltered = passwords.result
|
const passwordFiltered = passwords.result
|
||||||
.filter((item) => item.type === 1)
|
.filter((item) => item.type === 1)
|
||||||
.map((password: any) => {
|
.map((password: any) => {
|
||||||
@ -314,24 +399,37 @@ export class DoorLockService {
|
|||||||
return password;
|
return password;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Process passwords with optimized query handling
|
||||||
return fromVisitor
|
return fromVisitor
|
||||||
? convertKeysToCamelCase(passwordFiltered).map((password) => {
|
? Promise.all(
|
||||||
const timestampInSeconds = Math.floor(Date.now() / 1000);
|
convertKeysToCamelCase(passwordFiltered).map(async (password) => {
|
||||||
return {
|
const passwordFromDB = await this.getVisitorPasswordFromDB(
|
||||||
passwordId: `${password.id}`,
|
password.id,
|
||||||
invalidTime: `${password.invalidTime}`,
|
);
|
||||||
effectiveTime: `${password.effectiveTime}`,
|
const timestampInSeconds = Math.floor(Date.now() / 1000);
|
||||||
createdTime: '',
|
return {
|
||||||
passwordName: password.name,
|
passwordId: `${password.id}`,
|
||||||
passwordType: 'ONLINE_ONETIME',
|
invalidTime: `${password.invalidTime}`,
|
||||||
deviceUuid: doorLockUuid,
|
effectiveTime: `${password.effectiveTime}`,
|
||||||
passwordStatus: isExpired
|
createdTime: '',
|
||||||
? 'EXPIRED'
|
passwordName: password.name,
|
||||||
: timestampInSeconds > password.effectiveTime
|
passwordType: 'ONLINE_ONETIME',
|
||||||
? 'EFFECTIVE'
|
deviceUuid: doorLockUuid,
|
||||||
: 'TO_BE_EFFECTIVE',
|
deviceName: deviceTuyaDetails.name,
|
||||||
};
|
passwordStatus: isExpired
|
||||||
})
|
? 'EXPIRED'
|
||||||
|
: timestampInSeconds > password.effectiveTime
|
||||||
|
? 'EFFECTIVE'
|
||||||
|
: 'TO_BE_EFFECTIVE',
|
||||||
|
authorizerEmail: passwordFromDB
|
||||||
|
? passwordFromDB.user.email
|
||||||
|
: 'OTHER',
|
||||||
|
authorizerDate: passwordFromDB
|
||||||
|
? `${Math.floor(new Date(passwordFromDB.createdAt).getTime() / 1000)}`
|
||||||
|
: '',
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
)
|
||||||
: convertKeysToCamelCase(passwordFiltered);
|
: convertKeysToCamelCase(passwordFiltered);
|
||||||
}
|
}
|
||||||
if (fromVisitor) {
|
if (fromVisitor) {
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import {
|
|||||||
HttpStatus,
|
HttpStatus,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
Get,
|
Get,
|
||||||
|
Req,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { ApiTags, ApiBearerAuth } from '@nestjs/swagger';
|
import { ApiTags, ApiBearerAuth } from '@nestjs/swagger';
|
||||||
import {
|
import {
|
||||||
@ -31,11 +32,14 @@ export class VisitorPasswordController {
|
|||||||
@Post('temporary-password/online/multiple-time')
|
@Post('temporary-password/online/multiple-time')
|
||||||
async addOnlineTemporaryPasswordMultipleTime(
|
async addOnlineTemporaryPasswordMultipleTime(
|
||||||
@Body() addDoorLockOnlineMultipleDto: AddDoorLockOnlineMultipleDto,
|
@Body() addDoorLockOnlineMultipleDto: AddDoorLockOnlineMultipleDto,
|
||||||
|
@Req() req: any,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
const userUuid = req.user.uuid;
|
||||||
const temporaryPasswords =
|
const temporaryPasswords =
|
||||||
await this.visitorPasswordService.addOnlineTemporaryPasswordMultipleTime(
|
await this.visitorPasswordService.addOnlineTemporaryPasswordMultipleTime(
|
||||||
addDoorLockOnlineMultipleDto,
|
addDoorLockOnlineMultipleDto,
|
||||||
|
userUuid,
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -54,11 +58,14 @@ export class VisitorPasswordController {
|
|||||||
@Post('temporary-password/online/one-time')
|
@Post('temporary-password/online/one-time')
|
||||||
async addOnlineTemporaryPassword(
|
async addOnlineTemporaryPassword(
|
||||||
@Body() addDoorLockOnlineOneTimeDto: AddDoorLockOnlineOneTimeDto,
|
@Body() addDoorLockOnlineOneTimeDto: AddDoorLockOnlineOneTimeDto,
|
||||||
|
@Req() req: any,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
const userUuid = req.user.uuid;
|
||||||
const temporaryPasswords =
|
const temporaryPasswords =
|
||||||
await this.visitorPasswordService.addOnlineTemporaryPasswordOneTime(
|
await this.visitorPasswordService.addOnlineTemporaryPasswordOneTime(
|
||||||
addDoorLockOnlineOneTimeDto,
|
addDoorLockOnlineOneTimeDto,
|
||||||
|
userUuid,
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -77,11 +84,14 @@ export class VisitorPasswordController {
|
|||||||
@Post('temporary-password/offline/one-time')
|
@Post('temporary-password/offline/one-time')
|
||||||
async addOfflineOneTimeTemporaryPassword(
|
async addOfflineOneTimeTemporaryPassword(
|
||||||
@Body() addDoorLockOfflineOneTimeDto: AddDoorLockOfflineOneTimeDto,
|
@Body() addDoorLockOfflineOneTimeDto: AddDoorLockOfflineOneTimeDto,
|
||||||
|
@Req() req: any,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
const userUuid = req.user.uuid;
|
||||||
const temporaryPassword =
|
const temporaryPassword =
|
||||||
await this.visitorPasswordService.addOfflineOneTimeTemporaryPassword(
|
await this.visitorPasswordService.addOfflineOneTimeTemporaryPassword(
|
||||||
addDoorLockOfflineOneTimeDto,
|
addDoorLockOfflineOneTimeDto,
|
||||||
|
userUuid,
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -101,11 +111,14 @@ export class VisitorPasswordController {
|
|||||||
async addOfflineMultipleTimeTemporaryPassword(
|
async addOfflineMultipleTimeTemporaryPassword(
|
||||||
@Body()
|
@Body()
|
||||||
addDoorLockOfflineMultipleDto: AddDoorLockOfflineMultipleDto,
|
addDoorLockOfflineMultipleDto: AddDoorLockOfflineMultipleDto,
|
||||||
|
@Req() req: any,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
const userUuid = req.user.uuid;
|
||||||
const temporaryPassword =
|
const temporaryPassword =
|
||||||
await this.visitorPasswordService.addOfflineMultipleTimeTemporaryPassword(
|
await this.visitorPasswordService.addOfflineMultipleTimeTemporaryPassword(
|
||||||
addDoorLockOfflineMultipleDto,
|
addDoorLockOfflineMultipleDto,
|
||||||
|
userUuid,
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { VisitorPasswordRepository } from './../../../libs/common/src/modules/visitor-password/repositories/visitor-password.repository';
|
||||||
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
|
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
|
||||||
import { TuyaContext } from '@tuya/tuya-connector-nodejs';
|
import { TuyaContext } from '@tuya/tuya-connector-nodejs';
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
@ -26,6 +27,7 @@ export class VisitorPasswordService {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly configService: ConfigService,
|
private readonly configService: ConfigService,
|
||||||
private readonly deviceRepository: DeviceRepository,
|
private readonly deviceRepository: DeviceRepository,
|
||||||
|
private readonly visitorPasswordRepository: VisitorPasswordRepository,
|
||||||
private readonly emailService: EmailService,
|
private readonly emailService: EmailService,
|
||||||
private readonly doorLockService: DoorLockService,
|
private readonly doorLockService: DoorLockService,
|
||||||
private readonly deviceService: DeviceService,
|
private readonly deviceService: DeviceService,
|
||||||
@ -43,6 +45,7 @@ export class VisitorPasswordService {
|
|||||||
|
|
||||||
async addOfflineMultipleTimeTemporaryPassword(
|
async addOfflineMultipleTimeTemporaryPassword(
|
||||||
addDoorLockOfflineMultipleDto: AddDoorLockOfflineMultipleDto,
|
addDoorLockOfflineMultipleDto: AddDoorLockOfflineMultipleDto,
|
||||||
|
userUuid: string,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const deviceResults = await Promise.allSettled(
|
const deviceResults = await Promise.allSettled(
|
||||||
@ -87,7 +90,14 @@ export class VisitorPasswordService {
|
|||||||
emailBody,
|
emailBody,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (createMultipleOfflinePass.result.offline_temp_password_id) {
|
||||||
|
await this.visitorPasswordRepository.save({
|
||||||
|
passwordTuyaUuid: `${createMultipleOfflinePass.result.offline_temp_password_id}`,
|
||||||
|
user: {
|
||||||
|
uuid: userUuid,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
result: createMultipleOfflinePass.result,
|
result: createMultipleOfflinePass.result,
|
||||||
@ -156,6 +166,7 @@ export class VisitorPasswordService {
|
|||||||
|
|
||||||
async addOfflineOneTimeTemporaryPassword(
|
async addOfflineOneTimeTemporaryPassword(
|
||||||
addDoorLockOfflineOneTimeDto: AddDoorLockOfflineOneTimeDto,
|
addDoorLockOfflineOneTimeDto: AddDoorLockOfflineOneTimeDto,
|
||||||
|
userUuid: string,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const deviceResults = await Promise.allSettled(
|
const deviceResults = await Promise.allSettled(
|
||||||
@ -200,7 +211,14 @@ export class VisitorPasswordService {
|
|||||||
emailBody,
|
emailBody,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (createOnceOfflinePass.result.offline_temp_password_id) {
|
||||||
|
await this.visitorPasswordRepository.save({
|
||||||
|
passwordTuyaUuid: `${createOnceOfflinePass.result.offline_temp_password_id}`,
|
||||||
|
user: {
|
||||||
|
uuid: userUuid,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
result: createOnceOfflinePass.result,
|
result: createOnceOfflinePass.result,
|
||||||
@ -299,6 +317,7 @@ export class VisitorPasswordService {
|
|||||||
}
|
}
|
||||||
async addOnlineTemporaryPasswordMultipleTime(
|
async addOnlineTemporaryPasswordMultipleTime(
|
||||||
addDoorLockOnlineMultipleDto: AddDoorLockOnlineMultipleDto,
|
addDoorLockOnlineMultipleDto: AddDoorLockOnlineMultipleDto,
|
||||||
|
userUuid: string,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const deviceResults = await Promise.allSettled(
|
const deviceResults = await Promise.allSettled(
|
||||||
@ -343,7 +362,14 @@ export class VisitorPasswordService {
|
|||||||
emailBody,
|
emailBody,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (createPass.result.id) {
|
||||||
|
await this.visitorPasswordRepository.save({
|
||||||
|
passwordTuyaUuid: `${createPass.result.id}`,
|
||||||
|
user: {
|
||||||
|
uuid: userUuid,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
id: createPass.result.id,
|
id: createPass.result.id,
|
||||||
@ -431,18 +457,18 @@ export class VisitorPasswordService {
|
|||||||
this.doorLockService
|
this.doorLockService
|
||||||
.getOnlineTemporaryPasswordsMultiple(deviceId.uuid, true, true)
|
.getOnlineTemporaryPasswordsMultiple(deviceId.uuid, true, true)
|
||||||
.catch(() => {}),
|
.catch(() => {}),
|
||||||
this.doorLockService
|
|
||||||
.getOfflineOneTimeTemporaryPasswords(deviceId.uuid, true, true)
|
|
||||||
.catch(() => {}),
|
|
||||||
this.doorLockService
|
this.doorLockService
|
||||||
.getOfflineOneTimeTemporaryPasswords(deviceId.uuid, true, false)
|
.getOfflineOneTimeTemporaryPasswords(deviceId.uuid, true, false)
|
||||||
.catch(() => {}),
|
.catch(() => {}),
|
||||||
this.doorLockService
|
this.doorLockService
|
||||||
.getOfflineMultipleTimeTemporaryPasswords(deviceId.uuid, true, true)
|
.getOfflineOneTimeTemporaryPasswords(deviceId.uuid, true, true)
|
||||||
.catch(() => {}),
|
.catch(() => {}),
|
||||||
this.doorLockService
|
this.doorLockService
|
||||||
.getOfflineMultipleTimeTemporaryPasswords(deviceId.uuid, true, false)
|
.getOfflineMultipleTimeTemporaryPasswords(deviceId.uuid, true, false)
|
||||||
.catch(() => {}),
|
.catch(() => {}),
|
||||||
|
this.doorLockService
|
||||||
|
.getOfflineMultipleTimeTemporaryPasswords(deviceId.uuid, true, true)
|
||||||
|
.catch(() => {}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
return (await Promise.all(data)).flat().filter((datum) => {
|
return (await Promise.all(data)).flat().filter((datum) => {
|
||||||
@ -476,6 +502,7 @@ export class VisitorPasswordService {
|
|||||||
|
|
||||||
async addOnlineTemporaryPasswordOneTime(
|
async addOnlineTemporaryPasswordOneTime(
|
||||||
addDoorLockOnlineOneTimeDto: AddDoorLockOnlineOneTimeDto,
|
addDoorLockOnlineOneTimeDto: AddDoorLockOnlineOneTimeDto,
|
||||||
|
userUuid: string,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const deviceResults = await Promise.allSettled(
|
const deviceResults = await Promise.allSettled(
|
||||||
@ -519,7 +546,14 @@ export class VisitorPasswordService {
|
|||||||
emailBody,
|
emailBody,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (createPass.result.id) {
|
||||||
|
await this.visitorPasswordRepository.save({
|
||||||
|
passwordTuyaUuid: `${createPass.result.id}`,
|
||||||
|
user: {
|
||||||
|
uuid: userUuid,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
id: createPass.result.id,
|
id: createPass.result.id,
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import { DeviceService } from 'src/device/services';
|
|||||||
import { ProductRepository } from '@app/common/modules/product/repositories';
|
import { ProductRepository } from '@app/common/modules/product/repositories';
|
||||||
import { DeviceStatusFirebaseService } from '@app/common/firebase/devices-status/services/devices-status.service';
|
import { DeviceStatusFirebaseService } from '@app/common/firebase/devices-status/services/devices-status.service';
|
||||||
import { SpaceRepository } from '@app/common/modules/space/repositories';
|
import { SpaceRepository } from '@app/common/modules/space/repositories';
|
||||||
|
import { VisitorPasswordRepository } from '@app/common/modules/visitor-password/repositories';
|
||||||
@Module({
|
@Module({
|
||||||
imports: [ConfigModule, DeviceRepositoryModule, DoorLockModule],
|
imports: [ConfigModule, DeviceRepositoryModule, DoorLockModule],
|
||||||
controllers: [VisitorPasswordController],
|
controllers: [VisitorPasswordController],
|
||||||
@ -23,6 +24,7 @@ import { SpaceRepository } from '@app/common/modules/space/repositories';
|
|||||||
DeviceStatusFirebaseService,
|
DeviceStatusFirebaseService,
|
||||||
SpaceRepository,
|
SpaceRepository,
|
||||||
DeviceRepository,
|
DeviceRepository,
|
||||||
|
VisitorPasswordRepository,
|
||||||
],
|
],
|
||||||
exports: [VisitorPasswordService],
|
exports: [VisitorPasswordService],
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user