import { Injectable, Logger } from '@nestjs/common'; import IORedis, { Redis } from 'ioredis'; import { CacheConst } from './cache.const'; import { convertShortTimeToSecond, generateOTP } from 'src/share/tool'; import { AppConfigService } from 'src/config/app/app-config.service'; @Injectable() export class RedisClientService { private client: Redis; private logger: Logger = new Logger(RedisClientService.name); public readonly TTL_IMPORT: number = 60 * 60 * 24; public readonly TTL_OTP: number = 90; constructor(private configService: AppConfigService) { this.client = new IORedis(this.configService.redisUri); } getClient() { if (!this.client) { this.client = new IORedis(this.configService.redisUri); } return this.client; } private async delKeys(key: string) { try { const client = this.client; const keys = await this.client.keys(key); await Promise.all(keys.map((e) => client.del(e))); } catch (error) { return; } } async markLogin(uid: number, tid: string, prefix = 'admin') { try { const keyAccess = CacheConst.genKeyAccessToken(uid, tid, prefix); const keyRefresh = CacheConst.genKeyRefreshToken(uid, tid, prefix); const accessTokenTTL = convertShortTimeToSecond(this.configService.jwtExpiresIn) || 300; const refreshTokenTTL = convertShortTimeToSecond(this.configService.jwtRefreshIn) || 1000; await this.client.set(keyAccess, '1', 'EX', accessTokenTTL); await this.client.set(keyRefresh, '1', 'EX', refreshTokenTTL); } catch (error) { this.logger.error(error.message); } } async delMarkLogin(uid: string, tid: string, prefix = 'admin') { try { const keyAccess = CacheConst.genKeyAccessToken(uid, tid, prefix); const keyRefresh = CacheConst.genKeyRefreshToken(uid, tid, prefix); const keyPublicName = CacheConst.genKeyPubicName(uid, tid); await this.delKeys(keyAccess); await this.delKeys(keyRefresh); await this.delKeys(keyPublicName); } catch (error) { this.logger.error(error.message); } } async getPublicName(uid: string, tid: string) { const keyPublicName = CacheConst.genKeyPubicName(uid, tid); this.logger.debug( `${this.getPublicName.name} keyPublicName: ${keyPublicName}`, ); const publicName = await this.getClient().get(keyPublicName); this.logger.debug(`${this.getPublicName.name} publicName: ${publicName}`); return publicName; } async setPublicName(uid: string | number, tid: string, name: string) { const keyPublicName = CacheConst.genKeyPubicName(uid, tid); await this.getClient().set(keyPublicName, name); } async checkMarkLogin(uid: string | number, tid: string, prefix = 'admin') { try { const keyadminAccess = await this.client.get( `${CacheConst.genKeyAccessToken(uid, tid, prefix)}`, ); return { key: keyadminAccess, isMark: Boolean(keyadminAccess), }; } catch (error) { this.logger.error(error.message); return null; } } async checkRefreshTokenFound(uid: string, tid: string, prefix = 'admin') { try { const keyRefresh = await this.client.get( `${CacheConst.genKeyRefreshToken(uid, tid, prefix)}`, ); return Boolean(keyRefresh); } catch (error) { this.logger.error(error.message); return null; } } async setOTP(id: string, data: any) { const otp = generateOTP(); if (!id) { throw new Error('id not found'); } const jsonData = JSON.stringify(data); const key = `${otp}:${id}`; await this.client.set(key, jsonData, 'EX', this.TTL_OTP); return otp; } }