Files
certd/packages/ui/certd-server/src/modules/open/service/open-key-service.ts
T

89 lines
2.7 KiB
TypeScript
Raw Normal View History

2025-01-15 01:05:34 +08:00
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { BaseService, Constants, CodeException, PageReq } from '@certd/lib-server';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { OpenKeyEntity } from '../entity/open-key.js';
import { utils } from '@certd/basic';
import crypto from 'crypto';
export type OpenKey = {
userId: number;
keyId: string;
keySecret: string;
encrypt: boolean;
};
@Provide()
2025-01-15 01:05:34 +08:00
@Scope(ScopeEnum.Request, { allowDowngrade: true })
export class OpenKeyService extends BaseService<OpenKeyEntity> {
@InjectEntityModel(OpenKeyEntity)
repository: Repository<OpenKeyEntity>;
//@ts-ignore
getRepository() {
return this.repository;
}
async page(pageReq: PageReq<OpenKeyEntity>) {
return await super.page(pageReq);
}
2025-01-15 01:26:23 +08:00
async add(bean: OpenKeyEntity) {
return await this.generate(bean.userId);
}
async generate(userId: number) {
const keyId = utils.id.simpleNanoId(18) + '_key';
const secretKey = crypto.randomBytes(32);
2025-01-15 01:26:23 +08:00
const keySecret = Buffer.from(secretKey).toString('hex');
const entity = new OpenKeyEntity();
entity.userId = userId;
entity.keyId = keyId;
entity.keySecret = keySecret;
await this.repository.save(entity);
2025-01-15 01:26:23 +08:00
return entity;
}
async getByKeyId(keyId: string) {
return this.repository.findOne({ where: { keyId } });
}
async verifyOpenKey(openKey: string): Promise<OpenKey> {
// openkey 组成,content = base64({keyId,t,encrypt,signType}) ,sign = md5({keyId,t,encrypt,signType}secret) , key = content.sign
const [content, sign] = openKey.split('.');
const contentJson = Buffer.from(content, 'base64').toString();
const { keyId, t, encrypt, signType } = JSON.parse(contentJson);
// 正负不超过3分钟 ,timestamps单位为秒
if (Math.abs(Number(t) - Math.floor(Date.now() / 1000)) > 180) {
throw new CodeException(Constants.res.openKeyExpiresError);
}
const entity = await this.getByKeyId(keyId);
if (!entity) {
throw new Error('openKey不存在');
}
const secret = entity.keySecret;
let computedSign = '';
if (signType === 'md5') {
computedSign = utils.hash.md5(contentJson + secret);
} else if (signType === 'sha256') {
computedSign = utils.hash.sha256(contentJson + secret);
} else {
throw new CodeException(Constants.res.openKeySignTypeError);
}
if (computedSign !== sign) {
throw new CodeException(Constants.res.openKeySignError);
}
if (!entity.userId) {
throw new CodeException(Constants.res.openKeyError);
}
return {
userId: entity.userId,
keyId: entity.keyId,
keySecret: entity.keySecret,
encrypt: encrypt,
};
}
}