mirror of
https://github.com/certd/certd.git
synced 2026-08-04 04:15:52 +08:00
Compare commits
12
Commits
67f347197e
...
d125eb56b3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d125eb56b3 | ||
|
|
956d68695c | ||
|
|
83d81b64b3 | ||
|
|
a4ea82c04b | ||
|
|
8387fe0d5b | ||
|
|
cfd5b388f1 | ||
|
|
4ee6e38a94 | ||
|
|
3f87752d1f | ||
|
|
b91548eef4 | ||
|
|
1195417b97 | ||
|
|
8c2dfa9140 | ||
|
|
a3fbfe0bff |
+2
-1
@@ -30,4 +30,5 @@ test/**/*.js
|
||||
/packages/ui/certd-server/data/keys.yaml
|
||||
/packages/pro/
|
||||
test.js
|
||||
.history
|
||||
.history
|
||||
/logs
|
||||
@@ -7,7 +7,7 @@ import * as https from "node:https";
|
||||
import { merge } from "lodash-es";
|
||||
import { safePromise } from "./util.promise.js";
|
||||
import fs from "fs";
|
||||
|
||||
import sleep from "./util.sleep.js";
|
||||
const errorMap: Record<string, string> = {
|
||||
"ssl3_get_record:wrong version number": "http协议错误,服务端要求http协议,请检查是否使用了https请求",
|
||||
"getaddrinfo EAI_AGAIN": "无法解析域名,请检查网络连接或dns配置,更换docker-compose.yaml中dns配置",
|
||||
@@ -148,6 +148,16 @@ export function createAxiosService({ logger }: { logger: ILogger }) {
|
||||
// });
|
||||
// config.httpsAgent = agent;
|
||||
config.proxy = false; //必须 否则还会走一层代理,
|
||||
|
||||
config.retry = merge(
|
||||
{
|
||||
status: [421],
|
||||
count: 0,
|
||||
max: 3,
|
||||
delay: 1000,
|
||||
},
|
||||
config.retry
|
||||
);
|
||||
return config;
|
||||
},
|
||||
(error: Error) => {
|
||||
@@ -175,7 +185,7 @@ export function createAxiosService({ logger }: { logger: ILogger }) {
|
||||
}
|
||||
return response.data;
|
||||
},
|
||||
(error: any) => {
|
||||
async (error: any) => {
|
||||
const status = error.response?.status;
|
||||
let message = "";
|
||||
switch (status) {
|
||||
@@ -215,6 +225,9 @@ export function createAxiosService({ logger }: { logger: ILogger }) {
|
||||
case 302:
|
||||
//重定向
|
||||
return Promise.resolve(error.response);
|
||||
case 421:
|
||||
message = "源站请求超时";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -256,6 +269,22 @@ export function createAxiosService({ logger }: { logger: ILogger }) {
|
||||
if (error instanceof AggregateError) {
|
||||
logger.error("AggregateError", error);
|
||||
}
|
||||
|
||||
const originalRequest = error.config || {};
|
||||
logger.info(`config`, originalRequest);
|
||||
const retry = originalRequest.retry || {};
|
||||
if (retry.status && retry.status.includes(status)) {
|
||||
if (retry.max > 0 && retry.count < retry.max) {
|
||||
// 重试次数增加
|
||||
retry.count++;
|
||||
const delay = retry.delay * retry.count;
|
||||
logger.error(`status=${status},重试次数${retry.count},将在${delay}ms后重试,请求地址:${originalRequest.url}`);
|
||||
await sleep(delay);
|
||||
return service.request(originalRequest); // 重试请求
|
||||
}
|
||||
logger.error(`重试超过最大次数${retry.max},请求失败:${originalRequest.url}`);
|
||||
}
|
||||
|
||||
const err = new HttpError(error);
|
||||
if (error.response?.config?.logParams === false) {
|
||||
delete err.request?.params;
|
||||
|
||||
@@ -13,6 +13,19 @@
|
||||
|
||||
// await testLocker();
|
||||
|
||||
import { domainUtils } from "./dist/utils/util.domain.js";
|
||||
// import { domainUtils } from "./dist/utils/util.domain.js";
|
||||
|
||||
console.log(domainUtils.isIpv6("::0:0:0:FFFF:129.144.52.38"));
|
||||
// console.log(domainUtils.isIpv6("::0:0:0:FFFF:129.144.52.38"));
|
||||
|
||||
// import { http } from "./dist/utils/util.request.js";
|
||||
|
||||
// http
|
||||
// .request({
|
||||
// url: "https://www.baidu.com/234234/3333",
|
||||
// retry: {
|
||||
// status: [404],
|
||||
// },
|
||||
// })
|
||||
// .then(res => {
|
||||
// console.log(res.data);
|
||||
// });
|
||||
|
||||
@@ -122,6 +122,9 @@ export type TaskInstanceContext = {
|
||||
//用户信息
|
||||
user: UserInfo;
|
||||
|
||||
//项目id
|
||||
projectId?: number;
|
||||
|
||||
emitter: TaskEmitter;
|
||||
|
||||
//service 容器
|
||||
|
||||
@@ -65,7 +65,13 @@ export abstract class BaseController {
|
||||
if (!isEnterprise()) {
|
||||
return null
|
||||
}
|
||||
const projectIdStr = this.ctx.headers["project-id"] as string;
|
||||
let projectIdStr = this.ctx.headers["project-id"] as string;
|
||||
if (!projectIdStr){
|
||||
projectIdStr = this.ctx.request.query["projectId"] as string;
|
||||
}
|
||||
if (!projectIdStr){
|
||||
return null
|
||||
}
|
||||
if (!projectIdStr) {
|
||||
throw new Error("projectId 不能为空")
|
||||
}
|
||||
|
||||
@@ -233,13 +233,14 @@ export abstract class BaseService<T> {
|
||||
throw new PermissionException('权限不足');
|
||||
}
|
||||
|
||||
async batchDelete(ids: number[], userId: number) {
|
||||
if(userId >0){
|
||||
async batchDelete(ids: number[], userId: number,projectId?:number) {
|
||||
if(userId!=null){
|
||||
const list = await this.getRepository().find({
|
||||
where: {
|
||||
// @ts-ignore
|
||||
id: In(ids),
|
||||
userId,
|
||||
projectId,
|
||||
},
|
||||
})
|
||||
// @ts-ignore
|
||||
@@ -252,4 +253,19 @@ export abstract class BaseService<T> {
|
||||
async findOne(options: FindOneOptions<T>) {
|
||||
return await this.getRepository().findOne(options);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function checkUserProjectParam(userId: number, projectId: number) {
|
||||
if (projectId != null ){
|
||||
if( userId !==0) {
|
||||
throw new ValidateException('userId projectId 错误');
|
||||
}
|
||||
return true
|
||||
}else{
|
||||
if( userId > 0) {
|
||||
return true
|
||||
}
|
||||
throw new ValidateException('userId不能为空');
|
||||
}
|
||||
}
|
||||
@@ -2,17 +2,19 @@ import { IAccessService } from '@certd/pipeline';
|
||||
|
||||
export class AccessGetter implements IAccessService {
|
||||
userId: number;
|
||||
getter: <T>(id: any, userId?: number) => Promise<T>;
|
||||
constructor(userId: number, getter: (id: any, userId: number) => Promise<any>) {
|
||||
projectId?: number;
|
||||
getter: <T>(id: any, userId?: number, projectId?: number) => Promise<T>;
|
||||
constructor(userId: number, projectId: number, getter: (id: any, userId: number, projectId?: number) => Promise<any>) {
|
||||
this.userId = userId;
|
||||
this.projectId = projectId;
|
||||
this.getter = getter;
|
||||
}
|
||||
|
||||
async getById<T = any>(id: any) {
|
||||
return await this.getter<T>(id, this.userId);
|
||||
return await this.getter<T>(id, this.userId, this.projectId);
|
||||
}
|
||||
|
||||
async getCommonById<T = any>(id: any) {
|
||||
return await this.getter<T>(id, 0);
|
||||
return await this.getter<T>(id, 0,null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,10 +129,11 @@ export class AccessService extends BaseService<AccessEntity> {
|
||||
id: entity.id,
|
||||
name: entity.name,
|
||||
userId: entity.userId,
|
||||
projectId: entity.projectId,
|
||||
};
|
||||
}
|
||||
|
||||
async getAccessById(id: any, checkUserId: boolean, userId?: number): Promise<any> {
|
||||
async getAccessById(id: any, checkUserId: boolean, userId?: number, projectId?: number): Promise<any> {
|
||||
const entity = await this.info(id);
|
||||
if (entity == null) {
|
||||
throw new Error(`该授权配置不存在,请确认是否已被删除:id=${id}`);
|
||||
@@ -145,6 +146,9 @@ export class AccessService extends BaseService<AccessEntity> {
|
||||
throw new PermissionException('您对该Access授权无访问权限');
|
||||
}
|
||||
}
|
||||
if (projectId != null && projectId !== entity.projectId) {
|
||||
throw new PermissionException('您对该Access授权无访问权限');
|
||||
}
|
||||
|
||||
// const access = accessRegistry.get(entity.type);
|
||||
const setting = this.decryptAccessEntity(entity);
|
||||
@@ -152,12 +156,12 @@ export class AccessService extends BaseService<AccessEntity> {
|
||||
id: entity.id,
|
||||
...setting,
|
||||
};
|
||||
const accessGetter = new AccessGetter(userId, this.getById.bind(this));
|
||||
const accessGetter = new AccessGetter(userId,projectId, this.getById.bind(this));
|
||||
return await newAccess(entity.type, input,accessGetter);
|
||||
}
|
||||
|
||||
async getById(id: any, userId: number): Promise<any> {
|
||||
return await this.getAccessById(id, true, userId);
|
||||
async getById(id: any, userId: number, projectId?: number): Promise<any> {
|
||||
return await this.getAccessById(id, true, userId, projectId);
|
||||
}
|
||||
|
||||
decryptAccessEntity(entity: AccessEntity): any {
|
||||
@@ -188,23 +192,25 @@ export class AccessService extends BaseService<AccessEntity> {
|
||||
}
|
||||
|
||||
|
||||
async getSimpleByIds(ids: number[], userId: any) {
|
||||
async getSimpleByIds(ids: number[], userId: any, projectId?: number) {
|
||||
if (ids.length === 0) {
|
||||
return [];
|
||||
}
|
||||
if (!userId) {
|
||||
if (userId==null) {
|
||||
return [];
|
||||
}
|
||||
return await this.repository.find({
|
||||
where: {
|
||||
id: In(ids),
|
||||
userId,
|
||||
projectId,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
type: true,
|
||||
userId:true
|
||||
userId:true,
|
||||
projectId:true,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -70,7 +70,8 @@ export class AddonService extends BaseService<AddonEntity> {
|
||||
name: entity.name,
|
||||
userId: entity.userId,
|
||||
addonType: entity.addonType,
|
||||
type: entity.type
|
||||
type: entity.type,
|
||||
projectId: entity.projectId
|
||||
};
|
||||
}
|
||||
|
||||
@@ -84,17 +85,18 @@ export class AddonService extends BaseService<AddonEntity> {
|
||||
}
|
||||
|
||||
|
||||
async getSimpleByIds(ids: number[], userId: any) {
|
||||
async getSimpleByIds(ids: number[], userId: any,projectId?:number) {
|
||||
if (ids.length === 0) {
|
||||
return [];
|
||||
}
|
||||
if (!userId) {
|
||||
if (userId==null) {
|
||||
return [];
|
||||
}
|
||||
return await this.repository.find({
|
||||
where: {
|
||||
id: In(ids),
|
||||
userId
|
||||
userId,
|
||||
projectId
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
@@ -109,11 +111,12 @@ export class AddonService extends BaseService<AddonEntity> {
|
||||
}
|
||||
|
||||
|
||||
async getDefault(userId: number, addonType: string): Promise<any> {
|
||||
async getDefault(userId: number, addonType: string,projectId?:number): Promise<any> {
|
||||
const res = await this.repository.findOne({
|
||||
where: {
|
||||
userId,
|
||||
addonType
|
||||
addonType,
|
||||
projectId
|
||||
},
|
||||
order: {
|
||||
isDefault: "DESC"
|
||||
@@ -133,21 +136,23 @@ export class AddonService extends BaseService<AddonEntity> {
|
||||
type: res.type,
|
||||
name: res.name,
|
||||
userId: res.userId,
|
||||
setting
|
||||
setting,
|
||||
projectId: res.projectId
|
||||
};
|
||||
}
|
||||
|
||||
async setDefault(id: number, userId: number, addonType: string) {
|
||||
async setDefault(id: number, userId: number, addonType: string,projectId?:number) {
|
||||
if (!id) {
|
||||
throw new ValidateException("id不能为空");
|
||||
}
|
||||
if (!userId) {
|
||||
if (userId==null) {
|
||||
throw new ValidateException("userId不能为空");
|
||||
}
|
||||
await this.repository.update(
|
||||
{
|
||||
userId,
|
||||
addonType
|
||||
addonType,
|
||||
projectId
|
||||
},
|
||||
{
|
||||
isDefault: false
|
||||
@@ -157,7 +162,8 @@ export class AddonService extends BaseService<AddonEntity> {
|
||||
{
|
||||
id,
|
||||
userId,
|
||||
addonType
|
||||
addonType,
|
||||
projectId
|
||||
},
|
||||
{
|
||||
isDefault: true
|
||||
@@ -165,12 +171,12 @@ export class AddonService extends BaseService<AddonEntity> {
|
||||
);
|
||||
}
|
||||
|
||||
async getOrCreateDefault(opts: { addonType: string, type: string, inputs: any, userId: any }) {
|
||||
const { addonType, type, inputs, userId } = opts;
|
||||
async getOrCreateDefault(opts: { addonType: string, type: string, inputs: any, userId: any,projectId?:number }) {
|
||||
const { addonType, type, inputs, userId,projectId } = opts;
|
||||
|
||||
const addonDefine = this.getDefineByType(type, addonType);
|
||||
|
||||
const defaultConfig = await this.getDefault(userId, addonType);
|
||||
const defaultConfig = await this.getDefault(userId, addonType,projectId);
|
||||
if (defaultConfig) {
|
||||
return defaultConfig;
|
||||
}
|
||||
@@ -183,17 +189,19 @@ export class AddonService extends BaseService<AddonEntity> {
|
||||
type: type,
|
||||
name: addonDefine.title,
|
||||
setting: JSON.stringify(setting),
|
||||
isDefault: true
|
||||
isDefault: true,
|
||||
projectId
|
||||
});
|
||||
return this.buildAddonInstanceConfig(res);
|
||||
}
|
||||
|
||||
async getOneByType(req:{addonType:string,type:string,userId:number}) {
|
||||
async getOneByType(req:{addonType:string,type:string,userId:number,projectId?:number}) {
|
||||
return await this.repository.findOne({
|
||||
where: {
|
||||
addonType: req.addonType,
|
||||
type: req.type,
|
||||
userId: req.userId
|
||||
userId: req.userId,
|
||||
projectId: req.projectId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<div class="rounded pl-3 pr-3 px-2 py-1 flex-center flex pointer items-center bg-accent h-10 button-text">
|
||||
<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>
|
||||
{{ projectStore.currentProject?.name || "..." }}
|
||||
当前项目:{{ projectStore.currentProject?.name || "..." }}
|
||||
<fs-icon icon="ion:chevron-down-outline" class="ml-1"></fs-icon>
|
||||
</div>
|
||||
</a-dropdown>
|
||||
@@ -29,13 +29,14 @@ onMounted(async () => {
|
||||
|
||||
function handleMenuClick({ key }: any) {
|
||||
projectStore.changeCurrentProject(key);
|
||||
window.location.reload();
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
.project-selector {
|
||||
&.button-text {
|
||||
min-width: 100px;
|
||||
max-width: 150px;
|
||||
min-width: 150px;
|
||||
max-width: 250px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
@@ -10,6 +10,7 @@ import PageFooter from "./components/footer/index.vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import MaxKBChat from "/@/components/ai/index.vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useProjectStore } from "../store/project";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -77,15 +78,13 @@ const openChat = (q: string) => {
|
||||
chatBox.value.openChat({ q });
|
||||
};
|
||||
provide("fn:ai.open", openChat);
|
||||
|
||||
const projectStore = useProjectStore();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BasicLayout @clear-preferences-and-logout="handleLogout">
|
||||
<template #header-left-0>
|
||||
<div class="ml-1 mr-2">
|
||||
<project-selector class="flex-center header-btn" />
|
||||
</div>
|
||||
</template>
|
||||
<template #header-left-0> </template>
|
||||
<template #user-dropdown>
|
||||
<UserDropdown :avatar="avatar" :menus="menus" :text="userStore.userInfo?.nickName || userStore.userInfo?.username" description="" tag-text="" @logout="handleLogout" />
|
||||
</template>
|
||||
@@ -93,6 +92,9 @@ provide("fn:ai.open", openChat);
|
||||
<LockScreen :avatar @to-login="handleLogout" />
|
||||
</template>
|
||||
<template #header-right-0>
|
||||
<div v-if="projectStore.isEnterprise" class="ml-1 mr-2">
|
||||
<project-selector class="flex-center header-btn" />
|
||||
</div>
|
||||
<div class="hover:bg-accent ml-1 mr-2 cursor-pointer rounded-full hidden md:block">
|
||||
<tutorial-button class="flex-center header-btn" mode="nav" />
|
||||
</div>
|
||||
|
||||
@@ -311,6 +311,8 @@ export default {
|
||||
days: "天",
|
||||
lastCheckTime: "上次检查时间",
|
||||
disabled: "禁用启用",
|
||||
ipAddress: "IP地址",
|
||||
ipAddressHelper: "填写则固定检查此IP,不从DNS获取域名的IP地址",
|
||||
ipCheck: "开启IP检查",
|
||||
ipCheckHelper: "开启后,会检查IP(或源站)上的证书有效期",
|
||||
ipSyncAuto: "自动同步IP",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
import aboutResource from "/@/router/source/modules/about";
|
||||
import i18n from "/@/locales/i18n";
|
||||
import { useProjectStore } from "/@/store/project";
|
||||
|
||||
export const certdResources = [
|
||||
{
|
||||
@@ -20,7 +21,10 @@ export const certdResources = [
|
||||
path: "/certd/project",
|
||||
component: "/certd/project/index.vue",
|
||||
meta: {
|
||||
show: true,
|
||||
show: () => {
|
||||
const projectStore = useProjectStore();
|
||||
return projectStore.isEnterprise;
|
||||
},
|
||||
icon: "ion:apps",
|
||||
permission: "sys:settings:edit",
|
||||
keepAlive: true,
|
||||
|
||||
@@ -210,9 +210,11 @@ const headerSlots = computed(() => {
|
||||
</template>
|
||||
<!-- 侧边额外区域 -->
|
||||
<template #side-extra>
|
||||
1111
|
||||
<LayoutExtraMenu :accordion="preferences.navigation.accordion" :collapse="preferences.sidebar.extraCollapse" :menus="wrapperMenus(extraMenus)" :rounded="isMenuRounded" :theme="sidebarTheme" />
|
||||
</template>
|
||||
<template #side-extra-title>
|
||||
234234234
|
||||
<VbenLogo v-if="preferences.logo.enable" :text="preferences.app.name" :theme="theme" />
|
||||
</template>
|
||||
|
||||
|
||||
@@ -556,6 +556,20 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
},
|
||||
},
|
||||
ipAddress: {
|
||||
title: t("certd.monitor.ipAddress"),
|
||||
search: {
|
||||
show: false,
|
||||
},
|
||||
type: "text",
|
||||
form: {
|
||||
helper: t("certd.monitor.ipAddressHelper"),
|
||||
},
|
||||
column: {
|
||||
width: 150,
|
||||
sorter: true,
|
||||
},
|
||||
},
|
||||
groupId: {
|
||||
title: t("certd.fields.group"),
|
||||
type: "dict-select",
|
||||
|
||||
@@ -45,15 +45,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="tsx">
|
||||
import { notification } from "ant-design-vue";
|
||||
import { merge } from "lodash-es";
|
||||
import { reactive } from "vue";
|
||||
import * as api from "./api";
|
||||
import { UserSiteMonitorSetting } from "./api";
|
||||
import { notification } from "ant-design-vue";
|
||||
import { merge } from "lodash-es";
|
||||
import { useSettingStore } from "/src/store/settings";
|
||||
import NotificationSelector from "/@/views/certd/notification/notification-selector/index.vue";
|
||||
import { useUserStore } from "/@/store/user";
|
||||
import { utils } from "/@/utils";
|
||||
import NotificationSelector from "/@/views/certd/notification/notification-selector/index.vue";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { useSettingStore } from "/src/store/settings";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -74,6 +75,7 @@ async function loadUserSettings() {
|
||||
|
||||
loadUserSettings();
|
||||
const doSave = async (form: any) => {
|
||||
await utils.sleep(1);
|
||||
await api.SiteMonitorSettingsSave({
|
||||
...formState,
|
||||
});
|
||||
|
||||
@@ -54,6 +54,22 @@ CREATE INDEX "index_history_log_project_id" ON "pi_history_log" ("project_id");
|
||||
ALTER TABLE pi_template ADD COLUMN project_id integer;
|
||||
CREATE INDEX "index_template_project_id" ON "pi_template" ("project_id");
|
||||
|
||||
ALTER TABLE pi_sub_domain ADD COLUMN project_id integer;
|
||||
CREATE INDEX "index_sub_domain_project_id" ON "pi_sub_domain" ("project_id");
|
||||
|
||||
ALTER TABLE cd_cname_record ADD COLUMN project_id integer;
|
||||
CREATE INDEX "index_cname_record_project_id" ON "cd_cname_record" ("project_id");
|
||||
|
||||
ALTER TABLE cd_domain ADD COLUMN project_id integer;
|
||||
CREATE INDEX "index_domain_project_id" ON "cd_domain" ("project_id");
|
||||
|
||||
ALTER TABLE user_settings ADD COLUMN project_id integer;
|
||||
CREATE INDEX "index_user_settings_project_id" ON "user_settings" ("project_id");
|
||||
|
||||
ALTER TABLE cd_group ADD COLUMN project_id integer;
|
||||
CREATE INDEX "index_group_project_id" ON "cd_group" ("project_id");
|
||||
|
||||
|
||||
|
||||
|
||||
CREATE TABLE "cd_project_member"
|
||||
@@ -91,3 +107,6 @@ CREATE INDEX "index_audit_log_user_id" ON "cd_audit_log" ("user_id");
|
||||
CREATE INDEX "index_audit_log_project_id" ON "cd_audit_log" ("project_id");
|
||||
|
||||
|
||||
|
||||
ALTER TABLE cd_site_info ADD COLUMN ip_address varchar(128);
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ export class ConnectController extends BaseController {
|
||||
throw new Error(`未配置该OAuth类型:${type}`);
|
||||
}
|
||||
|
||||
const addon = await this.addonGetterService.getAddonById(setting.addonId, true, 0);
|
||||
const addon = await this.addonGetterService.getAddonById(setting.addonId, true, 0,null);
|
||||
if (!addon) {
|
||||
throw new Error("初始化OAuth插件失败");
|
||||
}
|
||||
@@ -251,7 +251,7 @@ export class ConnectController extends BaseController {
|
||||
provider.addonId = conf.addonId;
|
||||
provider.addonTitle = addonEntity.name;
|
||||
|
||||
const addon = await this.addonGetterService.getAddonById(conf.addonId,true,0);
|
||||
const addon = await this.addonGetterService.getAddonById(conf.addonId,true,0,null);
|
||||
const {logoutUrl} = await addon.buildLogoutUrl();
|
||||
if (logoutUrl){
|
||||
provider.logoutUrl = logoutUrl;
|
||||
|
||||
@@ -28,9 +28,11 @@ export class OpenCertController extends BaseOpenController {
|
||||
async get(@Body(ALL) bean: CertGetReq, @Query(ALL) query: CertGetReq) {
|
||||
const openKey: OpenKey = this.ctx.openKey;
|
||||
const userId = openKey.userId;
|
||||
if (!userId) {
|
||||
|
||||
if (userId==null) {
|
||||
throw new CodeException(Constants.res.openKeyError);
|
||||
}
|
||||
const projectId = openKey.projectId;
|
||||
|
||||
const req = merge({}, bean, query)
|
||||
|
||||
@@ -39,7 +41,8 @@ export class OpenCertController extends BaseOpenController {
|
||||
domains: req.domains,
|
||||
certId: req.certId,
|
||||
autoApply: req.autoApply??false,
|
||||
format: req.format
|
||||
format: req.format,
|
||||
projectId,
|
||||
});
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@@ -32,10 +32,12 @@ export class AddonController extends CrudController<AddonService> {
|
||||
|
||||
@Post("/page", { summary: Constants.per.authOnly })
|
||||
async page(@Body(ALL) body) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
body.query = body.query ?? {};
|
||||
delete body.query.userId;
|
||||
body.query.projectId = projectId;
|
||||
const buildQuery = qb => {
|
||||
qb.andWhere("user_id = :userId", { userId: this.getUserId() });
|
||||
qb.andWhere("user_id = :userId", { userId });
|
||||
};
|
||||
const res = await this.service.page({
|
||||
query: body.query,
|
||||
@@ -48,14 +50,18 @@ export class AddonController extends CrudController<AddonService> {
|
||||
|
||||
@Post("/list", { summary: Constants.per.authOnly })
|
||||
async list(@Body(ALL) body) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
body.query = body.query ?? {};
|
||||
body.query.userId = this.getUserId();
|
||||
body.query.userId = userId;
|
||||
body.query.projectId = projectId;
|
||||
return super.list(body);
|
||||
}
|
||||
|
||||
@Post("/add", { summary: Constants.per.authOnly })
|
||||
async add(@Body(ALL) bean) {
|
||||
bean.userId = this.getUserId();
|
||||
const {userId,projectId} = await this.getProjectUserIdRead();
|
||||
bean.userId = userId;
|
||||
bean.projectId = projectId;
|
||||
const type = bean.type;
|
||||
const addonType = bean.addonType;
|
||||
if (!type || !addonType) {
|
||||
@@ -73,7 +79,7 @@ export class AddonController extends CrudController<AddonService> {
|
||||
|
||||
@Post("/update", { summary: Constants.per.authOnly })
|
||||
async update(@Body(ALL) bean) {
|
||||
await this.service.checkUserId(bean.id, this.getUserId());
|
||||
await this.checkOwner(this.getService(), bean.id, "write");
|
||||
const old = await this.service.info(bean.id);
|
||||
if (!old) {
|
||||
throw new ValidateException("Addon配置不存在");
|
||||
@@ -90,18 +96,19 @@ export class AddonController extends CrudController<AddonService> {
|
||||
}
|
||||
}
|
||||
delete bean.userId;
|
||||
delete bean.projectId;
|
||||
return super.update(bean);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@@ -133,38 +140,42 @@ export class AddonController extends CrudController<AddonService> {
|
||||
async simpleInfo(@Query("addonType") addonType: string, @Query("id") id: number) {
|
||||
if (id === 0) {
|
||||
//获取默认
|
||||
const res = await this.service.getDefault(this.getUserId(), addonType);
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
const res = await this.service.getDefault(userId, addonType,projectId);
|
||||
if (!res) {
|
||||
throw new ValidateException("默认Addon配置不存在");
|
||||
}
|
||||
const simple = await this.service.getSimpleInfo(res.id);
|
||||
return this.ok(simple);
|
||||
}
|
||||
await this.authService.checkUserIdButAllowAdmin(this.ctx, this.service, id);
|
||||
await this.checkOwner(this.getService(), id, "read",true);
|
||||
const res = await this.service.getSimpleInfo(id);
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@Post("/getDefaultId", { summary: Constants.per.authOnly })
|
||||
async getDefaultId(@Query("addonType") addonType: string) {
|
||||
const res = await this.service.getDefault(this.getUserId(), addonType);
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
const res = await this.service.getDefault(userId, addonType,projectId);
|
||||
return this.ok(res?.id);
|
||||
}
|
||||
|
||||
@Post("/setDefault", { summary: Constants.per.authOnly })
|
||||
async setDefault(@Query("addonType") addonType: string, @Query("id") id: number) {
|
||||
await this.service.checkUserId(id, this.getUserId());
|
||||
const res = await this.service.setDefault(id, this.getUserId(), addonType);
|
||||
const {projectId,userId} = await this.checkOwner(this.getService(), id, "write",true);
|
||||
const res = await this.service.setDefault(id, userId, addonType,projectId);
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
|
||||
@Post("/options", { summary: Constants.per.authOnly })
|
||||
async options(@Query("addonType") addonType: string) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
const res = await this.service.list({
|
||||
query: {
|
||||
userId: this.getUserId(),
|
||||
addonType
|
||||
userId,
|
||||
addonType,
|
||||
projectId
|
||||
}
|
||||
});
|
||||
for (const item of res) {
|
||||
@@ -176,22 +187,16 @@ export class AddonController extends CrudController<AddonService> {
|
||||
|
||||
@Post("/handle", { summary: Constants.per.authOnly })
|
||||
async handle(@Body(ALL) body: AddonRequestHandleReq) {
|
||||
const userId = this.getUserId();
|
||||
let inputAddon = body.input.addon;
|
||||
if (body.input.id > 0) {
|
||||
await this.checkOwner(this.getService(), body.input.id, "write",true);
|
||||
const oldEntity = await this.service.info(body.input.id);
|
||||
if (oldEntity) {
|
||||
if (oldEntity.userId !== userId) {
|
||||
throw new Error("addon not found");
|
||||
}
|
||||
// const param: any = {
|
||||
// type: body.typeName,
|
||||
// setting: JSON.stringify(body.input.access),
|
||||
// };
|
||||
inputAddon = JSON.parse(oldEntity.setting);
|
||||
}
|
||||
}
|
||||
const serviceGetter = this.taskServiceBuilder.create({ userId });
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
const serviceGetter = this.taskServiceBuilder.create({ userId,projectId });
|
||||
|
||||
const ctx = {
|
||||
http: http,
|
||||
|
||||
@@ -20,10 +20,12 @@ export class GroupController extends CrudController<GroupService> {
|
||||
|
||||
@Post('/page', { summary: Constants.per.authOnly })
|
||||
async page(@Body(ALL) body: any) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
body.query = body.query ?? {};
|
||||
body.query.projectId = projectId;
|
||||
delete body.query.userId;
|
||||
const buildQuery = qb => {
|
||||
qb.andWhere('user_id = :userId', { userId: this.getUserId() });
|
||||
qb.andWhere('user_id = :userId', { userId });
|
||||
};
|
||||
const res = await this.service.page({
|
||||
query: body.query,
|
||||
@@ -36,40 +38,47 @@ export class GroupController extends CrudController<GroupService> {
|
||||
|
||||
@Post('/list', { summary: Constants.per.authOnly })
|
||||
async list(@Body(ALL) body: any) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
body.query = body.query ?? {};
|
||||
body.query.userId = this.getUserId();
|
||||
body.query.projectId = projectId;
|
||||
body.query.userId = userId;
|
||||
return await super.list(body);
|
||||
}
|
||||
|
||||
@Post('/add', { summary: Constants.per.authOnly })
|
||||
async add(@Body(ALL) bean: any) {
|
||||
bean.userId = this.getUserId();
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
bean.projectId = projectId;
|
||||
bean.userId = userId;
|
||||
return await super.add(bean);
|
||||
}
|
||||
|
||||
@Post('/update', { summary: Constants.per.authOnly })
|
||||
async update(@Body(ALL) bean) {
|
||||
await this.service.checkUserId(bean.id, this.getUserId());
|
||||
await this.checkOwner(this.getService(), bean.id, "write");
|
||||
delete bean.userId;
|
||||
delete bean.projectId;
|
||||
return await super.update(bean);
|
||||
}
|
||||
@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 await 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 await super.delete(id);
|
||||
}
|
||||
|
||||
@Post('/all', { summary: Constants.per.authOnly })
|
||||
async all(@Query('type') type: string) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
const list: any = await this.service.find({
|
||||
where: {
|
||||
userId: this.getUserId(),
|
||||
projectId,
|
||||
userId,
|
||||
type,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -18,8 +18,10 @@ export class DomainController extends CrudController<DomainService> {
|
||||
|
||||
@Post('/page', { summary: Constants.per.authOnly })
|
||||
async page(@Body(ALL) body: any) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
body.query = body.query ?? {};
|
||||
body.query.userId = this.getUserId();
|
||||
body.query.projectId = projectId;
|
||||
body.query.userId = userId;
|
||||
const domain = body.query.domain;
|
||||
delete body.query.domain;
|
||||
|
||||
@@ -40,41 +42,48 @@ export class DomainController extends CrudController<DomainService> {
|
||||
|
||||
@Post('/list', { summary: Constants.per.authOnly })
|
||||
async list(@Body(ALL) body: any) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
body.query = body.query ?? {};
|
||||
body.query.userId = this.getUserId();
|
||||
body.query.projectId = projectId;
|
||||
body.query.userId = userId;
|
||||
const list = await this.getService().list(body);
|
||||
return this.ok(list);
|
||||
}
|
||||
|
||||
@Post('/add', { summary: Constants.per.authOnly })
|
||||
async add(@Body(ALL) bean: any) {
|
||||
bean.userId = this.getUserId();
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
bean.projectId = projectId;
|
||||
bean.userId = userId;
|
||||
return super.add(bean);
|
||||
}
|
||||
|
||||
@Post('/update', { summary: Constants.per.authOnly })
|
||||
async update(@Body(ALL) bean: any) {
|
||||
await this.service.checkUserId(bean.id, this.getUserId());
|
||||
await this.checkOwner(this.getService(), bean.id, "write");
|
||||
delete bean.userId;
|
||||
delete bean.projectId;
|
||||
return super.update(bean);
|
||||
}
|
||||
|
||||
@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 {projectId,userId} = await this.getProjectUserIdRead();
|
||||
await this.service.delete(body.ids, {
|
||||
userId: this.getUserId(),
|
||||
userId: userId,
|
||||
projectId: projectId,
|
||||
});
|
||||
return this.ok();
|
||||
}
|
||||
@@ -83,9 +92,12 @@ export class DomainController extends CrudController<DomainService> {
|
||||
@Post('/import/start', { summary: Constants.per.authOnly })
|
||||
async importStart(@Body(ALL) body: any) {
|
||||
checkPlus();
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
const { key } = body;
|
||||
const req = {
|
||||
key, userId: this.getUserId(),
|
||||
key,
|
||||
userId: userId,
|
||||
projectId: projectId,
|
||||
}
|
||||
await this.service.startDomainImportTask(req);
|
||||
return this.ok();
|
||||
@@ -93,8 +105,10 @@ export class DomainController extends CrudController<DomainService> {
|
||||
|
||||
@Post('/import/status', { summary: Constants.per.authOnly })
|
||||
async importStatus() {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
const req = {
|
||||
userId: this.getUserId(),
|
||||
userId: userId,
|
||||
projectId: projectId,
|
||||
}
|
||||
const task = await this.service.getDomainImportTaskStatus(req);
|
||||
return this.ok(task);
|
||||
@@ -103,9 +117,11 @@ export class DomainController extends CrudController<DomainService> {
|
||||
|
||||
@Post('/import/delete', { summary: Constants.per.authOnly })
|
||||
async importDelete(@Body(ALL) body: any) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
const { key } = body;
|
||||
const req = {
|
||||
userId: this.getUserId(),
|
||||
userId: userId,
|
||||
projectId: projectId,
|
||||
key,
|
||||
}
|
||||
await this.service.deleteDomainImportTask(req);
|
||||
@@ -115,9 +131,11 @@ export class DomainController extends CrudController<DomainService> {
|
||||
@Post('/import/save', { summary: Constants.per.authOnly })
|
||||
async importSave(@Body(ALL) body: any) {
|
||||
checkPlus();
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
const { dnsProviderType, dnsProviderAccessId, key } = body;
|
||||
const req = {
|
||||
userId: this.getUserId(),
|
||||
userId: userId,
|
||||
projectId: projectId,
|
||||
dnsProviderType, dnsProviderAccessId, key
|
||||
}
|
||||
const item = await this.service.saveDomainImportTask(req);
|
||||
@@ -127,15 +145,19 @@ export class DomainController extends CrudController<DomainService> {
|
||||
|
||||
@Post('/sync/expiration/start', { summary: Constants.per.authOnly })
|
||||
async syncExpirationStart(@Body(ALL) body: any) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
await this.service.startSyncExpirationTask({
|
||||
userId: this.getUserId(),
|
||||
userId: userId,
|
||||
projectId: projectId,
|
||||
})
|
||||
return this.ok();
|
||||
}
|
||||
@Post('/sync/expiration/status', { summary: Constants.per.authOnly })
|
||||
async syncExpirationStatus(@Body(ALL) body: any) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
const status = await this.service.getSyncExpirationTaskStatus({
|
||||
userId: this.getUserId(),
|
||||
userId: userId,
|
||||
projectId: projectId,
|
||||
})
|
||||
return this.ok(status);
|
||||
}
|
||||
|
||||
@@ -17,8 +17,10 @@ export class CnameRecordController extends CrudController<CnameRecordService> {
|
||||
|
||||
@Post('/page', { summary: Constants.per.authOnly })
|
||||
async page(@Body(ALL) body: any) {
|
||||
const {userId,projectId} = await this.getProjectUserIdRead();
|
||||
body.query = body.query ?? {};
|
||||
body.query.userId = this.getUserId();
|
||||
body.query.userId = userId;
|
||||
body.query.projectId = projectId;
|
||||
const domain = body.query.domain;
|
||||
delete body.query.domain;
|
||||
|
||||
@@ -39,22 +41,27 @@ export class CnameRecordController extends CrudController<CnameRecordService> {
|
||||
|
||||
@Post('/list', { summary: Constants.per.authOnly })
|
||||
async list(@Body(ALL) body: any) {
|
||||
const {userId,projectId} = await this.getProjectUserIdRead();
|
||||
body.query = body.query ?? {};
|
||||
body.query.userId = this.getUserId();
|
||||
body.query.userId = userId;
|
||||
body.query.projectId = projectId;
|
||||
const list = await this.getService().list(body);
|
||||
return this.ok(list);
|
||||
}
|
||||
|
||||
@Post('/add', { summary: Constants.per.authOnly })
|
||||
async add(@Body(ALL) bean: any) {
|
||||
bean.userId = this.getUserId();
|
||||
const {userId,projectId} = await this.getProjectUserIdWrite();
|
||||
bean.userId = userId;
|
||||
bean.projectId = projectId;
|
||||
return super.add(bean);
|
||||
}
|
||||
|
||||
@Post('/update', { summary: Constants.per.authOnly })
|
||||
async update(@Body(ALL) bean: any) {
|
||||
await this.service.checkUserId(bean.id, this.getUserId());
|
||||
await this.checkOwner(this.getService(), bean.id, "write");
|
||||
delete bean.userId;
|
||||
delete bean.projectId;
|
||||
return super.update(bean);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ export class UserTwoFactorSettingController extends BaseController {
|
||||
@Post("/get", { summary: Constants.per.authOnly })
|
||||
async get() {
|
||||
const userId = this.getUserId();
|
||||
const setting = await this.service.getSetting<UserTwoFactorSetting>(userId, UserTwoFactorSetting);
|
||||
const setting = await this.service.getSetting<UserTwoFactorSetting>(userId,null, UserTwoFactorSetting);
|
||||
return this.ok(setting);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ export class UserTwoFactorSettingController extends BaseController {
|
||||
setting.authenticator.verified = false;
|
||||
}
|
||||
|
||||
await this.service.saveSetting(userId, setting);
|
||||
await this.service.saveSetting(userId,null, setting);
|
||||
return this.ok({});
|
||||
}
|
||||
|
||||
|
||||
@@ -65,13 +65,14 @@ export class UserSettingsController extends CrudController<UserSettingsService>
|
||||
|
||||
@Post('/get', { summary: Constants.per.authOnly })
|
||||
async get(@Query('key') key: string) {
|
||||
const entity = await this.service.getByKey(key, this.getUserId());
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
const entity = await this.service.getByKey(key, userId, projectId);
|
||||
return this.ok(entity);
|
||||
}
|
||||
@Post("/grant/get", { summary: Constants.per.authOnly })
|
||||
@Post("/grant/get", { summary: Constants.per.authOnly })
|
||||
async grantSettingsGet() {
|
||||
const userId = this.getUserId();
|
||||
const setting = await this.service.getSetting<UserGrantSetting>(userId, UserGrantSetting);
|
||||
const setting = await this.service.getSetting<UserGrantSetting>(userId, null, UserGrantSetting);
|
||||
return this.ok(setting);
|
||||
}
|
||||
|
||||
@@ -84,10 +85,8 @@ export class UserSettingsController extends CrudController<UserSettingsService>
|
||||
const setting = new UserGrantSetting();
|
||||
merge(setting, bean);
|
||||
|
||||
await this.service.saveSetting(userId, setting);
|
||||
await this.service.saveSetting(userId,null, setting);
|
||||
return this.ok({});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ export class CertInfoController extends CrudController<CertInfoService> {
|
||||
async update(@Body(ALL) bean) {
|
||||
await this.checkOwner(this.service,bean.id,"write");
|
||||
delete bean.userId;
|
||||
delete bean.projectId;
|
||||
return await super.update(bean);
|
||||
}
|
||||
@Post('/info', { summary: Constants.per.authOnly })
|
||||
|
||||
@@ -80,6 +80,7 @@ export class SiteInfoController extends CrudController<SiteInfoService> {
|
||||
async update(@Body(ALL) bean) {
|
||||
await this.checkOwner(this.service,bean.id,"write");
|
||||
delete bean.userId;
|
||||
delete bean.projectId;
|
||||
await this.service.update(bean);
|
||||
const entity = await this.service.info(bean.id);
|
||||
if (entity.disabled) {
|
||||
@@ -157,23 +158,18 @@ export class SiteInfoController extends CrudController<SiteInfoService> {
|
||||
|
||||
@Post("/setting/get", { summary: Constants.per.authOnly })
|
||||
async get() {
|
||||
const { userId } = await this.getProjectUserIdRead()
|
||||
const setting = await this.service.getSetting(userId)
|
||||
const { userId, projectId } = await this.getProjectUserIdRead()
|
||||
const setting = await this.service.getSetting(userId, projectId)
|
||||
return this.ok(setting);
|
||||
}
|
||||
|
||||
@Post("/setting/save", { summary: Constants.per.authOnly })
|
||||
async save(@Body(ALL) bean: any) {
|
||||
const { userId } = await this.getProjectUserIdWrite()
|
||||
if(userId === 0){
|
||||
if(!this.isAdmin()){
|
||||
throw new Error("仅管理员可以修改");
|
||||
}
|
||||
}
|
||||
const { userId, projectId} = await this.getProjectUserIdWrite()
|
||||
const setting = new UserSiteMonitorSetting();
|
||||
merge(setting, bean);
|
||||
|
||||
await this.service.saveSetting(userId, setting);
|
||||
await this.service.saveSetting(userId, projectId,setting);
|
||||
return this.ok({});
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ export class SiteInfoController extends CrudController<SiteIpService> {
|
||||
async update(@Body(ALL) bean) {
|
||||
await this.checkOwner(this.service,bean.id,"write");
|
||||
delete bean.userId;
|
||||
delete bean.projectId;
|
||||
await this.service.update(bean);
|
||||
const siteEntity = await this.siteInfoService.info(bean.siteId);
|
||||
if(!siteEntity.disabled){
|
||||
|
||||
@@ -19,8 +19,10 @@ export class OpenKeyController extends CrudController<OpenKeyService> {
|
||||
|
||||
@Post('/page', { summary: Constants.per.authOnly })
|
||||
async page(@Body(ALL) body: any) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
body.query = body.query ?? {};
|
||||
body.query.userId = this.getUserId();
|
||||
body.query.projectId = projectId;
|
||||
body.query.userId = userId;
|
||||
const res = await this.service.page({
|
||||
query: body.query,
|
||||
page: body.page,
|
||||
@@ -31,40 +33,45 @@ export class OpenKeyController extends CrudController<OpenKeyService> {
|
||||
|
||||
@Post('/list', { summary: Constants.per.authOnly })
|
||||
async list(@Body(ALL) body: any) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
body.query = body.query ?? {};
|
||||
body.query.userId = this.getUserId();
|
||||
body.query.projectId = projectId;
|
||||
body.query.userId = userId;
|
||||
return await super.list(body);
|
||||
}
|
||||
|
||||
@Post('/add', { summary: Constants.per.authOnly })
|
||||
async add(@Body(ALL) body: any) {
|
||||
body.userId = this.getUserId();
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
body.projectId = projectId;
|
||||
body.userId = userId;
|
||||
const res = await this.service.add(body);
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@Post('/update', { summary: Constants.per.authOnly })
|
||||
async update(@Body(ALL) bean) {
|
||||
await this.service.checkUserId(bean.id, this.getUserId());
|
||||
await this.checkOwner(this.getService(), bean.id, "write");
|
||||
delete bean.userId;
|
||||
delete bean.projectId;
|
||||
await this.service.update(bean);
|
||||
return this.ok();
|
||||
}
|
||||
@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 await 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 await super.delete(id);
|
||||
}
|
||||
|
||||
@Post('/getApiToken', { summary: Constants.per.authOnly })
|
||||
async getApiToken(@Body('id') id: number) {
|
||||
await this.service.checkUserId(id, this.getUserId());
|
||||
await this.checkOwner(this.getService(), id, "write");
|
||||
const token = await this.service.getApiToken(id);
|
||||
return this.ok(token);
|
||||
}
|
||||
|
||||
@@ -21,9 +21,11 @@ export class AccessController extends CrudController<AccessService> {
|
||||
|
||||
@Post('/page', { summary: Constants.per.authOnly })
|
||||
async page(@Body(ALL) body) {
|
||||
const { projectId, userId } = await this.getProjectUserIdRead()
|
||||
body.query = body.query ?? {};
|
||||
delete body.query.userId;
|
||||
body.query.userId = this.getUserId()
|
||||
body.query.userId = userId;
|
||||
body.query.projectId = projectId;
|
||||
let name = body.query?.name;
|
||||
delete body.query.name;
|
||||
const buildQuery = qb => {
|
||||
@@ -42,32 +44,37 @@ export class AccessController extends CrudController<AccessService> {
|
||||
|
||||
@Post('/list', { summary: Constants.per.authOnly })
|
||||
async list(@Body(ALL) body) {
|
||||
const { projectId, userId } = await this.getProjectUserIdRead()
|
||||
body.query = body.query ?? {};
|
||||
body.query.userId = this.getUserId();
|
||||
body.query.userId = userId;
|
||||
body.query.projectId = projectId;
|
||||
return super.list(body);
|
||||
}
|
||||
|
||||
@Post('/add', { summary: Constants.per.authOnly })
|
||||
async add(@Body(ALL) bean) {
|
||||
bean.userId = this.getUserId();
|
||||
const { projectId, userId } = await this.getProjectUserIdWrite()
|
||||
bean.userId = userId;
|
||||
bean.projectId = projectId;
|
||||
return super.add(bean);
|
||||
}
|
||||
|
||||
@Post('/update', { summary: Constants.per.authOnly })
|
||||
async update(@Body(ALL) bean) {
|
||||
await this.service.checkUserId(bean.id, this.getUserId());
|
||||
await this.checkOwner(this.getService(), bean.id, "write");
|
||||
delete bean.userId;
|
||||
delete bean.projectId;
|
||||
return super.update(bean);
|
||||
}
|
||||
@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);
|
||||
}
|
||||
|
||||
@@ -79,7 +86,8 @@ export class AccessController extends CrudController<AccessService> {
|
||||
|
||||
@Post('/getSecretPlain', { summary: Constants.per.authOnly })
|
||||
async getSecretPlain(@Body(ALL) body: { id: number; key: string }) {
|
||||
const value = await this.service.getById(body.id, this.getUserId());
|
||||
const {userId, projectId} = await this.checkOwner(this.getService(), body.id, "read");
|
||||
const value = await this.service.getById(body.id, userId, projectId);
|
||||
return this.ok(value[body.key]);
|
||||
}
|
||||
|
||||
@@ -102,14 +110,16 @@ export class AccessController extends CrudController<AccessService> {
|
||||
|
||||
@Post('/simpleInfo', { summary: Constants.per.authOnly })
|
||||
async simpleInfo(@Query('id') id: number) {
|
||||
await this.authService.checkUserIdButAllowAdmin(this.ctx, this.service, id);
|
||||
// await this.authService.checkUserIdButAllowAdmin(this.ctx, this.service, id);
|
||||
await this.checkOwner(this.getService(), id, "read",true);
|
||||
const res = await this.service.getSimpleInfo(id);
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@Post('/getDictByIds', { summary: Constants.per.authOnly })
|
||||
async getDictByIds(@Body('ids') ids: number[]) {
|
||||
const res = await this.service.getSimpleByIds(ids, this.getUserId());
|
||||
const { userId, projectId } = await this.getProjectUserIdRead()
|
||||
const res = await this.service.getSimpleByIds(ids, userId, projectId);
|
||||
return this.ok(res);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,9 +21,8 @@ export class CertController extends BaseController {
|
||||
|
||||
@Post('/get', { summary: Constants.per.authOnly })
|
||||
async getCert(@Query('id') id: number) {
|
||||
const userId = this.getUserId();
|
||||
|
||||
|
||||
const {userId} = await this.getProjectUserIdRead()
|
||||
|
||||
const pipleinUserId = await this.pipelineService.getPipelineUserId(id);
|
||||
|
||||
@@ -34,7 +33,7 @@ export class CertController extends BaseController {
|
||||
throw new PermissionException();
|
||||
}
|
||||
// 是否允许管理员查看
|
||||
const setting = await this.userSettingsService.getSetting<UserGrantSetting>(pipleinUserId, UserGrantSetting, false);
|
||||
const setting = await this.userSettingsService.getSetting<UserGrantSetting>(pipleinUserId,null, UserGrantSetting, false);
|
||||
if (setting?.allowAdminViewCerts !== true) {
|
||||
//不允许管理员查看
|
||||
throw new PermissionException("该流水线的用户还未授权管理员查看证书,请先让用户在”设置->授权委托“中打开开关");
|
||||
|
||||
@@ -14,7 +14,6 @@ export class DnsProviderController extends BaseController {
|
||||
|
||||
@Post('/list', { summary: Constants.per.authOnly })
|
||||
async list(@Query(ALL) query: any) {
|
||||
query.userId = this.getUserId();
|
||||
const list = this.service.getList();
|
||||
return this.ok(list);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ export class HandleController extends BaseController {
|
||||
|
||||
@Post('/access', { summary: Constants.per.authOnly })
|
||||
async accessRequest(@Body(ALL) body: AccessRequestHandleReq) {
|
||||
const userId = this.getUserId();
|
||||
const {projectId,userId} = await this.getProjectUserIdRead()
|
||||
let inputAccess = body.input.access;
|
||||
if (body.input.id > 0) {
|
||||
const oldEntity = await this.accessService.info(body.input.id);
|
||||
@@ -42,6 +42,9 @@ export class HandleController extends BaseController {
|
||||
if (oldEntity.userId !== this.getUserId()) {
|
||||
throw new Error('access not found');
|
||||
}
|
||||
if (oldEntity.projectId && oldEntity.projectId !== projectId) {
|
||||
throw new Error('access not found');
|
||||
}
|
||||
const param: any = {
|
||||
type: body.typeName,
|
||||
setting: JSON.stringify(body.input.access),
|
||||
@@ -50,7 +53,7 @@ export class HandleController extends BaseController {
|
||||
inputAccess = this.accessService.decryptAccessEntity(param);
|
||||
}
|
||||
}
|
||||
const accessGetter = new AccessGetter(userId, this.accessService.getById.bind(this.accessService));
|
||||
const accessGetter = new AccessGetter(userId,projectId, this.accessService.getById.bind(this.accessService));
|
||||
const access = await newAccess(body.typeName, inputAccess,accessGetter);
|
||||
|
||||
mergeUtils.merge(access, body.input);
|
||||
@@ -77,7 +80,7 @@ export class HandleController extends BaseController {
|
||||
|
||||
@Post('/plugin', { summary: Constants.per.authOnly })
|
||||
async pluginRequest(@Body(ALL) body: PluginRequestHandleReq) {
|
||||
const userId = this.getUserId();
|
||||
const {projectId,userId} = await this.getProjectUserIdRead()
|
||||
const pluginDefine = pluginRegistry.get(body.typeName);
|
||||
const pluginCls = await pluginDefine.target();
|
||||
if (pluginCls == null) {
|
||||
@@ -98,7 +101,7 @@ export class HandleController extends BaseController {
|
||||
});
|
||||
};
|
||||
|
||||
const taskServiceGetter = this.taskServiceBuilder.create({userId})
|
||||
const taskServiceGetter = this.taskServiceBuilder.create({userId,projectId})
|
||||
|
||||
const accessGetter = await taskServiceGetter.get<IAccessService>("accessService")
|
||||
//@ts-ignore
|
||||
@@ -118,6 +121,7 @@ export class HandleController extends BaseController {
|
||||
fileStore: undefined,
|
||||
signal: undefined,
|
||||
user: {id:userId,role:"user"},
|
||||
projectId,
|
||||
// pipelineContext: this.pipelineContext,
|
||||
// userContext: this.contextFactory.getContext('user', this.options.userId),
|
||||
// fileStore: new FileStore({
|
||||
|
||||
@@ -161,6 +161,7 @@ export class HistoryController extends CrudController<HistoryService> {
|
||||
async update(@Body(ALL) bean) {
|
||||
await this.checkOwner(this.getService(), bean.id,"write",true);
|
||||
delete bean.userId;
|
||||
delete bean.projectId;
|
||||
return super.update(bean);
|
||||
}
|
||||
|
||||
@@ -256,7 +257,7 @@ export class HistoryController extends CrudController<HistoryService> {
|
||||
throw new PermissionException();
|
||||
}
|
||||
// 是否允许管理员查看
|
||||
const setting = await this.userSettingsService.getSetting<UserGrantSetting>(history.userId, UserGrantSetting, false);
|
||||
const setting = await this.userSettingsService.getSetting<UserGrantSetting>(history.userId, null, UserGrantSetting, false);
|
||||
if (setting?.allowAdminViewCerts!==true) {
|
||||
//不允许管理员查看
|
||||
throw new PermissionException("该流水线的用户还未授权管理员下载证书,请先让用户在”设置->授权委托“中打开开关");
|
||||
|
||||
@@ -22,10 +22,12 @@ export class NotificationController extends CrudController<NotificationService>
|
||||
|
||||
@Post('/page', { summary: Constants.per.authOnly })
|
||||
async page(@Body(ALL) body) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
body.query = body.query ?? {};
|
||||
delete body.query.userId;
|
||||
body.query.projectId = projectId;
|
||||
const buildQuery = qb => {
|
||||
qb.andWhere('user_id = :userId', { userId: this.getUserId() });
|
||||
qb.andWhere('user_id = :userId', { userId: userId});
|
||||
};
|
||||
const res = await this.service.page({
|
||||
query: body.query,
|
||||
@@ -38,14 +40,18 @@ export class NotificationController extends CrudController<NotificationService>
|
||||
|
||||
@Post('/list', { summary: Constants.per.authOnly })
|
||||
async list(@Body(ALL) body) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
body.query = body.query ?? {};
|
||||
body.query.userId = this.getUserId();
|
||||
body.query.userId = userId;
|
||||
body.query.projectId = projectId;
|
||||
return super.list(body);
|
||||
}
|
||||
|
||||
@Post('/add', { summary: Constants.per.authOnly })
|
||||
async add(@Body(ALL) bean) {
|
||||
bean.userId = this.getUserId();
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
bean.userId = userId;
|
||||
bean.projectId = projectId;
|
||||
const type = bean.type;
|
||||
const define: NotificationDefine = this.service.getDefineByType(type);
|
||||
if (!define) {
|
||||
@@ -59,7 +65,7 @@ export class NotificationController extends CrudController<NotificationService>
|
||||
|
||||
@Post('/update', { summary: Constants.per.authOnly })
|
||||
async update(@Body(ALL) bean) {
|
||||
await this.service.checkUserId(bean.id, this.getUserId());
|
||||
await this.checkOwner(this.getService(), bean.id,"write");
|
||||
const old = await this.service.info(bean.id);
|
||||
if (!old) {
|
||||
throw new ValidateException('通知配置不存在');
|
||||
@@ -75,17 +81,18 @@ export class NotificationController extends CrudController<NotificationService>
|
||||
}
|
||||
}
|
||||
delete bean.userId;
|
||||
delete bean.projectId;
|
||||
return super.update(bean);
|
||||
}
|
||||
@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);
|
||||
}
|
||||
|
||||
@@ -118,44 +125,50 @@ export class NotificationController extends CrudController<NotificationService>
|
||||
|
||||
@Post('/simpleInfo', { summary: Constants.per.authOnly })
|
||||
async simpleInfo(@Query('id') id: number) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
if (id === 0) {
|
||||
//获取默认
|
||||
const res = await this.service.getDefault(this.getUserId());
|
||||
const res = await this.service.getDefault(userId,projectId);
|
||||
if (!res) {
|
||||
throw new ValidateException('默认通知配置不存在');
|
||||
}
|
||||
const simple = await this.service.getSimpleInfo(res.id);
|
||||
return this.ok(simple);
|
||||
}
|
||||
await this.authService.checkUserIdButAllowAdmin(this.ctx, this.service, id);
|
||||
await this.checkOwner(this.getService(), id,"read",true);
|
||||
const res = await this.service.getSimpleInfo(id);
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@Post('/getDefaultId', { summary: Constants.per.authOnly })
|
||||
async getDefaultId() {
|
||||
const res = await this.service.getDefault(this.getUserId());
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
const res = await this.service.getDefault(userId,projectId);
|
||||
return this.ok(res?.id);
|
||||
}
|
||||
|
||||
@Post('/setDefault', { summary: Constants.per.authOnly })
|
||||
async setDefault(@Query('id') id: number) {
|
||||
await this.service.checkUserId(id, this.getUserId());
|
||||
const res = await this.service.setDefault(id, this.getUserId());
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
await this.checkOwner(this.getService(), id,"write");
|
||||
const res = await this.service.setDefault(id, userId,projectId);
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@Post('/getOrCreateDefault', { summary: Constants.per.authOnly })
|
||||
async getOrCreateDefault(@Body('email') email: string) {
|
||||
const res = await this.service.getOrCreateDefault(email, this.getUserId());
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
const res = await this.service.getOrCreateDefault(email, userId,projectId);
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@Post('/options', { summary: Constants.per.authOnly })
|
||||
async options() {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
const res = await this.service.list({
|
||||
query: {
|
||||
userId: this.getUserId(),
|
||||
userId: userId,
|
||||
projectId: projectId,
|
||||
},
|
||||
});
|
||||
for (const item of res) {
|
||||
|
||||
@@ -97,16 +97,20 @@ export class PipelineController extends CrudController<PipelineService> {
|
||||
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('/save', { summary: Constants.per.authOnly })
|
||||
async save(@Body(ALL) bean: { addToMonitorEnabled: boolean, addToMonitorDomains: string } & PipelineEntity) {
|
||||
const { userId } = await this.getProjectUserIdWrite()
|
||||
const { userId ,projectId} = await this.getProjectUserIdWrite()
|
||||
if (bean.id > 0) {
|
||||
await this.checkOwner(this.getService(), bean.id,"write",true);
|
||||
const {userId,projectId} = await this.checkOwner(this.getService(), bean.id,"write",true);
|
||||
bean.userId = userId;
|
||||
bean.projectId = projectId;
|
||||
} else {
|
||||
bean.userId = userId;
|
||||
bean.projectId = projectId;
|
||||
}
|
||||
|
||||
if (!this.isAdmin()) {
|
||||
@@ -123,6 +127,7 @@ export class PipelineController extends CrudController<PipelineService> {
|
||||
await this.siteInfoService.doImport({
|
||||
text: bean.addToMonitorDomains,
|
||||
userId: userId,
|
||||
projectId: projectId,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -140,6 +145,7 @@ export class PipelineController extends CrudController<PipelineService> {
|
||||
async disabled(@Body(ALL) bean) {
|
||||
await this.checkOwner(this.getService(), bean.id,"write",true);
|
||||
delete bean.userId;
|
||||
delete bean.projectId;
|
||||
await this.service.disabled(bean.id, bean.disabled);
|
||||
return this.ok({});
|
||||
}
|
||||
|
||||
@@ -20,10 +20,12 @@ export class PipelineGroupController extends CrudController<PipelineGroupService
|
||||
|
||||
@Post('/page', { summary: Constants.per.authOnly })
|
||||
async page(@Body(ALL) body: any) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
body.query = body.query ?? {};
|
||||
delete body.query.userId;
|
||||
body.query.projectId = projectId;
|
||||
const buildQuery = qb => {
|
||||
qb.andWhere('user_id = :userId', { userId: this.getUserId() });
|
||||
qb.andWhere('user_id = :userId', { userId: userId });
|
||||
};
|
||||
const res = await this.service.page({
|
||||
query: body.query,
|
||||
@@ -36,40 +38,47 @@ export class PipelineGroupController extends CrudController<PipelineGroupService
|
||||
|
||||
@Post('/list', { summary: Constants.per.authOnly })
|
||||
async list(@Body(ALL) body: any) {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
body.query = body.query ?? {};
|
||||
body.query.userId = this.getUserId();
|
||||
body.query.userId = userId;
|
||||
body.query.projectId = projectId;
|
||||
return await super.list(body);
|
||||
}
|
||||
|
||||
@Post('/add', { summary: Constants.per.authOnly })
|
||||
async add(@Body(ALL) bean: any) {
|
||||
bean.userId = this.getUserId();
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
bean.userId = userId;
|
||||
bean.projectId = projectId;
|
||||
return await super.add(bean);
|
||||
}
|
||||
|
||||
@Post('/update', { summary: Constants.per.authOnly })
|
||||
async update(@Body(ALL) bean) {
|
||||
await this.service.checkUserId(bean.id, this.getUserId());
|
||||
await this.checkOwner(this.getService(), bean.id, "write");
|
||||
delete bean.userId;
|
||||
delete bean.projectId;
|
||||
return await super.update(bean);
|
||||
}
|
||||
@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 await 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 await super.delete(id);
|
||||
}
|
||||
|
||||
@Post('/all', { summary: Constants.per.authOnly })
|
||||
async all() {
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
const list: any = await this.service.find({
|
||||
where: {
|
||||
userId: this.getUserId(),
|
||||
userId: userId,
|
||||
projectId: projectId,
|
||||
},
|
||||
});
|
||||
return this.ok(list);
|
||||
|
||||
@@ -18,21 +18,18 @@ export class PluginController extends BaseController {
|
||||
|
||||
@Post('/list', { summary: Constants.per.authOnly })
|
||||
async list(@Query(ALL) query: any) {
|
||||
query.userId = this.getUserId();
|
||||
const list = await this.service.getEnabledBuiltInList();
|
||||
return this.ok(list);
|
||||
}
|
||||
|
||||
@Post('/groups', { summary: Constants.per.authOnly })
|
||||
async groups(@Query(ALL) query: any) {
|
||||
query.userId = this.getUserId();
|
||||
const group = await this.service.getEnabledBuildInGroup();
|
||||
return this.ok(group);
|
||||
}
|
||||
|
||||
@Post('/groupsList', { summary: Constants.per.authOnly })
|
||||
async groupsList(@Query(ALL) query: any) {
|
||||
query.userId = this.getUserId();
|
||||
const groups = pluginGroups
|
||||
const groupsList:any = []
|
||||
for (const key in groups) {
|
||||
|
||||
@@ -22,8 +22,8 @@ export class SubDomainController extends CrudController<SubDomainService> {
|
||||
|
||||
@Post('/parseDomain', { summary: Constants.per.authOnly })
|
||||
async parseDomain(@Body("fullDomain") fullDomain:string) {
|
||||
const userId = this.getUserId()
|
||||
const taskService = this.taskServiceBuilder.create({ userId: userId });
|
||||
const {projectId,userId} = await this.getProjectUserIdRead();
|
||||
const taskService = this.taskServiceBuilder.create({ userId: userId, projectId: projectId });
|
||||
const subDomainGetter = await taskService.getSubDomainsGetter();
|
||||
const domainParser = new DomainParser(subDomainGetter)
|
||||
const domain = await domainParser.parse(fullDomain)
|
||||
@@ -33,10 +33,12 @@ export class SubDomainController extends CrudController<SubDomainService> {
|
||||
|
||||
@Post('/page', { summary: Constants.per.authOnly })
|
||||
async page(@Body(ALL) body) {
|
||||
const {userId,projectId} = await this.getProjectUserIdRead();
|
||||
body.query = body.query ?? {};
|
||||
delete body.query.userId;
|
||||
body.query.projectId = projectId;
|
||||
const buildQuery = qb => {
|
||||
qb.andWhere('user_id = :userId', { userId: this.getUserId() });
|
||||
qb.andWhere('user_id = :userId', { userId: userId });
|
||||
};
|
||||
const res = await this.service.page({
|
||||
query: body.query,
|
||||
@@ -49,38 +51,44 @@ export class SubDomainController extends CrudController<SubDomainService> {
|
||||
|
||||
@Post('/list', { summary: Constants.per.authOnly })
|
||||
async list(@Body(ALL) body) {
|
||||
const {userId,projectId} = await this.getProjectUserIdRead();
|
||||
body.query = body.query ?? {};
|
||||
body.query.userId = this.getUserId();
|
||||
body.query.userId = userId;
|
||||
body.query.projectId = projectId;
|
||||
return super.list(body);
|
||||
}
|
||||
|
||||
@Post('/add', { summary: Constants.per.authOnly })
|
||||
async add(@Body(ALL) bean) {
|
||||
bean.userId = this.getUserId();
|
||||
const {userId,projectId} = await this.getProjectUserIdRead();
|
||||
bean.userId = userId;
|
||||
bean.projectId = projectId;
|
||||
return super.add(bean);
|
||||
}
|
||||
|
||||
@Post('/update', { summary: Constants.per.authOnly })
|
||||
async update(@Body(ALL) bean) {
|
||||
await this.service.checkUserId(bean.id, this.getUserId());
|
||||
await this.checkOwner(this.getService(), bean.id, "write");
|
||||
delete bean.userId;
|
||||
delete bean.projectId;
|
||||
return super.update(bean);
|
||||
}
|
||||
@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('/batchDelete', { summary: Constants.per.authOnly })
|
||||
async batchDelete(@Body('ids') ids: number[]) {
|
||||
await this.service.batchDelete(ids, this.getUserId());
|
||||
const {userId,projectId} = await this.getProjectUserIdWrite();
|
||||
await this.service.batchDelete(ids, userId, projectId);
|
||||
return this.ok({});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ export class TemplateController extends CrudController<TemplateService> {
|
||||
async update(@Body(ALL) bean) {
|
||||
await this.checkOwner(this.service, bean.id, "write");
|
||||
delete bean.userId;
|
||||
delete bean.projectId;
|
||||
return super.update(bean);
|
||||
}
|
||||
@Post('/info', { summary: Constants.per.authOnly })
|
||||
|
||||
@@ -84,7 +84,7 @@ export class AutoCRegisterCron {
|
||||
if(!setting?.cron){
|
||||
continue
|
||||
}
|
||||
await this.siteInfoService.registerSiteMonitorJob(item.userId)
|
||||
await this.siteInfoService.registerSiteMonitorJob(item.userId,item.projectId)
|
||||
}
|
||||
|
||||
if (this.immediateTriggerSiteMonitor) {
|
||||
|
||||
@@ -22,6 +22,9 @@ export class GroupEntity {
|
||||
@Column({ name: 'type', comment: '类型', length: 512 })
|
||||
type: string;
|
||||
|
||||
@Column({ name: 'project_id', comment: '项目Id' })
|
||||
projectId: number;
|
||||
|
||||
@Column({
|
||||
name: 'create_time',
|
||||
comment: '创建时间',
|
||||
|
||||
@@ -18,7 +18,7 @@ export class CaptchaService {
|
||||
const settings = await this.sysSettingsService.getPublicSettings();
|
||||
captchaAddonId = settings.captchaAddonId ?? 0;
|
||||
}
|
||||
const addon: ICaptchaAddon = await this.addonGetterService.getAddonById(captchaAddonId, true, 0, {
|
||||
const addon: ICaptchaAddon = await this.addonGetterService.getAddonById(captchaAddonId, true, 0,null, {
|
||||
type: "captcha",
|
||||
name: "image"
|
||||
});
|
||||
|
||||
@@ -135,23 +135,23 @@ export class EmailService implements IEmailService {
|
||||
}
|
||||
|
||||
async list(userId: any) {
|
||||
const userEmailSetting = await this.settingsService.getSetting<UserEmailSetting>(userId, UserEmailSetting)
|
||||
const userEmailSetting = await this.settingsService.getSetting<UserEmailSetting>(userId,null, UserEmailSetting)
|
||||
return userEmailSetting.list;
|
||||
}
|
||||
|
||||
async delete(userId: any, email: string) {
|
||||
const userEmailSetting = await this.settingsService.getSetting<UserEmailSetting>(userId, UserEmailSetting)
|
||||
const userEmailSetting = await this.settingsService.getSetting<UserEmailSetting>(userId, null, UserEmailSetting)
|
||||
userEmailSetting.list = userEmailSetting.list.filter(item => item !== email);
|
||||
await this.settingsService.saveSetting(userId, userEmailSetting)
|
||||
await this.settingsService.saveSetting(userId, null, userEmailSetting)
|
||||
}
|
||||
async add(userId: any, email: string) {
|
||||
const userEmailSetting = await this.settingsService.getSetting<UserEmailSetting>(userId, UserEmailSetting)
|
||||
const userEmailSetting = await this.settingsService.getSetting<UserEmailSetting>(userId, null, UserEmailSetting)
|
||||
//如果已存在
|
||||
if (userEmailSetting.list.includes(email)) {
|
||||
return
|
||||
}
|
||||
userEmailSetting.list.unshift(email)
|
||||
await this.settingsService.saveSetting(userId, userEmailSetting)
|
||||
await this.settingsService.saveSetting(userId, null, userEmailSetting)
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ export class EmailService implements IEmailService {
|
||||
const emailConf = await this.sysSettingsService.getSetting<SysEmailConf>(SysEmailConf);
|
||||
const template = emailConf?.templates?.[req.type]
|
||||
if (isPlus() && template && template.addonId) {
|
||||
const addon: ITemplateProvider<EmailContent> = await this.addonGetterService.getAddonById(template.addonId, true, 0)
|
||||
const addon: ITemplateProvider<EmailContent> = await this.addonGetterService.getAddonById(template.addonId, true, 0,null)
|
||||
if (addon) {
|
||||
content = await addon.buildContent({ data: req.data })
|
||||
}
|
||||
@@ -168,7 +168,7 @@ export class EmailService implements IEmailService {
|
||||
if (isPlus() && !content ) {
|
||||
//看看有没有通用模版
|
||||
if (emailConf?.templates?.common && emailConf?.templates?.common.addonId) {
|
||||
const addon: ITemplateProvider<EmailContent> = await this.addonGetterService.getAddonById(emailConf.templates.common.addonId, true, 0)
|
||||
const addon: ITemplateProvider<EmailContent> = await this.addonGetterService.getAddonById(emailConf.templates.common.addonId, true, 0,null)
|
||||
if (addon) {
|
||||
content = await addon.buildContent({ data: req.data })
|
||||
}
|
||||
|
||||
@@ -44,6 +44,9 @@ export class DomainEntity {
|
||||
@Column({ comment: 'http上传根目录', name: 'http_upload_root_dir', length: 512 })
|
||||
httpUploadRootDir: string;
|
||||
|
||||
@Column({ name: 'project_id', comment: '项目Id' })
|
||||
projectId: number;
|
||||
|
||||
@Column({
|
||||
comment: '创建时间',
|
||||
name: 'create_time',
|
||||
|
||||
@@ -18,6 +18,7 @@ import { DomainEntity } from '../entity/domain.js';
|
||||
|
||||
export interface SyncFromProviderReq {
|
||||
userId: number;
|
||||
projectId: number;
|
||||
dnsProviderType: string;
|
||||
dnsProviderAccessId: number;
|
||||
}
|
||||
@@ -108,10 +109,10 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
* @param userId
|
||||
* @param domains //去除* 且去重之后的域名列表
|
||||
*/
|
||||
async getDomainVerifiers(userId: number, domains: string[]): Promise<DomainVerifiers> {
|
||||
async getDomainVerifiers(userId: number, projectId: number, domains: string[]): Promise<DomainVerifiers> {
|
||||
|
||||
const mainDomainMap: Record<string, string> = {}
|
||||
const taskService = this.taskServiceBuilder.create({ userId: userId });
|
||||
const taskService = this.taskServiceBuilder.create({ userId: userId, projectId: projectId });
|
||||
const subDomainGetter = await taskService.getSubDomainsGetter();
|
||||
const domainParser = new DomainParser(subDomainGetter)
|
||||
|
||||
@@ -132,6 +133,7 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
where: {
|
||||
domain: In(allDomains),
|
||||
userId,
|
||||
projectId,
|
||||
disabled: false,
|
||||
}
|
||||
})
|
||||
@@ -152,6 +154,7 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
where: {
|
||||
domain: In(allDomains),
|
||||
userId,
|
||||
projectId,
|
||||
status: "valid",
|
||||
}
|
||||
})
|
||||
@@ -215,9 +218,9 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
}
|
||||
|
||||
|
||||
async startDomainImportTask(req: { userId: number, key: string }) {
|
||||
async startDomainImportTask(req: { userId: number, projectId: number, key: string }) {
|
||||
const key = req.key
|
||||
const setting = await this.userSettingService.getSetting<UserDomainImportSetting>(req.userId, UserDomainImportSetting)
|
||||
const setting = await this.userSettingService.getSetting<UserDomainImportSetting>(req.userId, req.projectId, UserDomainImportSetting)
|
||||
|
||||
const item = setting.domainImportList.find(item => item.key === key)
|
||||
if (!item) {
|
||||
@@ -232,6 +235,7 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
run: async (task: BackTask) => {
|
||||
await this._syncFromProvider({
|
||||
userId: req.userId,
|
||||
projectId: req.projectId,
|
||||
dnsProviderType,
|
||||
dnsProviderAccessId,
|
||||
}, task)
|
||||
@@ -240,13 +244,13 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
}
|
||||
|
||||
private async _syncFromProvider(req: SyncFromProviderReq, task: BackTask) {
|
||||
const { userId, dnsProviderType, dnsProviderAccessId } = req;
|
||||
const { userId, projectId, dnsProviderType, dnsProviderAccessId } = req;
|
||||
|
||||
const serviceGetter = this.taskServiceBuilder.create({ userId });
|
||||
const serviceGetter = this.taskServiceBuilder.create({ userId, projectId });
|
||||
const subDomainGetter = await serviceGetter.getSubDomainsGetter();
|
||||
const domainParser = new DomainParser(subDomainGetter)
|
||||
|
||||
const access = await this.accessService.getById(dnsProviderAccessId, userId);
|
||||
const access = await this.accessService.getById(dnsProviderAccessId, userId, projectId);
|
||||
const context = { access, logger, http, utils, domainParser, serviceGetter };
|
||||
// 翻页查询dns的记录
|
||||
const dnsProvider = await createDnsProvider({ dnsProviderType, context })
|
||||
@@ -272,6 +276,7 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
where: {
|
||||
domain,
|
||||
userId,
|
||||
projectId,
|
||||
}
|
||||
})
|
||||
if (old) {
|
||||
@@ -296,6 +301,7 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
//添加
|
||||
await this.add({
|
||||
userId,
|
||||
projectId,
|
||||
domain,
|
||||
dnsProviderType,
|
||||
dnsProviderAccess: dnsProviderAccessId,
|
||||
@@ -314,10 +320,11 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
logger.info(`从域名提供商${dnsProviderType}导入域名完成(${key}),共导入${task.total}个域名,跳过${task.getSkipCount()}个域名,成功${task.getSuccessCount()}个域名,失败${task.getErrorCount()}个域名`)
|
||||
}
|
||||
|
||||
async getDomainImportTaskStatus(req: { userId?: number }) {
|
||||
async getDomainImportTaskStatus(req: { userId?: number ,projectId?: number}) {
|
||||
const userId = req.userId || 0
|
||||
const projectId = req.projectId
|
||||
|
||||
const setting = await this.userSettingService.getSetting<UserDomainImportSetting>(userId, UserDomainImportSetting)
|
||||
const setting = await this.userSettingService.getSetting<UserDomainImportSetting>(userId, projectId, UserDomainImportSetting)
|
||||
const list = setting?.domainImportList || []
|
||||
|
||||
const taskList: any = []
|
||||
@@ -335,8 +342,9 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
return taskList
|
||||
}
|
||||
|
||||
async getProviderTitle(req: { userId?: number, dnsProviderType: string, dnsProviderAccessId: number }) {
|
||||
async getProviderTitle(req: { userId?: number, projectId?: number, dnsProviderType: string, dnsProviderAccessId: number }) {
|
||||
const userId = req.userId || 0
|
||||
const projectId = req.projectId
|
||||
const { dnsProviderType, dnsProviderAccessId } = req
|
||||
const dnsProviderDefine = dnsProviderRegistry.getDefine(dnsProviderType)
|
||||
if (!dnsProviderDefine) {
|
||||
@@ -346,6 +354,9 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
if (!access || access.userId !== userId) {
|
||||
throw new Error(`该授权(${dnsProviderAccessId})不存在,请检查是否已被删除`)
|
||||
}
|
||||
if (projectId && access.projectId !== projectId) {
|
||||
throw new Error(`该授权(${dnsProviderAccessId})不存在,请检查是否已被删除`)
|
||||
}
|
||||
return {
|
||||
title: `${dnsProviderDefine.title}_${access.name || ''}`,
|
||||
//@ts-ignore
|
||||
@@ -353,21 +364,22 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
}
|
||||
}
|
||||
|
||||
async addDomainImportTask(req: { userId?: number, dnsProviderType: string, dnsProviderAccessId: number, index?: number }) {
|
||||
async addDomainImportTask(req: { userId?: number, projectId?: number, dnsProviderType: string, dnsProviderAccessId: number, index?: number }) {
|
||||
const userId = req.userId || 0
|
||||
const projectId = req.projectId
|
||||
const { dnsProviderType, dnsProviderAccessId, index = 0 } = req
|
||||
const key = `user_${userId}_${dnsProviderType}_${dnsProviderAccessId}`
|
||||
|
||||
const { title, icon } = await this.getProviderTitle(req)
|
||||
|
||||
|
||||
const setting = await this.userSettingService.getSetting<UserDomainImportSetting>(userId, UserDomainImportSetting)
|
||||
const setting = await this.userSettingService.getSetting<UserDomainImportSetting>(userId, projectId, UserDomainImportSetting)
|
||||
setting.domainImportList = setting.domainImportList || []
|
||||
if (setting.domainImportList.find(item => item.key === key)) {
|
||||
throw new Error(`该域名导入任务${key}已存在`)
|
||||
}
|
||||
|
||||
const access = await this.accessService.getAccessById(dnsProviderAccessId, true, userId)
|
||||
const access = await this.accessService.getAccessById(dnsProviderAccessId, true, userId, projectId)
|
||||
if (!access) {
|
||||
throw new Error(`该授权(${dnsProviderAccessId})不存在,请检查是否已被删除`)
|
||||
}
|
||||
@@ -380,16 +392,17 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
icon: icon || '',
|
||||
}
|
||||
setting.domainImportList.splice(index, 0, item)
|
||||
await this.userSettingService.saveSetting(userId, setting)
|
||||
await this.userSettingService.saveSetting(userId, projectId, setting)
|
||||
|
||||
return item
|
||||
}
|
||||
|
||||
async deleteDomainImportTask(req: { userId?: number, key: string }) {
|
||||
async deleteDomainImportTask(req: { userId?: number, projectId?: number, key: string }) {
|
||||
const userId = req.userId || 0
|
||||
const { key } = req
|
||||
|
||||
const setting = await this.userSettingService.getSetting<UserDomainImportSetting>(userId, UserDomainImportSetting)
|
||||
const projectId = req.projectId
|
||||
const setting = await this.userSettingService.getSetting<UserDomainImportSetting>(userId, projectId, UserDomainImportSetting)
|
||||
setting.domainImportList = setting.domainImportList || []
|
||||
const index = setting.domainImportList.findIndex(item => item.key === key)
|
||||
if (index === -1) {
|
||||
@@ -397,13 +410,14 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
}
|
||||
setting.domainImportList.splice(index, 1)
|
||||
taskExecutor.clear(DOMAIN_IMPORT_TASK_TYPE, key)
|
||||
await this.userSettingService.saveSetting(userId, setting)
|
||||
await this.userSettingService.saveSetting(userId, projectId, setting)
|
||||
}
|
||||
|
||||
async saveDomainImportTask(req: { userId?: number, dnsProviderType: string, dnsProviderAccessId: number, key?: string }) {
|
||||
async saveDomainImportTask(req: { userId?: number, projectId?: number, dnsProviderType: string, dnsProviderAccessId: number, key?: string }) {
|
||||
const userId = req.userId || 0
|
||||
const projectId = req.projectId
|
||||
const { dnsProviderType, dnsProviderAccessId, key } = req
|
||||
const setting = await this.userSettingService.getSetting<UserDomainImportSetting>(userId, UserDomainImportSetting)
|
||||
const setting = await this.userSettingService.getSetting<UserDomainImportSetting>(userId, projectId, UserDomainImportSetting)
|
||||
setting.domainImportList = setting.domainImportList || []
|
||||
|
||||
let index = 0
|
||||
@@ -412,36 +426,46 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
if (index === -1) {
|
||||
throw new Error(`该域名导入任务${key}不存在`)
|
||||
}
|
||||
await this.deleteDomainImportTask({ userId, key })
|
||||
await this.deleteDomainImportTask({ userId, projectId, key })
|
||||
}
|
||||
|
||||
return await this.addDomainImportTask({ userId, dnsProviderType, dnsProviderAccessId, index })
|
||||
|
||||
|
||||
return await this.addDomainImportTask({ userId, projectId, dnsProviderType, dnsProviderAccessId, index })
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
async getSyncExpirationTaskStatus(req: { userId?: number }) {
|
||||
async getSyncExpirationTaskStatus(req: { userId?: number, projectId?: number }) {
|
||||
const userId = req.userId ?? 'all'
|
||||
const key = `user_${userId}`
|
||||
const projectId = req.projectId
|
||||
let key = `user_${userId}`
|
||||
if (projectId!=null) {
|
||||
key += `_${projectId}`
|
||||
}
|
||||
const task = taskExecutor.get(DOMAIN_EXPIRE_TASK_TYPE, key)
|
||||
return task
|
||||
}
|
||||
|
||||
async startSyncExpirationTask(req: { userId?: number }) {
|
||||
async startSyncExpirationTask(req: { userId?: number, projectId?: number }) {
|
||||
const userId = req.userId
|
||||
const key = `user_${userId ?? 'all'}`
|
||||
const projectId = req.projectId
|
||||
let key = `user_${userId ?? 'all'}`
|
||||
if (projectId!=null) {
|
||||
key += `_${projectId}`
|
||||
}
|
||||
taskExecutor.start(new BackTask({
|
||||
type: DOMAIN_EXPIRE_TASK_TYPE,
|
||||
key,
|
||||
title: `同步注册域名过期时间(${key}))`,
|
||||
run: async (task: BackTask) => {
|
||||
await this._syncDomainsExpirationDate({ userId, task })
|
||||
await this._syncDomainsExpirationDate({ userId, projectId, task })
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
private async _syncDomainsExpirationDate(req: { userId?: number, task: BackTask }) {
|
||||
private async _syncDomainsExpirationDate(req: { userId?: number, projectId?: number, task: BackTask }) {
|
||||
//同步所有域名的过期时间
|
||||
const pager = new Pager({
|
||||
pageNo: 1,
|
||||
@@ -498,6 +522,9 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
if (req.userId != null) {
|
||||
query.userId = req.userId
|
||||
}
|
||||
if (req.projectId != null) {
|
||||
query.projectId = req.projectId
|
||||
}
|
||||
const getDomainPage = async (pager: Pager) => {
|
||||
const pageRes = await this.page({
|
||||
query: query,
|
||||
@@ -549,5 +576,4 @@ export class DomainService extends BaseService<DomainEntity> {
|
||||
logger.info(`同步用户(${key})注册域名过期时间完成(${req.task.getSuccessCount()}个成功,${req.task.getErrorCount()}个失败)`)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,9 @@ export class CnameRecordEntity {
|
||||
@Column({ comment: '错误信息' })
|
||||
error: string
|
||||
|
||||
@Column({ name: 'project_id', comment: '项目Id' })
|
||||
projectId: number;
|
||||
|
||||
@Column({
|
||||
comment: '创建时间',
|
||||
name: 'create_time',
|
||||
|
||||
@@ -72,7 +72,7 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
|
||||
if (!param.domain) {
|
||||
throw new ValidateException("域名不能为空");
|
||||
}
|
||||
if (!param.userId) {
|
||||
if (param.userId == null) {
|
||||
throw new ValidateException("userId不能为空");
|
||||
}
|
||||
if (param.domain.startsWith("*.")) {
|
||||
|
||||
@@ -15,6 +15,9 @@ export class UserSettingsEntity {
|
||||
@Column({ name: 'setting', comment: '设置', length: 1024, nullable: true })
|
||||
setting: string;
|
||||
|
||||
@Column({ name: 'project_id', comment: '项目Id' })
|
||||
projectId: number;
|
||||
|
||||
@Column({
|
||||
name: 'create_time',
|
||||
comment: '创建时间',
|
||||
|
||||
@@ -23,7 +23,7 @@ export class TwoFactorService {
|
||||
const { authenticator } = await import("otplib");
|
||||
|
||||
authenticatorSetting.secret = authenticator.generateSecret()
|
||||
await this.userSettingsService.saveSetting(userId, setting);
|
||||
await this.userSettingsService.saveSetting(userId, null, setting);
|
||||
}
|
||||
|
||||
const user = await this.userService.info(userId);
|
||||
@@ -59,7 +59,7 @@ export class TwoFactorService {
|
||||
authenticatorSetting.enabled = true;
|
||||
authenticatorSetting.verified = true;
|
||||
|
||||
await this.userSettingsService.saveSetting(userId, setting);
|
||||
await this.userSettingsService.saveSetting(userId, null, setting);
|
||||
}
|
||||
|
||||
async offAuthenticator(userId:number) {
|
||||
@@ -71,11 +71,11 @@ export class TwoFactorService {
|
||||
setting.authenticator.enabled = false;
|
||||
setting.authenticator.verified = false;
|
||||
setting.authenticator.secret = '';
|
||||
await this.userSettingsService.saveSetting(userId, setting);
|
||||
await this.userSettingsService.saveSetting(userId, null, setting);
|
||||
}
|
||||
|
||||
async getSetting(userId:number) {
|
||||
return await this.userSettingsService.getSetting<UserTwoFactorSetting>(userId, UserTwoFactorSetting);
|
||||
return await this.userSettingsService.getSetting<UserTwoFactorSetting>(userId, null, UserTwoFactorSetting);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -37,26 +37,27 @@ export class UserSettingsService extends BaseService<UserSettingsEntity> {
|
||||
};
|
||||
}
|
||||
|
||||
async getByKey(key: string, userId: number): Promise<UserSettingsEntity | null> {
|
||||
if(!userId){
|
||||
async getByKey(key: string, userId: number, projectId: number): Promise<UserSettingsEntity | null> {
|
||||
if(userId == null){
|
||||
throw new Error('userId is required');
|
||||
}
|
||||
if (!key || !userId) {
|
||||
if (!key) {
|
||||
return null;
|
||||
}
|
||||
return await this.repository.findOne({
|
||||
where: {
|
||||
key,
|
||||
userId
|
||||
userId,
|
||||
projectId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async getSettingByKey(key: string, userId: number): Promise<any | null> {
|
||||
if(!userId){
|
||||
async getSettingByKey(key: string, userId: number, projectId: number): Promise<any | null> {
|
||||
if(userId == null){
|
||||
throw new Error('userId is required');
|
||||
}
|
||||
const entity = await this.getByKey(key, userId);
|
||||
const entity = await this.getByKey(key, userId, projectId);
|
||||
if (!entity) {
|
||||
return null;
|
||||
}
|
||||
@@ -67,7 +68,8 @@ export class UserSettingsService extends BaseService<UserSettingsEntity> {
|
||||
const entity = await this.repository.findOne({
|
||||
where: {
|
||||
key: bean.key,
|
||||
userId: bean.userId
|
||||
userId: bean.userId,
|
||||
projectId: bean.projectId
|
||||
}
|
||||
});
|
||||
if (entity) {
|
||||
@@ -80,12 +82,16 @@ export class UserSettingsService extends BaseService<UserSettingsEntity> {
|
||||
}
|
||||
|
||||
|
||||
async getSetting<T>( userId: number,type: any, cache:boolean = false): Promise<T> {
|
||||
if(!userId){
|
||||
async getSetting<T>( userId: number, projectId: number,type: any, cache:boolean = false): Promise<T> {
|
||||
if(userId==null){
|
||||
throw new Error('userId is required');
|
||||
}
|
||||
const key = type.__key__;
|
||||
const cacheKey = key + '_' + userId;
|
||||
let cacheKey = key + '_' + userId ;
|
||||
if (projectId) {
|
||||
cacheKey += '_' + projectId;
|
||||
}
|
||||
|
||||
if (cache) {
|
||||
const settings: T = UserSettingCache.get(cacheKey);
|
||||
if (settings) {
|
||||
@@ -94,7 +100,7 @@ export class UserSettingsService extends BaseService<UserSettingsEntity> {
|
||||
}
|
||||
|
||||
let newSetting: T = new type();
|
||||
const savedSettings = await this.getSettingByKey(key, userId);
|
||||
const savedSettings = await this.getSettingByKey(key, userId, projectId);
|
||||
newSetting = merge(newSetting, savedSettings);
|
||||
|
||||
if (cache) {
|
||||
@@ -103,11 +109,11 @@ export class UserSettingsService extends BaseService<UserSettingsEntity> {
|
||||
return newSetting;
|
||||
}
|
||||
|
||||
async saveSetting<T extends BaseSettings>(userId:number,bean: T) {
|
||||
if(!userId){
|
||||
async saveSetting<T extends BaseSettings>(userId:number, projectId: number,bean: T) {
|
||||
if(userId == null){
|
||||
throw new Error('userId is required');
|
||||
}
|
||||
const old = await this.getSetting(userId,bean.constructor)
|
||||
const old = await this.getSetting(userId, projectId,bean.constructor)
|
||||
bean = merge(old,bean)
|
||||
|
||||
const type: any = bean.constructor;
|
||||
@@ -115,7 +121,7 @@ export class UserSettingsService extends BaseService<UserSettingsEntity> {
|
||||
if(!key){
|
||||
throw new Error(`${type.name} must have __key__`);
|
||||
}
|
||||
const entity = await this.getByKey(key,userId);
|
||||
const entity = await this.getByKey(key,userId, projectId);
|
||||
const newEntity = new UserSettingsEntity();
|
||||
if (entity) {
|
||||
newEntity.id = entity.id;
|
||||
@@ -123,6 +129,7 @@ export class UserSettingsService extends BaseService<UserSettingsEntity> {
|
||||
newEntity.key = key;
|
||||
newEntity.title = type.__title__;
|
||||
newEntity.userId = userId;
|
||||
newEntity.projectId = projectId;
|
||||
}
|
||||
newEntity.setting = JSON.stringify(bean);
|
||||
await this.repository.save(newEntity);
|
||||
|
||||
@@ -71,6 +71,9 @@ export class SiteInfoEntity {
|
||||
@Column({ name: 'group_id', comment: '分组id' })
|
||||
groupId: number;
|
||||
|
||||
@Column({ name: 'ip_address', comment: 'IP地址', length: 128 })
|
||||
ipAddress: string;
|
||||
|
||||
@Column({ name: 'project_id', comment: '项目id' })
|
||||
projectId: number;
|
||||
|
||||
|
||||
@@ -27,10 +27,10 @@ export class CertInfoFacade {
|
||||
@Inject()
|
||||
userSettingsService : UserSettingsService
|
||||
|
||||
async getCertInfo(req: { domains?: string; certId?: number; userId: number,autoApply?:boolean,format?:string }) {
|
||||
const { domains, certId, userId } = req;
|
||||
async getCertInfo(req: { domains?: string; certId?: number; userId: number, projectId:number, autoApply?:boolean,format?:string }) {
|
||||
const { domains, certId, userId,projectId } = req;
|
||||
if (certId) {
|
||||
return await this.certInfoService.getCertInfoById({ id: certId, userId });
|
||||
return await this.certInfoService.getCertInfoById({ id: certId, userId, projectId });
|
||||
}
|
||||
if (!domains) {
|
||||
throw new CodeException({
|
||||
@@ -40,12 +40,12 @@ export class CertInfoFacade {
|
||||
}
|
||||
const domainArr = domains.split(',');
|
||||
|
||||
const matchedList = await this.certInfoService.getMatchCertList({domains:domainArr,userId})
|
||||
const matchedList = await this.certInfoService.getMatchCertList({domains:domainArr,userId,projectId})
|
||||
|
||||
if (matchedList.length === 0 ) {
|
||||
if(req.autoApply === true){
|
||||
//自动申请,先创建自动申请流水线
|
||||
const pipeline:PipelineEntity = await this.createAutoPipeline({domains:domainArr,userId})
|
||||
const pipeline:PipelineEntity = await this.createAutoPipeline({domains:domainArr,userId,projectId})
|
||||
await this.triggerApplyPipeline({pipelineId:pipeline.id})
|
||||
}else{
|
||||
throw new CodeException({
|
||||
@@ -69,7 +69,7 @@ export class CertInfoFacade {
|
||||
}
|
||||
}
|
||||
|
||||
return await this.certInfoService.getCertInfoById({ id: matched.id, userId: userId,format:req.format });
|
||||
return await this.certInfoService.getCertInfoById({ id: matched.id, userId: userId,projectId,format:req.format });
|
||||
|
||||
|
||||
|
||||
@@ -103,9 +103,9 @@ export class CertInfoFacade {
|
||||
return matched;
|
||||
}
|
||||
|
||||
async createAutoPipeline(req:{domains:string[],userId:number}){
|
||||
async createAutoPipeline(req:{domains:string[],userId:number,projectId:number}){
|
||||
|
||||
const verifierGetter = new DomainVerifierGetter(req.userId, this.domainService)
|
||||
const verifierGetter = new DomainVerifierGetter(req.userId, req.projectId, this.domainService)
|
||||
|
||||
const allDomains = []
|
||||
for (const item of req.domains) {
|
||||
@@ -124,7 +124,7 @@ export class CertInfoFacade {
|
||||
}
|
||||
}
|
||||
|
||||
const userEmailSetting = await this.userSettingsService.getSetting<UserEmailSetting>(req.userId,UserEmailSetting)
|
||||
const userEmailSetting = await this.userSettingsService.getSetting<UserEmailSetting>(req.userId,null, UserEmailSetting)
|
||||
if(!userEmailSetting.list){
|
||||
throw new CodeException(Constants.res.openEmailNotFound)
|
||||
}
|
||||
@@ -133,8 +133,9 @@ export class CertInfoFacade {
|
||||
return await this.pipelineService.createAutoPipeline({
|
||||
domains: req.domains,
|
||||
email,
|
||||
projectId: req.projectId,
|
||||
userId: req.userId,
|
||||
from:"OpenAPI"
|
||||
from: "OpenAPI"
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ export type UploadCertReq = {
|
||||
certReader: CertReader;
|
||||
fromType?: string;
|
||||
userId?: number;
|
||||
projectId?: number;
|
||||
file?:any
|
||||
};
|
||||
|
||||
@@ -31,7 +32,7 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
||||
}
|
||||
|
||||
async getUserDomainCount(userId: number) {
|
||||
if (!userId) {
|
||||
if (userId==null) {
|
||||
throw new Error('userId is required');
|
||||
}
|
||||
return await this.repository.sum('domainCount', {
|
||||
@@ -39,11 +40,12 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
||||
});
|
||||
}
|
||||
|
||||
async updateDomains(pipelineId: number, userId: number, domains: string[],fromType?:string) {
|
||||
async updateDomains(pipelineId: number, userId: number, projectId: number, domains: string[],fromType?:string) {
|
||||
const found = await this.repository.findOne({
|
||||
where: {
|
||||
pipelineId,
|
||||
userId,
|
||||
projectId,
|
||||
},
|
||||
});
|
||||
const bean = new CertInfoEntity();
|
||||
@@ -54,6 +56,7 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
||||
//create
|
||||
bean.pipelineId = pipelineId;
|
||||
bean.userId = userId;
|
||||
bean.projectId = projectId;
|
||||
bean.fromType = fromType
|
||||
if (!domains || domains.length === 0) {
|
||||
return;
|
||||
@@ -83,8 +86,8 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
||||
});
|
||||
}
|
||||
|
||||
async getMatchCertList(params: { domains: string[]; userId: number }) {
|
||||
const { domains, userId } = params;
|
||||
async getMatchCertList(params: { domains: string[]; userId: number,projectId?:number }) {
|
||||
const { domains, userId,projectId } = params;
|
||||
if (!domains) {
|
||||
throw new CodeException({
|
||||
...Constants.res.openCertNotFound,
|
||||
@@ -101,6 +104,7 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
||||
},
|
||||
where: {
|
||||
userId,
|
||||
projectId,
|
||||
},
|
||||
order: {
|
||||
id: 'DESC',
|
||||
@@ -113,9 +117,12 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
||||
});
|
||||
}
|
||||
|
||||
async getCertInfoById(req: { id: number; userId: number,format?:string }) {
|
||||
async getCertInfoById(req: { id: number; userId: number,projectId:number,format?:string }) {
|
||||
const entity = await this.info(req.id);
|
||||
if (!entity || entity.userId !== req.userId) {
|
||||
if (!entity || entity.userId !== req.userId ) {
|
||||
throw new CodeException(Constants.res.openCertNotFound);
|
||||
}
|
||||
if (req.projectId && entity.projectId !== req.projectId) {
|
||||
throw new CodeException(Constants.res.openCertNotFound);
|
||||
}
|
||||
|
||||
@@ -167,7 +174,8 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
||||
bean.effectiveTime = certReader.effective;
|
||||
bean.expiresTime = certReader.expires;
|
||||
bean.certProvider = certReader.detail.issuer.commonName;
|
||||
bean.userId = userId
|
||||
bean.userId = userId;
|
||||
bean.projectId = req.projectId;
|
||||
if(req.file){
|
||||
bean.certFile = req.file
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
}
|
||||
|
||||
async add(data: SiteInfoEntity) {
|
||||
if (!data.userId) {
|
||||
if (data.userId == null) {
|
||||
throw new Error("userId is required");
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
}
|
||||
|
||||
async getUserMonitorCount(userId: number) {
|
||||
if (!userId) {
|
||||
if (userId==null) {
|
||||
throw new Error("userId is required");
|
||||
}
|
||||
return await this.repository.count({
|
||||
@@ -110,7 +110,7 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
throw new Error("站点域名不能为空");
|
||||
}
|
||||
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(site.userId, UserSiteMonitorSetting);
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(site.userId,site.projectId, UserSiteMonitorSetting);
|
||||
const dnsServer = setting.dnsServer
|
||||
let customDns = null
|
||||
if (dnsServer && dnsServer.length > 0) {
|
||||
@@ -127,7 +127,8 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
host: site.domain,
|
||||
port: site.httpsPort,
|
||||
retryTimes,
|
||||
customDns
|
||||
customDns,
|
||||
ipAddress: site.ipAddress,
|
||||
});
|
||||
|
||||
const certi: PeerCertificate = res.certificate;
|
||||
@@ -162,7 +163,7 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
}
|
||||
await this.update(updateData);
|
||||
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(site.userId, UserSiteMonitorSetting)
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(site.userId,site.projectId, UserSiteMonitorSetting)
|
||||
//检查ip
|
||||
await this.checkAllIp(site,retryTimes,setting);
|
||||
|
||||
@@ -345,7 +346,7 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
}
|
||||
|
||||
async checkAllByUsers(userId: any,projectId?: number) {
|
||||
if (!userId) {
|
||||
if (userId==null) {
|
||||
throw new Error("userId is required");
|
||||
}
|
||||
const sites = await this.repository.find({
|
||||
@@ -356,16 +357,17 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
|
||||
async checkList(sites: SiteInfoEntity[],isCommon: boolean) {
|
||||
const cache = {}
|
||||
const getFromCache = async (userId: number) =>{
|
||||
if (cache[userId]) {
|
||||
return cache[userId];
|
||||
const getFromCache = async (userId: number,projectId?: number) =>{
|
||||
const key = `${userId}-${projectId??""}`
|
||||
if (cache[key]) {
|
||||
return cache[key];
|
||||
}
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId, UserSiteMonitorSetting)
|
||||
cache[userId] = setting
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId,projectId, UserSiteMonitorSetting)
|
||||
cache[key] = setting
|
||||
return setting;
|
||||
}
|
||||
for (const site of sites) {
|
||||
const setting = await getFromCache(site.userId)
|
||||
const setting = await getFromCache(site.userId,site.projectId)
|
||||
if (isCommon) {
|
||||
//公共的检查,排除有设置cron的用户
|
||||
if (setting?.cron) {
|
||||
@@ -381,17 +383,17 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
}
|
||||
}
|
||||
|
||||
async getSetting(userId: number) {
|
||||
return await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId, UserSiteMonitorSetting);
|
||||
async getSetting(userId: number,projectId?: number) {
|
||||
return await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId,projectId, UserSiteMonitorSetting);
|
||||
}
|
||||
|
||||
async saveSetting(userId: number, bean: UserSiteMonitorSetting) {
|
||||
await this.userSettingsService.saveSetting(userId, bean);
|
||||
async saveSetting(userId: number,projectId: number, bean: UserSiteMonitorSetting) {
|
||||
await this.userSettingsService.saveSetting(userId,projectId, bean);
|
||||
if(bean.cron){
|
||||
//注册job
|
||||
await this.registerSiteMonitorJob(userId);
|
||||
await this.registerSiteMonitorJob(userId,projectId);
|
||||
}else{
|
||||
this.clearSiteMonitorJob(userId);
|
||||
this.clearSiteMonitorJob(userId,projectId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -476,13 +478,13 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
await batchAdd(list);
|
||||
}
|
||||
|
||||
clearSiteMonitorJob(userId: number) {
|
||||
this.cron.remove(`siteMonitor-${userId}`);
|
||||
clearSiteMonitorJob(userId: number,projectId?: number) {
|
||||
this.cron.remove(`siteMonitor-${userId}-${projectId||""}`);
|
||||
}
|
||||
|
||||
async registerSiteMonitorJob(userId?: number) {
|
||||
async registerSiteMonitorJob(userId?: number,projectId?: number) {
|
||||
|
||||
if(!userId){
|
||||
if(userId == null){
|
||||
//注册公共job
|
||||
logger.info(`注册站点证书检查定时任务`)
|
||||
this.cron.register({
|
||||
@@ -494,27 +496,30 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
});
|
||||
logger.info(`注册站点证书检查定时任务完成`)
|
||||
}else{
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId, UserSiteMonitorSetting);
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId,projectId, UserSiteMonitorSetting);
|
||||
if (!setting.cron) {
|
||||
return;
|
||||
}
|
||||
//注册个人的
|
||||
//注册个人的 或项目的
|
||||
this.cron.register({
|
||||
name: `siteMonitor-${userId}`,
|
||||
name: `siteMonitor-${userId}-${projectId||""}`,
|
||||
cron: setting.cron,
|
||||
job: () => this.triggerJobOnce(userId),
|
||||
job: () => this.triggerJobOnce(userId,projectId),
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async triggerJobOnce(userId?:number) {
|
||||
logger.info(`站点证书检查开始执行[${userId??'所有用户'}]`);
|
||||
async triggerJobOnce(userId?:number,projectId?:number) {
|
||||
logger.info(`站点证书检查开始执行[${userId??'所有用户'}-${projectId??'所有项目'}]`);
|
||||
const query:any = { disabled: false };
|
||||
if(userId){
|
||||
query.userId = userId;
|
||||
if(projectId){
|
||||
query.projectId = projectId;
|
||||
}
|
||||
//判断是否已关闭
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId, UserSiteMonitorSetting);
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId,projectId, UserSiteMonitorSetting);
|
||||
if (!setting.cron) {
|
||||
return;
|
||||
}
|
||||
@@ -536,7 +541,7 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
await this.checkList(records,isCommon);
|
||||
}
|
||||
|
||||
logger.info(`站点证书检查完成[${userId??'所有用户'}]`);
|
||||
logger.info(`站点证书检查完成[${userId??'所有用户'}-${projectId??'所有项目'}]`);
|
||||
}
|
||||
|
||||
async batchDelete(ids: number[], userId: number,projectId?:number): Promise<void> {
|
||||
|
||||
@@ -67,7 +67,7 @@ export class SiteIpService extends BaseService<SiteIpEntity> {
|
||||
|
||||
const domain = entity.domain;
|
||||
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(entity.userId, UserSiteMonitorSetting);
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(entity.userId,entity.projectId, UserSiteMonitorSetting);
|
||||
|
||||
const dnsServer = setting.dnsServer
|
||||
let resolver = dns
|
||||
|
||||
@@ -9,6 +9,7 @@ import dayjs from 'dayjs';
|
||||
|
||||
export type OpenKey = {
|
||||
userId: number;
|
||||
projectId?: number;
|
||||
keyId: string;
|
||||
keySecret: string;
|
||||
encrypt: boolean;
|
||||
@@ -30,15 +31,16 @@ export class OpenKeyService extends BaseService<OpenKeyEntity> {
|
||||
}
|
||||
|
||||
async add(bean: OpenKeyEntity) {
|
||||
return await this.generate(bean.userId, bean.scope);
|
||||
return await this.generate(bean.userId,bean.projectId, bean.scope);
|
||||
}
|
||||
|
||||
async generate(userId: number, scope: string) {
|
||||
async generate(userId: number, projectId?: number, scope: string = 'open') {
|
||||
const keyId = utils.id.simpleNanoId(18) + '_key';
|
||||
const secretKey = crypto.randomBytes(32);
|
||||
const keySecret = Buffer.from(secretKey).toString('hex');
|
||||
const entity = new OpenKeyEntity();
|
||||
entity.userId = userId;
|
||||
entity.projectId = projectId;
|
||||
entity.keyId = keyId;
|
||||
entity.keySecret = keySecret;
|
||||
entity.scope = scope ?? 'open';
|
||||
@@ -80,7 +82,7 @@ export class OpenKeyService extends BaseService<OpenKeyEntity> {
|
||||
throw new CodeException(Constants.res.openKeySignError);
|
||||
}
|
||||
|
||||
if (!entity.userId) {
|
||||
if (entity.userId==null) {
|
||||
throw new CodeException(Constants.res.openKeyError);
|
||||
}
|
||||
|
||||
@@ -89,6 +91,7 @@ export class OpenKeyService extends BaseService<OpenKeyEntity> {
|
||||
keyId: entity.keyId,
|
||||
keySecret: entity.keySecret,
|
||||
encrypt: encrypt,
|
||||
projectId: entity.projectId,
|
||||
scope: entity.scope,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@ export class SubDomainEntity {
|
||||
@Column({ name: 'disabled', comment: '禁用' })
|
||||
disabled: boolean;
|
||||
|
||||
@Column({ name: 'project_id', comment: '项目Id' })
|
||||
projectId: number;
|
||||
|
||||
@Column({
|
||||
name: 'create_time',
|
||||
comment: '创建时间',
|
||||
|
||||
@@ -16,9 +16,10 @@ export class AddonGetterService {
|
||||
addonService: AddonService;
|
||||
|
||||
|
||||
async getAddonById(id: any, checkUserId: boolean, userId?: number, defaultAddon?:{type:string,name:string} ): Promise<any> {
|
||||
async getAddonById(id: any, checkUserId: boolean, userId?: number, projectId?: number, defaultAddon?:{type:string,name:string} ): Promise<any> {
|
||||
const serviceGetter = this.taskServiceBuilder.create({
|
||||
userId
|
||||
userId,
|
||||
projectId,
|
||||
});
|
||||
const ctx = {
|
||||
http,
|
||||
@@ -58,13 +59,13 @@ export class AddonGetterService {
|
||||
return await newAddon(entity.addonType, entity.type, input, ctx);
|
||||
}
|
||||
|
||||
async getById(id: any, userId: number): Promise<any> {
|
||||
return await this.getAddonById(id, true, userId);
|
||||
async getById(id: any, userId: number, projectId?: number): Promise<any> {
|
||||
return await this.getAddonById(id, true, userId, projectId);
|
||||
}
|
||||
|
||||
|
||||
async getBlank(addonType:string,subType:string){
|
||||
return await this.getAddonById(null,false,0,{
|
||||
async getBlank(addonType:string,subType:string,projectId?: number){
|
||||
return await this.getAddonById(null,false,0,projectId,{
|
||||
type: addonType, name:subType
|
||||
})
|
||||
}
|
||||
|
||||
+4
-2
@@ -3,15 +3,17 @@ import {DomainService} from "../../../cert/service/domain-service.js";
|
||||
|
||||
export class DomainVerifierGetter implements IDomainVerifierGetter {
|
||||
private userId: number;
|
||||
private projectId: number;
|
||||
private domainService: DomainService;
|
||||
|
||||
constructor(userId: number, domainService: DomainService) {
|
||||
constructor(userId: number, projectId: number, domainService: DomainService) {
|
||||
this.userId = userId;
|
||||
this.projectId = projectId;
|
||||
this.domainService = domainService;
|
||||
}
|
||||
|
||||
async getVerifiers(domains: string[]): Promise<DomainVerifiers>{
|
||||
return await this.domainService.getDomainVerifiers(this.userId,domains);
|
||||
return await this.domainService.getDomainVerifiers(this.userId,this.projectId,domains);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,22 +3,24 @@ import {NotificationService} from "../notification-service.js";
|
||||
|
||||
export class NotificationGetter implements INotificationService {
|
||||
userId: number;
|
||||
projectId: number;
|
||||
notificationService: NotificationService;
|
||||
|
||||
constructor(userId: number, notificationService: NotificationService) {
|
||||
constructor(userId: number, projectId: number, notificationService: NotificationService) {
|
||||
this.userId = userId;
|
||||
this.projectId = projectId;
|
||||
this.notificationService = notificationService;
|
||||
}
|
||||
|
||||
async getDefault() {
|
||||
return await this.notificationService.getDefault(this.userId);
|
||||
return await this.notificationService.getDefault(this.userId, this.projectId);
|
||||
}
|
||||
|
||||
async getById(id: any) {
|
||||
return await this.notificationService.getById(id, this.userId);
|
||||
return await this.notificationService.getById(id, this.userId, this.projectId);
|
||||
}
|
||||
|
||||
async send(req: NotificationSendReq): Promise<void> {
|
||||
return await this.notificationService.send(req, this.userId);
|
||||
return await this.notificationService.send(req, this.userId, this.projectId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,17 +4,19 @@ import { DomainService } from "../../../cert/service/domain-service.js";
|
||||
|
||||
export class SubDomainsGetter implements ISubDomainsGetter {
|
||||
userId: number;
|
||||
projectId: number;
|
||||
subDomainService: SubDomainService;
|
||||
domainService: DomainService;
|
||||
|
||||
constructor(userId: number, subDomainService: SubDomainService, domainService: DomainService) {
|
||||
constructor(userId: number, projectId: number, subDomainService: SubDomainService, domainService: DomainService) {
|
||||
this.userId = userId;
|
||||
this.projectId = projectId;
|
||||
this.subDomainService = subDomainService;
|
||||
this.domainService = domainService;
|
||||
}
|
||||
|
||||
async getSubDomains() {
|
||||
return await this.subDomainService.getListByUserId(this.userId)
|
||||
return await this.subDomainService.getListByUserId(this.userId, this.projectId)
|
||||
}
|
||||
|
||||
async hasSubDomain(fullDomain: string) {
|
||||
|
||||
+10
-6
@@ -15,9 +15,11 @@ const serviceNames = [
|
||||
]
|
||||
export class TaskServiceGetter implements IServiceGetter{
|
||||
private userId: number;
|
||||
private projectId: number;
|
||||
private appCtx : IMidwayContainer;
|
||||
constructor(userId:number,appCtx:IMidwayContainer) {
|
||||
constructor(userId:number,projectId:number,appCtx:IMidwayContainer) {
|
||||
this.userId = userId;
|
||||
this.projectId = projectId;
|
||||
this.appCtx = appCtx
|
||||
}
|
||||
async get<T>(serviceName: string): Promise<T> {
|
||||
@@ -46,12 +48,12 @@ export class TaskServiceGetter implements IServiceGetter{
|
||||
async getSubDomainsGetter(): Promise<SubDomainsGetter> {
|
||||
const subDomainsService:SubDomainService = await this.appCtx.getAsync("subDomainService")
|
||||
const domainService:DomainService = await this.appCtx.getAsync("domainService")
|
||||
return new SubDomainsGetter(this.userId, subDomainsService,domainService)
|
||||
return new SubDomainsGetter(this.userId,this.projectId, subDomainsService,domainService)
|
||||
}
|
||||
|
||||
async getAccessService(): Promise<AccessGetter> {
|
||||
const accessService:AccessService = await this.appCtx.getAsync("accessService")
|
||||
return new AccessGetter(this.userId, accessService.getById.bind(accessService));
|
||||
return new AccessGetter(this.userId, this.projectId, accessService.getById.bind(accessService));
|
||||
}
|
||||
|
||||
|
||||
@@ -62,12 +64,12 @@ export class TaskServiceGetter implements IServiceGetter{
|
||||
|
||||
async getNotificationService(): Promise<NotificationGetter> {
|
||||
const notificationService:NotificationService = await this.appCtx.getAsync("notificationService")
|
||||
return new NotificationGetter(this.userId, notificationService);
|
||||
return new NotificationGetter(this.userId, this.projectId, notificationService);
|
||||
}
|
||||
|
||||
async getDomainVerifierGetter(): Promise<DomainVerifierGetter> {
|
||||
const domainService:DomainService = await this.appCtx.getAsync("domainService")
|
||||
return new DomainVerifierGetter(this.userId, domainService);
|
||||
return new DomainVerifierGetter(this.userId, this.projectId, domainService);
|
||||
}
|
||||
}
|
||||
@Provide()
|
||||
@@ -78,12 +80,14 @@ export class TaskServiceBuilder {
|
||||
|
||||
create(req:TaskServiceCreateReq){
|
||||
const userId = req.userId;
|
||||
return new TaskServiceGetter(userId,this.appCtx)
|
||||
const projectId = req.projectId;
|
||||
return new TaskServiceGetter(userId,projectId,this.appCtx)
|
||||
}
|
||||
}
|
||||
|
||||
export type TaskServiceCreateReq = {
|
||||
userId: number;
|
||||
projectId?: number;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -84,17 +84,18 @@ export class NotificationService extends BaseService<NotificationEntity> {
|
||||
}
|
||||
}
|
||||
|
||||
async getById(id: number, userId: number): Promise<NotificationInstanceConfig> {
|
||||
async getById(id: number, userId: number, projectId?: number): Promise<NotificationInstanceConfig> {
|
||||
if (!id) {
|
||||
throw new ValidateException('id不能为空');
|
||||
}
|
||||
if (!userId) {
|
||||
if (userId==null) {
|
||||
throw new ValidateException('userId不能为空');
|
||||
}
|
||||
const res = await this.repository.findOne({
|
||||
where: {
|
||||
id,
|
||||
userId,
|
||||
projectId,
|
||||
},
|
||||
});
|
||||
if (!res) {
|
||||
@@ -114,10 +115,11 @@ export class NotificationService extends BaseService<NotificationEntity> {
|
||||
};
|
||||
}
|
||||
|
||||
async getDefault(userId: number): Promise<NotificationInstanceConfig> {
|
||||
async getDefault(userId: number, projectId?: number): Promise<NotificationInstanceConfig> {
|
||||
const res = await this.repository.findOne({
|
||||
where: {
|
||||
userId,
|
||||
projectId,
|
||||
},
|
||||
order: {
|
||||
isDefault: 'DESC',
|
||||
@@ -129,16 +131,17 @@ export class NotificationService extends BaseService<NotificationEntity> {
|
||||
return this.buildNotificationInstanceConfig(res);
|
||||
}
|
||||
|
||||
async setDefault(id: number, userId: number) {
|
||||
async setDefault(id: number, userId: number, projectId?: number) {
|
||||
if (!id) {
|
||||
throw new ValidateException('id不能为空');
|
||||
}
|
||||
if (!userId) {
|
||||
if (userId==null) {
|
||||
throw new ValidateException('userId不能为空');
|
||||
}
|
||||
await this.repository.update(
|
||||
{
|
||||
userId,
|
||||
projectId,
|
||||
},
|
||||
{
|
||||
isDefault: false,
|
||||
@@ -148,6 +151,7 @@ export class NotificationService extends BaseService<NotificationEntity> {
|
||||
{
|
||||
id,
|
||||
userId,
|
||||
projectId,
|
||||
},
|
||||
{
|
||||
isDefault: true,
|
||||
@@ -155,8 +159,8 @@ export class NotificationService extends BaseService<NotificationEntity> {
|
||||
);
|
||||
}
|
||||
|
||||
async getOrCreateDefault(email: string, userId: any) {
|
||||
const defaultConfig = await this.getDefault(userId);
|
||||
async getOrCreateDefault(email: string, userId: any, projectId?: number) {
|
||||
const defaultConfig = await this.getDefault(userId, projectId);
|
||||
if (defaultConfig) {
|
||||
return defaultConfig;
|
||||
}
|
||||
@@ -169,21 +173,22 @@ export class NotificationService extends BaseService<NotificationEntity> {
|
||||
name: '邮件通知',
|
||||
setting: JSON.stringify(setting),
|
||||
isDefault: true,
|
||||
projectId,
|
||||
});
|
||||
return this.buildNotificationInstanceConfig(res);
|
||||
}
|
||||
|
||||
async send(req: NotificationSendReq, userId?: number) {
|
||||
async send(req: NotificationSendReq, userId?: number, projectId?: number) {
|
||||
const logger = req.logger;
|
||||
let notifyConfig: NotificationInstanceConfig = null;
|
||||
if (req.id && req.id > 0) {
|
||||
notifyConfig = await this.getById(req.id, userId);
|
||||
notifyConfig = await this.getById(req.id, userId, projectId);
|
||||
if (!notifyConfig) {
|
||||
logger.warn(`未找到通知配置<${req.id}>,请确认是否已被删除`);
|
||||
}
|
||||
}
|
||||
if (!notifyConfig) {
|
||||
notifyConfig = await this.getDefault(userId);
|
||||
notifyConfig = await this.getDefault(userId, projectId);
|
||||
if (!notifyConfig) {
|
||||
logger.warn(`未找到默认通知配置`);
|
||||
}
|
||||
|
||||
@@ -256,7 +256,6 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
}
|
||||
|
||||
await this.doUpdatePipelineJson(bean, pipeline);
|
||||
|
||||
//保存域名信息到certInfo表
|
||||
let fromType = "pipeline";
|
||||
if (bean.type === "cert_upload") {
|
||||
@@ -264,7 +263,9 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
} else if (bean.type === "cert_auto") {
|
||||
fromType = "auto";
|
||||
}
|
||||
await this.certInfoService.updateDomains(pipeline.id, pipeline.userId || bean.userId, domains, fromType);
|
||||
const userId = pipeline.userId || bean.userId;
|
||||
const projectId = pipeline.projectId ?? bean.projectId ??null;
|
||||
await this.certInfoService.updateDomains(pipeline.id, userId, projectId , domains, fromType);
|
||||
return {
|
||||
...bean,
|
||||
version: pipeline.version,
|
||||
@@ -293,6 +294,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
bean.content = JSON.stringify(pipeline);
|
||||
await this.addOrUpdate(bean);
|
||||
await this.registerTrigger(bean);
|
||||
return bean
|
||||
}
|
||||
|
||||
private async checkMaxPipelineCount(bean: PipelineEntity, pipeline: Pipeline, domains: string[]) {
|
||||
@@ -1082,7 +1084,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
}
|
||||
}
|
||||
|
||||
async createAutoPipeline(req: { domains: string[]; email: string; userId: number, from: string }) {
|
||||
async createAutoPipeline(req: { domains: string[]; email: string; userId: number,projectId?:number, from: string }) {
|
||||
|
||||
const randomHour = Math.floor(Math.random() * 6);
|
||||
const randomMin = Math.floor(Math.random() * 60);
|
||||
@@ -1162,6 +1164,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
bean.type = "cert_auto";
|
||||
bean.disabled = false
|
||||
bean.keepHistoryCount = 30
|
||||
bean.projectId = req.projectId
|
||||
await this.save(bean)
|
||||
|
||||
|
||||
|
||||
@@ -22,13 +22,14 @@ export class SubDomainService extends BaseService<SubDomainEntity> {
|
||||
return this.repository;
|
||||
}
|
||||
|
||||
async getListByUserId(userId:number):Promise<string[]>{
|
||||
if (!userId) {
|
||||
async getListByUserId(userId:number, projectId?: number):Promise<string[]>{
|
||||
if (userId==null) {
|
||||
return [];
|
||||
}
|
||||
const list = await this.find({
|
||||
where: {
|
||||
userId,
|
||||
projectId,
|
||||
disabled: false,
|
||||
},
|
||||
});
|
||||
@@ -37,17 +38,18 @@ export class SubDomainService extends BaseService<SubDomainEntity> {
|
||||
}
|
||||
|
||||
async add(bean: SubDomainEntity) {
|
||||
const {domain, userId} = bean;
|
||||
const {domain, userId, projectId} = bean;
|
||||
if (!domain) {
|
||||
throw new Error('域名不能为空');
|
||||
}
|
||||
if (!userId) {
|
||||
if (userId==null) {
|
||||
throw new Error('用户ID不能为空');
|
||||
}
|
||||
const exist = await this.repository.findOne({
|
||||
where: {
|
||||
domain,
|
||||
userId,
|
||||
projectId,
|
||||
},
|
||||
});
|
||||
if (exist) {
|
||||
|
||||
@@ -6,7 +6,7 @@ export async function getEmailSettings(sysSettingService: SysSettingsService, us
|
||||
let conf = await sysSettingService.getSetting<SysEmailConf>(SysEmailConf);
|
||||
if (!conf.host || conf.usePlus == null) {
|
||||
//到userSetting里面去找
|
||||
const adminEmailSetting = await userSettingsService.getByKey('email', 1);
|
||||
const adminEmailSetting = await userSettingsService.getByKey('email', 1,null);
|
||||
if (adminEmailSetting) {
|
||||
const setting = JSON.parse(adminEmailSetting.setting);
|
||||
conf = _.merge(conf, setting);
|
||||
|
||||
@@ -63,7 +63,10 @@ export class JDCloudDnsProvider extends AbstractDnsProvider {
|
||||
domainId: domainId
|
||||
};
|
||||
}catch (e) {
|
||||
this.logger.error(e)
|
||||
if (e.error){
|
||||
this.logger.error(JSON.stringify(e.error))
|
||||
throw new Error(JSON.stringify(e.error))
|
||||
}
|
||||
throw e
|
||||
}
|
||||
|
||||
|
||||
+21
-14
@@ -7,9 +7,9 @@ import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: "SafelineDeployToWebsitePlugin",
|
||||
title: "雷池-更新证书",
|
||||
title: "雷池-更新证书(支持控制台和防护应用)",
|
||||
icon: "svg:icon-safeline",
|
||||
desc: "更新长亭雷池WAF的证书",
|
||||
desc: "更新长亭雷池WAF的证书,支持更新控制台和防护应用的证书。",
|
||||
group: pluginGroups.panel.key,
|
||||
default: {
|
||||
strategy: {
|
||||
@@ -51,7 +51,7 @@ export class SafelineDeployToWebsitePlugin extends AbstractTaskPlugin {
|
||||
title: "雷池证书",
|
||||
typeName: "SafelineDeployToWebsitePlugin",
|
||||
action: SafelineDeployToWebsitePlugin.prototype.onGetCertIds.name,
|
||||
helper: "请选择要更新的雷池的证书Id,需要先手动到雷池控制台上传一次",
|
||||
helper: "请选择要更新的雷池的证书Id,需要先手动到雷池控制台上传一次\n如果输入0,则表示新增证书,运行一次之后可以在雷池中使用该证书,最后记得在此处选择新上传的这个证书id,后续将进行自动更新",
|
||||
required: true,
|
||||
})
|
||||
)
|
||||
@@ -69,19 +69,26 @@ export class SafelineDeployToWebsitePlugin extends AbstractTaskPlugin {
|
||||
}
|
||||
|
||||
async uploadCert(certId: number) {
|
||||
await this.doRequest({
|
||||
const data:any = {
|
||||
manual: {
|
||||
crt: this.cert.crt,
|
||||
key: this.cert.key,
|
||||
},
|
||||
type: 2,
|
||||
};
|
||||
let type = "新增"
|
||||
// @ts-ignore
|
||||
if (certId !== "0" && certId >0) {
|
||||
//@ts-ignore
|
||||
data.id = parseInt(certId)
|
||||
type = "更新"
|
||||
}
|
||||
const res = await this.doRequest({
|
||||
url: "/api/open/cert",
|
||||
method: "post",
|
||||
data: {
|
||||
id: certId,
|
||||
manual: {
|
||||
crt: this.cert.crt,
|
||||
key: this.cert.key,
|
||||
},
|
||||
type: 2,
|
||||
},
|
||||
data:data
|
||||
});
|
||||
this.logger.info(`证书<${certId}>更新成功`);
|
||||
this.logger.info(`证书<${certId}>${type}成功,ID:${res}`);
|
||||
}
|
||||
|
||||
async doRequest(config: HttpRequestConfig<any>) {
|
||||
@@ -109,7 +116,7 @@ export class SafelineDeployToWebsitePlugin extends AbstractTaskPlugin {
|
||||
});
|
||||
const nodes = res?.nodes;
|
||||
if (!nodes || nodes.length === 0) {
|
||||
throw new Error("没有找到证书,请先在雷池控制台中手动上传证书,并关联防护站点,后续才可以自动更新");
|
||||
throw new Error("没有找到证书,请先在雷池控制台中手动上传证书,并关联防护站点或控制台面板使用该证书,后续才可以自动更新");
|
||||
}
|
||||
const options = nodes.map(item => {
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user