diff --git a/packages/plugins/plugin-lib/src/common/util.ts b/packages/plugins/plugin-lib/src/common/util.ts index 7cc889133..12f22e09c 100644 --- a/packages/plugins/plugin-lib/src/common/util.ts +++ b/packages/plugins/plugin-lib/src/common/util.ts @@ -43,6 +43,7 @@ export function createRemoteSelectInputDefine(opts?: { pager?: boolean; component?: any; value?: any; + pageSize?: number; }) { const title = opts?.title || "请选择"; const certDomainsInputKey = opts?.certDomainsInputKey || "certDomains"; @@ -71,6 +72,7 @@ export function createRemoteSelectInputDefine(opts?: { search, pager, multi, + pageSize: opts?.pageSize, watches: [certDomainsInputKey, accessIdInputKey, ...watches], ...opts.component, }, diff --git a/packages/ui/certd-client/src/components/plugins/common/remote-select.vue b/packages/ui/certd-client/src/components/plugins/common/remote-select.vue index 5782c54d9..4c1f61b52 100644 --- a/packages/ui/certd-client/src/components/plugins/common/remote-select.vue +++ b/packages/ui/certd-client/src/components/plugins/common/remote-select.vue @@ -64,6 +64,7 @@ const props = defineProps< search?: boolean; pager?: boolean; multi?: boolean; + pageSize?: number; } & ComponentPropsType >(); @@ -103,7 +104,7 @@ const loading = ref(false); const pagerRef: Ref = ref({ pageNo: 1, total: 0, - pageSize: 100, + pageSize: props.pageSize || 100, }); const getOptions = async () => { if (loading.value) { diff --git a/packages/ui/certd-client/src/views/certd/mine/user-profile.vue b/packages/ui/certd-client/src/views/certd/mine/user-profile.vue index 5eb1c35fe..841427a48 100644 --- a/packages/ui/certd-client/src/views/certd/mine/user-profile.vue +++ b/packages/ui/certd-client/src/views/certd/mine/user-profile.vue @@ -278,20 +278,22 @@ async function doRegisterPasskey(deviceName: string) { // type: "public-key", // })); - const credential = await (navigator.credentials as any).create({ - publicKey: { - challenge: Uint8Array.from(atob(options.challenge.replace(/-/g, "+").replace(/_/g, "/")), c => c.charCodeAt(0)), - rp: options.rp, - pubKeyCredParams: options.pubKeyCredParams, - timeout: options.timeout || 60000, - attestation: options.attestation, - // excludeCredentials: excludeCredentials, - user: { - id: new TextEncoder().encode(options.userId + ""), - name: userInfo.value.username, - displayName: deviceName, - }, + const publicKey = { + challenge: Uint8Array.from(atob(options.challenge.replace(/-/g, "+").replace(/_/g, "/")), c => c.charCodeAt(0)), + rp: options.rp, + pubKeyCredParams: options.pubKeyCredParams, + timeout: options.timeout || 60000, + attestation: options.attestation, + // excludeCredentials: excludeCredentials, + user: { + id: new TextEncoder().encode(options.userId + ""), + name: userInfo.value.username, + displayName: deviceName, }, + }; + console.log("passkey register publicKey:", publicKey); + const credential = await (navigator.credentials as any).create({ + publicKey, }); if (!credential) { diff --git a/packages/ui/certd-client/src/views/certd/pipeline/cert-view.vue b/packages/ui/certd-client/src/views/certd/pipeline/cert-view.vue index 555171342..9713bf9e2 100644 --- a/packages/ui/certd-client/src/views/certd/pipeline/cert-view.vue +++ b/packages/ui/certd-client/src/views/certd/pipeline/cert-view.vue @@ -100,7 +100,10 @@ function formatDate(dateStr: string): string { .cert-detail { table { width: 100%; - table-layout: fixed; + table-layout: fixed !important; + } + .ant-descriptions-item-label { + width: 90px; } .fingerprint { .label { diff --git a/packages/ui/certd-server/src/controller/user/pipeline/pipeline-controller.ts b/packages/ui/certd-server/src/controller/user/pipeline/pipeline-controller.ts index a78c651b4..fe47f586a 100644 --- a/packages/ui/certd-server/src/controller/user/pipeline/pipeline-controller.ts +++ b/packages/ui/certd-server/src/controller/user/pipeline/pipeline-controller.ts @@ -6,6 +6,7 @@ import { SiteInfoService } from '../../../modules/monitor/index.js'; import { HistoryService } from '../../../modules/pipeline/service/history-service.js'; import { PipelineService } from '../../../modules/pipeline/service/pipeline-service.js'; import { AuthService } from '../../../modules/sys/authority/service/auth-service.js'; +import { PipelineEntity } from '../../../modules/pipeline/entity/pipeline.js'; const pipelineExample = ` @@ -183,21 +184,15 @@ export class PipelineController extends CrudController { } - // @Post('/add', { description: Constants.per.authOnly }) - // async add(@Body(ALL) bean: PipelineEntity) { - // const { projectId, userId } = await this.getProjectUserIdWrite() - // bean.userId = userId - // bean.projectId = projectId - // return super.add(bean); - // } + @Post('/add', { description: Constants.per.authOnly }) + async add(@Body(ALL) bean: PipelineEntity) { + return await this.save(bean as any); + } - // @Post('/update', { description: Constants.per.authOnly }) - // async update(@Body(ALL) bean) { - // await this.checkOwner(this.getService(), bean.id,"write",true); - // delete bean.userId; - // delete bean.projectId; - // return super.update(bean); - // } + @Post('/update', { description: Constants.per.authOnly }) + async update(@Body(ALL) bean) { + return await this.save(bean); + } @Post('/save', { description: Constants.per.authOnly, summary: '新增/更新流水线' }) async save(@Body() bean: PipelineSaveDTO) { diff --git a/packages/ui/certd-server/src/modules/login/service/passkey-service.ts b/packages/ui/certd-server/src/modules/login/service/passkey-service.ts index 23feb3956..c6c33686b 100644 --- a/packages/ui/certd-server/src/modules/login/service/passkey-service.ts +++ b/packages/ui/certd-server/src/modules/login/service/passkey-service.ts @@ -1,4 +1,4 @@ -import { cache } from "@certd/basic"; +import { cache, logger } from "@certd/basic"; import { AuthException, BaseService, SysInstallInfo, SysSettingsService, SysSiteInfo } from "@certd/lib-server"; import { isComm } from "@certd/plus-core"; import { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core"; @@ -54,14 +54,14 @@ export class PasskeyService extends BaseService { const options = await generateRegistrationOptions({ rpName: rpName, rpID: rpId, - userID: new Uint8Array([userId]), + userID: new TextEncoder().encode(userId + ""), userName: username, userDisplayName: user.nickName || username, timeout: 60000, attestationType: "none", excludeCredentials: [], }); - + logger.info('[passkey] 注册选项:', JSON.stringify(options)); cache.set(`passkey:registration:${options.challenge}`, userId, { ttl: 5 * 60 * 1000, }); @@ -86,16 +86,24 @@ export class PasskeyService extends BaseService { const { rpId, origin } = await this.getRpInfo(); - const verification = await verifyRegistrationResponse({ + let verification: any = null; + const verifyReq = { response, expectedChallenge: challenge, expectedOrigin: origin, expectedRPID: rpId, - }); - + }; + try { + verification = await verifyRegistrationResponse(verifyReq); + } catch (error) { + // 后端验证时 + logger.error('[passkey] 注册验证失败:', JSON.stringify(verifyReq)); + throw new AuthException(`注册验证失败:${error.message || error}`); + } if (!verification.verified) { throw new AuthException("注册验证失败"); } + cache.delete(`passkey:registration:${challenge}`); diff --git a/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/base.ts b/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/base.ts index ca6622d81..342269ba1 100644 --- a/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/base.ts +++ b/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/base.ts @@ -20,6 +20,7 @@ export abstract class CertApplyBasePlugin extends CertApplyBaseConvertPlugin { @TaskInput({ title: "更新天数", + value:20, component: { name: "a-input-number", vModel: "value", diff --git a/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/getter/aliyun.ts b/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/getter/aliyun.ts index cc87214d0..98c1374f5 100644 --- a/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/getter/aliyun.ts +++ b/packages/ui/certd-server/src/plugins/plugin-cert/plugin/cert-plugin/getter/aliyun.ts @@ -28,11 +28,36 @@ export class CertApplyGetFormAliyunPlugin extends CertApplyBasePlugin { }) accessId!: string; + + @TaskInput( + { + title:"订单类型", + value:"CPACK", + component:{ + name:"a-select", + vModel:"value", + options:[ + { + label:"资源虚拟订单(一般选这个)", + value:"CPACK", + }, + { + label:"售卖订单", + value:"BUY", + } + ] + } + } + ) + orderType!: string; + + @TaskInput( createRemoteSelectInputDefine({ title: "证书订单ID", helper: "订阅模式的证书订单Id", typeName: "CertApplyGetFormAliyun", + pageSize: 50, component: { name: "RemoteSelect", vModel: "value", @@ -140,6 +165,7 @@ export class CertApplyGetFormAliyunPlugin extends CertApplyBasePlugin { pathname: `/`, data: { query: { + OrderType: this.orderType, Status: "ISSUED", CurrentPage: pager.pageNo, ShowSize : pager.pageSize, @@ -151,14 +177,27 @@ export class CertApplyGetFormAliyunPlugin extends CertApplyBasePlugin { return [] } - return list.map((item: any) => { - const label = `${item.Domain}<${item.OrderId}>`; + const total = res.TotalCount || 0; + + const records = list.map((item: any) => { + let value = item.OrderId; + let domain = item.Domain; + let label = `${item.Domain}<${item.OrderId}>`; + if (!item.OrderId) { + label = `${item.CommonName}<${item.Name}>`; + value = item.Name; + domain = item.CommonName; + } return { label: label, - value: item.OrderId, - Domain: item.Domain, + value: value, + Domain: domain, }; }); + return { + list:records, + total, + } } }