jjb-cmd 2.5.3 → 2.5.4

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/auth.js CHANGED
@@ -1 +1,71 @@
1
- const a0_0x2449d7=a0_0x16b9;function a0_0x16b9(_0x3e863c,_0x119508){const _0x42156b=a0_0x4215();return a0_0x16b9=function(_0x16b945,_0x2fcb1a){_0x16b945=_0x16b945-0x1ca;let _0x1a0111=_0x42156b[_0x16b945];return _0x1a0111;},a0_0x16b9(_0x3e863c,_0x119508);}(function(_0x1984c7,_0x8b3371){const _0xa43fa=a0_0x16b9,_0x5e5763=_0x1984c7();while(!![]){try{const _0x53ddbe=-parseInt(_0xa43fa(0x1eb))/0x1*(parseInt(_0xa43fa(0x1f1))/0x2)+parseInt(_0xa43fa(0x1e3))/0x3+-parseInt(_0xa43fa(0x1e7))/0x4*(parseInt(_0xa43fa(0x1d5))/0x5)+parseInt(_0xa43fa(0x1ca))/0x6+-parseInt(_0xa43fa(0x1de))/0x7*(-parseInt(_0xa43fa(0x1ed))/0x8)+-parseInt(_0xa43fa(0x1d0))/0x9+-parseInt(_0xa43fa(0x1ea))/0xa;if(_0x53ddbe===_0x8b3371)break;else _0x5e5763['push'](_0x5e5763['shift']());}catch(_0xa3f569){_0x5e5763['push'](_0x5e5763['shift']());}}}(a0_0x4215,0x1e1a1));const axios=require(a0_0x2449d7(0x1e4)),path=require(a0_0x2449d7(0x1e2)),{getApiHost}=require(a0_0x2449d7(0x1da)),{logInfo,logSuccess,logError,fileExists,deleteFile}=require(a0_0x2449d7(0x1e8)),{saveAuth,deleteAuth}=require(a0_0x2449d7(0x1ef)),{getCredentials,interactiveAuth}=require(a0_0x2449d7(0x1d8));function a0_0x4215(){const _0x457cfb=['用户认证成功','认证失败:\x20','39046ckWjmM','认证失败\x20(','join','网络连接失败:\x20无法连接到服务器','path','420963JNAtFk','axios','用户取消输入','已清理无效的认证信息','124MUuOgo','./utils','../.auth','144370mbVPOS','1811VDCenU','includes','200byNqLq','request','./crypto-utils','data','50eYPCBM','899820HeQtQS','认证信息已安全加密存储','status','正在验证用户凭证...','):\x20用户名或密码错误','username','1382193eXJEYN','请求失败\x20(','message','response','password','15025KZNGVy','):\x20','exports','./password-input','exit','./config','/api/auth'];a0_0x4215=function(){return _0x457cfb;};return a0_0x4215();}module[a0_0x2449d7(0x1d7)]=async _0x30e405=>{const _0x141099=a0_0x2449d7,_0x215bce=path[_0x141099(0x1e0)](__dirname,_0x141099(0x1e9));try{logInfo('启动交互式登录流程');const _0x5b6f59=await interactiveAuth(),_0x17f817=_0x5b6f59[_0x141099(0x1cf)],_0x3608a1=_0x5b6f59[_0x141099(0x1d4)];logInfo(_0x141099(0x1cd));const _0x1e41fa=await axios['post'](getApiHost()+_0x141099(0x1db),{'username':_0x17f817,'password':_0x3608a1});if(_0x1e41fa['data'][_0x141099(0x1cc)]){logSuccess(_0x141099(0x1dc));try{saveAuth(_0x17f817,_0x3608a1,_0x215bce),logSuccess(_0x141099(0x1cb));}catch(_0x234f0c){logError('保存认证信息失败:\x20'+_0x234f0c[_0x141099(0x1d2)]),process[_0x141099(0x1d9)](0x1);}}else logError(_0x141099(0x1dd)+(_0x1e41fa[_0x141099(0x1f0)][_0x141099(0x1d2)]||'未知错误')),fileExists(_0x215bce)&&(deleteAuth(_0x215bce),logInfo(_0x141099(0x1e6))),process[_0x141099(0x1d9)](0x1);}catch(_0xebae84){if(_0xebae84[_0x141099(0x1d2)][_0x141099(0x1ec)](_0x141099(0x1e5)))logError('用户取消登录操作');else{if(_0xebae84['response']){const _0x171726=_0xebae84[_0x141099(0x1d3)]['status'],_0xe17855=_0xebae84[_0x141099(0x1d3)][_0x141099(0x1f0)]?.[_0x141099(0x1d2)]||_0xebae84[_0x141099(0x1d2)];_0x171726===0x191||_0x171726===0x193?logError(_0x141099(0x1df)+_0x171726+_0x141099(0x1ce)):logError(_0x141099(0x1d1)+_0x171726+_0x141099(0x1d6)+_0xe17855);}else _0xebae84[_0x141099(0x1ee)]?logError(_0x141099(0x1e1)):logError('登录失败:\x20'+_0xebae84[_0x141099(0x1d2)]);}process[_0x141099(0x1d9)](0x1);}};
1
+ const axios = require('axios');
2
+ const path = require('path');
3
+ const { getApiHost } = require('./config');
4
+ const {
5
+ logInfo,
6
+ logSuccess,
7
+ logError,
8
+ fileExists,
9
+ deleteFile
10
+ } = require('./utils');
11
+ const { saveAuth, deleteAuth } = require('./crypto-utils');
12
+ const { getCredentials, interactiveAuth } = require('./password-input');
13
+
14
+ /**
15
+ * 用户认证模块
16
+ * @param {string[]} args - 命令行参数(不再使用)
17
+ */
18
+ module.exports = async (args) => {
19
+ const authPath = path.join(__dirname, '../.auth');
20
+
21
+ try {
22
+ // 强制使用完全交互式模式
23
+ logInfo('启动交互式登录流程');
24
+ const credentials = await interactiveAuth();
25
+ const username = credentials.username;
26
+ const password = credentials.password;
27
+
28
+ logInfo('正在验证用户凭证...');
29
+
30
+ // 验证登录
31
+ const response = await axios.post(`${getApiHost()}/api/auth`, {
32
+ username,
33
+ password
34
+ });
35
+
36
+ if (response.data.status) {
37
+ logSuccess('用户认证成功');
38
+ try {
39
+ saveAuth(username, password, authPath);
40
+ logSuccess('认证信息已安全加密存储');
41
+ } catch (error) {
42
+ logError(`保存认证信息失败: ${error.message}`);
43
+ process.exit(1);
44
+ }
45
+ } else {
46
+ logError(`认证失败: ${response.data.message || '未知错误'}`);
47
+ if (fileExists(authPath)) {
48
+ deleteAuth(authPath);
49
+ logInfo('已清理无效的认证信息');
50
+ }
51
+ process.exit(1);
52
+ }
53
+ } catch (error) {
54
+ if (error.message.includes('用户取消输入')) {
55
+ logError('用户取消登录操作');
56
+ } else if (error.response) {
57
+ const status = error.response.status;
58
+ const message = error.response.data?.message || error.message;
59
+ if (status === 401 || status === 403) {
60
+ logError(`认证失败 (${status}): 用户名或密码错误`);
61
+ } else {
62
+ logError(`请求失败 (${status}): ${message}`);
63
+ }
64
+ } else if (error.request) {
65
+ logError(`网络连接失败: 无法连接到服务器`);
66
+ } else {
67
+ logError(`登录失败: ${error.message}`);
68
+ }
69
+ process.exit(1);
70
+ }
71
+ };
@@ -1 +1,46 @@
1
- const a1_0x5a6c3c=a1_0x2c45;(function(_0x53e8db,_0x237484){const _0x454069=a1_0x2c45,_0x31b5cb=_0x53e8db();while(!![]){try{const _0x3a534a=parseInt(_0x454069(0xc1))/0x1+parseInt(_0x454069(0xc4))/0x2+parseInt(_0x454069(0xc3))/0x3+parseInt(_0x454069(0xb7))/0x4+parseInt(_0x454069(0xc9))/0x5+parseInt(_0x454069(0xca))/0x6+-parseInt(_0x454069(0xc2))/0x7;if(_0x3a534a===_0x237484)break;else _0x31b5cb['push'](_0x31b5cb['shift']());}catch(_0x58c2e2){_0x31b5cb['push'](_0x31b5cb['shift']());}}}(a1_0x5326,0x1cd36));const path=require(a1_0x5a6c3c(0xbe)),inquirer=require(a1_0x5a6c3c(0xc0)),{bootstrap}=require(a1_0x5a6c3c(0xb8)),{logInfo,logSuccess,logError,logWarning}=require(a1_0x5a6c3c(0xba));function a1_0x2c45(_0x21c699,_0x12f726){const _0x532634=a1_0x5326();return a1_0x2c45=function(_0x2c4586,_0x297b08){_0x2c4586=_0x2c4586-0xb6;let _0x27cf7c=_0x532634[_0x2c4586];return _0x27cf7c;},a1_0x2c45(_0x21c699,_0x12f726);}module[a1_0x5a6c3c(0xbd)]=async function(){const _0x5d6085=a1_0x5a6c3c,_0x271d1b=path['resolve']('./');logInfo(_0x5d6085(0xb9)),logWarning('此操作将优化当前目录下的代码,请确保已备份重要文件');const {confirmed:_0x5aeb48}=await inquirer[_0x5d6085(0xc8)]([{'type':'confirm','name':_0x5d6085(0xc6),'message':'是否确认优化代码?','default':![]}]);if(_0x5aeb48){logInfo(_0x5d6085(0xc7));try{bootstrap(_0x271d1b,0x64,()=>{const _0x340f69=_0x5d6085;logSuccess(_0x340f69(0xbf)),process['exit'](0x0);});}catch(_0x5ed75e){logError(_0x5d6085(0xbb)+_0x5ed75e[_0x5d6085(0xbc)]),process[_0x5d6085(0xb6)](0x1);}}else logInfo(_0x5d6085(0xc5)),process[_0x5d6085(0xb6)](0x0);};function a1_0x5326(){const _0x2ef530=['942696acAurL','exit','10236iJENuM','@cqsjjb/react-code-optimization','代码优化工具已启动','./utils','代码优化失败:\x20','message','exports','path','代码优化已完成','inquirer','71818Rngnrs','2584365CTfNsj','317634lNXwfo','48406CYOwMw','操作已取消','confirmed','正在分析代码结构...','prompt','628455YPEjjd'];a1_0x5326=function(){return _0x2ef530;};return a1_0x5326();}
1
+ const path = require('path');
2
+ const inquirer = require('inquirer');
3
+ const { bootstrap } = require('@cqsjjb/react-code-optimization');
4
+ const {
5
+ logInfo,
6
+ logSuccess,
7
+ logError,
8
+ logWarning
9
+ } = require('./utils');
10
+
11
+ /**
12
+ * 代码优化模块
13
+ * 使用 @cqsjjb/react-code-optimization 进行代码优化
14
+ */
15
+ module.exports = async function () {
16
+ const rootPath = path.resolve('./');
17
+
18
+ logInfo('代码优化工具已启动');
19
+ logWarning('此操作将优化当前目录下的代码,请确保已备份重要文件');
20
+
21
+ const { confirmed } = await inquirer.prompt([
22
+ {
23
+ type: 'confirm',
24
+ name: 'confirmed',
25
+ message: '是否确认优化代码?',
26
+ default: false
27
+ }
28
+ ]);
29
+
30
+ if (confirmed) {
31
+ logInfo('正在分析代码结构...');
32
+
33
+ try {
34
+ bootstrap(rootPath, 100, () => {
35
+ logSuccess('代码优化已完成');
36
+ process.exit(0);
37
+ });
38
+ } catch (error) {
39
+ logError(`代码优化失败: ${error.message}`);
40
+ process.exit(1);
41
+ }
42
+ } else {
43
+ logInfo('操作已取消');
44
+ process.exit(0);
45
+ }
46
+ };
package/src/config.js CHANGED
@@ -1 +1,122 @@
1
- function a2_0x1239(){const _0x5bc4e2=['6677867VEEKFr','96310kmEMkY','GIT_TEMP_JAVA','150fUoTWG','FqNrmFAgrxasMrbbjvq9','4558740lebucg','GIT_JAVA_ENV_JSON','CONFIG_FILE_HOST','http://192.168.1.242:10985','join','GIT_HOST','../package.json','http','hLqARY89CN6fUD3yg4NL','46502416wDmeFq','test','1793734WKZmEa','jjb-assembly-','d4wQ7dzEjYPsgVbKnYei','GIT_TEMP_DIR','gPSit8aJsLVmNzuQ5Cy4','3505460tuCMWL','now','http://120.26.210.58:8089','API_HOST_TEST','https://jcloud.cqjjb.cn','ywPtT3xCG6b_vAxp6sTj','https://cdn.cqjjb.cn/jjb-cloud-config','toString','httpMethod','2772748eZgDan','readFileSync','http://120.26.210.58:8088','7V-YUxhmh51Mdhgx4rq4','dev','CLOUD_PROJECT','path','getApiHost'];a2_0x1239=function(){return _0x5bc4e2;};return a2_0x1239();}const a2_0x202e9b=a2_0x2342;(function(_0x22dd3e,_0xea39fe){const _0x3789d1=a2_0x2342,_0x25a298=_0x22dd3e();while(!![]){try{const _0x48b683=-parseInt(_0x3789d1(0xb5))/0x1+-parseInt(_0x3789d1(0x94))/0x2+-parseInt(_0x3789d1(0xaa))/0x3+parseInt(_0x3789d1(0x9d))/0x4+-parseInt(_0x3789d1(0xa6))/0x5*(-parseInt(_0x3789d1(0xa8))/0x6)+-parseInt(_0x3789d1(0xa5))/0x7+parseInt(_0x3789d1(0xb3))/0x8;if(_0x48b683===_0xea39fe)break;else _0x25a298['push'](_0x25a298['shift']());}catch(_0x3d9430){_0x25a298['push'](_0x25a298['shift']());}}}(a2_0x1239,0xec35a));function a2_0x2342(_0x558a9a,_0x2a5a74){const _0x1239df=a2_0x1239();return a2_0x2342=function(_0x2342c3,_0x1d9339){_0x2342c3=_0x2342c3-0x90;let _0x18698e=_0x1239df[_0x2342c3];return _0x18698e;},a2_0x2342(_0x558a9a,_0x2a5a74);}const os=require('os'),path=require(a2_0x202e9b(0xa3)),fs=require('fs'),API_HOST=a2_0x202e9b(0x9f),API_HOST_HTTPS=a2_0x202e9b(0x98),API_HOST_TEST=a2_0x202e9b(0x96);exports[a2_0x202e9b(0xac)]=a2_0x202e9b(0x9a),exports['API_HOST']=API_HOST,exports[a2_0x202e9b(0x97)]=API_HOST_TEST,exports[a2_0x202e9b(0xaf)]=a2_0x202e9b(0xad),exports['GIT_TEMP_DIR']=a2_0x202e9b(0x90)+Date[a2_0x202e9b(0x95)](),exports[a2_0x202e9b(0xa7)]='jjb-assembly-java',exports[a2_0x202e9b(0xab)]={'development':a2_0x202e9b(0xa1),'production':'prod','test':a2_0x202e9b(0xb4)},exports[a2_0x202e9b(0xa2)]={'common':{'token':'G4HJRsHr9D7Ssmixegw2','projectId':0x117},'react-admin-component':{'token':'FT3pKzxpRynFkmddJ9Bs','projectId':0x154},'jjb-dva-runtime':{'token':a2_0x202e9b(0xb2),'projectId':0x23b},'jjb-common-lib':{'token':'e9njpBd1nS_LREN8GFpR','projectId':0x23c},'jjb-common-decorator':{'token':a2_0x202e9b(0x93),'projectId':0x23e},'vue-unisass-component':{'token':a2_0x202e9b(0x91),'projectId':0x153},'react-component':{'token':'snBxJ2i5kYarGGcsojhY','projectId':0x33f},'micro-app-ts':{'token':a2_0x202e9b(0xa0),'projectId':0x33e},'micro-app':{'token':a2_0x202e9b(0xa9),'projectId':0x33d},'lib':{'token':a2_0x202e9b(0x99),'projectId':0x33c}},exports['TEMPLATE_FOLDER']=path['join'](os['tmpdir'](),exports[a2_0x202e9b(0x92)]),exports[a2_0x202e9b(0xa4)]=()=>{const _0x23790a=a2_0x202e9b;try{const _0x2a1cdf=JSON['parse'](fs[_0x23790a(0x9e)](path[_0x23790a(0xae)](__dirname,_0x23790a(0xb0)))[_0x23790a(0x9b)]());return _0x2a1cdf['env']==='test'?API_HOST_TEST:_0x2a1cdf[_0x23790a(0x9c)]===_0x23790a(0xb1)?API_HOST:API_HOST_HTTPS;}catch(_0x53047e){return API_HOST_HTTPS;}};
1
+ const os = require('os');
2
+ const path = require('path');
3
+ const fs = require('fs');
4
+
5
+ /**
6
+ * API 主机配置
7
+ */
8
+ const API_HOST = 'http://120.26.210.58:8088';
9
+ const API_HOST_HTTPS = 'https://jcloud.cqjjb.cn';
10
+ const API_HOST_TEST = 'http://120.26.210.58:8089';
11
+
12
+ /**
13
+ * 配置文件主机地址
14
+ */
15
+ exports.CONFIG_FILE_HOST = 'https://cdn.cqjjb.cn/jjb-cloud-config';
16
+
17
+ /**
18
+ * API 主机地址
19
+ */
20
+ exports.API_HOST = API_HOST;
21
+
22
+ /**
23
+ * 测试环境 API 主机地址
24
+ */
25
+ exports.API_HOST_TEST = API_HOST_TEST;
26
+
27
+ /**
28
+ * Git 主机地址
29
+ */
30
+ exports.GIT_HOST = 'http://192.168.1.242:10985';
31
+
32
+ /**
33
+ * 临时目录名称
34
+ */
35
+ exports.GIT_TEMP_DIR = `jjb-assembly-${Date.now()}`;
36
+
37
+ /**
38
+ * Java 临时目录名称
39
+ */
40
+ exports.GIT_TEMP_JAVA = `jjb-assembly-java`;
41
+
42
+ /**
43
+ * Java 环境映射
44
+ */
45
+ exports.GIT_JAVA_ENV_JSON = {
46
+ development: 'dev',
47
+ production: 'prod',
48
+ test: 'test'
49
+ };
50
+ /**
51
+ * 云项目配置
52
+ * 包含各个项目的 token 和 projectId
53
+ */
54
+ exports.CLOUD_PROJECT = {
55
+ common: {
56
+ token: 'G4HJRsHr9D7Ssmixegw2',
57
+ projectId: 279
58
+ },
59
+ 'react-admin-component': {
60
+ token: 'FT3pKzxpRynFkmddJ9Bs',
61
+ projectId: 340
62
+ },
63
+ 'jjb-dva-runtime': {
64
+ token: 'hLqARY89CN6fUD3yg4NL',
65
+ projectId: 571
66
+ },
67
+ 'jjb-common-lib': {
68
+ token: 'e9njpBd1nS_LREN8GFpR',
69
+ projectId: 572
70
+ },
71
+ 'jjb-common-decorator': {
72
+ token: 'gPSit8aJsLVmNzuQ5Cy4',
73
+ projectId: 574
74
+ },
75
+ 'vue-unisass-component': {
76
+ token: 'd4wQ7dzEjYPsgVbKnYei',
77
+ projectId: 339
78
+ },
79
+ 'react-component': {
80
+ token: 'snBxJ2i5kYarGGcsojhY',
81
+ projectId: 831
82
+ },
83
+ 'micro-app-ts': {
84
+ token: '7V-YUxhmh51Mdhgx4rq4',
85
+ projectId: 830
86
+ },
87
+ 'micro-app': {
88
+ token: 'FqNrmFAgrxasMrbbjvq9',
89
+ projectId: 829
90
+ },
91
+ lib: {
92
+ token: 'ywPtT3xCG6b_vAxp6sTj',
93
+ projectId: 828
94
+ }
95
+ };
96
+
97
+ /**
98
+ * 模板文件夹路径
99
+ */
100
+ exports.TEMPLATE_FOLDER = path.join(os.tmpdir(), exports.GIT_TEMP_DIR);
101
+
102
+ /**
103
+ * 获取 API 主机地址
104
+ * 根据 package.json 中的配置决定使用哪个 API 主机
105
+ * @returns {string} API 主机地址
106
+ */
107
+ exports.getApiHost = () => {
108
+ try {
109
+ const packageJson = JSON.parse(
110
+ fs.readFileSync(path.join(__dirname, '../package.json')).toString()
111
+ );
112
+
113
+ if (packageJson.env === 'test') {
114
+ return API_HOST_TEST;
115
+ } else {
116
+ return packageJson.httpMethod === 'http' ? API_HOST : API_HOST_HTTPS;
117
+ }
118
+ } catch (error) {
119
+ // 如果读取 package.json 失败,默认返回 HTTPS 地址
120
+ return API_HOST_HTTPS;
121
+ }
122
+ };
@@ -1 +1,183 @@
1
- const a3_0x3f74e1=a3_0x20f1;function a3_0x20f1(_0x1237d0,_0x17b56e){const _0x1cdc72=a3_0x1cdc();return a3_0x20f1=function(_0x20f172,_0x44606a){_0x20f172=_0x20f172-0xaf;let _0x460260=_0x1cdc72[_0x20f172];return _0x460260;},a3_0x20f1(_0x1237d0,_0x17b56e);}function a3_0x1cdc(){const _0x57e1da=['algorithm','1969638lIkWxz','utf8','认证文件不存在','sha256','split','认证数据格式错误','2uMItDj','解密失败:\x20','slice','1153110fYEhRw','8201952AEpniZ','createDecipheriv','hex','435741XeuDzT','keyLength','existsSync','342546UXApSA','digest','createCipheriv','concat','unknown','readFileSync','username','final','createHash','1372742VMGEcX','保存认证信息失败:\x20','base64','toString','读取认证信息失败:\x20','exports','aes-256-cbc','path','unlinkSync','加密失败:\x20','update','176424Tayopa','join','saltLength','randomBytes','arch','from','platform','message','ivLength','删除认证文件失败:\x20'];a3_0x1cdc=function(){return _0x57e1da;};return a3_0x1cdc();}(function(_0x37f16c,_0x4f64e2){const _0x46f46f=a3_0x20f1,_0x3061fd=_0x37f16c();while(!![]){try{const _0x256e1c=parseInt(_0x46f46f(0xd9))/0x1+-parseInt(_0x46f46f(0xcf))/0x2*(-parseInt(_0x46f46f(0xd6))/0x3)+-parseInt(_0x46f46f(0xbe))/0x4+parseInt(_0x46f46f(0xd2))/0x5+parseInt(_0x46f46f(0xc9))/0x6+parseInt(_0x46f46f(0xb3))/0x7+-parseInt(_0x46f46f(0xd3))/0x8;if(_0x256e1c===_0x4f64e2)break;else _0x3061fd['push'](_0x3061fd['shift']());}catch(_0x7bb94d){_0x3061fd['push'](_0x3061fd['shift']());}}}(a3_0x1cdc,0x2a584));const crypto=require('crypto'),fs=require('fs'),path=require(a3_0x3f74e1(0xba)),CRYPTO_CONFIG={'algorithm':a3_0x3f74e1(0xb9),'keyLength':0x20,'ivLength':0x10,'saltLength':0x20};function deriveKey(_0x1c9303,_0x6bfe14){const _0x52e199=a3_0x3f74e1;return crypto['pbkdf2Sync'](_0x1c9303,_0x6bfe14,0x186a0,CRYPTO_CONFIG[_0x52e199(0xd7)],'sha512');}function generateSalt(){const _0x45ee46=a3_0x3f74e1;return crypto[_0x45ee46(0xc1)](CRYPTO_CONFIG['saltLength']);}function generateIV(){const _0x669a9d=a3_0x3f74e1;return crypto[_0x669a9d(0xc1)](CRYPTO_CONFIG[_0x669a9d(0xc6)]);}function encrypt(_0x5a90fd,_0x4594b8){const _0x1e330e=a3_0x3f74e1;try{const _0x49bf9c=generateSalt(),_0x193b24=generateIV(),_0x1e7762=deriveKey(_0x4594b8,_0x49bf9c),_0x10c7a1=crypto[_0x1e330e(0xdb)](CRYPTO_CONFIG['algorithm'],_0x1e7762,_0x193b24);_0x10c7a1['setAutoPadding'](!![]);let _0x5dbbc7=_0x10c7a1['update'](_0x5a90fd,'utf8',_0x1e330e(0xd5));_0x5dbbc7+=_0x10c7a1[_0x1e330e(0xb1)]('hex');const _0x42e1c8=Buffer[_0x1e330e(0xdc)]([_0x49bf9c,_0x193b24,Buffer[_0x1e330e(0xc3)](_0x5dbbc7,_0x1e330e(0xd5))]);return _0x42e1c8[_0x1e330e(0xb6)](_0x1e330e(0xb5));}catch(_0x52c36b){throw new Error(_0x1e330e(0xbc)+_0x52c36b[_0x1e330e(0xc5)]);}}function decrypt(_0x538efa,_0x3ab1c3){const _0x31b8c3=a3_0x3f74e1;try{const _0x532bdb=Buffer[_0x31b8c3(0xc3)](_0x538efa,'base64'),_0x2e5170=_0x532bdb[_0x31b8c3(0xd1)](0x0,CRYPTO_CONFIG[_0x31b8c3(0xc0)]),_0x3389a1=_0x532bdb[_0x31b8c3(0xd1)](CRYPTO_CONFIG['saltLength'],CRYPTO_CONFIG[_0x31b8c3(0xc0)]+CRYPTO_CONFIG[_0x31b8c3(0xc6)]),_0x3e9b01=_0x532bdb[_0x31b8c3(0xd1)](CRYPTO_CONFIG[_0x31b8c3(0xc0)]+CRYPTO_CONFIG[_0x31b8c3(0xc6)]),_0x41a493=deriveKey(_0x3ab1c3,_0x2e5170),_0x4d4f16=crypto[_0x31b8c3(0xd4)](CRYPTO_CONFIG[_0x31b8c3(0xc8)],_0x41a493,_0x3389a1);_0x4d4f16['setAutoPadding'](!![]);let _0x168c11=_0x4d4f16[_0x31b8c3(0xbd)](_0x3e9b01,null,'utf8');return _0x168c11+=_0x4d4f16[_0x31b8c3(0xb1)](_0x31b8c3(0xca)),_0x168c11;}catch(_0x52b8b5){throw new Error(_0x31b8c3(0xd0)+_0x52b8b5[_0x31b8c3(0xc5)]);}}function generateDeviceKey(){const _0x390dd9=a3_0x3f74e1,_0x33d0ab=require('os'),_0x56773e=[_0x33d0ab[_0x390dd9(0xc4)](),_0x33d0ab[_0x390dd9(0xc2)](),_0x33d0ab['hostname'](),_0x33d0ab['userInfo']()[_0x390dd9(0xb0)]||_0x390dd9(0xdd)][_0x390dd9(0xbf)]('|');return crypto[_0x390dd9(0xb2)](_0x390dd9(0xcc))[_0x390dd9(0xbd)](_0x56773e)[_0x390dd9(0xda)](_0x390dd9(0xd5));}function saveAuth(_0x570706,_0x353aa9,_0x41cbbb){const _0x564b25=a3_0x3f74e1;try{const _0x2966e5=generateDeviceKey(),_0x21089c=_0x570706+'/'+_0x353aa9,_0x55468c=encrypt(_0x21089c,_0x2966e5);return fs['writeFileSync'](_0x41cbbb,_0x55468c,{'mode':0x180}),!![];}catch(_0x1fab8b){throw new Error(_0x564b25(0xb4)+_0x1fab8b[_0x564b25(0xc5)]);}}function loadAuth(_0xf27fff){const _0xe49f2=a3_0x3f74e1;try{if(!fs[_0xe49f2(0xd8)](_0xf27fff))throw new Error(_0xe49f2(0xcb));const _0x5b8b23=generateDeviceKey(),_0x535322=fs[_0xe49f2(0xaf)](_0xf27fff,'utf8'),_0x322e71=decrypt(_0x535322,_0x5b8b23),[_0x5e20d3,_0x49178e]=_0x322e71[_0xe49f2(0xcd)]('/');if(!_0x5e20d3||!_0x49178e)throw new Error(_0xe49f2(0xce));return{'username':_0x5e20d3,'password':_0x49178e};}catch(_0x54a425){throw new Error(_0xe49f2(0xb7)+_0x54a425[_0xe49f2(0xc5)]);}}function deleteAuth(_0x2b353a){const _0x4a35a2=a3_0x3f74e1;try{fs[_0x4a35a2(0xd8)](_0x2b353a)&&fs[_0x4a35a2(0xbb)](_0x2b353a);}catch(_0x373378){throw new Error(_0x4a35a2(0xc7)+_0x373378['message']);}}module[a3_0x3f74e1(0xb8)]={'encrypt':encrypt,'decrypt':decrypt,'saveAuth':saveAuth,'loadAuth':loadAuth,'deleteAuth':deleteAuth,'generateDeviceKey':generateDeviceKey};
1
+ const crypto = require('crypto');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ /**
6
+ * 加密配置
7
+ */
8
+ const CRYPTO_CONFIG = {
9
+ algorithm: 'aes-256-cbc',
10
+ keyLength: 32, // 256 bits
11
+ ivLength: 16, // 128 bits
12
+ saltLength: 32 // 256 bits
13
+ };
14
+
15
+ /**
16
+ * 生成加密密钥
17
+ * @param {string} password - 主密码
18
+ * @param {Buffer} salt - 盐值
19
+ * @returns {Buffer} 加密密钥
20
+ */
21
+ function deriveKey(password, salt) {
22
+ return crypto.pbkdf2Sync(password, salt, 100000, CRYPTO_CONFIG.keyLength, 'sha512');
23
+ }
24
+
25
+ /**
26
+ * 生成随机盐值
27
+ * @returns {Buffer} 随机盐值
28
+ */
29
+ function generateSalt() {
30
+ return crypto.randomBytes(CRYPTO_CONFIG.saltLength);
31
+ }
32
+
33
+ /**
34
+ * 生成随机IV
35
+ * @returns {Buffer} 随机IV
36
+ */
37
+ function generateIV() {
38
+ return crypto.randomBytes(CRYPTO_CONFIG.ivLength);
39
+ }
40
+
41
+ /**
42
+ * 加密数据
43
+ * @param {string} text - 要加密的文本
44
+ * @param {string} password - 加密密码
45
+ * @returns {string} 加密后的数据(base64编码)
46
+ */
47
+ function encrypt(text, password) {
48
+ try {
49
+ const salt = generateSalt();
50
+ const iv = generateIV();
51
+ const key = deriveKey(password, salt);
52
+
53
+ const cipher = crypto.createCipheriv(CRYPTO_CONFIG.algorithm, key, iv);
54
+ cipher.setAutoPadding(true);
55
+
56
+ let encrypted = cipher.update(text, 'utf8', 'hex');
57
+ encrypted += cipher.final('hex');
58
+
59
+ // 组合数据:salt + iv + encrypted
60
+ const combined = Buffer.concat([salt, iv, Buffer.from(encrypted, 'hex')]);
61
+
62
+ return combined.toString('base64');
63
+ } catch (error) {
64
+ throw new Error(`加密失败: ${error.message}`);
65
+ }
66
+ }
67
+
68
+ /**
69
+ * 解密数据
70
+ * @param {string} encryptedData - 加密的数据(base64编码)
71
+ * @param {string} password - 解密密码
72
+ * @returns {string} 解密后的文本
73
+ */
74
+ function decrypt(encryptedData, password) {
75
+ try {
76
+ const combined = Buffer.from(encryptedData, 'base64');
77
+
78
+ // 分离数据
79
+ const salt = combined.slice(0, CRYPTO_CONFIG.saltLength);
80
+ const iv = combined.slice(CRYPTO_CONFIG.saltLength, CRYPTO_CONFIG.saltLength + CRYPTO_CONFIG.ivLength);
81
+ const encrypted = combined.slice(CRYPTO_CONFIG.saltLength + CRYPTO_CONFIG.ivLength);
82
+
83
+ const key = deriveKey(password, salt);
84
+
85
+ const decipher = crypto.createDecipheriv(CRYPTO_CONFIG.algorithm, key, iv);
86
+ decipher.setAutoPadding(true);
87
+
88
+ let decrypted = decipher.update(encrypted, null, 'utf8');
89
+ decrypted += decipher.final('utf8');
90
+
91
+ return decrypted;
92
+ } catch (error) {
93
+ throw new Error(`解密失败: ${error.message}`);
94
+ }
95
+ }
96
+
97
+ /**
98
+ * 生成设备特定的加密密钥
99
+ * 基于系统信息生成,确保密钥的唯一性
100
+ * @returns {string} 设备密钥
101
+ */
102
+ function generateDeviceKey() {
103
+ const os = require('os');
104
+ const machineInfo = [
105
+ os.platform(),
106
+ os.arch(),
107
+ os.hostname(),
108
+ os.userInfo().username || 'unknown'
109
+ ].join('|');
110
+
111
+ return crypto.createHash('sha256').update(machineInfo).digest('hex');
112
+ }
113
+
114
+ /**
115
+ * 安全存储认证信息
116
+ * @param {string} username - 用户名
117
+ * @param {string} password - 密码
118
+ * @param {string} authPath - 认证文件路径
119
+ */
120
+ function saveAuth(username, password, authPath) {
121
+ try {
122
+ const deviceKey = generateDeviceKey();
123
+ const authData = `${username}/${password}`;
124
+ const encryptedData = encrypt(authData, deviceKey);
125
+
126
+ // 设置文件权限为仅当前用户可读写
127
+ fs.writeFileSync(authPath, encryptedData, { mode: 0o600 });
128
+
129
+ return true;
130
+ } catch (error) {
131
+ throw new Error(`保存认证信息失败: ${error.message}`);
132
+ }
133
+ }
134
+
135
+ /**
136
+ * 安全读取认证信息
137
+ * @param {string} authPath - 认证文件路径
138
+ * @returns {Object} 包含用户名和密码的对象
139
+ */
140
+ function loadAuth(authPath) {
141
+ try {
142
+ if (!fs.existsSync(authPath)) {
143
+ throw new Error('认证文件不存在');
144
+ }
145
+
146
+ const deviceKey = generateDeviceKey();
147
+ const encryptedData = fs.readFileSync(authPath, 'utf8');
148
+ const decryptedData = decrypt(encryptedData, deviceKey);
149
+
150
+ const [username, password] = decryptedData.split('/');
151
+
152
+ if (!username || !password) {
153
+ throw new Error('认证数据格式错误');
154
+ }
155
+
156
+ return { username, password };
157
+ } catch (error) {
158
+ throw new Error(`读取认证信息失败: ${error.message}`);
159
+ }
160
+ }
161
+
162
+ /**
163
+ * 删除认证文件
164
+ * @param {string} authPath - 认证文件路径
165
+ */
166
+ function deleteAuth(authPath) {
167
+ try {
168
+ if (fs.existsSync(authPath)) {
169
+ fs.unlinkSync(authPath);
170
+ }
171
+ } catch (error) {
172
+ throw new Error(`删除认证文件失败: ${error.message}`);
173
+ }
174
+ }
175
+
176
+ module.exports = {
177
+ encrypt,
178
+ decrypt,
179
+ saveAuth,
180
+ loadAuth,
181
+ deleteAuth,
182
+ generateDeviceKey
183
+ };
@@ -1 +1,79 @@
1
- function a4_0x2713(_0x3a7204,_0x3527db){const _0x48063e=a4_0x4806();return a4_0x2713=function(_0x2713b0,_0x415d9a){_0x2713b0=_0x2713b0-0xe5;let _0x4fc99a=_0x48063e[_0x2713b0];return _0x4fc99a;},a4_0x2713(_0x3a7204,_0x3527db);}function a4_0x4806(){const _0x32bc12=['请输入账号:','2516136QJTfXj','请输入密码:','trim','./utils','密码不能为空','730000EBfYEP','2470875bvaZEP','账号不能为空','获取认证信息失败:\x20','240657RxxNqF','6220eezBhG','input','username','push','prompt','exports','3BtbWGG','7vkckDi','2180880udhFDf','1458488akJTtO','isTtyError','password','message'];a4_0x4806=function(){return _0x32bc12;};return a4_0x4806();}const a4_0xcb6d08=a4_0x2713;(function(_0x500358,_0x49f955){const _0x3eaf71=a4_0x2713,_0x2adf1c=_0x500358();while(!![]){try{const _0x3658c2=parseInt(_0x3eaf71(0xeb))/0x1+parseInt(_0x3eaf71(0xe7))/0x2*(parseInt(_0x3eaf71(0xf2))/0x3)+-parseInt(_0x3eaf71(0xec))/0x4+parseInt(_0x3eaf71(0xe8))/0x5+-parseInt(_0x3eaf71(0xfa))/0x6+-parseInt(_0x3eaf71(0xf3))/0x7*(parseInt(_0x3eaf71(0xf5))/0x8)+-parseInt(_0x3eaf71(0xf4))/0x9;if(_0x3658c2===_0x49f955)break;else _0x2adf1c['push'](_0x2adf1c['shift']());}catch(_0x561f4c){_0x2adf1c['push'](_0x2adf1c['shift']());}}}(a4_0x4806,0x3e152));const inquirer=require('inquirer'),{logError}=require(a4_0xcb6d08(0xe5));async function getCredentials(_0x50542b=null){const _0x42ebcf=a4_0xcb6d08;try{let _0x5b89e2=_0x50542b;const _0x5ddabd=[];!_0x5b89e2&&_0x5ddabd['push']({'type':_0x42ebcf(0xed),'name':_0x42ebcf(0xee),'message':_0x42ebcf(0xf9),'validate':_0x31b75a=>{const _0x3a7ebb=_0x42ebcf;if(!_0x31b75a||!_0x31b75a[_0x3a7ebb(0xfc)]())return _0x3a7ebb(0xe9);return!![];}});_0x5ddabd[_0x42ebcf(0xef)]({'type':_0x42ebcf(0xf7),'name':_0x42ebcf(0xf7),'message':_0x42ebcf(0xfb),'mask':'*','validate':_0x1cc089=>{const _0x4f24e2=_0x42ebcf;if(!_0x1cc089||!_0x1cc089[_0x4f24e2(0xfc)]())return _0x4f24e2(0xe6);return!![];}});const _0x182c76=await inquirer[_0x42ebcf(0xf0)](_0x5ddabd);_0x5b89e2=_0x5b89e2||_0x182c76[_0x42ebcf(0xee)][_0x42ebcf(0xfc)]();const _0x305853=_0x182c76['password'];return{'username':_0x5b89e2,'password':_0x305853};}catch(_0x994d80){_0x994d80[_0x42ebcf(0xf6)]?logError('获取认证信息失败:\x20当前环境不支持交互式输入'):logError(_0x42ebcf(0xea)+_0x994d80[_0x42ebcf(0xf8)]);throw _0x994d80;}}async function interactiveAuth(){return await getCredentials();}module[a4_0xcb6d08(0xf1)]={'getCredentials':getCredentials,'interactiveAuth':interactiveAuth};
1
+ const inquirer = require('inquirer');
2
+ const { logError } = require('./utils');
3
+
4
+ /**
5
+ * 安全密码输入工具
6
+ * 使用 inquirer 实现隐藏密码输入,防止在控制台显示明文密码
7
+ */
8
+
9
+ /**
10
+ * 安全获取用户名和密码
11
+ * @param {string} username - 用户名(如果已提供)
12
+ * @returns {Promise<Object>} 包含用户名和密码的对象
13
+ */
14
+ async function getCredentials(username = null) {
15
+ try {
16
+ let finalUsername = username;
17
+ const prompts = [];
18
+
19
+ // 如果没有提供用户名,则提示输入
20
+ if (!finalUsername) {
21
+ prompts.push({
22
+ type: 'input',
23
+ name: 'username',
24
+ message: '请输入账号:',
25
+ validate: (input) => {
26
+ if (!input || !input.trim()) {
27
+ return '账号不能为空';
28
+ }
29
+ return true;
30
+ }
31
+ });
32
+ }
33
+
34
+ // 获取密码(使用 inquirer 的 password 类型隐藏输入)
35
+ prompts.push({
36
+ type: 'password',
37
+ name: 'password',
38
+ message: '请输入密码:',
39
+ mask: '*',
40
+ validate: (input) => {
41
+ if (!input || !input.trim()) {
42
+ return '密码不能为空';
43
+ }
44
+ return true;
45
+ }
46
+ });
47
+
48
+ const answers = await inquirer.prompt(prompts);
49
+
50
+ finalUsername = finalUsername || answers.username.trim();
51
+ const password = answers.password;
52
+
53
+ return {
54
+ username: finalUsername,
55
+ password: password
56
+ };
57
+ } catch (error) {
58
+ if (error.isTtyError) {
59
+ logError(`获取认证信息失败: 当前环境不支持交互式输入`);
60
+ } else {
61
+ logError(`获取认证信息失败: ${error.message}`);
62
+ }
63
+ throw error;
64
+ }
65
+ }
66
+
67
+ /**
68
+ * 交互式认证输入
69
+ * 当命令行参数不足时使用
70
+ * @returns {Promise<Object>} 包含用户名和密码的对象
71
+ */
72
+ async function interactiveAuth() {
73
+ return await getCredentials();
74
+ }
75
+
76
+ module.exports = {
77
+ getCredentials,
78
+ interactiveAuth
79
+ };