ee-bin 1.5.0-beta.1 → 1.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/tools/encrypt.js CHANGED
@@ -1,316 +1,316 @@
1
- 'use strict';
2
-
3
- const path = require('path');
4
- const fs = require('fs');
5
- const fsPro = require('fs-extra');
6
- const is = require('is-type-of');
7
- const bytenode = require('bytenode');
8
- const crypto = require('crypto');
9
- const JavaScriptObfuscator = require('javascript-obfuscator');
10
- const globby = require('globby');
11
- const chalk = require('chalk');
12
- const Utils = require('../lib/utils');
13
-
14
- class Encrypt {
15
- constructor(options = {}) {
16
- // cli args
17
- const outputFolder = options.out || './public';
18
- const configFile = options.config || './electron/config/bin.js';
19
-
20
- this.basePath = process.cwd();
21
- this.encryptCodeDir = path.join(this.basePath, outputFolder);
22
-
23
- // 先从 bin config获取,没有的话从 config/encrypt.js
24
- const hasConfig = Utils.checkConfig(configFile);
25
- if (hasConfig) {
26
- const cfg = Utils.loadConfig(configFile);
27
- this.config = cfg.encrypt;
28
- }
29
- if (!this.config) {
30
- this.config = Utils.loadEncryptConfig();
31
- }
32
-
33
- this.filesExt = this.config.fileExt || ['.js'];
34
- this.type = this.config.type || 'confusion';
35
- this.bOpt = this.config.bytecodeOptions || {};
36
- this.cOpt = this.config.confusionOptions || {};
37
- this.cleanFiles = this.config.cleanFiles || ['./public/electron'];
38
- this.patterns = this.config.files || null;
39
- this.specificFiles = [ 'electron/preload/bridge.js' ];
40
-
41
- // 旧属性,将废弃
42
- this.dirs = [];
43
- const directory = this.config.directory || ['electron'];
44
- for (let i = 0; i < directory.length; i++) {
45
- let codeDirPath = path.join(this.basePath, directory[i]);
46
- if (fs.existsSync(codeDirPath)) {
47
- this.dirs.push(directory[i]);
48
- }
49
- }
50
-
51
- this.codefiles = this._initCodeFiles();
52
- console.log(chalk.blue('[ee-bin] [encrypt] ') + 'cleanFiles:' + this.cleanFiles);
53
- }
54
-
55
- /**
56
- * 初始化需要加密的文件列表
57
- */
58
- _initCodeFiles() {
59
- if (!this.patterns) return;
60
-
61
- const files = globby.sync(this.patterns, { cwd: this.basePath });
62
- return files;
63
- }
64
-
65
- /**
66
- * 备份代码
67
- */
68
- backup() {
69
- // clean
70
- this.cleanCode();
71
-
72
- console.log(chalk.blue('[ee-bin] [encrypt] ') + 'backup start');
73
- if (this.patterns) {
74
- this.codefiles.forEach((filepath) => {
75
- let source = path.join(this.basePath, filepath);
76
- if (fs.existsSync(source)) {
77
- let target = path.join(this.encryptCodeDir, filepath);
78
- fsPro.copySync(source, target);
79
- }
80
- })
81
- } else {
82
- // 旧的逻辑,将废弃
83
- for (let i = 0; i < this.dirs.length; i++) {
84
- // check code dir
85
- let codeDirPath = path.join(this.basePath, this.dirs[i]);
86
- if (!fs.existsSync(codeDirPath)) {
87
- console.log('[ee-bin] [encrypt] ERROR: backup %s is not exist', codeDirPath);
88
- return
89
- }
90
-
91
- // copy
92
- let targetDir = path.join(this.encryptCodeDir, this.dirs[i]);
93
- console.log('[ee-bin] [encrypt] backup target Dir:', targetDir);
94
- if (!fs.existsSync(targetDir)) {
95
- this.mkdir(targetDir);
96
- this.chmodPath(targetDir, '777');
97
- }
98
-
99
- fsPro.copySync(codeDirPath, targetDir);
100
- }
101
- }
102
-
103
- console.log(chalk.blue('[ee-bin] [encrypt] ') + 'backup end');
104
- return true;
105
- }
106
-
107
- /**
108
- * 清除加密代码
109
- */
110
- cleanCode() {
111
- this.cleanFiles.forEach((file) => {
112
- let tmpFile = path.join(this.basePath, file);
113
- this.rmBackup(tmpFile);
114
- console.log(chalk.blue('[ee-bin] [encrypt] ') + 'clean up tmp files:' + chalk.magenta(`${tmpFile}`));
115
- })
116
- }
117
-
118
- /**
119
- * 加密代码
120
- */
121
- encrypt() {
122
- console.log(chalk.blue('[ee-bin] [encrypt] ') + 'start ciphering');
123
- if (this.patterns) {
124
- for (const file of this.codefiles) {
125
- const fullpath = path.join(this.encryptCodeDir, file);
126
- if (!fs.statSync(fullpath).isFile()) continue;
127
-
128
- // 特殊文件处理
129
- if (this.specificFiles.includes(file)) {
130
- this.generate(fullpath, 'confusion');
131
- continue;
132
- }
133
-
134
- this.generate(fullpath);
135
- }
136
- } else {
137
- // 旧逻辑,将废弃
138
- console.log('[ee-bin] [encrypt] !!!!!! please use the new encryption method !!!!!!');
139
- for (let i = 0; i < this.dirs.length; i++) {
140
- let codeDirPath = path.join(this.encryptCodeDir, this.dirs[i]);
141
- this.loop(codeDirPath);
142
- }
143
- console.log('[ee-bin] [encrypt] !!!!!! please use the new encryption method !!!!!!');
144
- }
145
-
146
- console.log(chalk.blue('[ee-bin] [encrypt] ') + 'end ciphering');
147
- };
148
-
149
- /**
150
- * 递归
151
- */
152
- loop(dirPath) {
153
- let files = [];
154
- if (fs.existsSync(dirPath)) {
155
- files = fs.readdirSync(dirPath);
156
- files.forEach((file, index) => {
157
- let curPath = dirPath + '/' + file;
158
- if (fs.statSync(curPath).isDirectory()) {
159
- this.loop(curPath);
160
- } else {
161
- const extname = path.extname(curPath);
162
- if (this.filesExt.indexOf(extname) !== -1) {
163
- this.generate(curPath);
164
- }
165
- }
166
- });
167
- }
168
- }
169
-
170
- /**
171
- * 生成文件
172
- */
173
- generate(curPath, type) {
174
- let encryptType = type ? type : this.type;
175
-
176
- let tips = chalk.blue('[ee-bin] [encrypt] ') + 'file: ' + chalk.green(`${curPath}`) + ' ' + chalk.cyan(`(${encryptType})`);
177
- console.log(tips);
178
-
179
- if (encryptType == 'bytecode') {
180
- this.generateBytecodeFile(curPath);
181
- } else if (encryptType == 'confusion') {
182
- this.generateJSConfuseFile(curPath);
183
- } else {
184
- this.generateJSConfuseFile(curPath);
185
- this.generateBytecodeFile(curPath);
186
- }
187
- }
188
-
189
- /**
190
- * 使用 javascript-obfuscator 生成压缩/混淆文件
191
- */
192
- generateJSConfuseFile(file) {
193
- let opt = Object.assign({
194
- compact: true,
195
- stringArray: true,
196
- stringArrayThreshold: 1,
197
- }, this.cOpt);
198
-
199
- let code = fs.readFileSync(file, "utf8");
200
- let result = JavaScriptObfuscator.obfuscate(code, opt);
201
- fs.writeFileSync(file, result.getObfuscatedCode(), "utf8");
202
- }
203
-
204
- /**
205
- * 生成字节码文件
206
- */
207
- generateBytecodeFile(curPath) {
208
- if (path.extname(curPath) !== '.js') {
209
- return
210
- }
211
- //let jscFile = curPath.replace(/.js/g, '.jsc');
212
- let jscFile = curPath + 'c';
213
- let opt = Object.assign({
214
- filename: curPath,
215
- output: jscFile,
216
- electron: true
217
- }, this.bOpt);
218
-
219
- bytenode.compileFile(opt);
220
-
221
- //fs.writeFileSync(curPath, 'require("bytenode");module.exports = require("./'+path.basename(jscFile)+'");', 'utf8');
222
-
223
- fsPro.removeSync(curPath);
224
- }
225
-
226
- /**
227
- * 移除备份
228
- */
229
- rmBackup(file) {
230
- if (fs.existsSync(file)) {
231
- fsPro.removeSync(file);
232
- }
233
- return;
234
- }
235
-
236
- /**
237
- * 检查文件是否存在
238
- */
239
- fileExist(filePath) {
240
- try {
241
- return fs.statSync(filePath).isFile();
242
- } catch (err) {
243
- return false;
244
- }
245
- };
246
-
247
- mkdir(dirpath, dirname) {
248
- // 判断是否是第一次调用
249
- if (typeof dirname === 'undefined') {
250
- if (fs.existsSync(dirpath)) {
251
- return;
252
- }
253
- this.mkdir(dirpath, path.dirname(dirpath));
254
- } else {
255
- // 判断第二个参数是否正常,避免调用时传入错误参数
256
- if (dirname !== path.dirname(dirpath)) {
257
- this.mkdir(dirpath);
258
- return;
259
- }
260
- if (fs.existsSync(dirname)) {
261
- fs.mkdirSync(dirpath);
262
- } else {
263
- this.mkdir(dirname, path.dirname(dirname));
264
- fs.mkdirSync(dirpath);
265
- }
266
- }
267
- };
268
-
269
- chmodPath(path, mode) {
270
- let files = [];
271
- if (fs.existsSync(path)) {
272
- files = fs.readdirSync(path);
273
- files.forEach((file, index) => {
274
- const curPath = path + '/' + file;
275
- if (fs.statSync(curPath).isDirectory()) {
276
- this.chmodPath(curPath, mode); // 递归删除文件夹
277
- } else {
278
- fs.chmodSync(curPath, mode);
279
- }
280
- });
281
- fs.chmodSync(path, mode);
282
- }
283
- };
284
-
285
- md5(file) {
286
- const buffer = fs.readFileSync(file);
287
- const hash = crypto.createHash('md5');
288
- hash.update(buffer, 'utf8');
289
- const str = hash.digest('hex');
290
- return str;
291
- }
292
- }
293
-
294
- const run = (options = {}) => {
295
- const e = new Encrypt(options);
296
- if (!e.backup()) return;
297
- e.encrypt();
298
- }
299
-
300
- const clean = (options = {}) => {
301
- let files = options.dir !== undefined ? options.dir : ['./public/electron'];
302
- files = is.string(files) ? [files] : files;
303
-
304
- files.forEach((file) => {
305
- const tmpFile = path.join(process.cwd(), file);
306
- if (fs.existsSync(tmpFile)) {
307
- fsPro.removeSync(tmpFile);
308
- console.log(chalk.blue('[ee-bin] [encrypt] ') + 'clean up tmp files: ' + chalk.magenta(`${tmpFile}`));
309
- }
310
- })
311
- }
312
-
313
- module.exports = {
314
- run,
315
- clean,
1
+ 'use strict';
2
+
3
+ const path = require('path');
4
+ const fs = require('fs');
5
+ const fsPro = require('fs-extra');
6
+ const is = require('is-type-of');
7
+ const bytenode = require('bytenode');
8
+ const crypto = require('crypto');
9
+ const JavaScriptObfuscator = require('javascript-obfuscator');
10
+ const globby = require('globby');
11
+ const chalk = require('chalk');
12
+ const Utils = require('../lib/utils');
13
+
14
+ class Encrypt {
15
+ constructor(options = {}) {
16
+ // cli args
17
+ const outputFolder = options.out || './public';
18
+ const configFile = options.config || './electron/config/bin.js';
19
+
20
+ this.basePath = process.cwd();
21
+ this.encryptCodeDir = path.join(this.basePath, outputFolder);
22
+
23
+ // 先从 bin config获取,没有的话从 config/encrypt.js
24
+ const hasConfig = Utils.checkConfig(configFile);
25
+ if (hasConfig) {
26
+ const cfg = Utils.loadConfig(configFile);
27
+ this.config = cfg.encrypt;
28
+ }
29
+ if (!this.config) {
30
+ this.config = Utils.loadEncryptConfig();
31
+ }
32
+
33
+ this.filesExt = this.config.fileExt || ['.js'];
34
+ this.type = this.config.type || 'confusion';
35
+ this.bOpt = this.config.bytecodeOptions || {};
36
+ this.cOpt = this.config.confusionOptions || {};
37
+ this.cleanFiles = this.config.cleanFiles || ['./public/electron'];
38
+ this.patterns = this.config.files || null;
39
+ this.specificFiles = [ 'electron/preload/bridge.js' ];
40
+
41
+ // 旧属性,将废弃
42
+ this.dirs = [];
43
+ const directory = this.config.directory || ['electron'];
44
+ for (let i = 0; i < directory.length; i++) {
45
+ let codeDirPath = path.join(this.basePath, directory[i]);
46
+ if (fs.existsSync(codeDirPath)) {
47
+ this.dirs.push(directory[i]);
48
+ }
49
+ }
50
+
51
+ this.codefiles = this._initCodeFiles();
52
+ console.log(chalk.blue('[ee-bin] [encrypt] ') + 'cleanFiles:' + this.cleanFiles);
53
+ }
54
+
55
+ /**
56
+ * 初始化需要加密的文件列表
57
+ */
58
+ _initCodeFiles() {
59
+ if (!this.patterns) return;
60
+
61
+ const files = globby.sync(this.patterns, { cwd: this.basePath });
62
+ return files;
63
+ }
64
+
65
+ /**
66
+ * 备份代码
67
+ */
68
+ backup() {
69
+ // clean
70
+ this.cleanCode();
71
+
72
+ console.log(chalk.blue('[ee-bin] [encrypt] ') + 'backup start');
73
+ if (this.patterns) {
74
+ this.codefiles.forEach((filepath) => {
75
+ let source = path.join(this.basePath, filepath);
76
+ if (fs.existsSync(source)) {
77
+ let target = path.join(this.encryptCodeDir, filepath);
78
+ fsPro.copySync(source, target);
79
+ }
80
+ })
81
+ } else {
82
+ // 旧的逻辑,将废弃
83
+ for (let i = 0; i < this.dirs.length; i++) {
84
+ // check code dir
85
+ let codeDirPath = path.join(this.basePath, this.dirs[i]);
86
+ if (!fs.existsSync(codeDirPath)) {
87
+ console.log('[ee-bin] [encrypt] ERROR: backup %s is not exist', codeDirPath);
88
+ return
89
+ }
90
+
91
+ // copy
92
+ let targetDir = path.join(this.encryptCodeDir, this.dirs[i]);
93
+ console.log('[ee-bin] [encrypt] backup target Dir:', targetDir);
94
+ if (!fs.existsSync(targetDir)) {
95
+ this.mkdir(targetDir);
96
+ this.chmodPath(targetDir, '777');
97
+ }
98
+
99
+ fsPro.copySync(codeDirPath, targetDir);
100
+ }
101
+ }
102
+
103
+ console.log(chalk.blue('[ee-bin] [encrypt] ') + 'backup end');
104
+ return true;
105
+ }
106
+
107
+ /**
108
+ * 清除加密代码
109
+ */
110
+ cleanCode() {
111
+ this.cleanFiles.forEach((file) => {
112
+ let tmpFile = path.join(this.basePath, file);
113
+ this.rmBackup(tmpFile);
114
+ console.log(chalk.blue('[ee-bin] [encrypt] ') + 'clean up tmp files:' + chalk.magenta(`${tmpFile}`));
115
+ })
116
+ }
117
+
118
+ /**
119
+ * 加密代码
120
+ */
121
+ encrypt() {
122
+ console.log(chalk.blue('[ee-bin] [encrypt] ') + 'start ciphering');
123
+ if (this.patterns) {
124
+ for (const file of this.codefiles) {
125
+ const fullpath = path.join(this.encryptCodeDir, file);
126
+ if (!fs.statSync(fullpath).isFile()) continue;
127
+
128
+ // 特殊文件处理
129
+ if (this.specificFiles.includes(file)) {
130
+ this.generate(fullpath, 'confusion');
131
+ continue;
132
+ }
133
+
134
+ this.generate(fullpath);
135
+ }
136
+ } else {
137
+ // 旧逻辑,将废弃
138
+ console.log('[ee-bin] [encrypt] !!!!!! please use the new encryption method !!!!!!');
139
+ for (let i = 0; i < this.dirs.length; i++) {
140
+ let codeDirPath = path.join(this.encryptCodeDir, this.dirs[i]);
141
+ this.loop(codeDirPath);
142
+ }
143
+ console.log('[ee-bin] [encrypt] !!!!!! please use the new encryption method !!!!!!');
144
+ }
145
+
146
+ console.log(chalk.blue('[ee-bin] [encrypt] ') + 'end ciphering');
147
+ };
148
+
149
+ /**
150
+ * 递归
151
+ */
152
+ loop(dirPath) {
153
+ let files = [];
154
+ if (fs.existsSync(dirPath)) {
155
+ files = fs.readdirSync(dirPath);
156
+ files.forEach((file, index) => {
157
+ let curPath = dirPath + '/' + file;
158
+ if (fs.statSync(curPath).isDirectory()) {
159
+ this.loop(curPath);
160
+ } else {
161
+ const extname = path.extname(curPath);
162
+ if (this.filesExt.indexOf(extname) !== -1) {
163
+ this.generate(curPath);
164
+ }
165
+ }
166
+ });
167
+ }
168
+ }
169
+
170
+ /**
171
+ * 生成文件
172
+ */
173
+ generate(curPath, type) {
174
+ let encryptType = type ? type : this.type;
175
+
176
+ let tips = chalk.blue('[ee-bin] [encrypt] ') + 'file: ' + chalk.green(`${curPath}`) + ' ' + chalk.cyan(`(${encryptType})`);
177
+ console.log(tips);
178
+
179
+ if (encryptType == 'bytecode') {
180
+ this.generateBytecodeFile(curPath);
181
+ } else if (encryptType == 'confusion') {
182
+ this.generateJSConfuseFile(curPath);
183
+ } else {
184
+ this.generateJSConfuseFile(curPath);
185
+ this.generateBytecodeFile(curPath);
186
+ }
187
+ }
188
+
189
+ /**
190
+ * 使用 javascript-obfuscator 生成压缩/混淆文件
191
+ */
192
+ generateJSConfuseFile(file) {
193
+ let opt = Object.assign({
194
+ compact: true,
195
+ stringArray: true,
196
+ stringArrayThreshold: 1,
197
+ }, this.cOpt);
198
+
199
+ let code = fs.readFileSync(file, "utf8");
200
+ let result = JavaScriptObfuscator.obfuscate(code, opt);
201
+ fs.writeFileSync(file, result.getObfuscatedCode(), "utf8");
202
+ }
203
+
204
+ /**
205
+ * 生成字节码文件
206
+ */
207
+ generateBytecodeFile(curPath) {
208
+ if (path.extname(curPath) !== '.js') {
209
+ return
210
+ }
211
+ //let jscFile = curPath.replace(/.js/g, '.jsc');
212
+ let jscFile = curPath + 'c';
213
+ let opt = Object.assign({
214
+ filename: curPath,
215
+ output: jscFile,
216
+ electron: true
217
+ }, this.bOpt);
218
+
219
+ bytenode.compileFile(opt);
220
+
221
+ //fs.writeFileSync(curPath, 'require("bytenode");module.exports = require("./'+path.basename(jscFile)+'");', 'utf8');
222
+
223
+ fsPro.removeSync(curPath);
224
+ }
225
+
226
+ /**
227
+ * 移除备份
228
+ */
229
+ rmBackup(file) {
230
+ if (fs.existsSync(file)) {
231
+ fsPro.removeSync(file);
232
+ }
233
+ return;
234
+ }
235
+
236
+ /**
237
+ * 检查文件是否存在
238
+ */
239
+ fileExist(filePath) {
240
+ try {
241
+ return fs.statSync(filePath).isFile();
242
+ } catch (err) {
243
+ return false;
244
+ }
245
+ };
246
+
247
+ mkdir(dirpath, dirname) {
248
+ // 判断是否是第一次调用
249
+ if (typeof dirname === 'undefined') {
250
+ if (fs.existsSync(dirpath)) {
251
+ return;
252
+ }
253
+ this.mkdir(dirpath, path.dirname(dirpath));
254
+ } else {
255
+ // 判断第二个参数是否正常,避免调用时传入错误参数
256
+ if (dirname !== path.dirname(dirpath)) {
257
+ this.mkdir(dirpath);
258
+ return;
259
+ }
260
+ if (fs.existsSync(dirname)) {
261
+ fs.mkdirSync(dirpath);
262
+ } else {
263
+ this.mkdir(dirname, path.dirname(dirname));
264
+ fs.mkdirSync(dirpath);
265
+ }
266
+ }
267
+ };
268
+
269
+ chmodPath(path, mode) {
270
+ let files = [];
271
+ if (fs.existsSync(path)) {
272
+ files = fs.readdirSync(path);
273
+ files.forEach((file, index) => {
274
+ const curPath = path + '/' + file;
275
+ if (fs.statSync(curPath).isDirectory()) {
276
+ this.chmodPath(curPath, mode); // 递归删除文件夹
277
+ } else {
278
+ fs.chmodSync(curPath, mode);
279
+ }
280
+ });
281
+ fs.chmodSync(path, mode);
282
+ }
283
+ };
284
+
285
+ md5(file) {
286
+ const buffer = fs.readFileSync(file);
287
+ const hash = crypto.createHash('md5');
288
+ hash.update(buffer, 'utf8');
289
+ const str = hash.digest('hex');
290
+ return str;
291
+ }
292
+ }
293
+
294
+ const run = (options = {}) => {
295
+ const e = new Encrypt(options);
296
+ if (!e.backup()) return;
297
+ e.encrypt();
298
+ }
299
+
300
+ const clean = (options = {}) => {
301
+ let files = options.dir !== undefined ? options.dir : ['./public/electron'];
302
+ files = is.string(files) ? [files] : files;
303
+
304
+ files.forEach((file) => {
305
+ const tmpFile = path.join(process.cwd(), file);
306
+ if (fs.existsSync(tmpFile)) {
307
+ fsPro.removeSync(tmpFile);
308
+ console.log(chalk.blue('[ee-bin] [encrypt] ') + 'clean up tmp files: ' + chalk.magenta(`${tmpFile}`));
309
+ }
310
+ })
311
+ }
312
+
313
+ module.exports = {
314
+ run,
315
+ clean,
316
316
  };