fix: 修复偶尔下载证书报未授权的错误

This commit is contained in:
xiaojunnuo
2026-02-27 00:37:24 +08:00
parent b2c421600c
commit 316537eb4d
10 changed files with 48 additions and 14 deletions

View File

@@ -12,8 +12,8 @@
</template> </template>
<div class="rounded pl-3 pr-3 px-2 py-1 flex-center flex pointer items-center bg-accent h-10 button-text" title="当前项目"> <div class="rounded pl-3 pr-3 px-2 py-1 flex-center flex pointer items-center bg-accent h-10 button-text" title="当前项目">
<!-- <fs-icon icon="ion:apps" class="mr-1"></fs-icon> --> <!-- <fs-icon icon="ion:apps" class="mr-1"></fs-icon> -->
<fs-icon :icon="currentIcon" class="mr-5"></fs-icon>
当前项目{{ projectStore.currentProject?.name || "..." }} 当前项目{{ projectStore.currentProject?.name || "..." }}
<fs-icon :icon="currentIcon" class="ml-5"></fs-icon>
</div> </div>
</a-dropdown> </a-dropdown>
</template> </template>

View File

@@ -1,8 +1,8 @@
<template> <template>
<a-tag color="green" class="flex-center flex pointer items-center button-text" title="当前项目"> <a-tag color="green" class="flex-center flex pointer items-center button-text" title="当前项目">
<!-- <fs-icon icon="ion:apps" class="mr-1"></fs-icon> --> <!-- <fs-icon icon="ion:apps" class="mr-1"></fs-icon> -->
<fs-icon :icon="currentIcon" class="mr-5"></fs-icon>
当前项目{{ projectStore.currentProject?.name || "..." }} 当前项目{{ projectStore.currentProject?.name || "..." }}
<fs-icon :icon="currentIcon" class="ml-5"></fs-icon>
</a-tag> </a-tag>
</template> </template>

View File

@@ -12,6 +12,7 @@ import { useCertUpload } from "/@/views/certd/pipeline/cert-upload/use";
import { useSettingStore } from "/@/store/settings"; import { useSettingStore } from "/@/store/settings";
import { useProjectStore } from "/@/store/project"; import { useProjectStore } from "/@/store/project";
import { useDicts } from "../../dicts"; import { useDicts } from "../../dicts";
import { useUserStore } from "/@/store/user";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet { export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { t } = useI18n(); const { t } = useI18n();
@@ -39,6 +40,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
const { myProjectDict } = useDicts(); const { myProjectDict } = useDicts();
const settingStore = useSettingStore(); const settingStore = useSettingStore();
const projectStore = useProjectStore(); const projectStore = useProjectStore();
const userStore = useUserStore();
const model = useModal(); const model = useModal();
const viewCert = async (row: any) => { const viewCert = async (row: any) => {
const cert = await api.GetCert(row.id); const cert = await api.GetCert(row.id);
@@ -140,7 +142,12 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
notification.error({ message: t("certd.certificateNotGenerated") }); notification.error({ message: t("certd.certificateNotGenerated") });
return; return;
} }
window.open("/api/monitor/cert/download?id=" + row.id); let url = "/api/monitor/cert/download?id=" + row.id;
if (projectStore.isEnterprise) {
url += `&projectId=${projectStore.currentProject?.id}`;
}
url += `&token=${userStore.getToken}`;
window.open(url);
}, },
}, },
}, },

View File

@@ -3,8 +3,12 @@ import { notification } from "ant-design-vue";
import CertView from "/@/views/certd/pipeline/cert-view.vue"; import CertView from "/@/views/certd/pipeline/cert-view.vue";
import { env } from "/@/utils/util.env"; import { env } from "/@/utils/util.env";
import { useModal } from "/@/use/use-modal"; import { useModal } from "/@/use/use-modal";
import { useProjectStore } from "/@/store/project";
import { useUserStore } from "/@/store/user";
export function useCertViewer() { export function useCertViewer() {
const projectStore = useProjectStore();
const userStore = useUserStore();
const model = useModal(); const model = useModal();
const viewCert = async (id: number) => { const viewCert = async (id: number) => {
const cert = await api.GetCert(id); const cert = await api.GetCert(id);
@@ -33,7 +37,11 @@ export function useCertViewer() {
content: () => { content: () => {
const children = []; const children = [];
for (const file of files) { for (const file of files) {
const downloadUrl = `${env.API}/pi/history/download?pipelineId=${id}&fileId=${file.id}`; let downloadUrl = `${env.API}/pi/history/download?pipelineId=${id}&fileId=${file.id}`;
if (projectStore.isEnterprise) {
downloadUrl += `&projectId=${projectStore.currentProject?.id}`;
}
downloadUrl += `&token=${userStore.getToken}`;
children.push( children.push(
<div> <div>
<div class={"flex-o m-5"}> <div class={"flex-o m-5"}>

View File

@@ -40,9 +40,7 @@ export class LoginController extends BaseController {
} }
private writeTokenCookie(token: { expire: any; token: any }) { private writeTokenCookie(token: { expire: any; token: any }) {
this.ctx.cookies.set("certd_token", token.token, { // this.loginService.writeTokenCookie(this.ctx,token);
maxAge: 1000 * token.expire
});
} }
@Post('/loginBySms', { summary: Constants.per.guest }) @Post('/loginBySms', { summary: Constants.per.guest })

View File

@@ -70,6 +70,8 @@ export class ConnectController extends BaseController {
}) })
return this.ok({ loginUrl, ticket }); return this.ok({ loginUrl, ticket });
} }
@Get('/callback/:type', { summary: Constants.per.guest }) @Get('/callback/:type', { summary: Constants.per.guest })
public async callback(@Param('type') type: string, @Query() query: Record<string, string>) { public async callback(@Param('type') type: string, @Query() query: Record<string, string>) {
@@ -154,10 +156,15 @@ export class ConnectController extends BaseController {
}); });
} }
this.writeTokenCookie(loginRes);
//返回登录成功token //返回登录成功token
return this.ok(loginRes); return this.ok(loginRes);
} }
private writeTokenCookie(token: { expire: any; token: any }) {
// this.loginService.writeTokenCookie(this.ctx,token);
}
@Post('/autoRegister', { summary: Constants.per.guest }) @Post('/autoRegister', { summary: Constants.per.guest })
public async autoRegister(@Body(ALL) body: { validationCode: string, type: string }) { public async autoRegister(@Body(ALL) body: { validationCode: string, type: string }) {
@@ -183,6 +190,7 @@ export class ConnectController extends BaseController {
}); });
const loginRes = await this.loginService.generateToken(newUser); const loginRes = await this.loginService.generateToken(newUser);
this.writeTokenCookie(loginRes);
return this.ok(loginRes); return this.ok(loginRes);
} }

View File

@@ -162,12 +162,15 @@ export class CertInfoController extends CrudController<CertInfoService> {
@Get('/download', { summary: Constants.per.authOnly }) @Get('/download', { summary: Constants.per.authOnly })
async download(@Query('id') id: number) { async download(@Query('id') id: number) {
await this.checkOwner(this.getService(),id,"read"); const {userId,projectId} =await this.checkOwner(this.getService(),id,"read");
const certInfo = await this.getService().info(id) const certInfo = await this.getService().info(id)
if (certInfo == null) { if (certInfo == null) {
throw new CommonException('file not found'); throw new CommonException('file not found');
} }
if (certInfo.userId !== this.getUserId()) { if (certInfo.userId !== userId) {
throw new CommonException('file not found');
}
if (projectId && certInfo.projectId !== projectId) {
throw new CommonException('file not found'); throw new CommonException('file not found');
} }
// koa send file // koa send file

View File

@@ -241,7 +241,7 @@ export class HistoryController extends CrudController<HistoryService> {
history = await this.service.getLastHistory(pipelineId); history = await this.service.getLastHistory(pipelineId);
} }
if (history == null) { if (history == null) {
throw new CommonException('historyId is null'); throw new CommonException('流水线还未运行过');
} }
const {projectId} = await this.getProjectUserIdRead() const {projectId} = await this.getProjectUserIdRead()
if (projectId) { if (projectId) {

View File

@@ -199,6 +199,12 @@ export class LoginService {
return this.generateToken(info); return this.generateToken(info);
} }
writeTokenCookie(ctx:any,token: { expire: any; token: any }) {
ctx.cookies.set("certd_token", token.token, {
maxAge: 1000 * token.expire
});
}
/** /**
* 生成token * 生成token

View File

@@ -842,7 +842,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
.addSelect("count(1)", "count") .addSelect("count(1)", "count")
.where({ .where({
userId: param.userId, userId: param.userId,
projectId: param.projectId projectId: param.projectId,
isTemplate: false
}) })
.groupBy("status") .groupBy("status")
.getRawMany(); .getRawMany();
@@ -856,7 +857,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
.addSelect("count(1)", "count") .addSelect("count(1)", "count")
.where({ .where({
userId: param.userId, userId: param.userId,
projectId: param.projectId projectId: param.projectId,
isTemplate: false
}) })
.groupBy("disabled") .groupBy("disabled")
.getRawMany(); .getRawMany();
@@ -880,7 +882,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
where: { where: {
userId, userId,
disabled: false, disabled: false,
projectId projectId,
isTemplate: false
} }
}); });
await this.fillLastVars(list); await this.fillLastVars(list);
@@ -902,7 +905,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
.addSelect("COUNT(1) AS count") .addSelect("COUNT(1) AS count")
.where({ .where({
// 0点 // 0点
createTime: MoreThan(todayEnd.add(-param.days, "day").toDate()) createTime: MoreThan(todayEnd.add(-param.days, "day").toDate()),
isTemplate: false
}) })
.groupBy("date") .groupBy("date")
.getRawMany(); .getRawMany();