jjb-cmd 2.5.8 → 2.6.0

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/src/utils.js CHANGED
@@ -1,228 +1 @@
1
- const fs = require('fs');
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_0x58f855=a9_0x561c;function a9_0x561c(_0x59dfad,_0x158614){_0x59dfad=_0x59dfad-0x1e8;const _0x4f33ac=a9_0x4f33();let _0x561cee=_0x4f33ac[_0x59dfad];return _0x561cee;}function a9_0x4f33(){const _0x5be2b6=['vite.config.mjs','filter','length','green','readFileSync','chalk','log','environment','rmdirSync','1058689kuWJAR','3484255fMkOjI','existsSync','child_process','pipe','9xRdRVA','文件复制失败:\x20','createWriteStream','12ynMoOf','yellow','jjb.config.js','start/src/main/resources/templates','13wXGpAv','isDirectory','vite.config.js','[工作目录:\x20','path','创建目录失败:\x20','forEach','2AbFTeS','execSync','lstatSync','mkdirSync','error','71997PUNuCc','dirname','unlinkSync','mkdir','10475280pfSlfb','309804jvPrMv','join','createReadStream','stat','statSync','6611164gZPqpv','执行命令:\x20','10aeuCNp','message','2525303jDBNeA','244MyxjsK','utf8','close','vite.config.ts'];a9_0x4f33=function(){return _0x5be2b6;};return a9_0x4f33();}(function(_0x5dc021,_0x18e774){const _0x52b606=a9_0x561c,_0x3a0db4=_0x5dc021();while(!![]){try{const _0x47a1d6=-parseInt(_0x52b606(0x217))/0x1*(parseInt(_0x52b606(0x1f6))/0x2)+parseInt(_0x52b606(0x1fb))/0x3*(-parseInt(_0x52b606(0x20a))/0x4)+parseInt(_0x52b606(0x218))/0x5*(parseInt(_0x52b606(0x1eb))/0x6)+parseInt(_0x52b606(0x205))/0x7+parseInt(_0x52b606(0x1ff))/0x8*(parseInt(_0x52b606(0x1e8))/0x9)+parseInt(_0x52b606(0x207))/0xa*(-parseInt(_0x52b606(0x209))/0xb)+parseInt(_0x52b606(0x200))/0xc*(parseInt(_0x52b606(0x1ef))/0xd);if(_0x47a1d6===_0x18e774)break;else _0x3a0db4['push'](_0x3a0db4['shift']());}catch(_0x298ad8){_0x3a0db4['push'](_0x3a0db4['shift']());}}}(a9_0x4f33,0xe0e5c));const fs=require('fs'),path=require(a9_0x58f855(0x1f3)),child_process=require(a9_0x58f855(0x21a)),chalk=require(a9_0x58f855(0x213)),CONSTANTS={'MAX_BUFFER_SIZE':0x3b9aca00,'SYNC_DELAY':0x3e8,'DEFAULT_BRANCH':'master','CONFIG_FILE_NAME':a9_0x58f855(0x1ed),'BUILD_OUTPUT_DIR':'dist','TEMPLATES_PATH':a9_0x58f855(0x1ee)};function logInfo(_0x29f92b,_0x1e3941=''){const _0x4bc83f=a9_0x58f855,_0x296c7d=chalk['blue']('ℹ'),_0x3d99ce=_0x1e3941?_0x296c7d+'\x20'+_0x29f92b+'\x20'+_0x1e3941:_0x296c7d+'\x20'+_0x29f92b;console[_0x4bc83f(0x214)](_0x3d99ce);}function logSuccess(_0x5242a2){const _0x95ebeb=a9_0x58f855;console[_0x95ebeb(0x214)](chalk[_0x95ebeb(0x211)]('✓\x20'+_0x5242a2));}function logWarning(_0x584d05){const _0x50cb95=a9_0x58f855;console[_0x50cb95(0x214)](chalk[_0x50cb95(0x1ec)]('⚠\x20'+_0x584d05));}function logError(_0x37ce65){console['log'](chalk['red']('✗\x20'+_0x37ce65));}function executeCommand(_0x951521,_0x328aa9,_0x3df097={}){const _0x30f917=a9_0x58f855;return logInfo(_0x30f917(0x206)+_0x951521,_0x328aa9?_0x30f917(0x1f2)+_0x328aa9+']':''),child_process[_0x30f917(0x1f7)](_0x951521,{'cwd':_0x328aa9,..._0x3df097});}function deleteFolderRecursive(_0x3bd27b){const _0x1273dc=a9_0x58f855;fs['existsSync'](_0x3bd27b)&&(fs['readdirSync'](_0x3bd27b)[_0x1273dc(0x1f5)](_0x2405bd=>{const _0x44796a=_0x1273dc,_0x1c508f=path[_0x44796a(0x201)](_0x3bd27b,_0x2405bd);fs[_0x44796a(0x1f8)](_0x1c508f)[_0x44796a(0x1f0)]()?deleteFolderRecursive(_0x1c508f):fs[_0x44796a(0x1fd)](_0x1c508f);}),fs[_0x1273dc(0x216)](_0x3bd27b));}function fileExists(_0x47e0d1){const _0x5d9306=a9_0x58f855;return fs[_0x5d9306(0x219)](_0x47e0d1);}function readFile(_0x2aae42,_0x1fd219='utf8'){const _0x5b0440=a9_0x58f855;return fs[_0x5b0440(0x212)](_0x2aae42,_0x1fd219);}function writeFile(_0x6d9beb,_0x3ceaa8,_0x94b94=a9_0x58f855(0x20b)){fs['writeFileSync'](_0x6d9beb,_0x3ceaa8,_0x94b94);}function createDir(_0x4bb6cb){const _0xbdbf2b=a9_0x58f855;!fs[_0xbdbf2b(0x219)](_0x4bb6cb)&&fs[_0xbdbf2b(0x1f9)](_0x4bb6cb,{'recursive':!![]});}function isViteProject(_0xf3fc71){const _0x40688d=a9_0x58f855;return fileExists(path[_0x40688d(0x201)](_0xf3fc71,_0x40688d(0x1f1)))||fileExists(path[_0x40688d(0x201)](_0xf3fc71,_0x40688d(0x20d)))||fileExists(path['join'](_0xf3fc71,_0x40688d(0x20e)));}function validateConfig(_0x49e0bc,_0x7ddd67){const _0x2f2683=a9_0x58f855,_0x2b488e=_0x7ddd67[_0x2f2683(0x20f)](_0x334db1=>!_0x49e0bc[_0x334db1]);return{'isValid':_0x2b488e[_0x2f2683(0x210)]===0x0,'missingFields':_0x2b488e};}function validateEnvironment(_0x936151,_0x3c32e0){const _0x595cda=a9_0x58f855;return _0x936151[_0x595cda(0x215)]&&_0x936151['environment'][_0x3c32e0];}function DeleteDirAllFile(_0x3e0ba7,_0x7dd16b){const _0x3050ac=a9_0x58f855;let _0x233f0e=[];fs[_0x3050ac(0x219)](_0x3e0ba7)?(_0x233f0e=fs['readdirSync'](_0x3e0ba7),_0x233f0e[_0x3050ac(0x1f5)](function(_0x581c32,_0x15f2b2){const _0x11b2f3=_0x3050ac;let _0x45f363=path['join'](_0x3e0ba7,_0x581c32);fs[_0x11b2f3(0x204)](_0x45f363)[_0x11b2f3(0x1f0)]()?DeleteDirAllFile(_0x45f363):fs[_0x11b2f3(0x1fd)](_0x45f363);}),fs[_0x3050ac(0x216)](_0x3e0ba7),_0x7dd16b&&_0x7dd16b()):_0x7dd16b&&_0x7dd16b();}function CopyFile(_0x475d3c,_0x5bfe8c,_0x281c4a){const _0x1eaa3a=a9_0x58f855,_0x475401=path[_0x1eaa3a(0x1fc)](_0x5bfe8c);!fs[_0x1eaa3a(0x219)](_0x475401)&&fs['mkdirSync'](_0x475401,{'recursive':!![]});const _0x5f1d26=fs['createReadStream'](_0x475d3c),_0x332db4=fs['createWriteStream'](_0x5bfe8c);_0x5f1d26['pipe'](_0x332db4),_0x332db4['on'](_0x1eaa3a(0x20c),function(){_0x281c4a&&_0x281c4a();}),_0x332db4['on'](_0x1eaa3a(0x1fa),function(_0x3a1ca0){const _0x5d25f0=_0x1eaa3a;logError(_0x5d25f0(0x1e9)+_0x3a1ca0[_0x5d25f0(0x208)]),_0x281c4a&&_0x281c4a();});}function CopyFolder(_0x5c68cf,_0x217789,_0x4b3d11){const _0x5d1bca=a9_0x58f855;!fs[_0x5d1bca(0x219)](_0x217789)&&fs[_0x5d1bca(0x1f9)](_0x217789,{'recursive':!![]}),fs['readdir'](_0x5c68cf,function(_0x323f51,_0x127006){const _0x277409=_0x5d1bca;let _0x28996b=0x0;const _0x2ad984=function(){const _0x59a4ec=a9_0x561c;++_0x28996b===_0x127006[_0x59a4ec(0x210)]&&_0x4b3d11&&_0x4b3d11();};if(_0x323f51){_0x2ad984();return;}_0x127006[_0x277409(0x1f5)](function(_0x2e2b4c){const _0x49188e=_0x277409,_0x4b0f4d=path['join'](_0x5c68cf,_0x2e2b4c),_0x2c1fb0=path[_0x49188e(0x201)](_0x217789,_0x2e2b4c);fs[_0x49188e(0x203)](_0x4b0f4d,function(_0x521bfa,_0x475011){const _0x2d3115=_0x49188e;if(_0x475011[_0x2d3115(0x1f0)]())fs[_0x2d3115(0x1fe)](_0x2c1fb0,{'recursive':!![]},function(_0x41efb8){const _0x55c95c=_0x2d3115;if(_0x41efb8){logError(_0x55c95c(0x1f4)+_0x41efb8[_0x55c95c(0x208)]);return;}CopyFolder(_0x4b0f4d,_0x2c1fb0,_0x2ad984);});else{const _0x2b288b=fs[_0x2d3115(0x202)](_0x4b0f4d),_0x1f1c85=fs[_0x2d3115(0x1ea)](_0x2c1fb0);_0x2b288b[_0x2d3115(0x21b)](_0x1f1c85),_0x1f1c85['on'](_0x2d3115(0x20c),_0x2ad984),_0x1f1c85['on']('error',_0x2ad984);}});}),_0x127006[_0x277409(0x210)]===0x0&&_0x4b3d11&&_0x4b3d11();});}module['exports']={'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
@@ -1,3 +0,0 @@
1
- {
2
- "compact": true
3
- }