修复 JSON.parse 错误,修复删除环境变量名称过长

This commit is contained in:
whyour 2023-08-27 12:41:06 +08:00
parent 648b9c4520
commit e2bd15683e
9 changed files with 129 additions and 102 deletions

View File

@ -6,6 +6,7 @@ import { celebrate, Joi } from 'celebrate';
import multer from 'multer'; import multer from 'multer';
import config from '../config'; import config from '../config';
import fs from 'fs'; import fs from 'fs';
import { safeJSONParse } from '../config/util';
const route = Router(); const route = Router();
const storage = multer.diskStorage({ const storage = multer.diskStorage({
@ -200,7 +201,7 @@ export default (app: Router) => {
try { try {
const envService = Container.get(EnvService); const envService = Container.get(EnvService);
const fileContent = await fs.promises.readFile(req!.file!.path, 'utf8'); const fileContent = await fs.promises.readFile(req!.file!.path, 'utf8');
const parseContent = JSON.parse(fileContent); const parseContent = safeJSONParse(fileContent);
const data = Array.isArray(parseContent) const data = Array.isArray(parseContent)
? parseContent ? parseContent
: [parseContent]; : [parseContent];

View File

@ -1,6 +1,6 @@
import dotenv from 'dotenv'; import dotenv from 'dotenv';
import path from 'path'; import path from 'path';
import { createRandomString } from './util'; import { createRandomString } from './share';
process.env.NODE_ENV = process.env.NODE_ENV || 'development'; process.env.NODE_ENV = process.env.NODE_ENV || 'development';

84
back/config/share.ts Normal file
View File

@ -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('');
}

View File

@ -9,6 +9,9 @@ import { promisify } from 'util';
import { load } from 'js-yaml'; import { load } from 'js-yaml';
import config from './index'; import config from './index';
import { TASK_COMMAND } from './const'; import { TASK_COMMAND } from './const';
import Logger from '../loaders/logger';
export * from './share';
export function getFileContentByName(fileName: string) { export function getFileContentByName(fileName: string) {
if (fs.existsSync(fileName)) { if (fs.existsSync(fileName)) {
@ -36,91 +39,6 @@ export function getLastModifyFilePath(dir: string) {
return filePath; 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) { export function getToken(req: any) {
const { authorization = '' } = req.headers; const { authorization = '' } = req.headers;
if (authorization && authorization.split(' ')[0] === 'Bearer') { if (authorization && authorization.split(' ')[0] === 'Bearer') {
@ -562,3 +480,16 @@ export async function getUniqPath(command: string, id: string): Promise<string>
return `${str}${id}`; return `${str}${id}`;
} }
export function safeJSONParse(value?: string) {
if (!value) {
return {};
}
try {
return JSON.parse(value);
} catch (error) {
Logger.error('[JSON.parse失败]', error)
return {};
}
}

View File

@ -5,7 +5,7 @@ import routes from '../api';
import config from '../config'; import config from '../config';
import jwt, { UnauthorizedError } from 'express-jwt'; import jwt, { UnauthorizedError } from 'express-jwt';
import fs from 'fs'; import fs from 'fs';
import { getPlatform, getToken } from '../config/util'; import { getPlatform, getToken, safeJSONParse } from '../config/util';
import Container from 'typedi'; import Container from 'typedi';
import OpenService from '../services/open'; import OpenService from '../services/open';
import rewrite from 'express-urlrewrite'; import rewrite from 'express-urlrewrite';
@ -38,7 +38,7 @@ export default ({ app }: { app: Application }) => {
app.use( app.use(
jwt({ jwt({
secret: config.secret as string, secret: config.secret,
algorithms: ['HS384'], algorithms: ['HS384'],
}).unless({ }).unless({
path: [...config.apiWhiteList, /^\/open\//], path: [...config.apiWhiteList, /^\/open\//],
@ -85,7 +85,7 @@ export default ({ app }: { app: Application }) => {
const data = fs.readFileSync(config.authConfigFile, 'utf8'); const data = fs.readFileSync(config.authConfigFile, 'utf8');
if (data && headerToken) { if (data && headerToken) {
const { token = '', tokens = {} } = JSON.parse(data); const { token = '', tokens = {} } = safeJSONParse(data);
if (headerToken === token || tokens[req.platform] === headerToken) { if (headerToken === token || tokens[req.platform] === headerToken) {
return next(); return next();
} }

View File

@ -5,7 +5,7 @@ import { Container } from 'typedi';
import SockService from '../services/sock'; import SockService from '../services/sock';
import config from '../config/index'; import config from '../config/index';
import fs from 'fs'; import fs from 'fs';
import { getPlatform } from '../config/util'; import { getPlatform, safeJSONParse } from '../config/util';
export default async ({ server }: { server: Server }) => { export default async ({ server }: { server: Server }) => {
const echo = sockJs.createServer({ prefix: '/api/ws', log: () => {} }); 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 platform = getPlatform(conn.headers['user-agent'] || '') || 'desktop';
const headerToken = conn.url.replace(`${conn.pathname}?token=`, ''); const headerToken = conn.url.replace(`${conn.pathname}?token=`, '');
if (data) { if (data) {
const { token = '', tokens = {} } = JSON.parse(data); const { token = '', tokens = {} } = safeJSONParse(data);
if (headerToken === token || tokens[platform] === headerToken) { if (headerToken === token || tokens[platform] === headerToken) {
conn.write(JSON.stringify({ type: 'ping', message: 'hanhh' })); conn.write(JSON.stringify({ type: 'ping', message: 'hanhh' }));
sockService.addClient(conn); sockService.addClient(conn);

View File

@ -5,7 +5,7 @@ import { Crontab, CrontabModel, CrontabStatus } from '../data/cron';
import { exec, execSync } from 'child_process'; import { exec, execSync } from 'child_process';
import fs from 'fs'; import fs from 'fs';
import cron_parser from 'cron-parser'; 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 { promises, existsSync } from 'fs';
import { Op, where, col as colFn, FindOptions, fn } from 'sequelize'; import { Op, where, col as colFn, FindOptions, fn } from 'sequelize';
import path from 'path'; import path from 'path';
@ -309,9 +309,9 @@ export default class CronService {
const searchText = params?.searchValue; const searchText = params?.searchValue;
const page = Number(params?.page || '0'); const page = Number(params?.page || '0');
const size = Number(params?.size || '0'); const size = Number(params?.size || '0');
const viewQuery = JSON.parse(params?.queryString || '{}'); const viewQuery = safeJSONParse(params?.queryString);
const filterQuery = JSON.parse(params?.filters || '{}'); const filterQuery = safeJSONParse(params?.filters);
const sorterQuery = JSON.parse(params?.sorter || '{}'); const sorterQuery = safeJSONParse(params?.sorter);
let query: any = {}; let query: any = {};
let order = [ let order = [

View File

@ -5,6 +5,7 @@ import {
fileExist, fileExist,
getNetIp, getNetIp,
getPlatform, getPlatform,
safeJSONParse,
} from '../config/util'; } from '../config/util';
import config from '../config'; import config from '../config';
import * as fs from 'fs'; import * as fs from 'fs';
@ -327,7 +328,7 @@ export default class UserService {
private getAuthInfo() { private getAuthInfo() {
const content = fs.readFileSync(config.authConfigFile, 'utf8'); const content = fs.readFileSync(config.authConfigFile, 'utf8');
return JSON.parse(content || '{}'); return safeJSONParse(content);
} }
private updateAuthInfo(authInfo: any, info: any) { private updateAuthInfo(authInfo: any, info: any) {

View File

@ -42,7 +42,7 @@ import useTableScrollHeight from '@/hooks/useTableScrollHeight';
import Copy from '../../components/copy'; import Copy from '../../components/copy';
import { useVT } from 'virtualizedtableforantd4'; import { useVT } from 'virtualizedtableforantd4';
const { Text } = Typography; const { Paragraph } = Typography;
const { Search } = Input; const { Search } = Input;
enum Status { enum Status {
@ -246,9 +246,14 @@ const Env = () => {
? intl.get('启用') ? intl.get('启用')
: intl.get('禁用')} : intl.get('禁用')}
Env{' '} Env{' '}
<Text style={{ wordBreak: 'break-all' }} type="warning"> <Paragraph
style={{ wordBreak: 'break-all', display: 'inline' }}
ellipsis={{ rows: 6, expandable: true }}
type="warning"
copyable
>
{record.value} {record.value}
</Text>{' '} </Paragraph>{' '}
{intl.get('吗')} {intl.get('吗')}
</> </>
), ),
@ -302,9 +307,14 @@ const Env = () => {
content: ( content: (
<> <>
{intl.get('确认删除变量')}{' '} {intl.get('确认删除变量')}{' '}
<Text style={{ wordBreak: 'break-all' }} type="warning"> <Paragraph
style={{ wordBreak: 'break-all', display: 'inline' }}
ellipsis={{ rows: 6, expandable: true }}
type="warning"
copyable
>
{record.name}: {record.value} {record.name}: {record.value}
</Text>{' '} </Paragraph>{' '}
{intl.get('吗')} {intl.get('吗')}
</> </>
), ),