underpost 2.7.83 → 2.7.91

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.
Files changed (60) hide show
  1. package/.github/workflows/ghpkg.yml +41 -1
  2. package/.github/workflows/pwa-microservices-template.page.yml +54 -0
  3. package/.vscode/settings.json +7 -0
  4. package/CHANGELOG.md +64 -16
  5. package/bin/cron.js +47 -0
  6. package/bin/db.js +60 -7
  7. package/bin/deploy.js +345 -15
  8. package/bin/file.js +17 -1
  9. package/bin/index.js +1 -1
  10. package/bin/util.js +31 -1
  11. package/conf.js +18 -4
  12. package/docker-compose.yml +1 -1
  13. package/package.json +3 -3
  14. package/src/api/core/core.router.js +9 -9
  15. package/src/api/core/core.service.js +12 -4
  16. package/src/api/default/default.service.js +4 -4
  17. package/src/api/file/file.service.js +3 -3
  18. package/src/api/user/user.service.js +10 -8
  19. package/src/client/components/core/CommonJs.js +3 -0
  20. package/src/client/components/core/CssCore.js +30 -3
  21. package/src/client/components/core/Docs.js +110 -10
  22. package/src/client/components/core/LoadingAnimation.js +4 -2
  23. package/src/client/components/core/Modal.js +224 -22
  24. package/src/client/components/core/Panel.js +1 -1
  25. package/src/client/components/core/PanelForm.js +2 -1
  26. package/src/client/components/core/Responsive.js +34 -5
  27. package/src/client/components/core/RichText.js +4 -2
  28. package/src/client/components/core/WebComponent.js +44 -0
  29. package/src/client/components/core/Worker.js +13 -15
  30. package/src/client/public/default/plantuml/client-conf.svg +1 -1
  31. package/src/client/public/default/plantuml/client-schema.svg +1 -1
  32. package/src/client/public/default/plantuml/cron-conf.svg +1 -1
  33. package/src/client/public/default/plantuml/cron-schema.svg +1 -1
  34. package/src/client/public/default/plantuml/server-conf.svg +1 -1
  35. package/src/client/public/default/plantuml/server-schema.svg +1 -1
  36. package/src/client/public/default/plantuml/ssr-conf.svg +1 -1
  37. package/src/client/public/default/plantuml/ssr-schema.svg +1 -1
  38. package/src/client/public/default/site.webmanifest +69 -0
  39. package/src/client/ssr/components/body/CacheControl.js +1 -1
  40. package/src/client/ssr/components/head/Production.js +1 -0
  41. package/src/client/ssr/components/head/Pwa.js +146 -0
  42. package/src/client/ssr/components/head/Seo.js +14 -0
  43. package/src/client/ssr/pages/maintenance.js +14 -0
  44. package/src/client/ssr/pages/offline.js +21 -0
  45. package/src/client/sw/default.sw.js +4 -2
  46. package/src/db/DataBaseProvider.js +12 -1
  47. package/src/db/mongo/MongooseDB.js +0 -1
  48. package/src/runtime/lampp/Lampp.js +9 -9
  49. package/src/server/backup.js +82 -70
  50. package/src/server/client-build.js +46 -94
  51. package/src/server/conf.js +82 -18
  52. package/src/server/crypto.js +91 -0
  53. package/src/server/dns.js +48 -16
  54. package/src/server/network.js +94 -7
  55. package/src/server/proxy.js +27 -27
  56. package/src/server/runtime.js +4 -2
  57. package/src/server/ssl.js +2 -2
  58. package/src/client/ssr/offline/default.index.js +0 -31
  59. package/src/cron.js +0 -30
  60. package/src/server/cron.js +0 -35
@@ -0,0 +1,91 @@
1
+ import crypto from 'crypto';
2
+ import fs from 'fs-extra';
3
+
4
+ const CryptoBuilder = {
5
+ symmetric: {
6
+ instance: function (options = { iv: '', encryptionKey: '' }) {
7
+ // Generate a random 32-byte encryption key
8
+ const encryptionKey = option?.encryptionKey ? options.encryptionKey : crypto.randomBytes(32);
9
+ const iv = option?.iv ? options.iv : crypto.randomBytes(16); // Generate a new Initialization Vector (IV) for each encryption
10
+
11
+ // Function to encrypt data
12
+ function encryptData(plaintext = '') {
13
+ const cipher = crypto.createCipheriv('aes-256-cbc', encryptionKey, iv);
14
+ let encrypted = cipher.update(plaintext, 'utf8', 'hex');
15
+ encrypted += cipher.final('hex');
16
+ return `${iv.toString('hex')}:${encrypted}`;
17
+ }
18
+
19
+ // Function to decrypt data
20
+ function decryptData(ciphertext = '') {
21
+ const [ivHex, encrypted] = ciphertext.split(':');
22
+ const _iv = Buffer.from(ivHex, 'hex');
23
+ const decipher = crypto.createDecipheriv('aes-256-cbc', encryptionKey, _iv);
24
+ let decrypted = decipher.update(encrypted, 'hex', 'utf8');
25
+ decrypted += decipher.final('utf8');
26
+ return decrypted;
27
+ }
28
+
29
+ return {
30
+ encryptionKey,
31
+ iv,
32
+ encryptData,
33
+ decryptData,
34
+ };
35
+ },
36
+ },
37
+ asymmetric: {
38
+ instance: function (
39
+ options = {
40
+ publicKey: '', // fs.readFileSync('./key.pem', 'utf8')
41
+ privateKey: '', // fs.readFileSync('./key.pem', 'utf8')
42
+ },
43
+ ) {
44
+ // Generate a new key pair
45
+ const { privateKey, publicKey } = options
46
+ ? options
47
+ : crypto.generateKeyPairSync('rsa', {
48
+ modulusLength: 2048, // Key size in bits
49
+ publicKeyEncoding: {
50
+ type: 'spki',
51
+ format: 'pem',
52
+ },
53
+ privateKeyEncoding: {
54
+ type: 'pkcs8',
55
+ format: 'pem',
56
+ },
57
+ });
58
+
59
+ // Function to encrypt data
60
+ function encryptData(plaintext) {
61
+ const buffer = Buffer.from(plaintext, 'utf8');
62
+ const encrypted = crypto.publicEncrypt(publicKey, buffer);
63
+ return encrypted.toString('hex');
64
+ }
65
+
66
+ // Function to decrypt data
67
+ function decryptData(ciphertext) {
68
+ const buffer = Buffer.from(ciphertext, 'hex');
69
+ const decrypted = crypto.privateDecrypt(privateKey, buffer);
70
+ return decrypted.toString('utf8');
71
+ }
72
+
73
+ fs.writeFileSync('./public.pem', publicKey);
74
+ fs.writeFileSync('./private.pem', privateKey);
75
+
76
+ const result = {
77
+ privateKey: fs.readFileSync('./public.pem', 'utf8'),
78
+ publicKey: fs.readFileSync('./private.pem', 'utf8'),
79
+ encryptData,
80
+ decryptData,
81
+ };
82
+
83
+ fs.removeSync('./public.pem');
84
+ fs.removeSync('./private.pem');
85
+
86
+ return result;
87
+ },
88
+ },
89
+ };
90
+
91
+ export { CryptoBuilder };
package/src/server/dns.js CHANGED
@@ -1,38 +1,47 @@
1
1
  import axios from 'axios';
2
2
  import dotenv from 'dotenv';
3
3
  import fs from 'fs';
4
- import cron from 'node-cron';
4
+ import https from 'https';
5
5
 
6
6
  import { ip } from './network.js';
7
7
  import { loggerFactory } from './logger.js';
8
8
  import { isIPv4 } from 'is-ip';
9
+ import { shellExec } from './process.js';
10
+
11
+ const httpsAgent = new https.Agent({
12
+ rejectUnauthorized: false,
13
+ });
14
+
15
+ axios.defaults.httpsAgent = httpsAgent;
9
16
 
10
17
  dotenv.config();
11
18
 
12
19
  const logger = loggerFactory(import.meta);
13
20
 
14
21
  const Dns = {
15
- ip: null,
16
- ipDaemon: null,
22
+ repoUrl: `https://${process.env.GITHUB_TOKEN}@github.com/${process.env.GITHUB_USERNAME}/${process.env.GITHUB_DNS_REPO}.git`,
17
23
  callback: () => null,
18
- InitIpDaemon: async function () {
19
- // WAN | NAT-VPS | LAN
24
+ InitIpDaemon: async function ({ deployId }) {
25
+ // NAT-VPS modem/router device configuration:
26
+ // LAN --> [NAT-VPS] --> WAN
20
27
  // enabled DMZ Host to proxy IP 80-443 (79-444) sometimes router block first port
21
- // LAN server or device's local servers port -> 3000-3100 (2999-3101)
22
- // DNS Records: [ANAME](Address Dynamic) -> [A](ipv4) host | [AAAA](ipv6) host -> [ip]
28
+ // disabled local red DHCP
29
+ // verify inet ip proxy server address
23
30
  // DHCP (Dynamic Host Configuration Protocol) LAN reserver IP -> MAC ID
31
+ // LAN server or device's local servers port -> 3000-3100 (2999-3101)
32
+ // DNS Records: [ANAME](Address Dynamic) -> [A](ipv4) host | [AAAA](ipv6) host -> [public-ip]
24
33
  // Forward the router's TCP/UDP ports to the LAN device's IP address
25
34
 
26
- const privateCronConfPath = `./engine-private/conf/${process.argv[2]}/conf.cron.json`;
35
+ const privateCronConfPath = `./engine-private/conf/${deployId}/conf.cron.json`;
27
36
 
28
37
  const confCronPath = fs.existsSync(privateCronConfPath) ? privateCronConfPath : './conf/conf.cron.json';
29
-
30
38
  let confCronData = JSON.parse(fs.readFileSync(confCronPath, 'utf8'));
31
39
  if (confCronData.ipDaemon.disabled) return;
32
40
  Dns.ip = confCronData.ipDaemon.ip;
33
41
  logger.info(`Current ip`, Dns.ip);
34
- if (Dns.ipDaemon) clearInterval(Dns.ipDaemon);
35
42
  const callback = async () => {
43
+ logger.info('init dns ip callback');
44
+ await logger.setUpInfo();
36
45
  let testIp;
37
46
  try {
38
47
  testIp = await ip.public.ipv4();
@@ -41,15 +50,12 @@ const Dns = {
41
50
  }
42
51
  if (testIp && typeof testIp === 'string' && isIPv4(testIp) && Dns.ip !== testIp) {
43
52
  logger.info(`New ip`, testIp);
44
- Dns.ip = testIp;
45
- confCronData.ipDaemon.ip = Dns.ip;
46
- fs.writeFileSync(confCronPath, JSON.stringify(confCronData, null, 4), 'utf8');
47
53
  for (const recordType of Object.keys(confCronData.records)) {
48
54
  switch (recordType) {
49
55
  case 'A':
50
56
  for (const dnsProvider of confCronData.records[recordType]) {
51
57
  if (typeof Dns.services.updateIp[dnsProvider.dns] === 'function')
52
- await Dns.services.updateIp[dnsProvider.dns](dnsProvider);
58
+ await Dns.services.updateIp[dnsProvider.dns]({ ...dnsProvider, ip: testIp });
53
59
  }
54
60
  break;
55
61
 
@@ -57,16 +63,28 @@ const Dns = {
57
63
  break;
58
64
  }
59
65
  }
66
+ try {
67
+ const ipUrlTest = `https://${process.env.DEFAULT_DEPLOY_HOST}`;
68
+ const response = await axios.get(ipUrlTest);
69
+ const verifyIp = response.request.socket.remoteAddress;
70
+ logger.info(ipUrlTest + ' IP', verifyIp);
71
+ if (verifyIp === testIp) {
72
+ await this.saveIp(confCronPath, confCronData, testIp);
73
+ } else logger.error('ip not updated');
74
+ } catch (error) {
75
+ logger.error(error), 'ip not updated';
76
+ }
60
77
  }
61
78
  };
79
+ await callback();
62
80
  this.callback = callback;
63
81
  return callback;
64
82
  },
65
83
  services: {
66
84
  updateIp: {
67
85
  dondominio: (options) => {
68
- const { user, api_key, host, dns } = options;
69
- const url = `https://dondns.dondominio.com/json/?user=${user}&password=${api_key}&host=${host}&ip=${Dns.ip}`;
86
+ const { user, api_key, host, dns, ip } = options;
87
+ const url = `https://dondns.dondominio.com/json/?user=${user}&password=${api_key}&host=${host}&ip=${ip}`;
70
88
  logger.info(`${dns} update ip url`, url);
71
89
  if (process.env.NODE_ENV !== 'production') return false;
72
90
  return new Promise((resolve) => {
@@ -84,6 +102,20 @@ const Dns = {
84
102
  },
85
103
  },
86
104
  },
105
+ saveIp: async (confCronPath, confCronData, ip) => {
106
+ Dns.ip = ip;
107
+ confCronData.ipDaemon.ip = ip;
108
+ fs.writeFileSync(confCronPath, JSON.stringify(confCronData, null, 4), 'utf8');
109
+ shellExec(
110
+ `cd ./engine-private` +
111
+ ` && git pull ${Dns.repoUrl}` +
112
+ ` && git add . && git commit -m "update ip ${new Date().toLocaleDateString()}"` +
113
+ ` && git push ${Dns.repoUrl}`,
114
+ {
115
+ disableLog: true,
116
+ },
117
+ );
118
+ },
87
119
  };
88
120
 
89
121
  export { Dns };
@@ -5,6 +5,8 @@ import { publicIp, publicIpv4, publicIpv6 } from 'public-ip';
5
5
  import { killPortProcess } from 'kill-port-process';
6
6
  import { loggerFactory } from './logger.js';
7
7
  import { orderArrayFromAttrInt } from '../client/components/core/CommonJs.js';
8
+ import { DataBaseProvider } from '../db/DataBaseProvider.js';
9
+ import { getDeployId } from './conf.js';
8
10
 
9
11
  // Network Address Translation Management
10
12
 
@@ -66,12 +68,86 @@ const logRuntimeRouter = () => {
66
68
  logger.info('Runtime network', displayLog);
67
69
  };
68
70
 
69
- const saveRuntimeRouter = () =>
70
- fs.writeFileSync(
71
- `./tmp/runtime-router.${process.argv[3] ? process.argv[3] : 'default'}.json`,
72
- JSON.stringify(networkRouter, null, 4),
73
- 'utf-8',
74
- );
71
+ const saveRuntimeRouter = async () => {
72
+ try {
73
+ const deployId = process.env.DEFAULT_DEPLOY_ID;
74
+ const host = process.env.DEFAULT_DEPLOY_HOST;
75
+ const path = process.env.DEFAULT_DEPLOY_PATH;
76
+ const confServerPath = `./engine-private/conf/${deployId}/conf.server.json`;
77
+ const confServer = JSON.parse(fs.readFileSync(confServerPath, 'utf8'));
78
+ const { db } = confServer[host][path];
79
+
80
+ let closeConn;
81
+ if (!DataBaseProvider.instance[`${host}${path}`]) {
82
+ await DataBaseProvider.load({ apis: ['instance'], host, path, db });
83
+ closeConn = true;
84
+ }
85
+
86
+ /** @type {import('../api/instance/instance.model.js').InstanceModel} */
87
+ const Instance = DataBaseProvider.instance[`${host}${path}`].mongoose.models.Instance;
88
+
89
+ for (const _host of Object.keys(networkRouter)) {
90
+ for (const _path of Object.keys(networkRouter[_host])) {
91
+ const body = {
92
+ host: _host,
93
+ path: _path,
94
+ deployId: getDeployId(),
95
+ client: networkRouter[_host][_path].client,
96
+ runtime: networkRouter[_host][_path].runtime,
97
+ port: networkRouter[_host][_path].port,
98
+ apis: networkRouter[_host][_path].apis,
99
+ };
100
+ const instance = await Instance.findOne({ deployId: body.deployId, port: body.port });
101
+ if (instance) {
102
+ await Instance.findByIdAndUpdate(instance._id, body);
103
+ } else {
104
+ await new Instance(body).save();
105
+ }
106
+ }
107
+ }
108
+
109
+ if (closeConn) await DataBaseProvider.instance[`${host}${path}`].mongoose.close();
110
+ } catch (error) {
111
+ logger.error(error);
112
+ }
113
+ };
114
+
115
+ const netWorkCron = [];
116
+
117
+ const saveRuntimeCron = async () => {
118
+ try {
119
+ const deployId = process.env.DEFAULT_DEPLOY_ID;
120
+ const host = process.env.DEFAULT_DEPLOY_HOST;
121
+ const path = process.env.DEFAULT_DEPLOY_PATH;
122
+ const confServerPath = `./engine-private/conf/${deployId}/conf.server.json`;
123
+ const confServer = JSON.parse(fs.readFileSync(confServerPath, 'utf8'));
124
+ const { db } = confServer[host][path];
125
+
126
+ let closeConn;
127
+ if (!DataBaseProvider.instance[`${host}${path}`]) {
128
+ await DataBaseProvider.load({ apis: ['cron'], host, path, db });
129
+ closeConn = true;
130
+ }
131
+
132
+ /** @type {import('../api/cron/cron.model.js').CronModel} */
133
+ const Cron = DataBaseProvider.instance[`${host}${path}`].mongoose.models.Cron;
134
+
135
+ // await Cron.insertMany(netWorkCron);
136
+
137
+ for (const cronInstance of netWorkCron) {
138
+ const cron = await Cron.findOne({ deployId: cronInstance.deployId, jobId: cronInstance.jobId });
139
+ if (cron) {
140
+ await Cron.findByIdAndUpdate(cron._id, cronInstance);
141
+ } else {
142
+ await new Cron(cronInstance).save();
143
+ }
144
+ }
145
+
146
+ if (closeConn) await DataBaseProvider.instance[`${host}${path}`].mongoose.close();
147
+ } catch (error) {
148
+ logger.error(error);
149
+ }
150
+ };
75
151
 
76
152
  const listenServerFactory = (logic = async () => {}) => {
77
153
  return {
@@ -109,6 +185,7 @@ const listenPortController = async (server, port, metadata) =>
109
185
  ? `https://${host}${path}`
110
186
  : `http://${host}:${port}${path}`,
111
187
  local: `http://localhost:${port}${path}`,
188
+ apis: metadata.apis,
112
189
  };
113
190
 
114
191
  return resolve(true);
@@ -119,4 +196,14 @@ const listenPortController = async (server, port, metadata) =>
119
196
  }
120
197
  });
121
198
 
122
- export { ip, network, listenPortController, networkRouter, saveRuntimeRouter, logRuntimeRouter, listenServerFactory };
199
+ export {
200
+ ip,
201
+ network,
202
+ listenPortController,
203
+ networkRouter,
204
+ netWorkCron,
205
+ saveRuntimeRouter,
206
+ logRuntimeRouter,
207
+ listenServerFactory,
208
+ saveRuntimeCron,
209
+ };
@@ -9,7 +9,8 @@ import { loggerFactory, loggerMiddleware } from './logger.js';
9
9
  import { listenPortController, network } from './network.js';
10
10
  import { orderArrayFromAttrInt } from '../client/components/core/CommonJs.js';
11
11
  import { createSslServer, sslRedirectMiddleware } from './ssl.js';
12
- import { buildProxyRouter } from './conf.js';
12
+ import { buildProxyRouter, maintenanceMiddleware } from './conf.js';
13
+ import { getRootDirectory } from './process.js';
13
14
 
14
15
  dotenv.config();
15
16
 
@@ -25,6 +26,9 @@ const buildProxy = async () => {
25
26
  for (let port of Object.keys(proxyRouter)) {
26
27
  port = parseInt(port);
27
28
  const hosts = proxyRouter[port];
29
+ const proxyPath = '/';
30
+ const proxyHost = 'localhost';
31
+ const runningData = { host: proxyHost, path: proxyPath, client: null, runtime: 'nodejs', meta: import.meta };
28
32
  const app = express();
29
33
 
30
34
  // set logger
@@ -47,6 +51,7 @@ const buildProxy = async () => {
47
51
  onProxyReq: (proxyReq, req, res, options) => {
48
52
  // https://wtools.io/check-http-status-code
49
53
  // http://nexodev.org
54
+ maintenanceMiddleware(req, res, port, proxyRouter);
50
55
  sslRedirectMiddleware(req, res, port, proxyRouter);
51
56
  },
52
57
  pathRewrite: {
@@ -54,30 +59,27 @@ const buildProxy = async () => {
54
59
  // '^/target-path': '/',
55
60
  },
56
61
  };
57
-
58
- // build router
59
- Object.keys(hosts).map((hostKey) => {
60
- let { host, path, target, proxy, peer } = hosts[hostKey];
61
- if (process.env.NODE_ENV === 'development') host = `localhost`;
62
-
63
- if (!proxy.includes(port)) return;
64
- const absoluteHost = [80, 443].includes(port)
65
- ? `${host}${path === '/' ? '' : path}`
66
- : `${host}:${port}${path === '/' ? '' : path}`;
67
-
68
- if (!(absoluteHost in options.router)) options.router[absoluteHost] = target;
69
- });
70
- if (Object.keys(options.router).length === 0) continue;
71
-
72
- // order router
73
- const router = {};
74
- for (const absoluteHostKey of orderArrayFromAttrInt(Object.keys(options.router), 'length'))
75
- router[absoluteHostKey] = options.router[absoluteHostKey];
76
- options.router = router;
77
-
78
- // instance proxy server
79
- const proxyPath = '/';
80
- const proxyHost = 'localhost';
62
+ if (!process.argv.includes('maintenance')) {
63
+ // build router
64
+ Object.keys(hosts).map((hostKey) => {
65
+ let { host, path, target, proxy, peer } = hosts[hostKey];
66
+ if (process.env.NODE_ENV === 'development') host = `localhost`;
67
+
68
+ if (!proxy.includes(port)) return;
69
+ const absoluteHost = [80, 443].includes(port)
70
+ ? `${host}${path === '/' ? '' : path}`
71
+ : `${host}:${port}${path === '/' ? '' : path}`;
72
+
73
+ if (!(absoluteHost in options.router)) options.router[absoluteHost] = target;
74
+ });
75
+ if (Object.keys(options.router).length === 0) continue;
76
+
77
+ // order router
78
+ const router = {};
79
+ for (const absoluteHostKey of orderArrayFromAttrInt(Object.keys(options.router), 'length'))
80
+ router[absoluteHostKey] = options.router[absoluteHostKey];
81
+ options.router = router;
82
+ }
81
83
 
82
84
  const filter = false
83
85
  ? (pathname, req) => {
@@ -88,8 +90,6 @@ const buildProxy = async () => {
88
90
  app.use(proxyPath, createProxyMiddleware(filter, options));
89
91
  await network.port.portClean(port);
90
92
 
91
- const runningData = { host: proxyHost, path: proxyPath, client: null, runtime: 'nodejs', meta: import.meta };
92
-
93
93
  switch (process.env.NODE_ENV) {
94
94
  case 'production':
95
95
  switch (port) {
@@ -18,13 +18,14 @@ import { DataBaseProvider } from '../db/DataBaseProvider.js';
18
18
  import { createProxyMiddleware } from 'http-proxy-middleware';
19
19
  import { createPeerServer } from './peer.js';
20
20
  import { Lampp } from '../runtime/lampp/Lampp.js';
21
+ import { getDeployId } from './conf.js';
21
22
 
22
23
  dotenv.config();
23
24
 
24
25
  const logger = loggerFactory(import.meta);
25
26
 
26
27
  const buildRuntime = async () => {
27
- const deployId = `${process.argv[3] ? process.argv[3] : 'default'}`;
28
+ const deployId = getDeployId();
28
29
 
29
30
  const collectDefaultMetrics = promClient.collectDefaultMetrics;
30
31
  collectDefaultMetrics();
@@ -95,6 +96,7 @@ export PATH=$PATH:/opt/lampp/bin`,
95
96
  runtime,
96
97
  client,
97
98
  meta: import.meta,
99
+ apis,
98
100
  };
99
101
 
100
102
  let redirectUrl;
@@ -325,7 +327,7 @@ export PATH=$PATH:/opt/lampp/bin`,
325
327
  apis && process.env.NODE_ENV === 'development' ? [`http://localhost:${currentPort + 2}`] : [],
326
328
  ),
327
329
  };
328
- logger.info('originPayload', originPayload);
330
+ // logger.info('originPayload', originPayload);
329
331
  app.use(cors(originPayload));
330
332
 
331
333
  if (redirect) {
package/src/server/ssl.js CHANGED
@@ -16,7 +16,7 @@ const buildSSL = async (host) => {
16
16
  const files = await fs.readdir(sslPath);
17
17
 
18
18
  for (const folderHost of files)
19
- if (folderHost.match(host.split('/')[0])) {
19
+ if (folderHost.match(host.split('/')[0]) && host.split('.')[0] === folderHost.split('.')[0]) {
20
20
  for (const i of [''].concat(range(1, 10))) {
21
21
  const privateKeyPath = `${sslPath}/${folderHost}/privkey${i}.pem`;
22
22
  const certificatePath = `${sslPath}/${folderHost}/cert${i}.pem`;
@@ -51,7 +51,7 @@ const buildSSL = async (host) => {
51
51
  fs.writeFileSync(`./engine-private/ssl/${host}/_ca_bundle.crt`, ca, 'utf8');
52
52
  fs.writeFileSync(`./engine-private/ssl/${host}/_ca_full_bundle.crt`, caFull, 'utf8');
53
53
 
54
- // fs.removeSync(`${sslPath}/${folderHost}`);
54
+ fs.removeSync(`${sslPath}/${folderHost}`);
55
55
  return true;
56
56
  }
57
57
  }
@@ -1,31 +0,0 @@
1
- import { htmls, loggerFactory } from '../common/SsrCore.js';
2
- import { Alert } from '../common/Alert.js';
3
- import { Translate } from '../common/Translate.js';
4
- import { Worker } from '../common/Worker.js';
5
- /*imports*/
6
-
7
- const logger = loggerFactory({ url: '/offline.js' });
8
-
9
- window.onload = () =>
10
- Worker.instance({
11
- render: async () => {
12
- window.ononline = async () => {
13
- location.href = '/';
14
- };
15
- window.onoffline = async () => {
16
- htmls(`.page-render`, html`${await Alert.noInternet({ Translate })}`);
17
- };
18
- try {
19
- if (navigator.onLine) {
20
- const maintenance = await fetch(location.origin + '/favicon.ico');
21
- if (maintenance.status !== 200) {
22
- htmls(`.page-render`, html`${await Alert.maintenance({ Translate })}`);
23
- } else window.ononline();
24
- }
25
- throw new Error(`no internet connection`);
26
- } catch (error) {
27
- logger.error(error);
28
- window.onoffline();
29
- }
30
- },
31
- });
package/src/cron.js DELETED
@@ -1,30 +0,0 @@
1
- 'use strict';
2
-
3
- // https://nodejs.org/api
4
- // https://expressjs.com/en/4x/api.html
5
-
6
- import dotenv from 'dotenv';
7
- import { loggerFactory } from './server/logger.js';
8
- import { Dns } from './server/dns.js';
9
- import { ProcessController } from './server/process.js';
10
- import { Config } from './server/conf.js';
11
- import { BackUpManagement } from './server/backup.js';
12
- import { CronManagement } from './server/cron.js';
13
-
14
- dotenv.config();
15
-
16
- await Config.build();
17
-
18
- const logger = loggerFactory(import.meta);
19
-
20
- await logger.setUpInfo();
21
-
22
- // every minutes
23
- CronManagement.add('ip', '* * * * *', await Dns.InitIpDaemon());
24
-
25
- // every day at 1 am
26
- CronManagement.add('backup', '0 1 * * *', await BackUpManagement.Init());
27
-
28
- await CronManagement.init();
29
-
30
- ProcessController.init(logger);
@@ -1,35 +0,0 @@
1
- import cron from 'node-cron';
2
- import { loggerFactory } from './logger.js';
3
-
4
- const logger = loggerFactory(import.meta);
5
-
6
- const CronManagement = {
7
- data: {},
8
- init: function () {
9
- // verify tokens
10
- // https://github.com/settings/tokens
11
- for (const cronKey of Object.keys(this.data)) {
12
- if (this.data[cronKey].valid) {
13
- this.data[cronKey].task.start();
14
- logger.info(`Cron task "${this.data[cronKey].name}" started`);
15
- } else {
16
- logger.error(
17
- `Invalid cron expression "${this.data[cronKey].expression}" for task "${this.data[cronKey].name}"`,
18
- );
19
- }
20
- }
21
- },
22
- add: function (name = 'task', expression = '* * * * *', callback = async () => null) {
23
- const args = { name, expression, valid: cron.validate(expression) };
24
- this.data[name] = {
25
- ...args,
26
- task: cron.schedule(expression, callback, {
27
- scheduled: false,
28
- timezone: process.env.TIME_ZONE || 'America/New_York',
29
- name,
30
- }),
31
- };
32
- },
33
- };
34
-
35
- export { CronManagement };