pull/199/head
xiaojunnuo 2024-09-30 18:00:51 +08:00
parent 8d42273665
commit 17a9beb514
12 changed files with 149 additions and 22 deletions

View File

@ -27,7 +27,10 @@ export class AccessRequestHandler<T = any> {
throw new Error("action is required"); throw new Error("action is required");
} }
const methodName = `on${_.upperFirst(req.action)}`; let methodName = req.action;
if (!req.action.startsWith("on")) {
methodName = `on${_.upperFirst(req.action)}`;
}
// @ts-ignore // @ts-ignore
const method = this[methodName]; const method = this[methodName];
@ -38,4 +41,3 @@ export class AccessRequestHandler<T = any> {
throw new Error(`action ${req.action} not found`); throw new Error(`action ${req.action} not found`);
} }
} }

View File

@ -4,7 +4,7 @@ import { FileStore } from "../core/file-store.js";
import { Logger } from "log4js"; import { Logger } from "log4js";
import { IAccessService } from "../access/index.js"; import { IAccessService } from "../access/index.js";
import { IEmailService } from "../service/index.js"; import { IEmailService } from "../service/index.js";
import { IContext, PluginRequestHandleReq } from "../core/index.js"; import { IContext, PluginRequestHandleReq, RunnableCollection } from "../core/index.js";
import { ILogger, logger, utils } from "../utils/index.js"; import { ILogger, logger, utils } from "../utils/index.js";
import { HttpClient } from "../utils/util.request"; import { HttpClient } from "../utils/util.request";
import dayjs from "dayjs"; import dayjs from "dayjs";
@ -165,7 +165,10 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
throw new Error("action is required"); throw new Error("action is required");
} }
const methodName = `on${_.upperFirst(req.action)}`; let methodName = req.action;
if (!req.action.startsWith("on")) {
methodName = `on${_.upperFirst(req.action)}`;
}
// @ts-ignore // @ts-ignore
const method = this[methodName]; const method = this[methodName];
@ -179,6 +182,21 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
isAdmin() { isAdmin() {
return this.ctx.user.role === "admin"; return this.ctx.user.role === "admin";
} }
getStepFromPipeline(stepId: string) {
let found: any = null;
RunnableCollection.each(this.ctx.pipeline.stages, (step) => {
if (step.id === stepId) {
found = step;
return;
}
});
return found;
}
getStepIdFromRefInput(ref = ".") {
return ref.split(".")[1];
}
} }
export type OutputVO = { export type OutputVO = {

View File

@ -139,6 +139,7 @@ export const http = createAxiosService({ logger }) as HttpClient;
export type HttpClientResponse<R> = any; export type HttpClientResponse<R> = any;
export type HttpRequestConfig<D> = { export type HttpRequestConfig<D> = {
skipSslVerify?: boolean; skipSslVerify?: boolean;
skipCheckRes?: boolean;
} & AxiosRequestConfig<D>; } & AxiosRequestConfig<D>;
export type HttpClient = { export type HttpClient = {
request<D = any, R = any>(config: HttpRequestConfig<D>): Promise<HttpClientResponse<R>>; request<D = any, R = any>(config: HttpRequestConfig<D>): Promise<HttpClientResponse<R>>;

View File

@ -65,6 +65,13 @@ export class CertReader {
return { detail, expires }; return { detail, expires };
} }
getAllDomains() {
const { detail } = this.getCrtDetail();
const domains = [detail.domains.commonName];
domains.push(...detail.domains.altNames);
return domains;
}
saveToFile(type: "crt" | "key" | "pfx" | "der" | "ic", filepath?: string) { saveToFile(type: "crt" | "key" | "pfx" | "der" | "ic", filepath?: string) {
if (!this.cert[type]) { if (!this.cert[type]) {
return; return;

View File

@ -0,0 +1,61 @@
<script setup lang="ts">
import { inject, ref, watch } from "vue";
const props = defineProps<{
inputKey?: string;
modelValue?: string[];
}>();
const emit = defineEmits<{
"update:modelValue": any;
}>();
const pipeline: any = inject("pipeline");
function findStepFromPipeline(targetStepId: string) {
for (const stage of pipeline.value.stages) {
for (const task of stage.tasks) {
for (const step of task.steps) {
if (step.id === targetStepId) {
return step;
}
}
}
}
}
const errorRef = ref("");
function getDomainFromPipeline(inputKey: string) {
if (!inputKey) {
errorRef.value = "请先选择域名证书";
return;
}
const targetStepId = inputKey.split(".")[1];
const certStep = findStepFromPipeline(targetStepId);
if (!certStep) {
errorRef.value = "找不到目标步骤,请先选择域名证书";
return;
}
const domain = certStep.input["domains"];
emit("update:modelValue", domain);
}
watch(
() => {
return props.inputKey;
},
(inputKey: string) => {
getDomainFromPipeline(inputKey);
},
{
immediate: true
}
);
</script>
<template>
<a-select mode="tags" readonly :value="modelValue" />
<div>{{ errorRef }}</div>
</template>
<style lang="less"></style>

View File

@ -22,6 +22,19 @@ const getOptions = async () => {
}); });
}; };
const filterOption = (input: string, option: any) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.value).toLowerCase().indexOf(input.toLowerCase());
};
let isFirst = true;
async function onClick() {
if (!isFirst) {
return;
}
isFirst = false;
optionsRef.value = await getOptions();
}
watch( watch(
() => { () => {
const values = []; const values = [];
@ -35,13 +48,20 @@ watch(
}, },
async () => { async () => {
optionsRef.value = await getOptions(); optionsRef.value = await getOptions();
}, }
{ immediate: true }
); );
</script> </script>
<template> <template>
<a-select class="remote-select" :options="optionsRef" :value="value" @update:value="emit('update:value', $event)" /> <a-select
class="remote-select"
show-search
:filter-option="filterOption"
:options="optionsRef"
:value="value"
@click="onClick"
@update:value="emit('update:value', $event)"
/>
</template> </template>
<style lang="less"></style> <style lang="less"></style>

View File

@ -1,8 +1,10 @@
import SynologyIdDeviceGetter from "./synology/device-id-getter.vue"; import SynologyIdDeviceGetter from "./synology/device-id-getter.vue";
import RemoteSelect from "./common/remote-select.vue"; import RemoteSelect from "./common/remote-select.vue";
import CertDomainsGetter from "./common/cert-domains-getter.vue";
export default { export default {
install(app: any) { install(app: any) {
app.component("SynologyDeviceIdGetter", SynologyIdDeviceGetter); app.component("SynologyDeviceIdGetter", SynologyIdDeviceGetter);
app.component("RemoteSelect", RemoteSelect); app.component("RemoteSelect", RemoteSelect);
app.component("CertDomainsGetter", CertDomainsGetter);
} }
}; };

View File

@ -7,10 +7,10 @@ export type ComponentPropsType = {
value?: any; value?: any;
}; };
export type RequestHandleReq<T = any> = { export type RequestHandleReq<T = any> = {
type: strin; type: string;
typeName: string; typeName: string;
action: string; action: string;
data: any; data?: any;
input: T; input: T;
}; };

View File

@ -4,6 +4,20 @@
# server: # server:
# baseUrl: 'http://127.0.0.1:11007' # baseUrl: 'http://127.0.0.1:11007'
#flyway:
# scriptDir: './db/migration-pg'
#typeorm:
# dataSource:
# default:
# type: postgres
# host: localhost
# port: 5433
# username: postgres
# password: root
# database: postgres
plus: plus:
server: server:
baseUrls: ['https://api.ai.handsfree.work', 'https://api.ai.docmirror.cn'] baseUrls: ['https://api.ai.handsfree.work', 'https://api.ai.docmirror.cn']

View File

@ -16,7 +16,7 @@
"build": "mwtsc --cleanOutDir --skipLibCheck", "build": "mwtsc --cleanOutDir --skipLibCheck",
"build-on-docker": "node ./before-build.js && npm run build", "build-on-docker": "node ./before-build.js && npm run build",
"up-mw-deps": "npx midway-version -u -w", "up-mw-deps": "npx midway-version -u -w",
"heap": "clinic heapprofiler -- node ./bootstrap.js", "heap": "clinic heapprofiler -- node ./bootstrap.js",
"flame": "clinic flame -- node ./bootstrap.js" "flame": "clinic flame -- node ./bootstrap.js"
}, },
"dependencies": { "dependencies": {

View File

@ -37,22 +37,19 @@ export class HandleController extends BaseController {
//@ts-ignore //@ts-ignore
const access = new accessCls(); const access = new accessCls();
let isNew = true; let inputAccess = body.input.access;
if (body.input.id > 0) { if (body.input.id > 0) {
const oldEntity = await this.accessService.info(body.input.id); const oldEntity = await this.accessService.info(body.input.id);
if (!oldEntity) { if (oldEntity) {
isNew = false; const param: any = {
const param = {
type: body.typeName, type: body.typeName,
setting: JSON.stringify(body.input.access), setting: JSON.stringify(body.input.access),
}; };
this.accessService.encryptSetting(param, oldEntity); this.accessService.encryptSetting(param, oldEntity);
body.input.access = JSON.parse(param.setting); inputAccess = this.accessService.decryptAccessEntity(param);
} }
} }
if (isNew) { mergeUtils.merge(access, inputAccess);
mergeUtils.merge(access, body.input.access);
}
const ctx: AccessRequestHandleContext = { const ctx: AccessRequestHandleContext = {
http: http, http: http,

View File

@ -108,6 +108,14 @@ export class AccessService extends BaseService<AccessEntity> implements IAccessS
throw new Error(`该授权配置不存在,请确认是否已被删除:id=${id}`); throw new Error(`该授权配置不存在,请确认是否已被删除:id=${id}`);
} }
// const access = accessRegistry.get(entity.type); // const access = accessRegistry.get(entity.type);
const setting = this.decryptAccessEntity(entity);
return {
id: entity.id,
...setting,
};
}
decryptAccessEntity(entity: AccessEntity): any {
let setting = {}; let setting = {};
if (entity.encryptSetting && entity.encryptSetting !== '{}') { if (entity.encryptSetting && entity.encryptSetting !== '{}') {
setting = JSON.parse(entity.encryptSetting); setting = JSON.parse(entity.encryptSetting);
@ -123,10 +131,7 @@ export class AccessService extends BaseService<AccessEntity> implements IAccessS
} else if (entity.setting) { } else if (entity.setting) {
setting = JSON.parse(entity.setting); setting = JSON.parse(entity.setting);
} }
return { return setting;
id: entity.id,
...setting,
};
} }
getDefineList() { getDefineList() {