chore: project fix

This commit is contained in:
xiaojunnuo
2026-03-04 23:53:19 +08:00
parent 17dd77cc96
commit 5ee3874b7e
14 changed files with 48 additions and 48 deletions

View File

@@ -170,9 +170,7 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
}
if (this.ctx?.define?.onlyAdmin) {
if (!this.isAdmin()) {
throw new Error("只有管理员才能运行此任务");
}
this.checkAdmin();
}
}
@@ -284,6 +282,12 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
return this.ctx.user.role === "admin";
}
checkAdmin() {
if (!this.isAdmin()) {
throw new Error("只有“管理员”或“系统级项目”才有权限运行此插件任务");
}
}
getStepFromPipeline(stepId: string) {
let found: any = null;
RunnableCollection.each(this.ctx.pipeline.stages, step => {

View File

@@ -734,7 +734,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
}),
},
column: {
width: 100,
width: 140,
sorter: true,
align: "center",
},
@@ -757,7 +757,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
helper: t("monitor.ipSyncModeHelper"),
},
column: {
width: 100,
width: 140,
sorter: true,
align: "center",
},
@@ -779,7 +779,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
helper: t("monitor.ipIgnoreCoherenceHelper"),
},
column: {
width: 100,
width: 180,
sorter: true,
align: "center",
},

View File

@@ -16,13 +16,16 @@ import { useCertViewer } from "/@/views/certd/pipeline/use";
import { useI18n } from "/src/locales";
import { useDicts } from "../dicts";
import { useProjectStore } from "/@/store/project";
import { useCrudPermission } from "/@/plugin/permission";
export default function ({ crudExpose, context: { selectedRowKeys, openCertApplyDialog, hasActionPermission } }: CreateCrudOptionsProps): CreateCrudOptionsRet {
export default function ({ crudExpose, context: { selectedRowKeys, openCertApplyDialog, permission } }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const router = useRouter();
const lastResRef = ref();
const { t } = useI18n();
const { hasActionPermission } = useCrudPermission({ permission });
const { openUploadCreateDialog } = useCertUpload();
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {

View File

@@ -104,7 +104,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
helper: t("certd.ent.isSystemHelper"),
},
column: {
width: 100,
width: 150,
},
},
adminId: {

View File

@@ -20,8 +20,6 @@ export class CnameProviderController extends BaseController {
@Post('/list', { summary: Constants.per.authOnly })
async list(@Body(ALL) body: any) {
body.query = body.query ?? {};
body.query.userId = this.getUserId();
const res = await this.providerService.list({});
return this.ok(res);
}

View File

@@ -67,50 +67,51 @@ export class CnameRecordController extends CrudController<CnameRecordService> {
@Post('/info', { summary: Constants.per.authOnly })
async info(@Query('id') id: number) {
await this.service.checkUserId(id, this.getUserId());
await this.checkOwner(this.getService(), id, "read");
return super.info(id);
}
@Post('/delete', { summary: Constants.per.authOnly })
async delete(@Query('id') id: number) {
await this.service.checkUserId(id, this.getUserId());
await this.checkOwner(this.getService(), id, "write");
return super.delete(id);
}
@Post('/deleteByIds', { summary: Constants.per.authOnly })
async deleteByIds(@Body(ALL) body: any) {
const {userId,projectId} = await this.getProjectUserIdWrite();
await this.service.delete(body.ids, {
userId: this.getUserId(),
userId,
projectId,
});
return this.ok();
}
@Post('/getByDomain', { summary: Constants.per.authOnly })
async getByDomain(@Body(ALL) body: { domain: string; createOnNotFound: boolean }) {
const userId = this.getUserId();
const res = await this.service.getByDomain(body.domain, userId, body.createOnNotFound);
const {userId,projectId} = await this.getProjectUserIdRead();
const res = await this.service.getByDomain(body.domain, userId,projectId, body.createOnNotFound);
return this.ok(res);
}
@Post('/verify', { summary: Constants.per.authOnly })
async verify(@Body(ALL) body: { id: number }) {
const userId = this.getUserId();
await this.service.checkUserId(body.id, userId);
await this.checkOwner(this.getService(), body.id, "read");
const res = await this.service.verify(body.id);
return this.ok(res);
}
@Post('/resetStatus', { summary: Constants.per.authOnly })
async resetStatus(@Body(ALL) body: { id: number }) {
const userId = this.getUserId();
await this.service.checkUserId(body.id, userId);
await this.checkOwner(this.getService(), body.id, "read");
const res = await this.service.resetStatus(body.id);
return this.ok(res);
}
@Post('/import', { summary: Constants.per.authOnly })
async import(@Body(ALL) body: { domainList: string; cnameProviderId: any }) {
const userId = this.getUserId();
const {userId,projectId} = await this.getProjectUserIdWrite();
const res = await this.service.doImport({
userId,
projectId,
domainList: body.domainList,
cnameProviderId: body.cnameProviderId,
});

View File

@@ -164,8 +164,8 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
// // 3. 检查原域名是否有cname记录
// }
async getWithAccessByDomain(domain: string, userId: number) {
const record: CnameRecord = await this.getByDomain(domain, userId);
async getWithAccessByDomain(domain: string, userId: number,projectId?:number) {
const record: CnameRecord = await this.getByDomain(domain, userId,projectId);
if (record.cnameProvider.id > 0) {
//自定义cname服务
record.cnameProvider.access = await this.accessService.getAccessById(record.cnameProvider.accessId, false);
@@ -179,17 +179,17 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
return record;
}
async getByDomain(domain: string, userId: number, createOnNotFound = true) {
async getByDomain(domain: string, userId: number,projectId?:number, createOnNotFound = true) {
if (!domain) {
throw new ValidateException("domain不能为空");
}
if (userId == null) {
throw new ValidateException("userId不能为空");
}
let record = await this.getRepository().findOne({ where: { domain, userId } });
let record = await this.getRepository().findOne({ where: { domain, userId,projectId } });
if (record == null) {
if (createOnNotFound) {
record = await this.add({ domain, userId });
record = await this.add({ domain, userId,projectId });
} else {
throw new ValidateException(`找不到${domain}的CNAME记录`);
}
@@ -489,8 +489,8 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
await this.getRepository().update(id, { status: "cname", mainDomain: "" });
}
async doImport(req:{ userId: number; domainList: string; cnameProviderId: any }) {
const {userId,cnameProviderId,domainList} = req;
async doImport(req:{ userId: number; projectId: number; domainList: string; cnameProviderId: any }) {
const {userId,projectId,cnameProviderId,domainList} = req;
const domains = domainList.split("\n").map(item => item.trim()).filter(item => item.length > 0);
if (domains.length === 0) {
throw new ValidateException("域名列表不能为空");
@@ -504,18 +504,19 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
key: "user_"+userId,
title: "导入CNAME记录",
run: async (task) => {
await this._import({ userId, domains, cnameProviderId },task);
await this._import({ userId,projectId, domains, cnameProviderId },task);
}
}));
}
async _import(req :{ userId: number; domains: string[]; cnameProviderId: any },task:BackTask) {
async _import(req :{ userId: number; projectId: number; domains: string[]; cnameProviderId: any },task:BackTask) {
const userId = req.userId;
for (const domain of req.domains) {
const old = await this.getRepository().findOne({
where: {
userId: req.userId,
domain,
projectId: req.projectId,
},
});
if (old) {
@@ -526,6 +527,7 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
await this.add({
userId,
domain: domain,
projectId: req.projectId,
cnameProviderId: req.cnameProviderId,
});
}catch(e){

View File

@@ -2,13 +2,15 @@ import { CnameRecord, ICnameProxyService } from '@certd/pipeline';
export class CnameProxyService implements ICnameProxyService {
userId: number;
getter: <T>(domain: string, userId?: number) => Promise<T>;
constructor(userId: number, getter: (domain: string, userId: number) => Promise<any>) {
projectId: number;
getter: <T>(domain: string, userId?: number, projectId?: number) => Promise<T>;
constructor(userId: number, projectId: number, getter: (domain: string, userId: number, projectId: number) => Promise<any>) {
this.userId = userId;
this.projectId = projectId;
this.getter = getter;
}
async getByDomain(domain: string): Promise<CnameRecord> {
return await this.getter<CnameRecord>(domain, this.userId);
return await this.getter<CnameRecord>(domain, this.userId, this.projectId);
}
}

View File

@@ -59,7 +59,7 @@ export class TaskServiceGetter implements IServiceGetter{
async getCnameProxyService(): Promise<CnameProxyService> {
const cnameRecordService:CnameRecordService = await this.appCtx.getAsync("cnameRecordService")
return new CnameProxyService(this.userId, cnameRecordService.getWithAccessByDomain.bind(cnameRecordService));
return new CnameProxyService(this.userId, this.projectId, cnameRecordService.getWithAccessByDomain.bind(cnameRecordService));
}
async getNotificationService(): Promise<NotificationGetter> {

View File

@@ -157,9 +157,7 @@ export class DBBackupPlugin extends AbstractPlusTaskPlugin {
async onInstance() {}
async execute(): Promise<void> {
if (!this.isAdmin()) {
throw new Error("只有管理员才能运行此任务");
}
this.checkAdmin();
this.logger.info("开始备份数据库");

View File

@@ -32,9 +32,7 @@ export class DeployToCertdPlugin extends AbstractTaskPlugin {
cert!: CertInfo;
async onInstance() { }
async execute(): Promise<void> {
if (!this.isAdmin()) {
throw new Error('只有管理员才能运行此任务');
}
this.checkAdmin();
//部署证书
let crtPath = "ssl/cert.crt";

View File

@@ -17,9 +17,7 @@ import { httpsServer } from '../../modules/auto/https/server.js';
export class RestartCertdPlugin extends AbstractTaskPlugin {
async onInstance() {}
async execute(): Promise<void> {
if (!this.isAdmin()) {
throw new Error('只有管理员才能运行此任务');
}
this.checkAdmin();
this.logger.info('Certd https server 将在 3 秒后重启');
await this.ctx.utils.sleep(3000);
await httpsServer.restart();

View File

@@ -47,9 +47,7 @@ export class CustomScriptPlugin extends AbstractTaskPlugin {
async onInstance() {}
async execute(): Promise<void> {
if (!this.isAdmin()) {
throw new Error('只有管理员才能运行此任务');
}
this.checkAdmin();
this.logger.info('执行自定义脚本:\n', this.script);
const ctx: CustomScriptContext = {
CertReader,

View File

@@ -198,9 +198,7 @@ export class CopyCertToLocalPlugin extends AbstractTaskPlugin {
fs.copyFileSync(srcFile, destFile);
}
async execute(): Promise<void> {
if (!this.isAdmin()) {
throw new Error('只有管理员才能运行此任务');
}
this.checkAdmin();
let { crtPath, keyPath, icPath, pfxPath, derPath, jksPath } = this;
const certReader = new CertReader(this.cert);