diff --git a/back/api/env.ts b/back/api/env.ts index c05e8c60..32b72124 100644 --- a/back/api/env.ts +++ b/back/api/env.ts @@ -6,6 +6,7 @@ import { celebrate, Joi } from 'celebrate'; import multer from 'multer'; import config from '../config'; import fs from 'fs'; +import { safeJSONParse } from '../config/util'; const route = Router(); const storage = multer.diskStorage({ @@ -200,7 +201,7 @@ export default (app: Router) => { try { const envService = Container.get(EnvService); const fileContent = await fs.promises.readFile(req!.file!.path, 'utf8'); - const parseContent = JSON.parse(fileContent); + const parseContent = safeJSONParse(fileContent); const data = Array.isArray(parseContent) ? parseContent : [parseContent]; diff --git a/back/config/index.ts b/back/config/index.ts index 952324bf..7ed21b6f 100644 --- a/back/config/index.ts +++ b/back/config/index.ts @@ -1,6 +1,6 @@ import dotenv from 'dotenv'; import path from 'path'; -import { createRandomString } from './util'; +import { createRandomString } from './share'; process.env.NODE_ENV = process.env.NODE_ENV || 'development'; diff --git a/back/config/share.ts b/back/config/share.ts new file mode 100644 index 00000000..8577feea --- /dev/null +++ b/back/config/share.ts @@ -0,0 +1,84 @@ +export function createRandomString(min: number, max: number): string { + const num = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; + const english = [ + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + ]; + const ENGLISH = [ + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', + ]; + const special = ['-', '_']; + const config = num.concat(english).concat(ENGLISH).concat(special); + + const arr = []; + arr.push(getOne(num)); + arr.push(getOne(english)); + arr.push(getOne(ENGLISH)); + arr.push(getOne(special)); + + const len = min + Math.floor(Math.random() * (max - min + 1)); + + for (let i = 4; i < len; i++) { + arr.push(config[Math.floor(Math.random() * config.length)]); + } + + const newArr = []; + for (let j = 0; j < len; j++) { + newArr.push(arr.splice(Math.random() * arr.length, 1)[0]); + } + + function getOne(arr: any[]) { + return arr[Math.floor(Math.random() * arr.length)]; + } + + return newArr.join(''); +} \ No newline at end of file diff --git a/back/config/util.ts b/back/config/util.ts index 5816535b..58b42ebc 100644 --- a/back/config/util.ts +++ b/back/config/util.ts @@ -9,6 +9,9 @@ import { promisify } from 'util'; import { load } from 'js-yaml'; import config from './index'; import { TASK_COMMAND } from './const'; +import Logger from '../loaders/logger'; + +export * from './share'; export function getFileContentByName(fileName: string) { if (fs.existsSync(fileName)) { @@ -36,91 +39,6 @@ export function getLastModifyFilePath(dir: string) { return filePath; } -export function createRandomString(min: number, max: number): string { - const num = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; - const english = [ - 'a', - 'b', - 'c', - 'd', - 'e', - 'f', - 'g', - 'h', - 'i', - 'j', - 'k', - 'l', - 'm', - 'n', - 'o', - 'p', - 'q', - 'r', - 's', - 't', - 'u', - 'v', - 'w', - 'x', - 'y', - 'z', - ]; - const ENGLISH = [ - 'A', - 'B', - 'C', - 'D', - 'E', - 'F', - 'G', - 'H', - 'I', - 'J', - 'K', - 'L', - 'M', - 'N', - 'O', - 'P', - 'Q', - 'R', - 'S', - 'T', - 'U', - 'V', - 'W', - 'X', - 'Y', - 'Z', - ]; - const special = ['-', '_']; - const config = num.concat(english).concat(ENGLISH).concat(special); - - const arr = []; - arr.push(getOne(num)); - arr.push(getOne(english)); - arr.push(getOne(ENGLISH)); - arr.push(getOne(special)); - - const len = min + Math.floor(Math.random() * (max - min + 1)); - - for (let i = 4; i < len; i++) { - arr.push(config[Math.floor(Math.random() * config.length)]); - } - - const newArr = []; - for (let j = 0; j < len; j++) { - newArr.push(arr.splice(Math.random() * arr.length, 1)[0]); - } - - function getOne(arr: any[]) { - return arr[Math.floor(Math.random() * arr.length)]; - } - - return newArr.join(''); -} - export function getToken(req: any) { const { authorization = '' } = req.headers; if (authorization && authorization.split(' ')[0] === 'Bearer') { @@ -562,3 +480,16 @@ export async function getUniqPath(command: string, id: string): Promise return `${str}${id}`; } + +export function safeJSONParse(value?: string) { + if (!value) { + return {}; + } + + try { + return JSON.parse(value); + } catch (error) { + Logger.error('[JSON.parse失败]', error) + return {}; + } +} \ No newline at end of file diff --git a/back/loaders/express.ts b/back/loaders/express.ts index 3ae2450d..7f1a06f2 100644 --- a/back/loaders/express.ts +++ b/back/loaders/express.ts @@ -5,7 +5,7 @@ import routes from '../api'; import config from '../config'; import jwt, { UnauthorizedError } from 'express-jwt'; import fs from 'fs'; -import { getPlatform, getToken } from '../config/util'; +import { getPlatform, getToken, safeJSONParse } from '../config/util'; import Container from 'typedi'; import OpenService from '../services/open'; import rewrite from 'express-urlrewrite'; @@ -38,7 +38,7 @@ export default ({ app }: { app: Application }) => { app.use( jwt({ - secret: config.secret as string, + secret: config.secret, algorithms: ['HS384'], }).unless({ path: [...config.apiWhiteList, /^\/open\//], @@ -85,7 +85,7 @@ export default ({ app }: { app: Application }) => { const data = fs.readFileSync(config.authConfigFile, 'utf8'); if (data && headerToken) { - const { token = '', tokens = {} } = JSON.parse(data); + const { token = '', tokens = {} } = safeJSONParse(data); if (headerToken === token || tokens[req.platform] === headerToken) { return next(); } diff --git a/back/loaders/sock.ts b/back/loaders/sock.ts index f5370d01..47feeee5 100644 --- a/back/loaders/sock.ts +++ b/back/loaders/sock.ts @@ -5,7 +5,7 @@ import { Container } from 'typedi'; import SockService from '../services/sock'; import config from '../config/index'; import fs from 'fs'; -import { getPlatform } from '../config/util'; +import { getPlatform, safeJSONParse } from '../config/util'; export default async ({ server }: { server: Server }) => { const echo = sockJs.createServer({ prefix: '/api/ws', log: () => {} }); @@ -20,7 +20,7 @@ export default async ({ server }: { server: Server }) => { const platform = getPlatform(conn.headers['user-agent'] || '') || 'desktop'; const headerToken = conn.url.replace(`${conn.pathname}?token=`, ''); if (data) { - const { token = '', tokens = {} } = JSON.parse(data); + const { token = '', tokens = {} } = safeJSONParse(data); if (headerToken === token || tokens[platform] === headerToken) { conn.write(JSON.stringify({ type: 'ping', message: 'hanhh' })); sockService.addClient(conn); diff --git a/back/services/cron.ts b/back/services/cron.ts index 69c36e76..17c403b3 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -5,7 +5,7 @@ import { Crontab, CrontabModel, CrontabStatus } from '../data/cron'; import { exec, execSync } from 'child_process'; import fs from 'fs'; import cron_parser from 'cron-parser'; -import { getFileContentByName, fileExist, killTask, getUniqPath } from '../config/util'; +import { getFileContentByName, fileExist, killTask, getUniqPath, safeJSONParse } from '../config/util'; import { promises, existsSync } from 'fs'; import { Op, where, col as colFn, FindOptions, fn } from 'sequelize'; import path from 'path'; @@ -309,9 +309,9 @@ export default class CronService { const searchText = params?.searchValue; const page = Number(params?.page || '0'); const size = Number(params?.size || '0'); - const viewQuery = JSON.parse(params?.queryString || '{}'); - const filterQuery = JSON.parse(params?.filters || '{}'); - const sorterQuery = JSON.parse(params?.sorter || '{}'); + const viewQuery = safeJSONParse(params?.queryString); + const filterQuery = safeJSONParse(params?.filters); + const sorterQuery = safeJSONParse(params?.sorter); let query: any = {}; let order = [ diff --git a/back/services/user.ts b/back/services/user.ts index c25a0c75..607c778e 100644 --- a/back/services/user.ts +++ b/back/services/user.ts @@ -5,6 +5,7 @@ import { fileExist, getNetIp, getPlatform, + safeJSONParse, } from '../config/util'; import config from '../config'; import * as fs from 'fs'; @@ -327,7 +328,7 @@ export default class UserService { private getAuthInfo() { const content = fs.readFileSync(config.authConfigFile, 'utf8'); - return JSON.parse(content || '{}'); + return safeJSONParse(content); } private updateAuthInfo(authInfo: any, info: any) { diff --git a/src/pages/env/index.tsx b/src/pages/env/index.tsx index 65d148bc..9a1456ed 100644 --- a/src/pages/env/index.tsx +++ b/src/pages/env/index.tsx @@ -42,7 +42,7 @@ import useTableScrollHeight from '@/hooks/useTableScrollHeight'; import Copy from '../../components/copy'; import { useVT } from 'virtualizedtableforantd4'; -const { Text } = Typography; +const { Paragraph } = Typography; const { Search } = Input; enum Status { @@ -246,9 +246,14 @@ const Env = () => { ? intl.get('启用') : intl.get('禁用')} Env{' '} - + {record.value} - {' '} + {' '} {intl.get('吗')} ), @@ -302,9 +307,14 @@ const Env = () => { content: ( <> {intl.get('确认删除变量')}{' '} - + {record.name}: {record.value} - {' '} + {' '} {intl.get('吗')} ),