biz-a-cli 2.3.43 → 2.3.52
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/bin/directHubEvent.js +57 -0
- package/bin/hub.js +64 -21
- package/bin/hubEvent.js +71 -20
- package/mailController.js +1 -1
- package/package.json +5 -4
- package/readme.md +22 -1
- package/scheduler/datalib.js +1 -7
- package/tests/data.test.js +5 -14
- package/tests/mailCtl.test.js +4 -4
- package/bin/log/debug.log +0 -33
- package/bin/log/error.log +0 -33
- package/bin/log/exception.log +0 -0
- package/bin/log/info.log +0 -33
- package/bin/node +0 -0
- package/log/debug.log +0 -1
- package/log/error.log +0 -1
- package/log/exception.log +0 -0
- package/log/info.log +0 -1
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import axios from 'axios'
|
|
2
|
+
import { IDLE_SOCKET_TIMEOUT_MILLISECONDS } from './hubEvent.js'
|
|
3
|
+
import { Tunnel as QuickTunnel } from 'cloudflared'
|
|
4
|
+
|
|
5
|
+
export async function localhostTunnel(port){
|
|
6
|
+
function notifyUser(){
|
|
7
|
+
console.log(`${new Date()}: Direct hub only available within local LAN. Please restart CLI to try again.`)
|
|
8
|
+
}
|
|
9
|
+
const qt = QuickTunnel.quick('127.0.0.1:'+port)
|
|
10
|
+
qt.on('Disconnected', ()=>{console.log('DISCONNECTED');notifyUser()})
|
|
11
|
+
let url = await new Promise((resolve)=>{
|
|
12
|
+
let tunnelURL = ''
|
|
13
|
+
qt.once('url', (qtUrl)=>{console.log('URL obtained');tunnelURL=qtUrl})
|
|
14
|
+
qt.once('connected', (conn)=>{console.log('CONNECTED', conn); resolve(tunnelURL)})
|
|
15
|
+
qt.once('exit', (code)=>{resolve('')})
|
|
16
|
+
qt.once('error', (err)=>{resolve('')})
|
|
17
|
+
})
|
|
18
|
+
if (!url) {
|
|
19
|
+
notifyUser()
|
|
20
|
+
}
|
|
21
|
+
return url
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function directHubEvent(serverSocket, argv){
|
|
25
|
+
serverSocket.on('connection', (clientSocket) => {
|
|
26
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
27
|
+
console.log('BizA Client Socket', clientSocket.id)
|
|
28
|
+
clientSocket.on('disconnect', (reason)=>{console.log(`Socket ${clientSocket.id} disconnected. Reason : ${reason}`)})
|
|
29
|
+
}
|
|
30
|
+
clientSocket.on('APISocket', (reqData, resCB)=>{
|
|
31
|
+
const socketResponse = (resp)=>{return {status: resp.status, statusText: resp.statusText, headers: resp.headers, body: resp.data, url: `${argv['hostname']}:${argv['port']+resp.config.url}`}}
|
|
32
|
+
if (argv['subdomain'].localeCompare(reqData.subDomain)==0) {
|
|
33
|
+
const apiAddress = `${argv['secure']==true ? 'https://' : 'http://'}${argv['hostname']}:${argv['port']}`
|
|
34
|
+
axios.request({
|
|
35
|
+
timeout: IDLE_SOCKET_TIMEOUT_MILLISECONDS,
|
|
36
|
+
baseURL: apiAddress,
|
|
37
|
+
url: reqData.path,
|
|
38
|
+
method: reqData.method,
|
|
39
|
+
headers: reqData.headers,
|
|
40
|
+
data: reqData.body,
|
|
41
|
+
// decompress: false, // if we need to interfered default Agent compression
|
|
42
|
+
responseType: reqData.responseType,
|
|
43
|
+
maxContentLength: Infinity,
|
|
44
|
+
})
|
|
45
|
+
.then(response=>{
|
|
46
|
+
resCB(null, socketResponse(response))
|
|
47
|
+
})
|
|
48
|
+
.catch(error=>{
|
|
49
|
+
resCB(error, null)
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
resCB({status: 401, statusText: 'bad subdomain', url: `${argv['hostname']}:${argv['port']+reqData.path}`}, null)
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
}
|
package/bin/hub.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import yargs from 'yargs';
|
|
4
|
-
import { io as
|
|
4
|
+
import { io as ioClient } from "socket.io-client";
|
|
5
5
|
import hubEvent from './hubEvent.js'
|
|
6
6
|
import { createLogger, transports, format } from "winston";
|
|
7
|
+
import { Server as ioServer } from 'socket.io'
|
|
8
|
+
import os from 'node:os'
|
|
9
|
+
import { directHubEvent, localhostTunnel }from './directHubEvent.js'
|
|
7
10
|
|
|
8
11
|
const logger = createLogger({
|
|
9
12
|
level: 'info',
|
|
@@ -27,7 +30,7 @@ process.on('unhandledRejection', (err) => { //debug
|
|
|
27
30
|
logger.error('Unhandled Rejection:', err)
|
|
28
31
|
});
|
|
29
32
|
|
|
30
|
-
const
|
|
33
|
+
const defaultPort = 3002;
|
|
31
34
|
const argv = yargs(process.argv.slice(2))
|
|
32
35
|
.usage('Usage: $0 [options]')
|
|
33
36
|
.options('s', {
|
|
@@ -39,34 +42,46 @@ const argv = yargs(process.argv.slice(2))
|
|
|
39
42
|
})
|
|
40
43
|
.options('sub', {
|
|
41
44
|
alias: 'subdomain',
|
|
42
|
-
describe: '
|
|
45
|
+
describe: 'Public URL the tunnel server is forwarding to us',
|
|
43
46
|
type: 'string',
|
|
44
47
|
demandOption: true
|
|
45
48
|
})
|
|
46
49
|
.options('h', {
|
|
47
50
|
alias: 'hostname',
|
|
48
51
|
default: '127.0.0.1',
|
|
49
|
-
describe: '
|
|
52
|
+
describe: 'Address of API server for forwarding over socket-tunnel. Please emit "HTTP" or "HTTPS" from address',
|
|
50
53
|
type: 'string',
|
|
51
54
|
demandOption: true
|
|
52
55
|
})
|
|
53
|
-
.options('d', {
|
|
54
|
-
alias: 'dbindex',
|
|
55
|
-
default: 2,
|
|
56
|
-
describe: '(Required) Biz-A Database Index (Callback Feature)',
|
|
57
|
-
type: 'number',
|
|
58
|
-
demandOption: false
|
|
59
|
-
})
|
|
60
56
|
.options('p', {
|
|
61
57
|
alias: 'port',
|
|
62
58
|
default: 212,
|
|
63
|
-
describe: 'Port of
|
|
59
|
+
describe: 'Port of API server for forwarding over socket-tunnel',
|
|
60
|
+
type: 'number',
|
|
61
|
+
demandOption: false
|
|
62
|
+
})
|
|
63
|
+
.options('secure', {
|
|
64
|
+
default: false,
|
|
65
|
+
describe: 'Is API server using ssl (HTTPS) ?',
|
|
66
|
+
type: 'boolean',
|
|
67
|
+
demandOption: false
|
|
68
|
+
})
|
|
69
|
+
.options('publish', {
|
|
70
|
+
default: true,
|
|
71
|
+
describe: 'Will the CLI be published to the internet??',
|
|
72
|
+
type: 'boolean',
|
|
73
|
+
demandOption: false
|
|
74
|
+
})
|
|
75
|
+
.options('d', {
|
|
76
|
+
alias: 'dbindex',
|
|
77
|
+
default: 2,
|
|
78
|
+
describe: 'Biz-A Database Index (Callback Feature)',
|
|
64
79
|
type: 'number',
|
|
65
80
|
demandOption: false
|
|
66
81
|
})
|
|
67
82
|
.options('sp', {
|
|
68
83
|
alias: 'serverport',
|
|
69
|
-
default:
|
|
84
|
+
default: defaultPort,
|
|
70
85
|
describe: 'Express Port (Callback Feature)',
|
|
71
86
|
type: 'number',
|
|
72
87
|
demandOption: false
|
|
@@ -89,12 +104,15 @@ if (!argv['server'] || !argv['subdomain'] || !argv['port']) {
|
|
|
89
104
|
}
|
|
90
105
|
}
|
|
91
106
|
|
|
92
|
-
//
|
|
93
107
|
import express from 'express';
|
|
94
108
|
import compression from 'compression';
|
|
95
109
|
import cors from 'cors';
|
|
96
110
|
const app = express();
|
|
97
111
|
import { runCliScript } from '../callbackController.js'
|
|
112
|
+
import fs from "fs"
|
|
113
|
+
import http from 'http'
|
|
114
|
+
import https from 'https'
|
|
115
|
+
import path from 'node:path'
|
|
98
116
|
|
|
99
117
|
app.use(compression());
|
|
100
118
|
app.use(cors());
|
|
@@ -102,17 +120,42 @@ app.use(express.json({ limit: '100mb' }));
|
|
|
102
120
|
|
|
103
121
|
app.set('args', argv);
|
|
104
122
|
|
|
105
|
-
|
|
106
123
|
app.use('/cb', runCliScript);
|
|
107
124
|
|
|
108
|
-
|
|
109
|
-
|
|
125
|
+
|
|
126
|
+
// create HTTP(s) Server
|
|
127
|
+
const keyFile = path.join(import.meta.dirname, "../cert/key.pem")
|
|
128
|
+
const certFile = path.join(import.meta.dirname, "../cert/cert.pem")
|
|
129
|
+
const rootFile = path.join(import.meta.dirname, "../cert/root.pem")
|
|
130
|
+
const isHttps = (fs.existsSync(keyFile) && fs.existsSync(certFile) && fs.existsSync(rootFile))
|
|
131
|
+
const getProtocol = ()=>(isHttps ? 'Https://' : 'Http://')
|
|
132
|
+
let server = isHttps ? https.createServer({key: fs.readFileSync(keyFile), cert: fs.readFileSync(certFile), ca: fs.readFileSync(rootFile),}, app) : http.createServer(app)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
// publish CLI with tunnel
|
|
136
|
+
argv.publicUrl = (argv.publish==true) ? await localhostTunnel(argv.serverport) : ''
|
|
137
|
+
|
|
138
|
+
// prepare CLI Address
|
|
139
|
+
argv.cliAddress = ()=>{
|
|
140
|
+
const ip = Object.values(os.networkInterfaces()).flat().reduce((ip, {family, address, internal})=> ip || !internal && family==='IPv4' && address, undefined)
|
|
141
|
+
return {ip, port: argv.serverport, address: `${ip}:${argv.serverport}`, publicUrl: argv.publicUrl}
|
|
142
|
+
}
|
|
143
|
+
const cliAddress = argv.cliAddress()
|
|
144
|
+
server.listen(argv.serverport, () => {
|
|
145
|
+
console.log(`${new Date()}: CLI is listening at ${getProtocol() + (process.env.HOST || cliAddress.ip || 'localhost')}:${cliAddress.port} `);
|
|
110
146
|
});
|
|
111
|
-
//
|
|
112
147
|
|
|
113
|
-
let socket = ioc(argv['server']);
|
|
114
|
-
hubEvent(socket, argv);
|
|
115
148
|
|
|
116
|
-
|
|
149
|
+
// BizA CLI as socket client to BizA SERVER
|
|
150
|
+
await hubEvent(ioClient(argv['server'], {query: {cliAddress: cliAddress.address }}), argv);
|
|
151
|
+
console.log(`${new Date()}: CLI connected to BizA Server using sub domain "${argv['subdomain']}"`)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
// BizA CLI as socket server for BizA CLIENT
|
|
155
|
+
const serverCORSOrigin = ['https://biz-a.id', 'https://test.biz-a.id', /\.biz-a\.id$/].concat((process.env.NODE_ENV === 'production') ? [] : [`http://${cliAddress.ip}:4200`, 'http://localhost:4200'])
|
|
156
|
+
// console.log('Allowed Origins', serverCORSOrigin)
|
|
157
|
+
directHubEvent(new ioServer(server, {cors: {origin: serverCORSOrigin}}), argv)
|
|
158
|
+
console.log(`${new Date()}: CLI is listening at "${cliAddress.publicUrl ? cliAddress.publicUrl : cliAddress.address}"`)
|
|
159
|
+
|
|
117
160
|
|
|
118
161
|
export { app }
|
package/bin/hubEvent.js
CHANGED
|
@@ -1,62 +1,112 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import net from 'node:net';
|
|
3
|
+
import tls from 'node:tls';
|
|
3
4
|
import { createRequire } from "module";
|
|
4
5
|
const require = createRequire(import.meta.url);
|
|
5
6
|
const ss = require('socket.io-stream'); //SCY: Temporary, next will be replaced with import
|
|
7
|
+
import { Transform } from 'node:stream'
|
|
8
|
+
// import { pipeline } from 'node:stream'
|
|
6
9
|
|
|
7
|
-
const IDLE_SOCKET_TIMEOUT_MILLISECONDS = 1000 * 30;
|
|
10
|
+
export const IDLE_SOCKET_TIMEOUT_MILLISECONDS = 1000 * 30;
|
|
11
|
+
|
|
12
|
+
export const socketAgent = isUsingHttps=>(isUsingHttps==true) ? tls : net
|
|
8
13
|
|
|
9
14
|
export default async (socket, argv) => new Promise((resolve, reject) => {
|
|
15
|
+
|
|
10
16
|
const connectCb = () => {
|
|
11
|
-
console.log(new Date() + ': connected to
|
|
12
|
-
console.log(new Date() + ': requesting subdomain ' + argv['subdomain'] + ' via ' + argv['server']);
|
|
17
|
+
// console.log(new Date() + ': connected to BizA Server');
|
|
18
|
+
// console.log(new Date() + ': requesting subdomain ' + argv['subdomain'] + ' via ' + argv['server']);
|
|
13
19
|
|
|
14
20
|
socket.emit('createTunnel', argv['subdomain'], (err) => {
|
|
15
21
|
if (err) {
|
|
16
22
|
console.log(new Date() + ': [error] ' + err);
|
|
17
23
|
reject(err);
|
|
18
24
|
} else {
|
|
19
|
-
console.log(new Date() + ': registered with server successfully');
|
|
25
|
+
// console.log(new Date() + ': registered with server successfully');
|
|
20
26
|
|
|
21
|
-
// clean and concat requested url
|
|
22
|
-
let url;
|
|
23
|
-
// let subdomain = argv['subdomain'].toString();
|
|
24
|
-
let server = argv['server'].toString();
|
|
27
|
+
// // clean and concat requested url
|
|
28
|
+
// let url;
|
|
29
|
+
// // let subdomain = argv['subdomain'].toString();
|
|
30
|
+
// let server = argv['server'].toString();
|
|
25
31
|
|
|
26
|
-
url = server;
|
|
32
|
+
// url = server;
|
|
27
33
|
|
|
28
|
-
// resolve promise with requested URL
|
|
29
|
-
resolve(url);
|
|
34
|
+
// // resolve promise with requested URL
|
|
35
|
+
// resolve(url);
|
|
36
|
+
|
|
37
|
+
resolve(argv['server'].toString());
|
|
30
38
|
}
|
|
31
39
|
});
|
|
32
40
|
}
|
|
41
|
+
|
|
33
42
|
const incomingHubCb = (clientId) => {
|
|
34
|
-
console.log(clientId, 'incoming clientId')
|
|
35
|
-
|
|
43
|
+
// console.log(clientId, 'incoming clientId')
|
|
44
|
+
|
|
45
|
+
let addCLIAddressAsResponseHeader = new Transform({
|
|
46
|
+
transform(chunk, encoding, next){
|
|
47
|
+
const apiResponse = chunk.toString().toLowerCase()
|
|
48
|
+
const cliAddress = argv.cliAddress()
|
|
49
|
+
if ( (apiResponse.indexOf('200 ok') > -1) && (apiResponse.indexOf('server: datasnaphttpservice') > -1) && (cliAddress.publicUrl || cliAddress.address)) {
|
|
50
|
+
// don't use string to insert additional headers, chunk can have mixed content of string and binary data
|
|
51
|
+
const response = Buffer.from(chunk)
|
|
52
|
+
const delimiter = '\r\n\r\n'
|
|
53
|
+
const delimiterPos = response.indexOf(delimiter)
|
|
54
|
+
const header = Buffer.concat([
|
|
55
|
+
Buffer.copyBytesFrom(response, 0, delimiterPos),
|
|
56
|
+
Buffer.from(
|
|
57
|
+
'\r\n' +
|
|
58
|
+
'Access-Control-Expose-Headers: biza-cli-address\r\n' +
|
|
59
|
+
`biza-cli-address: ${cliAddress.publicUrl ? cliAddress.publicUrl : cliAddress.address}\r\n` +
|
|
60
|
+
'\r\n'
|
|
61
|
+
)
|
|
62
|
+
])
|
|
63
|
+
const body = (response.length>delimiterPos+delimiter.length) ? Buffer.copyBytesFrom(response, delimiterPos+4) : Buffer.from('')
|
|
64
|
+
this.push(body.length>0 ? Buffer.concat([header, body]) : header)
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
this.push(chunk)
|
|
68
|
+
}
|
|
69
|
+
next()
|
|
70
|
+
}
|
|
71
|
+
})
|
|
36
72
|
|
|
73
|
+
// let client = net.connect(argv['port'], argv['hostname']);
|
|
74
|
+
let client = socketAgent(argv['secure']).connect(argv['port'], argv['hostname']);
|
|
37
75
|
client.on('connect', () => {
|
|
38
|
-
console.log(`client connected to ${argv['hostname']}:${argv['port']}`)
|
|
76
|
+
// console.log(`client connected to ${argv['hostname']}:${argv['port']}`)
|
|
39
77
|
let s = ss.createStream();
|
|
40
|
-
|
|
78
|
+
|
|
79
|
+
// s.pipe(client).pipe(s);
|
|
80
|
+
s.pipe(client).pipe(addCLIAddressAsResponseHeader).pipe(s)
|
|
81
|
+
|
|
82
|
+
// use pipeline for better performance, back pressure, memory management, error handling and clean up
|
|
83
|
+
// pipeline(s, client, addCLIAddressAsResponseHeader, s, (err)=>{if (err) {console.error(err)}}) // Not work well with heroku
|
|
41
84
|
|
|
42
85
|
s.on('end', () => {
|
|
43
|
-
client.destroy()
|
|
44
|
-
})
|
|
86
|
+
client.destroy()
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
socket.once(clientId, ()=>{ // hub server shall notify us to end pipeline as soon as possible
|
|
90
|
+
client.end()
|
|
91
|
+
})
|
|
92
|
+
|
|
45
93
|
ss(socket).emit(clientId, s);
|
|
46
94
|
})
|
|
47
95
|
|
|
48
96
|
client.setTimeout(IDLE_SOCKET_TIMEOUT_MILLISECONDS);
|
|
49
|
-
client.on('timeout', () => {
|
|
50
|
-
client.end()
|
|
97
|
+
client.on('timeout', () => { // in case client not notify to end pipeline, then inactivity timeout will end it
|
|
98
|
+
client.end()
|
|
51
99
|
});
|
|
52
100
|
|
|
53
|
-
client.on('error', () => {
|
|
101
|
+
client.on('error', (err) => {
|
|
54
102
|
// handle connection refusal (create a stream and immediately close it)
|
|
103
|
+
console.error('API Error : ', err)
|
|
55
104
|
let s = ss.createStream();
|
|
56
105
|
ss(socket).emit(clientId, s);
|
|
57
106
|
s.end();
|
|
58
107
|
});
|
|
59
108
|
}
|
|
109
|
+
|
|
60
110
|
const cliReqCb = async (data, callback) => {
|
|
61
111
|
const { path, method, ...remainData } = data;
|
|
62
112
|
|
|
@@ -67,6 +117,7 @@ export default async (socket, argv) => new Promise((resolve, reject) => {
|
|
|
67
117
|
})
|
|
68
118
|
callback(result.data);
|
|
69
119
|
}
|
|
120
|
+
|
|
70
121
|
socket.on('connect', connectCb);
|
|
71
122
|
socket.on('incomingClient', incomingHubCb)
|
|
72
123
|
socket.on('cli-req', cliReqCb);
|
package/mailController.js
CHANGED
|
@@ -6,7 +6,7 @@ function createEmailTransport(req, config) {
|
|
|
6
6
|
);
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export async function
|
|
9
|
+
export async function sendMailCliScript(req) {
|
|
10
10
|
try {
|
|
11
11
|
const transporter = createEmailTransport(req, req.body.config);
|
|
12
12
|
const sendResult = await transporter.sendMail(req.body.mailOptions);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "biz-a-cli",
|
|
3
3
|
"nameDev": "biz-a-cli-dev",
|
|
4
|
-
"version": "2.3.
|
|
4
|
+
"version": "2.3.52",
|
|
5
5
|
"versionDev": "0.0.30",
|
|
6
6
|
"description": "",
|
|
7
7
|
"main": "bin/index.js",
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
"biza": "bin/app.js"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"axios": "^1.
|
|
31
|
+
"axios": "^1.7.8",
|
|
32
|
+
"cloudflared": "^0.6.0",
|
|
32
33
|
"compression": "^1.7.5",
|
|
33
34
|
"cors": "^2.8.5",
|
|
34
35
|
"dayjs": "^1.11.10",
|
|
@@ -36,6 +37,7 @@
|
|
|
36
37
|
"mongodb": "^6.5.0",
|
|
37
38
|
"net": "^1.0.2",
|
|
38
39
|
"nodemailer": "^6.9.12",
|
|
40
|
+
"socket.io": "^4.7.5",
|
|
39
41
|
"socket.io-client": "^4.7.5",
|
|
40
42
|
"socket.io-stream": "^0.9.1",
|
|
41
43
|
"tar": "^7.4.0",
|
|
@@ -45,8 +47,7 @@
|
|
|
45
47
|
"yargs": "^17.7.2"
|
|
46
48
|
},
|
|
47
49
|
"devDependencies": {
|
|
48
|
-
"jest": "^29.7.0"
|
|
49
|
-
"socket.io": "^4.7.5"
|
|
50
|
+
"jest": "^29.7.0"
|
|
50
51
|
},
|
|
51
52
|
"jest": {
|
|
52
53
|
"transform": {},
|
package/readme.md
CHANGED
|
@@ -61,4 +61,25 @@
|
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
> [!CAUTION]
|
|
64
|
-
> **The *uploadBizA*, *uploadApp*, *deleteApp* commands are deprecated and will be removed in the future.**
|
|
64
|
+
> **The *uploadBizA*, *uploadApp*, *deleteApp* commands are deprecated and will be removed in the future.**
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
## III. Hub
|
|
68
|
+
|
|
69
|
+
### a. Using HTTP
|
|
70
|
+
hub --server [BizA Hub Server] --sub [subdomain] --hostname [ip_API] --port [port_API]
|
|
71
|
+
|
|
72
|
+
Example :
|
|
73
|
+
hub --server https://biz-a.herokuapp.com --sub imamatek --hostname localhost --port 212
|
|
74
|
+
|
|
75
|
+
### b. Using HTTPs (SSL)
|
|
76
|
+
hub --server [BizA Hub Server] --sub [subdomain] --hostname [ip_API] --port [port_API] --secure
|
|
77
|
+
|
|
78
|
+
Example :
|
|
79
|
+
hub --server https://biz-a.herokuapp.com --sub imamatek --hostname localhost --port 212 --secure
|
|
80
|
+
|
|
81
|
+
### c. Publish Hub
|
|
82
|
+
hub --server [BizA Hub Server] --sub [subdomain] --hostname [ip_API] --port [port_API] --publish [true]
|
|
83
|
+
|
|
84
|
+
Example :
|
|
85
|
+
hub --server https://biz-a.herokuapp.com --sub imamatek --hostname localhost --port 212 --publish=false
|
package/scheduler/datalib.js
CHANGED
|
@@ -221,13 +221,7 @@ export function getInputData(config, trigger) {
|
|
|
221
221
|
dbindex: config.dbindex,
|
|
222
222
|
finaDbIndex: config.finaDbIndex,
|
|
223
223
|
subdomain: config.subdomain,
|
|
224
|
-
smtp:
|
|
225
|
-
user: config.smtp.auth.user,
|
|
226
|
-
pass: config.smtp.auth.pass,
|
|
227
|
-
host: config.smtp.host,
|
|
228
|
-
port: config.smtp.port,
|
|
229
|
-
secure: config.smtp.secure
|
|
230
|
-
}
|
|
224
|
+
smtp: config.smtp
|
|
231
225
|
},
|
|
232
226
|
body: trigger.data
|
|
233
227
|
}
|
package/tests/data.test.js
CHANGED
|
@@ -112,21 +112,12 @@ describe('data test', () => {
|
|
|
112
112
|
arguments: {
|
|
113
113
|
hostname: 'localhost',
|
|
114
114
|
port: 212,
|
|
115
|
-
dbindex:
|
|
116
|
-
finaDbIndex:
|
|
117
|
-
subdomain:
|
|
118
|
-
smtp:
|
|
119
|
-
user: 'abc',
|
|
120
|
-
pass: '123',
|
|
121
|
-
host: 'mail.imamatek.com',
|
|
122
|
-
port: 465,
|
|
123
|
-
secure: true
|
|
124
|
-
}
|
|
115
|
+
dbindex: config.dbindex,
|
|
116
|
+
finaDbIndex: config.finaDbIndex,
|
|
117
|
+
subdomain: config.subdomain,
|
|
118
|
+
smtp: config.smtp
|
|
125
119
|
},
|
|
126
|
-
body:
|
|
127
|
-
_id: 1,
|
|
128
|
-
name: 'New Watcher 1'
|
|
129
|
-
}
|
|
120
|
+
body: trigger.data
|
|
130
121
|
});
|
|
131
122
|
});
|
|
132
123
|
|
package/tests/mailCtl.test.js
CHANGED
|
@@ -11,12 +11,12 @@ jest.unstable_mockModule('nodemailer', () => ({
|
|
|
11
11
|
createTransport: (data) => mockCreateTransport(data)
|
|
12
12
|
}))
|
|
13
13
|
|
|
14
|
-
const {
|
|
14
|
+
const { sendMailCliScript } = await import('../mailController.js');
|
|
15
15
|
|
|
16
16
|
describe('Mail Controller', () => {
|
|
17
17
|
let req;
|
|
18
18
|
|
|
19
|
-
test('transporter.
|
|
19
|
+
test('transporter.sendMailCliScript is called', async () => {
|
|
20
20
|
req = {
|
|
21
21
|
body: {
|
|
22
22
|
companyname: 'abc',
|
|
@@ -27,12 +27,12 @@ describe('Mail Controller', () => {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
mockSendMail.mockResolvedValue('OK');
|
|
30
|
-
expect(await
|
|
30
|
+
expect(await sendMailCliScript(req)).toEqual('OK');
|
|
31
31
|
expect(mockSendMail).toBeCalledTimes(1);
|
|
32
32
|
expect(mockCreateTransport).toHaveBeenCalledWith({ smtp: 'test' });
|
|
33
33
|
|
|
34
34
|
mockSendMail.mockRejectedValue({ message: 'error' });
|
|
35
|
-
expect(await
|
|
35
|
+
expect(await sendMailCliScript(req)).toEqual('error');
|
|
36
36
|
|
|
37
37
|
expect(mockSendMail).toBeCalledTimes(2);
|
|
38
38
|
})
|