jjb-cmd 2.5.7 → 2.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/ai-pull.js +1 -711
- package/src/auth.js +1 -71
- package/src/code-optimization.js +1 -46
- package/src/config.js +1 -122
- package/src/crypto-utils.js +1 -183
- package/src/password-input.js +1 -79
- package/src/publish.js +1 -307
- package/src/push.js +1 -417
- package/src/rm-rf.js +1 -49
- package/src/utils.js +1 -228
- package/SECURITY.md +0 -71
- package/build.js +0 -20
- package/obf.config.json +0 -3
package/src/utils.js
CHANGED
|
@@ -1,228 +1 @@
|
|
|
1
|
-
const
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const child_process = require('child_process');
|
|
4
|
-
const chalk = require('chalk');
|
|
5
|
-
|
|
6
|
-
// 常量定义
|
|
7
|
-
const CONSTANTS = {
|
|
8
|
-
MAX_BUFFER_SIZE: 1000000000, // 1GB
|
|
9
|
-
SYNC_DELAY: 1000, // 1秒
|
|
10
|
-
DEFAULT_BRANCH: 'master',
|
|
11
|
-
CONFIG_FILE_NAME: 'jjb.config.js',
|
|
12
|
-
BUILD_OUTPUT_DIR: 'dist',
|
|
13
|
-
TEMPLATES_PATH: 'start/src/main/resources/templates'
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// 日志函数
|
|
18
|
-
function logInfo(message, path = '') {
|
|
19
|
-
const prefix = chalk.blue('ℹ');
|
|
20
|
-
const output = path ? `${prefix} ${message} ${path}` : `${prefix} ${message}`;
|
|
21
|
-
console.log(output);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function logSuccess(message) {
|
|
25
|
-
console.log(chalk.green(`✓ ${message}`));
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function logWarning(message) {
|
|
29
|
-
console.log(chalk.yellow(`⚠ ${message}`));
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function logError(message) {
|
|
33
|
-
console.log(chalk.red(`✗ ${message}`));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// 统一的命令执行函数
|
|
37
|
-
function executeCommand(command, cwd, options = {}) {
|
|
38
|
-
logInfo(`执行命令: ${command}`, cwd ? `[工作目录: ${cwd}]` : '');
|
|
39
|
-
return child_process.execSync(command, { cwd, ...options });
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// 文件处理函数
|
|
43
|
-
function deleteFolderRecursive(folderPath) {
|
|
44
|
-
if (fs.existsSync(folderPath)) {
|
|
45
|
-
fs.readdirSync(folderPath).forEach((file) => {
|
|
46
|
-
const curPath = path.join(folderPath, file);
|
|
47
|
-
if (fs.lstatSync(curPath).isDirectory()) {
|
|
48
|
-
// 递归删除子文件夹
|
|
49
|
-
deleteFolderRecursive(curPath);
|
|
50
|
-
} else {
|
|
51
|
-
// 删除文件
|
|
52
|
-
fs.unlinkSync(curPath);
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
// 删除空文件夹
|
|
56
|
-
fs.rmdirSync(folderPath);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// 检查文件是否存在
|
|
61
|
-
function fileExists(filePath) {
|
|
62
|
-
return fs.existsSync(filePath);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// 读取文件内容
|
|
66
|
-
function readFile(filePath, encoding = 'utf8') {
|
|
67
|
-
return fs.readFileSync(filePath, encoding);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// 写入文件内容
|
|
71
|
-
function writeFile(filePath, content, encoding = 'utf8') {
|
|
72
|
-
fs.writeFileSync(filePath, content, encoding);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// 创建目录
|
|
76
|
-
function createDir(dirPath) {
|
|
77
|
-
if (!fs.existsSync(dirPath)) {
|
|
78
|
-
fs.mkdirSync(dirPath, { recursive: true });
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// 检查是否为 Vite 项目
|
|
83
|
-
function isViteProject(rootPath) {
|
|
84
|
-
return fileExists(path.join(rootPath, 'vite.config.js')) ||
|
|
85
|
-
fileExists(path.join(rootPath, 'vite.config.ts')) ||
|
|
86
|
-
fileExists(path.join(rootPath, 'vite.config.mjs'));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// 验证配置对象
|
|
90
|
-
function validateConfig(config, requiredFields) {
|
|
91
|
-
const missingFields = requiredFields.filter(field => !config[field]);
|
|
92
|
-
return {
|
|
93
|
-
isValid: missingFields.length === 0,
|
|
94
|
-
missingFields
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// 验证环境配置
|
|
99
|
-
function validateEnvironment(config, environment) {
|
|
100
|
-
return config.environment && config.environment[environment];
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* @description 清空当前目录
|
|
105
|
-
* @param filePath
|
|
106
|
-
* @param callback
|
|
107
|
-
* @constructor
|
|
108
|
-
*/
|
|
109
|
-
function DeleteDirAllFile(filePath, callback) {
|
|
110
|
-
let files = [];
|
|
111
|
-
if (fs.existsSync(filePath)) {
|
|
112
|
-
files = fs.readdirSync(filePath);
|
|
113
|
-
files.forEach(function (file, index) {
|
|
114
|
-
let curPath = path.join(filePath, file);
|
|
115
|
-
if (fs.statSync(curPath).isDirectory()) {
|
|
116
|
-
DeleteDirAllFile(curPath);
|
|
117
|
-
} else {
|
|
118
|
-
fs.unlinkSync(curPath);
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
fs.rmdirSync(filePath);
|
|
122
|
-
callback && callback();
|
|
123
|
-
} else {
|
|
124
|
-
callback && callback();
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* @description 复制单个文件
|
|
130
|
-
* @param srcFile
|
|
131
|
-
* @param tarFile
|
|
132
|
-
* @param cb
|
|
133
|
-
*/
|
|
134
|
-
function CopyFile(srcFile, tarFile, cb) {
|
|
135
|
-
// 确保目标目录存在
|
|
136
|
-
const tarDir = path.dirname(tarFile);
|
|
137
|
-
if (!fs.existsSync(tarDir)) {
|
|
138
|
-
fs.mkdirSync(tarDir, { recursive: true });
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const rs = fs.createReadStream(srcFile);
|
|
142
|
-
const ws = fs.createWriteStream(tarFile);
|
|
143
|
-
|
|
144
|
-
rs.pipe(ws);
|
|
145
|
-
|
|
146
|
-
ws.on('close', function() {
|
|
147
|
-
cb && cb();
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
ws.on('error', function(err) {
|
|
151
|
-
logError(`文件复制失败: ${err.message}`);
|
|
152
|
-
cb && cb();
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* @description 复制文件夹及子目录文件
|
|
158
|
-
* @param srcDir
|
|
159
|
-
* @param tarDir
|
|
160
|
-
* @param cb
|
|
161
|
-
*/
|
|
162
|
-
function CopyFolder(srcDir, tarDir, cb) {
|
|
163
|
-
// 确保目标目录存在
|
|
164
|
-
if (!fs.existsSync(tarDir)) {
|
|
165
|
-
fs.mkdirSync(tarDir, { recursive: true });
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
fs.readdir(srcDir, function (err, files) {
|
|
169
|
-
|
|
170
|
-
let count = 0;
|
|
171
|
-
const checkEnd = function () {
|
|
172
|
-
++count === files.length && cb && cb();
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
if (err) {
|
|
176
|
-
checkEnd();
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
files.forEach(function (file) {
|
|
181
|
-
const srcPath = path.join(srcDir, file);
|
|
182
|
-
const tarPath = path.join(tarDir, file);
|
|
183
|
-
|
|
184
|
-
fs.stat(srcPath, function (err, stats) {
|
|
185
|
-
if (stats.isDirectory()) {
|
|
186
|
-
fs.mkdir(tarPath, { recursive: true }, function (err) {
|
|
187
|
-
if (err) {
|
|
188
|
-
logError(`创建目录失败: ${err.message}`);
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
CopyFolder(srcPath, tarPath, checkEnd);
|
|
193
|
-
});
|
|
194
|
-
} else {
|
|
195
|
-
// 复制文件
|
|
196
|
-
const rs = fs.createReadStream(srcPath);
|
|
197
|
-
const ws = fs.createWriteStream(tarPath);
|
|
198
|
-
rs.pipe(ws);
|
|
199
|
-
ws.on('close', checkEnd);
|
|
200
|
-
ws.on('error', checkEnd);
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
});
|
|
204
|
-
//为空时直接回调
|
|
205
|
-
files.length === 0 && cb && cb();
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
module.exports = {
|
|
211
|
-
CONSTANTS,
|
|
212
|
-
logInfo,
|
|
213
|
-
logSuccess,
|
|
214
|
-
logWarning,
|
|
215
|
-
logError,
|
|
216
|
-
executeCommand,
|
|
217
|
-
deleteFolderRecursive,
|
|
218
|
-
fileExists,
|
|
219
|
-
readFile,
|
|
220
|
-
writeFile,
|
|
221
|
-
createDir,
|
|
222
|
-
isViteProject,
|
|
223
|
-
validateConfig,
|
|
224
|
-
validateEnvironment,
|
|
225
|
-
DeleteDirAllFile,
|
|
226
|
-
CopyFile,
|
|
227
|
-
CopyFolder
|
|
228
|
-
};
|
|
1
|
+
const a9_0x12bb3a=a9_0x2c72;(function(_0xa20a9d,_0x1f6d52){const _0x5e63bf=a9_0x2c72,_0x571f50=_0xa20a9d();while(!![]){try{const _0x112d5d=-parseInt(_0x5e63bf(0xc8))/0x1*(parseInt(_0x5e63bf(0xc4))/0x2)+parseInt(_0x5e63bf(0xde))/0x3+-parseInt(_0x5e63bf(0xe2))/0x4+-parseInt(_0x5e63bf(0xda))/0x5+-parseInt(_0x5e63bf(0xbe))/0x6*(-parseInt(_0x5e63bf(0xd5))/0x7)+parseInt(_0x5e63bf(0xd7))/0x8+-parseInt(_0x5e63bf(0xb7))/0x9*(parseInt(_0x5e63bf(0xc1))/0xa);if(_0x112d5d===_0x1f6d52)break;else _0x571f50['push'](_0x571f50['shift']());}catch(_0x235922){_0x571f50['push'](_0x571f50['shift']());}}}(a9_0x4f55,0x5338c));const fs=require('fs'),path=require(a9_0x12bb3a(0xba)),child_process=require('child_process'),chalk=require(a9_0x12bb3a(0xc6)),CONSTANTS={'MAX_BUFFER_SIZE':0x3b9aca00,'SYNC_DELAY':0x3e8,'DEFAULT_BRANCH':'master','CONFIG_FILE_NAME':a9_0x12bb3a(0xcb),'BUILD_OUTPUT_DIR':a9_0x12bb3a(0xcd),'TEMPLATES_PATH':a9_0x12bb3a(0xc0)};function logInfo(_0x3bc67b,_0x469b17=''){const _0x290ed1=chalk['blue']('ℹ'),_0x1508fb=_0x469b17?_0x290ed1+'\x20'+_0x3bc67b+'\x20'+_0x469b17:_0x290ed1+'\x20'+_0x3bc67b;console['log'](_0x1508fb);}function logSuccess(_0x386246){const _0xe97995=a9_0x12bb3a;console[_0xe97995(0xbf)](chalk['green']('✓\x20'+_0x386246));}function a9_0x4f55(){const _0x1c3214=['createReadStream','statSync','unlinkSync','1022058bBIAqE','writeFileSync','message','join','1364112fWAwck','mkdir','[工作目录:\x20','1063323KfGiRV','red','exports','path','pipe','existsSync','isDirectory','414mpxZQs','log','start/src/main/resources/templates','30kWBGeV','utf8','vite.config.js','22916HcoZMc','environment','chalk','close','2BOGKgn','createWriteStream','dirname','jjb.config.js','forEach','dist','vite.config.mjs','lstatSync','stat','length','rmdirSync','readdirSync','文件复制失败:\x20','49357YkfOcK','mkdirSync','4295488FrLDJf','filter','yellow','1524400RXLmhf'];a9_0x4f55=function(){return _0x1c3214;};return a9_0x4f55();}function logWarning(_0xc843cb){const _0x1c803f=a9_0x12bb3a;console['log'](chalk[_0x1c803f(0xd9)]('⚠\x20'+_0xc843cb));}function logError(_0x14efee){const _0x52037f=a9_0x12bb3a;console[_0x52037f(0xbf)](chalk[_0x52037f(0xb8)]('✗\x20'+_0x14efee));}function executeCommand(_0x4f889d,_0x3a7145,_0x4a0ea1={}){const _0x465498=a9_0x12bb3a;return logInfo('执行命令:\x20'+_0x4f889d,_0x3a7145?_0x465498(0xb6)+_0x3a7145+']':''),child_process['execSync'](_0x4f889d,{'cwd':_0x3a7145,..._0x4a0ea1});}function deleteFolderRecursive(_0x3473aa){const _0x3a8455=a9_0x12bb3a;fs['existsSync'](_0x3473aa)&&(fs[_0x3a8455(0xd3)](_0x3473aa)[_0x3a8455(0xcc)](_0x19182c=>{const _0x3b1fa0=_0x3a8455,_0xc2fae5=path['join'](_0x3473aa,_0x19182c);fs[_0x3b1fa0(0xcf)](_0xc2fae5)['isDirectory']()?deleteFolderRecursive(_0xc2fae5):fs[_0x3b1fa0(0xdd)](_0xc2fae5);}),fs['rmdirSync'](_0x3473aa));}function a9_0x2c72(_0x182041,_0x1aa5e8){_0x182041=_0x182041-0xb6;const _0x4f554c=a9_0x4f55();let _0x2c72b9=_0x4f554c[_0x182041];return _0x2c72b9;}function fileExists(_0x3ab628){const _0x25a1c8=a9_0x12bb3a;return fs[_0x25a1c8(0xbc)](_0x3ab628);}function readFile(_0x80a46f,_0xba19f9=a9_0x12bb3a(0xc2)){return fs['readFileSync'](_0x80a46f,_0xba19f9);}function writeFile(_0x5d8390,_0x3e7248,_0x1ac04a=a9_0x12bb3a(0xc2)){const _0x510b76=a9_0x12bb3a;fs[_0x510b76(0xdf)](_0x5d8390,_0x3e7248,_0x1ac04a);}function createDir(_0x25abf9){const _0xc9b696=a9_0x12bb3a;!fs[_0xc9b696(0xbc)](_0x25abf9)&&fs[_0xc9b696(0xd6)](_0x25abf9,{'recursive':!![]});}function isViteProject(_0x51934e){const _0x3f3644=a9_0x12bb3a;return fileExists(path[_0x3f3644(0xe1)](_0x51934e,_0x3f3644(0xc3)))||fileExists(path[_0x3f3644(0xe1)](_0x51934e,'vite.config.ts'))||fileExists(path[_0x3f3644(0xe1)](_0x51934e,_0x3f3644(0xce)));}function validateConfig(_0x5119e5,_0x2a062e){const _0x4a8e9b=a9_0x12bb3a,_0x134efa=_0x2a062e[_0x4a8e9b(0xd8)](_0x426edd=>!_0x5119e5[_0x426edd]);return{'isValid':_0x134efa[_0x4a8e9b(0xd1)]===0x0,'missingFields':_0x134efa};}function validateEnvironment(_0x1a230d,_0x4ea07a){const _0x1998b6=a9_0x12bb3a;return _0x1a230d[_0x1998b6(0xc5)]&&_0x1a230d[_0x1998b6(0xc5)][_0x4ea07a];}function DeleteDirAllFile(_0x2656fe,_0x4a970a){const _0x220d54=a9_0x12bb3a;let _0x143fbe=[];fs[_0x220d54(0xbc)](_0x2656fe)?(_0x143fbe=fs[_0x220d54(0xd3)](_0x2656fe),_0x143fbe[_0x220d54(0xcc)](function(_0x544563,_0x33704e){const _0xae97e8=_0x220d54;let _0x3f1723=path[_0xae97e8(0xe1)](_0x2656fe,_0x544563);fs[_0xae97e8(0xdc)](_0x3f1723)['isDirectory']()?DeleteDirAllFile(_0x3f1723):fs[_0xae97e8(0xdd)](_0x3f1723);}),fs[_0x220d54(0xd2)](_0x2656fe),_0x4a970a&&_0x4a970a()):_0x4a970a&&_0x4a970a();}function CopyFile(_0x245bea,_0x4dfe2a,_0x3fc609){const _0x2d500f=a9_0x12bb3a,_0x27d332=path[_0x2d500f(0xca)](_0x4dfe2a);!fs[_0x2d500f(0xbc)](_0x27d332)&&fs['mkdirSync'](_0x27d332,{'recursive':!![]});const _0x4f09c=fs[_0x2d500f(0xdb)](_0x245bea),_0x4a8002=fs[_0x2d500f(0xc9)](_0x4dfe2a);_0x4f09c[_0x2d500f(0xbb)](_0x4a8002),_0x4a8002['on'](_0x2d500f(0xc7),function(){_0x3fc609&&_0x3fc609();}),_0x4a8002['on']('error',function(_0x3f42c0){const _0x19c66b=_0x2d500f;logError(_0x19c66b(0xd4)+_0x3f42c0['message']),_0x3fc609&&_0x3fc609();});}function CopyFolder(_0x4df34a,_0x4959db,_0x28db90){const _0x309437=a9_0x12bb3a;!fs[_0x309437(0xbc)](_0x4959db)&&fs[_0x309437(0xd6)](_0x4959db,{'recursive':!![]}),fs['readdir'](_0x4df34a,function(_0x34e042,_0x335c97){const _0xa5d176=_0x309437;let _0x33c6a3=0x0;const _0x4a7921=function(){++_0x33c6a3===_0x335c97['length']&&_0x28db90&&_0x28db90();};if(_0x34e042){_0x4a7921();return;}_0x335c97[_0xa5d176(0xcc)](function(_0x550753){const _0x207ed2=_0xa5d176,_0x11b56e=path['join'](_0x4df34a,_0x550753),_0x43756c=path[_0x207ed2(0xe1)](_0x4959db,_0x550753);fs[_0x207ed2(0xd0)](_0x11b56e,function(_0x5374b8,_0x5d13d7){const _0xab89f2=_0x207ed2;if(_0x5d13d7[_0xab89f2(0xbd)]())fs[_0xab89f2(0xe3)](_0x43756c,{'recursive':!![]},function(_0x418a1c){const _0x1081a1=_0xab89f2;if(_0x418a1c){logError('创建目录失败:\x20'+_0x418a1c[_0x1081a1(0xe0)]);return;}CopyFolder(_0x11b56e,_0x43756c,_0x4a7921);});else{const _0xc5776d=fs[_0xab89f2(0xdb)](_0x11b56e),_0x19b3dd=fs[_0xab89f2(0xc9)](_0x43756c);_0xc5776d['pipe'](_0x19b3dd),_0x19b3dd['on'](_0xab89f2(0xc7),_0x4a7921),_0x19b3dd['on']('error',_0x4a7921);}});}),_0x335c97['length']===0x0&&_0x28db90&&_0x28db90();});}module[a9_0x12bb3a(0xb9)]={'CONSTANTS':CONSTANTS,'logInfo':logInfo,'logSuccess':logSuccess,'logWarning':logWarning,'logError':logError,'executeCommand':executeCommand,'deleteFolderRecursive':deleteFolderRecursive,'fileExists':fileExists,'readFile':readFile,'writeFile':writeFile,'createDir':createDir,'isViteProject':isViteProject,'validateConfig':validateConfig,'validateEnvironment':validateEnvironment,'DeleteDirAllFile':DeleteDirAllFile,'CopyFile':CopyFile,'CopyFolder':CopyFolder};
|
package/SECURITY.md
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# 安全优化说明
|
|
2
|
-
|
|
3
|
-
## 认证安全优化
|
|
4
|
-
|
|
5
|
-
本项目已对认证系统进行了安全优化,主要改进包括:
|
|
6
|
-
|
|
7
|
-
### 🔐 加密存储
|
|
8
|
-
- **之前**: 用户名和密码以明文形式存储在 `.auth` 文件中
|
|
9
|
-
- **现在**: 使用 AES-256-CBC 加密算法对认证信息进行加密存储
|
|
10
|
-
|
|
11
|
-
### 🔒 密码输入安全
|
|
12
|
-
- **之前**: 命令行输入密码时明文显示,存在安全风险
|
|
13
|
-
- **现在**: 支持多种安全的密码输入方式
|
|
14
|
-
- 交互式隐藏输入:密码输入时显示 `*` 字符
|
|
15
|
-
- 支持只提供用户名,密码安全输入
|
|
16
|
-
- 支持完全交互式登录
|
|
17
|
-
|
|
18
|
-
### 🛡️ 安全特性
|
|
19
|
-
1. **设备绑定**: 基于系统信息生成唯一设备密钥,确保认证信息只能在当前设备上解密
|
|
20
|
-
2. **文件权限**: 认证文件权限设置为 `0o600`,仅文件所有者可读写
|
|
21
|
-
3. **盐值随机化**: 每次加密都使用随机盐值,防止彩虹表攻击
|
|
22
|
-
4. **密钥派生**: 使用 PBKDF2 算法派生加密密钥,增强安全性
|
|
23
|
-
|
|
24
|
-
### 🔧 技术实现
|
|
25
|
-
- 使用 Node.js 内置 `crypto` 模块
|
|
26
|
-
- AES-256-CBC 加密算法
|
|
27
|
-
- PBKDF2 密钥派生函数(100,000 次迭代)
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
### 📁 文件变更
|
|
31
|
-
- `src/crypto-utils.js` - 新增加密工具模块
|
|
32
|
-
- `src/password-input.js` - 新增安全密码输入模块
|
|
33
|
-
- `src/auth.js` - 更新为使用加密存储和安全密码输入
|
|
34
|
-
- `src/push.js` - 更新为使用解密读取
|
|
35
|
-
- `src/publish.js` - 更新为使用解密读取
|
|
36
|
-
- `bin/command.js` - 更新为支持异步认证
|
|
37
|
-
|
|
38
|
-
### ⚠️ 注意事项
|
|
39
|
-
1. 认证信息与设备绑定,更换设备需要重新登录
|
|
40
|
-
2. 如果系统信息发生变化,可能需要重新登录
|
|
41
|
-
3. 建议定期更新密码以增强安全性
|
|
42
|
-
|
|
43
|
-
### 🔄 向后兼容
|
|
44
|
-
- 新版本会自动处理旧的明文认证文件
|
|
45
|
-
- 首次使用时会自动迁移到加密存储
|
|
46
|
-
|
|
47
|
-
### 📖 使用说明
|
|
48
|
-
|
|
49
|
-
#### 安全登录方式
|
|
50
|
-
1. **完全交互式登录**(推荐):
|
|
51
|
-
```bash
|
|
52
|
-
jjb-cmd auth
|
|
53
|
-
# 系统会提示输入用户名和密码,密码输入时显示 * 字符
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
2. **只提供用户名**:
|
|
57
|
-
```bash
|
|
58
|
-
jjb-cmd auth myusername
|
|
59
|
-
# 系统会提示输入密码,密码输入时显示 * 字符
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
3. **传统命令行方式**(不推荐,密码会明文显示):
|
|
63
|
-
```bash
|
|
64
|
-
jjb-cmd auth myusername mypassword
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
#### 安全特性
|
|
68
|
-
- 密码输入时自动隐藏显示
|
|
69
|
-
- 支持 Ctrl+C 取消输入
|
|
70
|
-
- 支持 Backspace 删除输入
|
|
71
|
-
- 认证信息加密存储,与设备绑定
|
package/build.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
const child_process = require('child_process');
|
|
2
|
-
const utils = require('./src/utils');
|
|
3
|
-
|
|
4
|
-
// 执行代码混淆
|
|
5
|
-
child_process.execSync(`npx javascript-obfuscator src --output publish/src --config obf.config.json`);
|
|
6
|
-
console.log('obf Done!');
|
|
7
|
-
|
|
8
|
-
// 复制bin目录
|
|
9
|
-
utils.CopyFolder('./bin', './publish/bin', () => {
|
|
10
|
-
console.log('bin Folder Done!');
|
|
11
|
-
|
|
12
|
-
// 复制其他文件
|
|
13
|
-
utils.CopyFile('./package.json', './publish/package.json', () => {
|
|
14
|
-
utils.CopyFile('./README.md', './publish/README.md', () => {
|
|
15
|
-
utils.CopyFile('./LICENSE', './publish/LICENSE', () => {
|
|
16
|
-
console.log('ALL Done !');
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
});
|
|
20
|
-
});
|
package/obf.config.json
DELETED