biz-a-cli 2.3.57 → 2.3.59

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/acert/cert.pem ADDED
@@ -0,0 +1,30 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIFETCCA/mgAwIBAgISAy9vNfN4oz9jqfWTmMRu02nfMA0GCSqGSIb3DQEBCwUA
3
+ MDMxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQwwCgYDVQQD
4
+ EwNSMTAwHhcNMjQxMTAxMDg0OTE4WhcNMjUwMTMwMDg0OTE3WjAfMR0wGwYDVQQD
5
+ ExRmaW5hYXBpLmltYW1hdGVrLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
6
+ AQoCggEBAOyS1No1NffpYCX/Z42GTyKj7gUjH1zOfib3hzssMzik52bufQMhOOAQ
7
+ edoel4vpaIS3Lvlu7Fs3rvsNowKN6aumKubQ2f1Y0SPraPVgAn62IKruyp0LZERJ
8
+ LYyXeQKqAEoTtSttwSRQPKetMdt3ZqrMMrPESn8F+DRJu+UHYTuSD/EXoRgN7xws
9
+ /XRcZ0uwgdHzxbdb9Yu5nggRCVCeZxdys8rE6V0cwfhnL+OFEwIicuFjLVC39IFd
10
+ vTPUrsmHa8vI6UqihwbPcSPIZAGvTHAVd5MfdpohL68iyjnhA2h3k8/PGuB5r46+
11
+ w6sRehjee/6jBgbZ88v+H1N8kndi60UCAwEAAaOCAjEwggItMA4GA1UdDwEB/wQE
12
+ AwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIw
13
+ ADAdBgNVHQ4EFgQUxrXUYW+PB53gPR6a27Vk26uUOTkwHwYDVR0jBBgwFoAUu7zD
14
+ R6XkvKnGw6RyDBCNojXhyOgwVwYIKwYBBQUHAQEESzBJMCIGCCsGAQUFBzABhhZo
15
+ dHRwOi8vcjEwLm8ubGVuY3Iub3JnMCMGCCsGAQUFBzAChhdodHRwOi8vcjEwLmku
16
+ bGVuY3Iub3JnLzA5BgNVHREEMjAwghRmaW5hYXBpLmltYW1hdGVrLmNvbYIYd3d3
17
+ LmZpbmFhcGkuaW1hbWF0ZWsuY29tMBMGA1UdIAQMMAowCAYGZ4EMAQIBMIIBAwYK
18
+ KwYBBAHWeQIEAgSB9ASB8QDvAHYA5tIxY0B3jMEQQQbXcbnOwdJA9paEhvu6hzId
19
+ /R43jlAAAAGS5x+2PgAABAMARzBFAiAroNBzBHS3LSCNM6Dc/3TA5Ak0xoYLptQy
20
+ 9LBVBVKKtgIhANubgbJdUVh0ya/LFmB7JT18mHlfHju9ssF5vD0NZ8pUAHUAzxFW
21
+ 7tUufK/zh1vZaS6b6RpxZ0qwF+ysAdJbd87MOwgAAAGS5x+2gwAABAMARjBEAiAy
22
+ PilRRtrRLhmz7IL67cP4RKYXMn5Eu4X+CFJbDQe5mgIgfJhbmniYYZ6mZHzBKJAL
23
+ S3Py8Nci8LucQBQ7tEievO4wDQYJKoZIhvcNAQELBQADggEBAAtDQtiwYdREPpT0
24
+ HKJh9HvdkoYM1+r6/D+f4x2f3HYB9kY4S9xpgzMpWrPAoJHyUTiLBZkb3fMNe5z2
25
+ 3IJu+FwmIBRXM4+qLvAcqGaNmjWg+kXKeUv1oS3QDZ8dao8jjFtlnaPYv5moC17p
26
+ wb9nsj+oj3yQFvVXPgBEpDNBOGnPMNYPA9KEvHC0+E4pF7MbOcPgEV/c5eHEMmOY
27
+ yZTQV5nXDixLE9enFjKjiIlA0tZYCfXjuw1N4ohyrIvnL3ClagQvU5tnheWxndUI
28
+ xo7XFFAM9lTSqo09Yj43tyPGpYX3rSX6PwT81I1ih4FL/jh7C/kb9PfaZdLGK/Vg
29
+ nqkihj0=
30
+ -----END CERTIFICATE-----
package/acert/key.pem ADDED
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEogIBAAKCAQEA7JLU2jU19+lgJf9njYZPIqPuBSMfXM5+JveHOywzOKTnZu59
3
+ AyE44BB52h6Xi+lohLcu+W7sWzeu+w2jAo3pq6Yq5tDZ/VjRI+to9WACfrYgqu7K
4
+ nQtkREktjJd5AqoAShO1K23BJFA8p60x23dmqswys8RKfwX4NEm75QdhO5IP8Reh
5
+ GA3vHCz9dFxnS7CB0fPFt1v1i7meCBEJUJ5nF3KzysTpXRzB+Gcv44UTAiJy4WMt
6
+ ULf0gV29M9SuyYdry8jpSqKHBs9xI8hkAa9McBV3kx92miEvryLKOeEDaHeTz88a
7
+ 4Hmvjr7DqxF6GN57/qMGBtnzy/4fU3ySd2LrRQIDAQABAoIBAB+Wz6M/fbBX0kXg
8
+ n8QvDfwTJaI7+WEcFY5AeSc2lLRYmKmO6NR1KDILISo18Yh2J0WpbDVUUW0wt0XA
9
+ oWai6nPIIWxmsOT6ahrAwWgaZNrkmOIaNqXXspDHsLRYOYlYh+dcUFG3OxYNPLwr
10
+ DUA/5k6iK5cDe+sQMf9RZSyE2r/oVEzYpj06uv2pkmhQA1TBmSl2PNyvpBD+6+BW
11
+ 1va7PmsajEpul3jJEoprLPDyGt5cbwArjOfewUzTJhhuO5r64HdtbnV8DAAVF9Cb
12
+ 3Y3NCXnmION18U0nlGLZXWXRnzM2AxhkP4Rq0AVCZJEMsqxihaIhdoLnrUQwEGGu
13
+ V3SXV5UCgYEA+LS3fopOM0RORE3bkbdsjfgZebVBYZRxzHR45LNhO+AP6EVePnY7
14
+ JUJFhSa8VXx8ApK+J1jEEAZxuhX1AnKGa5XDci8z0lQiBMJX7Hw/AW39wWDoEP8e
15
+ VrwkG42zLN7IKyOStycbrV8IyqGsyGh7pPdiIcLuwKun+oBtkDBtFmMCgYEA84MG
16
+ Yb7WdSAUyD+tsNfYAieChqoQfh+9KM3CWO675FMAoxBNMLobaHqjOLPcQg6yAzs7
17
+ tRlIX1vA5Pfkhz1kiddb6d9NFDyxsoo6fSXR56KIMuNLadgvLi6mkAnZYbt4DT4s
18
+ TXjD4v/tYnRWZaftEEnGGD0RXvPU8UHozKgtNDcCgYBOhC8R4fQCN2RGKBZTkIbS
19
+ 4yqXw+NaPRUYKQUpnn/p+TjMaWnxaj4N6zgrayk2C9DStyUVIu7y6DXrO5dYKHPL
20
+ b0J+v+wqUKlUu04quKbjeqgL7t4Uz5XyZ/82O6v/VG35QIfHDq+sMj6CSjxUILg4
21
+ QmlWo0XgydCEQxtT1BX8ZQKBgAwJ5j7e2Gth8qUTwNqFUUCKA4H01mvl1cw2n+0V
22
+ oGRhVh65p5dJHCHGLluXSMRbRaGzQ/hoD5PnTVoEh1/IQTgvVXPyfjUJ6x8QhmO5
23
+ gu8YsfMSGaBZ97sow0NLuVuDkSPWdwo9djG6xVmgtsS/0JCFlS2Nl1ZCZ7ylrYSw
24
+ q8txAoGAF3C5BIh7oBrVvPF6QtsA4SS19JraupOz9S/YZIvqx8rpq0chtKtXntiO
25
+ j2526G0NPM9+tpl5sknRYQ7Aj712OQMT5RklE+H07UqEZYxFupZww5ccbT6QbZuf
26
+ Ug+Rh443tcKjhCMVcbvpLEhh0My2DucFOXlBtlFc0wO03snkR8k=
27
+ -----END RSA PRIVATE KEY-----
package/acert/root.pem ADDED
@@ -0,0 +1,29 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIFBTCCAu2gAwIBAgIQS6hSk/eaL6JzBkuoBI110DANBgkqhkiG9w0BAQsFADBP
3
+ MQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFy
4
+ Y2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMTAeFw0yNDAzMTMwMDAwMDBa
5
+ Fw0yNzAzMTIyMzU5NTlaMDMxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBF
6
+ bmNyeXB0MQwwCgYDVQQDEwNSMTAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
7
+ AoIBAQDPV+XmxFQS7bRH/sknWHZGUCiMHT6I3wWd1bUYKb3dtVq/+vbOo76vACFL
8
+ YlpaPAEvxVgD9on/jhFD68G14BQHlo9vH9fnuoE5CXVlt8KvGFs3Jijno/QHK20a
9
+ /6tYvJWuQP/py1fEtVt/eA0YYbwX51TGu0mRzW4Y0YCF7qZlNrx06rxQTOr8IfM4
10
+ FpOUurDTazgGzRYSespSdcitdrLCnF2YRVxvYXvGLe48E1KGAdlX5jgc3421H5KR
11
+ mudKHMxFqHJV8LDmowfs/acbZp4/SItxhHFYyTr6717yW0QrPHTnj7JHwQdqzZq3
12
+ DZb3EoEmUVQK7GH29/Xi8orIlQ2NAgMBAAGjgfgwgfUwDgYDVR0PAQH/BAQDAgGG
13
+ MB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATASBgNVHRMBAf8ECDAGAQH/
14
+ AgEAMB0GA1UdDgQWBBS7vMNHpeS8qcbDpHIMEI2iNeHI6DAfBgNVHSMEGDAWgBR5
15
+ tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAKG
16
+ Fmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0gBAwwCjAIBgZngQwBAgEwJwYD
17
+ VR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVuY3Iub3JnLzANBgkqhkiG9w0B
18
+ AQsFAAOCAgEAkrHnQTfreZ2B5s3iJeE6IOmQRJWjgVzPw139vaBw1bGWKCIL0vIo
19
+ zwzn1OZDjCQiHcFCktEJr59L9MhwTyAWsVrdAfYf+B9haxQnsHKNY67u4s5Lzzfd
20
+ u6PUzeetUK29v+PsPmI2cJkxp+iN3epi4hKu9ZzUPSwMqtCceb7qPVxEbpYxY1p9
21
+ 1n5PJKBLBX9eb9LU6l8zSxPWV7bK3lG4XaMJgnT9x3ies7msFtpKK5bDtotij/l0
22
+ GaKeA97pb5uwD9KgWvaFXMIEt8jVTjLEvwRdvCn294GPDF08U8lAkIv7tghluaQh
23
+ 1QnlE4SEN4LOECj8dsIGJXpGUk3aU3KkJz9icKy+aUgA+2cP21uh6NcDIS3XyfaZ
24
+ QjmDQ993ChII8SXWupQZVBiIpcWO4RqZk3lr7Bz5MUCwzDIA359e57SSq5CCkY0N
25
+ 4B6Vulk7LktfwrdGNVI5BsC9qqxSwSKgRJeZ9wygIaehbHFHFhcBaMDKpiZlBHyz
26
+ rsnnlFXCb5s8HKn5LsUgGvB24L7sGNZP2CX7dhHov+YhD+jozLW2p9W4959Bz2Ei
27
+ RmqDtmiXLnzqTpXbI+suyCsohKRg6Un0RC47+cpiVwHiXZAW+cn8eiNIjqbVgXLx
28
+ KPpdzvvtTnOPlC7SQZSYmdunr3Bf9b77AiC/ZidstK36dRILKz7OA54=
29
+ -----END CERTIFICATE-----
package/bin/app.js CHANGED
@@ -3,318 +3,217 @@
3
3
  import yargs from "yargs"
4
4
  import axios from "axios"
5
5
  import fs from "fs"
6
- import { runInNewContext } from "vm"
7
- import uglify from "uglify-js"
8
6
  import * as tar from "tar"
9
7
  import { verify, sign, privateDecrypt, constants as cryptoConstants, randomBytes, createCipheriv } from "node:crypto"
10
8
  import { basename } from "node:path"
11
9
  import { env } from "../envs/env.js"
12
- import * as vm from 'node:vm'
10
+ import { prepareScript, encryptScript } from "./script.js"
13
11
 
14
12
  const keyFolderPath = process.argv[1].substring(0, process.argv[1].lastIndexOf("\\bin")) + "\\key"
15
13
 
16
- yargs(process.argv.slice(2))
17
- .option("s", {
18
- alias: "server",
19
- describe: `Server URL (ex: ${env.BIZA_SERVER_LINK} or http://192.168.1.1 or https://finaapi.imamatek.com)`,
20
- type: "string",
21
- demandOption: true
22
- })
23
- .option("i", {
24
- alias: "dbIndex",
25
- default: 2,
26
- describe: "database index",
27
- type: "number",
28
- demandOption: false
29
- })
30
- .option("sub", {
31
- alias: "subdomain",
32
- describe: "Subdomain",
33
- type: "string",
34
- demandOption: false
35
- })
36
- .option("p", {
37
- alias: "apiPort",
38
- default : 212,
39
- describe: "FINA API Port",
40
- type: "number",
41
- demandOption: false,
42
- })
43
- .command('add', 'Add Biz-A Application',
44
- {
45
- 'd': {
46
- alias: "workingDir",
47
- describe: "Path to templates directory",
48
- type: "string",
49
- demandOption: false,
50
- default: process.cwd(),
51
- },
52
- 'v': {
53
- alias: "verbose",
54
- describe: "Print info to console",
55
- type: "boolean",
56
- demandOption: false,
57
- default: false,
58
- }
14
+ const options = {
15
+ "s" : {
16
+ alias: "server",
17
+ describe: `API or Server URL (ex: ${env.BIZA_SERVER_LINK} or http://192.168.1.1 or https://finaapi.imamatek.com)`,
18
+ type: "string",
19
+ demandOption: true,
20
+ default: 'http://localhost'
59
21
  },
60
- async (options)=>{
61
-
62
- function printInfo(msg){if (options.verbose) {console.log(msg)}}
63
-
64
- const prepareKeys = async ()=>{
65
- const data = Buffer.from(JSON.stringify({issuer: 'CLI', acquirer: 'Client'})).toString('base64')
66
- const privateKey = fs.readFileSync(`${keyFolderPath}\\cliPrivate.pem`)
67
- const signature = sign('sha256', data, {key: privateKey, passphrase: 'Biz-A@cli', padding: cryptoConstants.RSA_PKCS1_PSS_PADDING}).toString('base64')
68
- const res = await axios.get(env.BIZA_SERVER_LINK+'/api/issuerKey', {params: {data, signature}})
69
- if ((res.data.data!=null) && verify('sha256', res.data.data, {key: fs.readFileSync(`${keyFolderPath}\\serverPublic.pem`), padding: cryptoConstants.RSA_PKCS1_PSS_PADDING}, Buffer.from(res.data.signature, 'base64'))) {
70
- const resData = JSON.parse(Buffer.from(res.data.data, 'base64').toString())
71
- const decryptedAESKey = privateDecrypt({key: privateKey, passphrase: 'Biz-A@cli', padding: cryptoConstants.RSA_PKCS1_OAEP_PADDING}, Buffer.from(resData.issuer.key, 'base64')).toString()
72
- const cliSignature = (signedData)=>sign('sha256', signedData, {key: privateKey, passphrase: 'Biz-A@cli', padding: cryptoConstants.RSA_PKCS1_PSS_PADDING}).toString('base64')
73
- const acquirerData = Buffer.from(JSON.stringify(resData.acquirer)).toString('base64')
74
- const signature = cliSignature(acquirerData)
75
- return {encryptKey: decryptedAESKey, metadata: {acquirer: {data: acquirerData, signature}}}
76
- }
77
- else {
78
- return null
79
- }
80
- }
81
-
82
- function replacer(key, value) {
83
- /*
84
- // with line break
85
- if (typeof value == 'function') {
86
- let arr = value.toString().replace(/(\r\n|\n|\r)/gm, "°").split("°");
87
- if (arr.length < 3) throw 'Function must be minimal 3 lines';
88
- return [
89
- 'window.Function',
90
- getParam(arr[0]),
91
- arr.slice(1, arr.length - 1)
92
- ];
93
- } else {
94
- return value;
95
- }
96
- */
97
-
98
- // without line break
99
- if (typeof value == 'function') {
100
- const fnScript = value.toString()
101
- let params, body = ''
102
- if (fnScript.indexOf('{')==-1) {
103
- const arr = fnScript.split('=>')
104
- params = arr[0]
105
- body = arr.slice(1).join()
106
- } else {
107
- params = fnScript.split('{')[0]
108
- body = fnScript.substring(fnScript.indexOf('{')+1, fnScript.lastIndexOf('}'))
109
- }
110
- params = params.replace(/(\s|=>|\(|\)|function)/gim, '')
111
- printInfo(['window.Function', params, body])
112
- return ['window.Function', params, body]
113
- } else {
114
- return value;
115
- }
116
- }
117
-
118
- const minifiedIt = async (fileName) => {
119
- const dataFile = fs.readFileSync(fileName);
120
- printInfo(`===================\n${fileName.toUpperCase()}\n===================`)
121
-
122
- const minifyResult = uglify.minify(dataFile.toString(), {compress: false, mangle: false})
123
- if (minifyResult.error ) {throw (`${fileName}:${minifyResult.error.line}:${minifyResult.error.col}: ` + minifyResult.error)}
124
- let jsMinData = minifyResult.code
125
- jsMinData = jsMinData.replace('module.exports=get;', '') // Ex : at "executeBlockLib.js" of Imamatek App, will throw error. We need this line code for testing or debugging
126
- const minifiedBuffer = Buffer.from(jsMinData)
127
- printInfo(['Minify : \n', minifiedBuffer.toString()].join(''))
128
-
129
- let stringifyData = ''
130
- const isJsonFile = fileName.split('.').pop().toLowerCase().match(/^(json)$/)
131
-
132
- // compile using node.js VM
133
- try {
134
- printInfo('Running script with VM')
135
- if (isJsonFile) {
136
- const vmResult = runInNewContext(minifiedBuffer.toString())
137
- stringifyData = vmResult ? JSON.stringify((typeof vmResult=='function') ? vmResult() : (vmResult || ''), replacer) : ''
138
- } else {
139
- // for handling "get" function in local scope (let, var, const)
140
- const sandbox = vm.createContext({script: ''});
141
- vm.runInContext(
142
- minifiedBuffer.toString() + "\n script = (typeof get=='undefined') ? '' : (typeof get=='function') ? get() : (get||'')",
143
- sandbox
144
- )
145
- stringifyData = JSON.stringify(sandbox.script, replacer)
146
- }
147
- } catch (err){
148
- printInfo(`${fileName} : ` + err) // Do not log it as error, we will try to compile the script using ES6 Import
149
- stringifyData = ''
150
- }
151
-
152
- const isEmptyScript = (scriptText)=>((typeof scriptText=='undefined') || (scriptText===null) || (scriptText.trim()==='""') || (typeof scriptText=='string' && scriptText.trim().length==0))
153
-
154
- // compile using ES6 Import
155
- if (isEmptyScript(stringifyData)) {
156
- try {
157
- printInfo('Running script with Import function')
158
- const lib = await import(`file://${process.cwd()}\\${fileName}`, isJsonFile ? {assert: {type: "json"}} : {})
159
- stringifyData = JSON.stringify((typeof lib.default=='function') ? lib.default() : (lib.default || ''), replacer).replace(/ /g,'') // remove trailing whitespace
160
- // stringifyData = stringifyData.replace(/\\r\\n/g,'') // remove line break. We can not do this because "inline css" still requires line breaks
161
- } catch (error){
162
- throw(`${fileName} : ` + error)
163
- }
164
- }
165
-
166
- if (isEmptyScript(stringifyData)) {
167
- throw(`${fileName} : ` + 'Failed to compile template script.\nPlease make sure the script is correct and not returning empty result')
168
- } else {
169
- printInfo('Array function :')
170
- printInfo(['Stringify : \n', stringifyData].join(''))
171
- }
172
- // console.log('RESULT =>', stringifyData)
173
- printInfo('===================')
174
- return Buffer.from(stringifyData)
22
+ "i" : {
23
+ alias: "dbIndex",
24
+ default: 2,
25
+ describe: "database index",
26
+ type: "number",
27
+ demandOption: false
28
+ },
29
+ "sub": {
30
+ alias: "subdomain",
31
+ describe: "Subdomain",
32
+ type: "string",
33
+ demandOption: false
34
+ },
35
+ "p": {
36
+ alias: "apiPort",
37
+ default : 212,
38
+ describe: "FINA API Port",
39
+ type: "number",
40
+ demandOption: false,
41
+ }
42
+ }
43
+
44
+ const addCommandOptions = {
45
+ 'd': {
46
+ alias: "workingDir",
47
+ describe: "Path to templates directory",
48
+ type: "string",
49
+ demandOption: false,
50
+ default: process.cwd(),
51
+ },
52
+ 'v': {
53
+ alias: "verbose",
54
+ describe: "Print info to console",
55
+ type: "boolean",
56
+ demandOption: false,
57
+ default: false,
58
+ }
59
+ }
60
+
61
+ const removeCommandOptions = {
62
+ 'n': {
63
+ alias: "appName",
64
+ describe: "Application name",
65
+ type: "string",
66
+ demandOption: true,
67
+ default: ""
68
+ }
69
+ }
70
+
71
+ Object
72
+ .keys(options)
73
+ .reduce((app, optKey)=>app = app.option(optKey, options[optKey]), yargs(process.argv.slice(2)))
74
+ .command('add', 'Add Biz-A Application', addCommandOptions, async (options)=>{
75
+
76
+ const prepareKeys = async ()=>{
77
+ const data = Buffer.from(JSON.stringify({issuer: 'CLI', acquirer: 'Client'})).toString('base64')
78
+ const privateKey = fs.readFileSync(`${keyFolderPath}\\cliPrivate.pem`)
79
+ const signature = sign('sha256', data, {key: privateKey, passphrase: 'Biz-A@cli', padding: cryptoConstants.RSA_PKCS1_PSS_PADDING}).toString('base64')
80
+ const res = await axios.get(env.BIZA_SERVER_LINK+'/api/issuerKey', {params: {data, signature}})
81
+ if ((res.data.data!=null) && verify('sha256', res.data.data, {key: fs.readFileSync(`${keyFolderPath}\\serverPublic.pem`), padding: cryptoConstants.RSA_PKCS1_PSS_PADDING}, Buffer.from(res.data.signature, 'base64'))) {
82
+ const resData = JSON.parse(Buffer.from(res.data.data, 'base64').toString())
83
+ const decryptedAESKey = privateDecrypt({key: privateKey, passphrase: 'Biz-A@cli', padding: cryptoConstants.RSA_PKCS1_OAEP_PADDING}, Buffer.from(resData.issuer.key, 'base64')).toString()
84
+ const cliSignature = (signedData)=>sign('sha256', signedData, {key: privateKey, passphrase: 'Biz-A@cli', padding: cryptoConstants.RSA_PKCS1_PSS_PADDING}).toString('base64')
85
+ const acquirerData = Buffer.from(JSON.stringify(resData.acquirer)).toString('base64')
86
+ const signature = cliSignature(acquirerData)
87
+ return {encryptKey: decryptedAESKey, metadata: {acquirer: {data: acquirerData, signature}}}
175
88
  }
176
-
177
- const encryptIt = (data, encryptKey)=>{
178
- const initializeVector = randomBytes(16) // "iv" is unique for each template file
179
- const cipher = createCipheriv('aes-256-cbc', Buffer.from(encryptKey, 'base64'), initializeVector)
180
- return Buffer.concat([initializeVector, cipher.update(data), cipher.final()]) // we put "iv" at beginning of cipherText, seperate it when doing decryption
89
+ else {
90
+ return null
181
91
  }
92
+ }
182
93
 
183
- const compressIt = (fileName, folderPath)=>{
184
- // tar v7.1.0 -> tested 10x times, 2-3x times last compressed file have empty content
185
- // tar v.7.4.0 -> tested 1000x times, all files have content (used app.test.js)
186
- let compressSuccess = false
187
- const maxRetry = 10
188
- let retryCount = 0
189
- do {
190
- tar.c({file: fileName, cwd: folderPath, gzip: {level:9}, strict: true, sync: true}, fs.readdirSync(folderPath))
191
- compressSuccess = true
192
- tar.t({file: fileName, cwd: folderPath, sync: true, onentry: (entry)=>{
193
- if (entry.size==0) {
194
- compressSuccess = false
195
- }
196
- }})
197
- if (compressSuccess==false) {
198
- fs.unlinkSync(fileName)
199
- retryCount++
94
+ const compressIt = (fileName, folderPath)=>{
95
+ // tar v7.1.0 -> tested 10x times, 2-3x times last compressed file have empty content
96
+ // tar v.7.4.0 -> tested 1000x times, all files have content (used app.test.js)
97
+ let compressSuccess = false
98
+ const maxRetry = 10
99
+ let retryCount = 0
100
+ do {
101
+ tar.c({file: fileName, cwd: folderPath, gzip: {level:9}, strict: true, sync: true}, fs.readdirSync(folderPath))
102
+ compressSuccess = true
103
+ tar.t({file: fileName, cwd: folderPath, sync: true, onentry: (entry)=>{
104
+ if (entry.size==0) {
105
+ compressSuccess = false
200
106
  }
107
+ }})
108
+ if (compressSuccess==false) {
109
+ fs.unlinkSync(fileName)
110
+ retryCount++
201
111
  }
202
- while ((compressSuccess==false) && (retryCount<=maxRetry))
203
- }
204
-
205
- const getFileList = ()=>{
206
- return (fs.readdirSync(process.cwd())).filter((fileName)=>{
207
- const stat = fs.statSync(fileName)
208
- return stat.isFile() && (stat.size>0) && ((fileName.split('.').pop().toLowerCase().match(/^(js)$/) || (fileName.toLowerCase()=='menu.json')))
209
- })
210
112
  }
113
+ while ((compressSuccess==false) && (retryCount<=maxRetry))
114
+ }
211
115
 
212
- async function addApp() {
213
- /*
214
- hex => 2 char = 1 bytes => can be encrypted
215
- base64 => 4 char = 3 bytes => can be encrypted. Smaller size compare to Hex
216
- utf8 => 1 char = 1 - 4 bytes => can not be encrypted, encryption need precise bytes per Character. Smallest Size compare to Hex and base64
217
- */
218
- process.chdir(options.workingDir)
219
- try {
220
- const bundlingStart = performance.now()
221
- const rootFolder = './upload/'
222
- const bundleName = basename(process.cwd()).trim().replace(' ', '').toLowerCase()
223
- const bundleFolder = rootFolder+bundleName+'/'
224
- const files = getFileList()
225
- if (files.length>0) {
226
- const keys = await prepareKeys()
227
- let processedFile = 0
228
- fs.rmSync(rootFolder, {force: true, recursive: true})
229
- fs.mkdirSync(bundleFolder, {recursive: true})
230
- for (const file of files) {
231
- const fileName = file.toLowerCase();
232
- // if (['finalib.js', 'solib.js'].indexOf(fileName)==-1) {continue}
233
- const minifiedData = await minifiedIt(fileName);
234
- const encryptedData = encryptIt(minifiedData, keys.encryptKey)
235
- if (fileName=='menu.json') {
236
- keys.metadata['menu'] = encryptedData.toString('base64')
237
- } else {
238
- fs.writeFileSync(bundleFolder+fileName, encryptedData.toString('base64'))
239
- }
240
- processedFile++
241
- }
242
- const bundleFile = `${rootFolder}${bundleName}.tgz`
243
- compressIt(bundleFile, bundleFolder)
244
- console.log(`Finished packing ${processedFile} files into "${bundleFile}" (${((performance.now()-bundlingStart)/1000).toFixed(2)}s)`)
116
+ const getFileList = ()=>{
117
+ return (fs.readdirSync(process.cwd())).filter((fileName)=>{
118
+ const stat = fs.statSync(fileName)
119
+ return stat.isFile() && (stat.size>0) && ((fileName.split('.').pop().toLowerCase().match(/^(js)$/) || (fileName.toLowerCase()=='menu.json')))
120
+ })
121
+ }
245
122
 
246
- // send to FINAPI
247
- const uploadingStart = performance.now()
248
- const data = (fs.readFileSync(bundleFile)).toString('base64') // *.tgz to base64String
249
- const baseUrl = 'fina/rest/TOrmMethod/%22setApp%22'
250
- const url = options.sub ?
251
- `${options.server}/hub/${baseUrl}?subdomain=${options.sub}` :
252
- `${options.server}:${options.apiPort}/${baseUrl}`
253
- const headers = {'Content-Type': 'text/plain'}
254
- const param = { _parameters: [options.dbIndex, bundleName, data, keys.metadata] }
255
- const res = await axios.post(url, param, { headers: headers });
256
- if (res.data.success) {
257
- console.log(`Finished uploading "${bundleFile}" (${((performance.now()-uploadingStart)/1000).toFixed(2)}s)`)
258
- fs.rmSync(rootFolder, {force: true, recursive: true})
123
+ async function addApp() {
124
+ /*
125
+ hex => 2 char = 1 bytes => can be encrypted
126
+ base64 => 4 char = 3 bytes => can be encrypted. Smaller size compare to Hex
127
+ utf8 => 1 char = 1 - 4 bytes => can not be encrypted, encryption need precise bytes per Character. Smallest Size compare to Hex and base64
128
+ */
129
+ process.chdir(options.workingDir)
130
+ try {
131
+ const bundlingStart = performance.now()
132
+ const rootFolder = './upload/'
133
+ const bundleName = basename(process.cwd()).trim().replace(' ', '').toLowerCase()
134
+ const bundleFolder = rootFolder+bundleName+'/'
135
+ const files = getFileList()
136
+ if (files.length>0) {
137
+ const keys = await prepareKeys()
138
+ let processedFile = 0
139
+ fs.rmSync(rootFolder, {force: true, recursive: true})
140
+ fs.mkdirSync(bundleFolder, {recursive: true})
141
+ for (const file of files) {
142
+ const fileName = file.toLowerCase();
143
+ const encryptedScript = encryptScript(await prepareScript(fileName, fs.readFileSync(fileName).toString(), options.verbose), keys.encryptKey)
144
+ if (fileName=='menu.json') {
145
+ keys.metadata['menu'] = encryptedScript.toString('base64')
259
146
  } else {
260
- console.error(res.data.error)
147
+ fs.writeFileSync(bundleFolder+fileName, encryptedScript.toString('base64'))
261
148
  }
262
- } else {
263
- console.error('Nothing to upload. Please recheck your app folder.')
264
- }
265
- } catch (e) {
266
- console.error(e.response?.data ? e.response.data : e)
267
- // console.error({e})
268
- }
269
- }
270
149
 
271
- await addApp()
272
- }
273
- )
274
- .command('remove', 'Remove Biz-A Application',
275
- {
276
- 'n': {
277
- alias: "appName",
278
- describe: "Application name",
279
- type: "string",
280
- demandOption: true,
281
- default: ""
282
- }
283
- },
284
- (options)=>{
285
- (async () => {
286
- try {
287
- const baseUrl = 'fina/rest/TOrmMethod/%22deleteApp%22'
150
+ processedFile++
151
+ }
152
+ const bundleFile = `${rootFolder}${bundleName}.tgz`
153
+ compressIt(bundleFile, bundleFolder)
154
+ console.log(`Finished packing ${processedFile} files into "${bundleFile}" (${((performance.now()-bundlingStart)/1000).toFixed(2)}s)`)
155
+
156
+ // send to API
157
+ const uploadingStart = performance.now()
158
+ const data = (fs.readFileSync(bundleFile)).toString('base64') // *.tgz to base64String
159
+ const baseUrl = 'fina/rest/TOrmMethod/%22setApp%22'
288
160
  const url = options.sub ?
289
161
  `${options.server}/hub/${baseUrl}?subdomain=${options.sub}` :
290
162
  `${options.server}:${options.apiPort}/${baseUrl}`
291
163
  const headers = {'Content-Type': 'text/plain'}
292
- const deleteApps = options.appName.trim().replaceAll(' ', '').toLowerCase()
293
- const param = { _parameters: [options.dbIndex, deleteApps] }
164
+ const param = { _parameters: [options.dbIndex, bundleName, data, keys.metadata] }
294
165
  const res = await axios.post(url, param, { headers: headers });
295
- if (res.data?.success) {
296
- if (deleteApps=='') {
297
- console.log('All apps removed')
298
- } else {
299
- const failedList = (res.data._f && (typeof res.data._f=='string')) ? res.data._f.trim().replaceAll(' ', '').toLowerCase().split(',') : []
300
- const removeList = deleteApps.split(',')
301
- removeList.forEach((app)=>{
302
- console.log(`${app} ${failedList.indexOf(app)==-1 ? 'removed' : 'not found'}`)
303
- })
304
- }
166
+ if (res.data.success) {
167
+ console.log(`Finished uploading "${bundleFile}" (${((performance.now()-uploadingStart)/1000).toFixed(2)}s)`)
168
+ fs.rmSync(rootFolder, {force: true, recursive: true})
305
169
  } else {
306
170
  console.error(res.data.error)
307
171
  }
308
- return res
309
- } catch (e) {
310
- const errMsg = (e.response?.data ? e.response.data : e)
311
- console.error(errMsg)
312
- return errMsg
172
+ } else {
173
+ console.error('Nothing to upload. Please recheck your app folder.')
313
174
  }
314
- })()
175
+ } catch (e) {
176
+ console.error(e.response?.data ? e.response.data : e)
177
+ }
315
178
  }
316
- )
179
+
180
+ await addApp()
181
+ })
182
+ .command('remove', 'Remove Biz-A Application', removeCommandOptions, (options)=>{
183
+ (async () => {
184
+ try {
185
+ const baseUrl = 'fina/rest/TOrmMethod/%22deleteApp%22'
186
+ const url = options.sub ?
187
+ `${options.server}/hub/${baseUrl}?subdomain=${options.sub}` :
188
+ `${options.server}:${options.apiPort}/${baseUrl}`
189
+ const headers = {'Content-Type': 'text/plain'}
190
+ const deleteApps = options.appName.trim().replaceAll(' ', '').toLowerCase()
191
+ const param = { _parameters: [options.dbIndex, deleteApps] }
192
+ const res = await axios.post(url, param, { headers: headers });
193
+ if (res.data?.success) {
194
+ if (deleteApps=='') {
195
+ console.log('All apps removed')
196
+ } else {
197
+ const failedList = (res.data._f && (typeof res.data._f=='string')) ? res.data._f.trim().replaceAll(' ', '').toLowerCase().split(',') : []
198
+ const removeList = deleteApps.split(',')
199
+ removeList.forEach((app)=>{
200
+ console.log(`${app} ${failedList.indexOf(app)==-1 ? 'removed' : 'not found'}`)
201
+ })
202
+ }
203
+ } else {
204
+ console.error(res.data.error)
205
+ }
206
+ return res
207
+ } catch (e) {
208
+ const errMsg = (e.response?.data ? e.response.data : e)
209
+ console.error(errMsg)
210
+ return errMsg
211
+ }
212
+ })()
213
+ })
317
214
  .recommendCommands()
318
215
  .demandCommand(1, 'You need at least one command before moving on')
319
216
  .strict()
320
- .parse();
217
+ .parse();
218
+
219
+ export {options, addCommandOptions, removeCommandOptions}
package/bin/debug.log ADDED
@@ -0,0 +1,8 @@
1
+ [0605/214853.957:ERROR:registration_protocol_win.cc(108)] CreateFile: The system cannot find the file specified. (0x2)
2
+ [0605/214854.309:ERROR:registration_protocol_win.cc(108)] CreateFile: The system cannot find the file specified. (0x2)
3
+ [0605/214858.135:ERROR:registration_protocol_win.cc(108)] CreateFile: The system cannot find the file specified. (0x2)
4
+ [0605/214858.290:ERROR:registration_protocol_win.cc(108)] CreateFile: The system cannot find the file specified. (0x2)
5
+ [0605/220244.156:ERROR:registration_protocol_win.cc(108)] CreateFile: The system cannot find the file specified. (0x2)
6
+ [0605/220244.455:ERROR:registration_protocol_win.cc(108)] CreateFile: The system cannot find the file specified. (0x2)
7
+ [0605/220248.011:ERROR:registration_protocol_win.cc(108)] CreateFile: The system cannot find the file specified. (0x2)
8
+ [0605/220248.180:ERROR:registration_protocol_win.cc(108)] CreateFile: The system cannot find the file specified. (0x2)