underpost 2.7.81 → 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.
- package/.github/workflows/ghpkg.yml +41 -1
- package/.github/workflows/publish.yml +17 -18
- package/.github/workflows/pwa-microservices-template.page.yml +54 -0
- package/.vscode/settings.json +7 -0
- package/CHANGELOG.md +64 -16
- package/bin/cron.js +47 -0
- package/bin/db.js +60 -7
- package/bin/deploy.js +345 -15
- package/bin/file.js +17 -1
- package/bin/index.js +1 -1
- package/bin/util.js +31 -1
- package/conf.js +18 -4
- package/docker-compose.yml +1 -1
- package/package.json +3 -3
- package/src/api/core/core.router.js +9 -9
- package/src/api/core/core.service.js +12 -4
- package/src/api/default/default.service.js +4 -4
- package/src/api/file/file.service.js +3 -3
- package/src/api/user/user.service.js +10 -8
- package/src/client/components/core/CommonJs.js +3 -0
- package/src/client/components/core/CssCore.js +30 -3
- package/src/client/components/core/Docs.js +110 -10
- package/src/client/components/core/LoadingAnimation.js +4 -2
- package/src/client/components/core/Modal.js +224 -22
- package/src/client/components/core/Panel.js +1 -1
- package/src/client/components/core/PanelForm.js +2 -1
- package/src/client/components/core/Responsive.js +34 -5
- package/src/client/components/core/RichText.js +4 -2
- package/src/client/components/core/WebComponent.js +44 -0
- package/src/client/components/core/Worker.js +13 -15
- package/src/client/public/default/plantuml/client-conf.svg +1 -1
- package/src/client/public/default/plantuml/client-schema.svg +1 -1
- package/src/client/public/default/plantuml/cron-conf.svg +1 -1
- package/src/client/public/default/plantuml/cron-schema.svg +1 -1
- package/src/client/public/default/plantuml/server-conf.svg +1 -1
- package/src/client/public/default/plantuml/server-schema.svg +1 -1
- package/src/client/public/default/plantuml/ssr-conf.svg +1 -1
- package/src/client/public/default/plantuml/ssr-schema.svg +1 -1
- package/src/client/public/default/site.webmanifest +69 -0
- package/src/client/ssr/components/body/CacheControl.js +1 -1
- package/src/client/ssr/components/head/Production.js +1 -0
- package/src/client/ssr/components/head/Pwa.js +146 -0
- package/src/client/ssr/components/head/Seo.js +14 -0
- package/src/client/ssr/pages/maintenance.js +14 -0
- package/src/client/ssr/pages/offline.js +21 -0
- package/src/client/sw/default.sw.js +4 -2
- package/src/db/DataBaseProvider.js +12 -1
- package/src/db/mongo/MongooseDB.js +0 -1
- package/src/runtime/lampp/Lampp.js +9 -9
- package/src/server/backup.js +82 -70
- package/src/server/client-build.js +46 -94
- package/src/server/conf.js +82 -18
- package/src/server/crypto.js +91 -0
- package/src/server/dns.js +48 -16
- package/src/server/network.js +94 -7
- package/src/server/proxy.js +27 -27
- package/src/server/runtime.js +4 -2
- package/src/server/ssl.js +2 -2
- package/src/client/ssr/offline/default.index.js +0 -31
- package/src/cron.js +0 -30
- package/src/server/cron.js +0 -35
package/bin/deploy.js
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
Cmd,
|
|
26
26
|
restoreMacroDb,
|
|
27
27
|
fixDependencies,
|
|
28
|
+
setUpProxyMaintenanceServer,
|
|
28
29
|
} from '../src/server/conf.js';
|
|
29
30
|
import { buildClient } from '../src/server/client-build.js';
|
|
30
31
|
import { range, setPad, timer, uniqueArray } from '../src/client/components/core/CommonJs.js';
|
|
@@ -32,6 +33,8 @@ import toJsonSchema from 'to-json-schema';
|
|
|
32
33
|
import simpleGit from 'simple-git';
|
|
33
34
|
import { MongooseDB } from '../src/db/mongo/MongooseDB.js';
|
|
34
35
|
import { Lampp } from '../src/runtime/lampp/Lampp.js';
|
|
36
|
+
import { DefaultConf } from '../conf.js';
|
|
37
|
+
import { JSONweb } from '../src/server/client-formatted.js';
|
|
35
38
|
|
|
36
39
|
const logger = loggerFactory(import.meta);
|
|
37
40
|
|
|
@@ -152,10 +155,15 @@ try {
|
|
|
152
155
|
await deployRun(dataDeploy);
|
|
153
156
|
} else {
|
|
154
157
|
loadConf(process.argv[3]);
|
|
155
|
-
shellExec(`npm start ${process.argv
|
|
158
|
+
shellExec(`npm start ${process.argv.includes('maintenance') ? 'maintenance' : ''}`);
|
|
156
159
|
}
|
|
157
160
|
}
|
|
158
161
|
break;
|
|
162
|
+
|
|
163
|
+
case 'remove-await-deploy': {
|
|
164
|
+
if (fs.existsSync(`./tmp/await-deploy`)) fs.remove(`./tmp/await-deploy`);
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
159
167
|
case 'new-nodejs-app':
|
|
160
168
|
{
|
|
161
169
|
const deployId = process.argv[3];
|
|
@@ -222,21 +230,18 @@ try {
|
|
|
222
230
|
break;
|
|
223
231
|
case 'build-full-client':
|
|
224
232
|
{
|
|
233
|
+
if (!process.argv[3]) process.argv[3] = 'default';
|
|
225
234
|
const { deployId, folder } = loadConf(process.argv[3]);
|
|
226
235
|
|
|
227
|
-
let argHost = process.argv[4] ? process.argv[4].split(',') :
|
|
228
|
-
let argPath = process.argv[5] ? process.argv[5].split(',') :
|
|
236
|
+
let argHost = process.argv[4] ? process.argv[4].split(',') : [];
|
|
237
|
+
let argPath = process.argv[5] ? process.argv[5].split(',') : [];
|
|
229
238
|
let deployIdSingleReplicas = [];
|
|
230
239
|
const serverConf = deployId
|
|
231
240
|
? JSON.parse(fs.readFileSync(`./conf/conf.server.json`, 'utf8'))
|
|
232
241
|
: Config.default.server;
|
|
233
|
-
if (!deployId) {
|
|
234
|
-
argHost = 'default.net';
|
|
235
|
-
argPath = '/';
|
|
236
|
-
}
|
|
237
242
|
for (const host of Object.keys(serverConf)) {
|
|
238
243
|
for (const path of Object.keys(serverConf[host])) {
|
|
239
|
-
if (argHost && argPath && (!argHost.includes(host) || !argPath.includes(path))) {
|
|
244
|
+
if (argHost.length && argPath.length && (!argHost.includes(host) || !argPath.includes(path))) {
|
|
240
245
|
delete serverConf[host][path];
|
|
241
246
|
} else {
|
|
242
247
|
serverConf[host][path].liteBuild = process.argv.includes('l') ? true : false;
|
|
@@ -278,6 +283,154 @@ try {
|
|
|
278
283
|
}
|
|
279
284
|
break;
|
|
280
285
|
|
|
286
|
+
case 'adminer': {
|
|
287
|
+
const directory = '/dd/engine/public/adminer';
|
|
288
|
+
// const host = '127.0.0.1';
|
|
289
|
+
const host = 'localhost';
|
|
290
|
+
const port = 80;
|
|
291
|
+
if (!process.argv.includes('server')) {
|
|
292
|
+
if (fs.existsSync(directory)) fs.removeSync(directory);
|
|
293
|
+
fs.mkdirSync(directory, { recursive: true });
|
|
294
|
+
shellExec(`cd ${directory} && wget https://www.adminer.org/latest.php -O adminer.php`);
|
|
295
|
+
}
|
|
296
|
+
Lampp.removeRouter();
|
|
297
|
+
Lampp.appendRouter(` Listen ${port}
|
|
298
|
+
<VirtualHost *:${port}>
|
|
299
|
+
DocumentRoot "${directory}"
|
|
300
|
+
ServerName ${host}:${port}
|
|
301
|
+
|
|
302
|
+
<Directory "${directory}">
|
|
303
|
+
Options Indexes FollowSymLinks MultiViews
|
|
304
|
+
AllowOverride All
|
|
305
|
+
Require all granted
|
|
306
|
+
</Directory>
|
|
307
|
+
|
|
308
|
+
</VirtualHost>
|
|
309
|
+
`);
|
|
310
|
+
if (Lampp.enabled() && Lampp.router) Lampp.initService({ daemon: true });
|
|
311
|
+
shellExec(`open /opt/lampp/apache2/conf/httpd.conf`);
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
case 'pma':
|
|
316
|
+
{
|
|
317
|
+
const directory = '/dd/engine/public/phpmyadmin';
|
|
318
|
+
// const host = '127.0.0.1';
|
|
319
|
+
const host = 'localhost';
|
|
320
|
+
const port = 80;
|
|
321
|
+
// data config path: /etc/phpmyadmin
|
|
322
|
+
|
|
323
|
+
// The config.inc.php file is not required, and only needed for custom configurations
|
|
324
|
+
|
|
325
|
+
// phpmyadmin will first refer to ./libraries/config.default.php to retrieve the default values.
|
|
326
|
+
|
|
327
|
+
// If for some reason you need to modify the default values, and the ./config.inc.php
|
|
328
|
+
// file doesn't exist, you will need to create one as per the Installation documentation.
|
|
329
|
+
|
|
330
|
+
// You will also need to configure pmadb for some of phpmyadmin's special features such as bookmarks.
|
|
331
|
+
|
|
332
|
+
// CREATE USER 'pma'@'localhost' IDENTIFIED VIA mysql_native_password USING 'pmapass';
|
|
333
|
+
// GRANT SELECT, INSERT, UPDATE, DELETE ON `<pma_db>`.* TO 'pma'@'localhost';
|
|
334
|
+
|
|
335
|
+
if (!process.argv.includes('server')) {
|
|
336
|
+
// if (fs.existsSync(directory)) fs.removeSync(directory);
|
|
337
|
+
shellExec(`sudo apt install phpmyadmin php-mbstring php-zip php-gd php-json php-curl`);
|
|
338
|
+
shellExec(`sudo phpenmod mbstring`);
|
|
339
|
+
shellExec(
|
|
340
|
+
`cd /usr/share/phpmyadmin && git init && git add . && git commit -m "Base phpMyAdmin implementation"`,
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// if (!fs.existsSync(directory)) fs.mkdirSync(directory, { recursive: true });
|
|
345
|
+
// if (!fs.existsSync('./public/phpmyadmin/phpmyadmin'))
|
|
346
|
+
// fs.copySync('/usr/share/phpmyadmin', './public/phpmyadmin/phpmyadmin');
|
|
347
|
+
|
|
348
|
+
Lampp.removeRouter();
|
|
349
|
+
Lampp.appendRouter(` Listen ${port} `);
|
|
350
|
+
if (Lampp.enabled() && Lampp.router) Lampp.initService({ daemon: true });
|
|
351
|
+
// shellExec(`open /opt/lampp/apache2/conf/httpd.conf`);
|
|
352
|
+
|
|
353
|
+
// Create a link in /var/www like this:
|
|
354
|
+
|
|
355
|
+
// sudo ln -s /usr/share/phpmyadmin /var/www/
|
|
356
|
+
|
|
357
|
+
// Note: since 14.04 you may want to use /var/www/html/ instead of /var/www/
|
|
358
|
+
|
|
359
|
+
// If that's not working for you, you need to include PHPMyAdmin inside apache configuration.
|
|
360
|
+
|
|
361
|
+
// Open apache.conf using your favorite editor, mine is vim :)
|
|
362
|
+
|
|
363
|
+
// sudo vim /etc/apache2/apache2.conf
|
|
364
|
+
|
|
365
|
+
// Then add the following line:
|
|
366
|
+
|
|
367
|
+
// Include /etc/phpmyadmin/apache.conf
|
|
368
|
+
|
|
369
|
+
// For Ubuntu 15.04 and 16.04
|
|
370
|
+
|
|
371
|
+
// sudo ln -s /etc/phpmyadmin/apache.conf /etc/apache2/conf-available/phpmyadmin.conf
|
|
372
|
+
// sudo a2enconf phpmyadmin.conf
|
|
373
|
+
// sudo service apache2 reload
|
|
374
|
+
break;
|
|
375
|
+
Lampp.appendRouter(` Listen ${port}
|
|
376
|
+
|
|
377
|
+
<VirtualHost *:${port}>
|
|
378
|
+
DocumentRoot "${directory}"
|
|
379
|
+
ServerName ${host}:${port}
|
|
380
|
+
|
|
381
|
+
<Directory "${directory}">
|
|
382
|
+
Options Indexes FollowSymLinks MultiViews
|
|
383
|
+
AllowOverride All
|
|
384
|
+
Require all granted
|
|
385
|
+
</Directory>
|
|
386
|
+
|
|
387
|
+
</VirtualHost>`);
|
|
388
|
+
// phpMyAdmin default Apache configuration:
|
|
389
|
+
Lampp.appendRouter(`
|
|
390
|
+
|
|
391
|
+
Listen ${port}
|
|
392
|
+
|
|
393
|
+
Alias /phpmyadmin /usr/share/phpmyadmin
|
|
394
|
+
|
|
395
|
+
<Directory /usr/share/phpmyadmin>
|
|
396
|
+
Options Indexes FollowSymLinks
|
|
397
|
+
DirectoryIndex index.php
|
|
398
|
+
|
|
399
|
+
<IfModule mod_php5.c>
|
|
400
|
+
AddType application/x-httpd-php .php
|
|
401
|
+
|
|
402
|
+
php_flag magic_quotes_gpc Off
|
|
403
|
+
php_flag track_vars On
|
|
404
|
+
php_flag register_globals Off
|
|
405
|
+
php_value include_path .
|
|
406
|
+
</IfModule>
|
|
407
|
+
|
|
408
|
+
</Directory>
|
|
409
|
+
|
|
410
|
+
# Authorize for setup
|
|
411
|
+
<Directory /usr/share/phpmyadmin/setup>
|
|
412
|
+
<IfModule mod_authn_file.c>
|
|
413
|
+
AuthType Basic
|
|
414
|
+
AuthName "phpMyAdmin Setup"
|
|
415
|
+
AuthUserFile /etc/phpmyadmin/htpasswd.setup
|
|
416
|
+
</IfModule>
|
|
417
|
+
Require valid-user
|
|
418
|
+
</Directory>
|
|
419
|
+
|
|
420
|
+
# Disallow web access to directories that don't need it
|
|
421
|
+
<Directory /usr/share/phpmyadmin/libraries>
|
|
422
|
+
Order Deny,Allow
|
|
423
|
+
Deny from All
|
|
424
|
+
</Directory>
|
|
425
|
+
<Directory /usr/share/phpmyadmin/setup/lib>
|
|
426
|
+
Order Deny,Allow
|
|
427
|
+
Deny from All
|
|
428
|
+
</Directory>
|
|
429
|
+
|
|
430
|
+
`);
|
|
431
|
+
}
|
|
432
|
+
break;
|
|
433
|
+
|
|
281
434
|
case 'update-package':
|
|
282
435
|
const files = await fs.readdir(`./engine-private/conf`, { recursive: true });
|
|
283
436
|
const originPackage = JSON.parse(fs.readFileSync(`./package.json`, 'utf8'));
|
|
@@ -294,21 +447,37 @@ try {
|
|
|
294
447
|
{
|
|
295
448
|
if (fs.existsSync(`./tmp/await-deploy`)) fs.remove(`./tmp/await-deploy`);
|
|
296
449
|
const dataDeploy = getDataDeploy({ deployGroupId: process.argv[3], buildSingleReplica: true });
|
|
297
|
-
await
|
|
450
|
+
if (!process.argv[4]) await setUpProxyMaintenanceServer({ deployGroupId: process.argv[3] });
|
|
451
|
+
await deployRun(
|
|
452
|
+
process.argv[4] ? dataDeploy.filter((d) => d.deployId.match(process.argv[4])) : dataDeploy,
|
|
453
|
+
true,
|
|
454
|
+
);
|
|
298
455
|
}
|
|
299
456
|
break;
|
|
300
457
|
|
|
301
|
-
case '
|
|
458
|
+
case 'build-macro':
|
|
302
459
|
{
|
|
303
|
-
if (fs.existsSync(`./tmp/await-deploy`)) fs.remove(`./tmp/await-deploy`);
|
|
304
460
|
const dataDeploy = getDataDeploy({ deployGroupId: process.argv[3], buildSingleReplica: true });
|
|
305
461
|
for (const deploy of dataDeploy) {
|
|
306
|
-
|
|
307
|
-
|
|
462
|
+
if (!process.argv[4] || (process.argv[4] && process.argv[4] === deploy.deployId)) {
|
|
463
|
+
shellExec(Cmd.conf(deploy.deployId));
|
|
464
|
+
shellExec(Cmd.build(deploy.deployId));
|
|
465
|
+
}
|
|
308
466
|
}
|
|
309
|
-
await deployRun(dataDeploy, true);
|
|
310
467
|
}
|
|
311
468
|
break;
|
|
469
|
+
case 'macro': {
|
|
470
|
+
shellExec(`git checkout .`);
|
|
471
|
+
shellExec(`node bin/deploy build-macro ${process.argv.slice(3).join(' ')}`);
|
|
472
|
+
shellExec(`git checkout .`);
|
|
473
|
+
shellExec(`node bin/deploy run-macro ${process.argv.slice(3).join(' ')}`);
|
|
474
|
+
break;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
case 'keep-server': {
|
|
478
|
+
await setUpProxyMaintenanceServer({ deployGroupId: process.argv[3] });
|
|
479
|
+
break;
|
|
480
|
+
}
|
|
312
481
|
case 'prometheus':
|
|
313
482
|
case 'prom':
|
|
314
483
|
{
|
|
@@ -452,7 +621,7 @@ try {
|
|
|
452
621
|
`./engine-private/replica/${replicaDeployId}/package.json`,
|
|
453
622
|
fs
|
|
454
623
|
.readFileSync(`./engine-private/replica/${replicaDeployId}/package.json`, 'utf8')
|
|
455
|
-
.replaceAll(
|
|
624
|
+
.replaceAll(`${deployId}`, `${replicaDeployId}`),
|
|
456
625
|
'utf8',
|
|
457
626
|
);
|
|
458
627
|
}
|
|
@@ -666,6 +835,167 @@ ${uniqueArray(logs.all.map((log) => `- ${log.author_name} ([${log.author_email}]
|
|
|
666
835
|
break;
|
|
667
836
|
}
|
|
668
837
|
|
|
838
|
+
case 'update-default-conf': {
|
|
839
|
+
const host = process.argv[3] ? process.argv[3] : 'underpostnet.github.io';
|
|
840
|
+
const path = process.argv[4] ? process.argv[4] : '/pwa-microservices-template-ghpkg';
|
|
841
|
+
DefaultConf.server = {
|
|
842
|
+
[host]: { [path]: DefaultConf.server['default.net']['/'] },
|
|
843
|
+
};
|
|
844
|
+
DefaultConf.server[host][path].apiBaseProxyPath = '/';
|
|
845
|
+
DefaultConf.server[host][path].apiBaseHost = 'www.nexodev.org';
|
|
846
|
+
fs.writeFileSync(
|
|
847
|
+
'./conf.js',
|
|
848
|
+
`
|
|
849
|
+
const DefaultConf = ${JSONweb(DefaultConf)};
|
|
850
|
+
|
|
851
|
+
export { DefaultConf }
|
|
852
|
+
|
|
853
|
+
`,
|
|
854
|
+
'utf8',
|
|
855
|
+
);
|
|
856
|
+
|
|
857
|
+
break;
|
|
858
|
+
}
|
|
859
|
+
case 'ssh-export-server-keys': {
|
|
860
|
+
fs.copyFile('/etc/ssh/ssh_host_rsa_key', './engine-private/deploy/ssh_host_rsa_key');
|
|
861
|
+
fs.copyFile('/etc/ssh/ssh_host_rsa_key.pub', './engine-private/deploy/ssh_host_rsa_key.pub');
|
|
862
|
+
break;
|
|
863
|
+
}
|
|
864
|
+
case 'ssh-import-server-keys': {
|
|
865
|
+
fs.copyFile('./engine-private/deploy/ssh_host_rsa_key', '/etc/ssh/ssh_host_rsa_key');
|
|
866
|
+
fs.copyFile('./engine-private/deploy/ssh_host_rsa_key.pub', '/etc/ssh/ssh_host_rsa_key.pub');
|
|
867
|
+
break;
|
|
868
|
+
}
|
|
869
|
+
case 'ssh-import-client-keys': {
|
|
870
|
+
const host = process.argv[3];
|
|
871
|
+
shellExec(`node bin/deploy set-ssh-keys ./engine-private/deploy/ssh_host_rsa_key${host ? ` ${host}` : ``} clean`);
|
|
872
|
+
break;
|
|
873
|
+
}
|
|
874
|
+
case 'ssh-keys': {
|
|
875
|
+
// create ssh keys
|
|
876
|
+
const sshAccount = process.argv[3]; // [sudo username]@[host/ip]
|
|
877
|
+
const destPath = process.argv[4];
|
|
878
|
+
// shellExec(`ssh-keygen -t ed25519 -C "${sshAccount}" -f ${destPath}`);
|
|
879
|
+
if (fs.existsSync(destPath)) {
|
|
880
|
+
fs.removeSync(destPath);
|
|
881
|
+
fs.removeSync(destPath + '.pub');
|
|
882
|
+
}
|
|
883
|
+
shellExec(`ssh-keygen -t rsa -b 4096 -C "${sshAccount}" -f ${destPath}`);
|
|
884
|
+
// add host to keyscan
|
|
885
|
+
// shellExec(`ssh-keyscan -t rsa ${sshAccount.split(`@`)[1]} >> ~/.ssh/known_hosts`);
|
|
886
|
+
break;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
case 'set-ssh-keys': {
|
|
890
|
+
const files = ['authorized_keys', 'id_rsa', 'id_rsa.pub', 'known_hosts ', 'known_hosts.old'];
|
|
891
|
+
|
|
892
|
+
// > write
|
|
893
|
+
// >> append
|
|
894
|
+
|
|
895
|
+
// /root/.ssh/id_rsa
|
|
896
|
+
// /root/.ssh/id_rsa.pub
|
|
897
|
+
if (process.argv.includes('clean')) {
|
|
898
|
+
for (const file of files) {
|
|
899
|
+
if (fs.existsSync(`/root/.ssh/${file}`)) {
|
|
900
|
+
logger.info('remove', `/root/.ssh/${file}`);
|
|
901
|
+
fs.removeSync(`/root/.ssh/${file}`);
|
|
902
|
+
}
|
|
903
|
+
fs.writeFileSync(`/root/.ssh/${file}`, '', 'utf8');
|
|
904
|
+
}
|
|
905
|
+
shellExec('eval `ssh-agent -s`' + ` && ssh-add -D`);
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
const destPath = process.argv[3];
|
|
909
|
+
const sshAuthKeyTarget = '/root/.ssh/authorized_keys';
|
|
910
|
+
if (!fs.existsSync(sshAuthKeyTarget)) shellExec(`touch ${sshAuthKeyTarget}`);
|
|
911
|
+
shellExec(`cat ${destPath}.pub > ${sshAuthKeyTarget}`);
|
|
912
|
+
shellExec(`cat ${destPath} >> ${sshAuthKeyTarget}`);
|
|
913
|
+
|
|
914
|
+
if (!fs.existsSync('/root/.ssh/id_rsa')) shellExec(`touch ${'/root/.ssh/id_rsa'}`);
|
|
915
|
+
shellExec(`cat ${destPath} > ${'/root/.ssh/id_rsa'}`);
|
|
916
|
+
|
|
917
|
+
if (!fs.existsSync('/root/.ssh/id_rsa.pub')) shellExec(`touch ${'/root/.ssh/id_rsa.pub'}`);
|
|
918
|
+
shellExec(`cat ${destPath}.pub > ${'/root/.ssh/id_rsa.pub'}`);
|
|
919
|
+
|
|
920
|
+
shellExec(`chmod 700 /root/.ssh/`);
|
|
921
|
+
for (const file of files) {
|
|
922
|
+
shellExec(`chmod 600 /root/.ssh/${file}`);
|
|
923
|
+
}
|
|
924
|
+
const host = process.argv[4];
|
|
925
|
+
// add key
|
|
926
|
+
shellExec('eval `ssh-agent -s`' + ' && ssh-add /root/.ssh/id_rsa' + ' && ssh-add -l');
|
|
927
|
+
if (host) shellExec(`ssh-keyscan -H ${host} >> ~/.ssh/known_hosts`);
|
|
928
|
+
shellExec(`sudo systemctl enable ssh`);
|
|
929
|
+
shellExec(`sudo systemctl restart ssh`);
|
|
930
|
+
shellExec(`sudo systemctl status ssh`);
|
|
931
|
+
|
|
932
|
+
break;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
case 'ssh': {
|
|
936
|
+
if (!process.argv.includes('server')) {
|
|
937
|
+
shellExec(`sudo apt update`);
|
|
938
|
+
shellExec(`sudo apt install openssh-server -y`);
|
|
939
|
+
shellExec(`sudo apt install ssh-askpass`);
|
|
940
|
+
}
|
|
941
|
+
shellExec(`sudo systemctl enable ssh`);
|
|
942
|
+
shellExec(`sudo systemctl restart ssh`);
|
|
943
|
+
shellExec(`sudo systemctl status ssh`);
|
|
944
|
+
// sudo service ssh restart
|
|
945
|
+
shellExec(`ip a`);
|
|
946
|
+
|
|
947
|
+
// adduser newuser
|
|
948
|
+
// usermod -aG sudo newuser
|
|
949
|
+
|
|
950
|
+
// ssh -i '/path/to/keyfile' username@server
|
|
951
|
+
|
|
952
|
+
// ssh-keygen -t ed25519 -C "your_email@example.com" -f $HOME/.ssh/id_rsa
|
|
953
|
+
|
|
954
|
+
// legacy: ssh-keygen -t rsa -b 4096 -C "your_email@example.com" -f $HOME/.ssh/id_rsa
|
|
955
|
+
|
|
956
|
+
// vi .ssh/authorized_keys
|
|
957
|
+
// chmod 700 .ssh
|
|
958
|
+
// chmod 600 authorized_keys
|
|
959
|
+
|
|
960
|
+
// cat id_rsa.pub > .ssh/authorized_keys
|
|
961
|
+
|
|
962
|
+
// add public key to authorized keys
|
|
963
|
+
// cat .ssh/id_ed25519.pub | ssh [sudo username]@[host/ip] 'cat >> .ssh/authorized_keys'
|
|
964
|
+
|
|
965
|
+
// 2. Open /etc/ssh/sshd_config file
|
|
966
|
+
// nano /etc/ssh/sshd_config
|
|
967
|
+
|
|
968
|
+
// 3. add example code to last line of file
|
|
969
|
+
// Match User newuser
|
|
970
|
+
// PasswordAuthentication yes
|
|
971
|
+
|
|
972
|
+
// ssh [sudo username]@[host/ip]
|
|
973
|
+
// open port 22
|
|
974
|
+
|
|
975
|
+
// init ssh agent service
|
|
976
|
+
// eval `ssh-agent -s`
|
|
977
|
+
|
|
978
|
+
// list keys
|
|
979
|
+
// ssh-add -l
|
|
980
|
+
|
|
981
|
+
// add key
|
|
982
|
+
// ssh-add /root/.ssh/id_rsa
|
|
983
|
+
|
|
984
|
+
// remove
|
|
985
|
+
// ssh-add -d /path/to/private/key
|
|
986
|
+
|
|
987
|
+
// remove all
|
|
988
|
+
// ssh-add -D
|
|
989
|
+
|
|
990
|
+
// sshpass -p ${{ secrets.PSWD }} ssh -o StrictHostKeyChecking=no -p 22 ${{ secrets.USER}}@${{ secrets.VPS_IP }} 'cd /home/adam && ./deploy.sh'
|
|
991
|
+
|
|
992
|
+
// copies the public key of your default identity (use -i identity_file for other identities) to the remote host.
|
|
993
|
+
// ssh-copy-id user@hostname.example.com
|
|
994
|
+
// ssh-copy-id "user@hostname.example.com -p <port-number>"
|
|
995
|
+
|
|
996
|
+
break;
|
|
997
|
+
}
|
|
998
|
+
|
|
669
999
|
default:
|
|
670
1000
|
break;
|
|
671
1001
|
}
|
package/bin/file.js
CHANGED
|
@@ -2,7 +2,7 @@ import fs from 'fs-extra';
|
|
|
2
2
|
|
|
3
3
|
import { loggerFactory } from '../src/server/logger.js';
|
|
4
4
|
import { cap, getCapVariableName, getDirname } from '../src/client/components/core/CommonJs.js';
|
|
5
|
-
import { shellExec } from '../src/server/process.js';
|
|
5
|
+
import { shellCd, shellExec } from '../src/server/process.js';
|
|
6
6
|
import walk from 'ignore-walk';
|
|
7
7
|
import { validateTemplatePath } from '../src/server/conf.js';
|
|
8
8
|
|
|
@@ -76,6 +76,22 @@ try {
|
|
|
76
76
|
fs.copySync(`./.vscode`, `../pwa-microservices-template/.vscode`);
|
|
77
77
|
fs.copySync(`./.github`, `../pwa-microservices-template/.github`);
|
|
78
78
|
fs.copySync(`./src/client/public/default`, `../pwa-microservices-template/src/client/public/default`);
|
|
79
|
+
|
|
80
|
+
shellCd('../pwa-microservices-template');
|
|
81
|
+
for (const deletePath of ['CHANGELOG.md', 'README.md', 'package-lock.json', 'package.json']) {
|
|
82
|
+
shellExec(`git checkout ${deletePath}`);
|
|
83
|
+
}
|
|
84
|
+
for (const deletePath of [
|
|
85
|
+
'.github/workflows/coverall.yml',
|
|
86
|
+
'.github/workflows/docker-image.yml',
|
|
87
|
+
'.github/workflows/deploy.ssh.yml',
|
|
88
|
+
'.github/workflows/deploy.api-rest.yml',
|
|
89
|
+
'bin/web3.js',
|
|
90
|
+
'src/ipfs.js',
|
|
91
|
+
'src/k8s.js',
|
|
92
|
+
]) {
|
|
93
|
+
fs.removeSync('../pwa-microservices-template/' + deletePath);
|
|
94
|
+
}
|
|
79
95
|
}
|
|
80
96
|
|
|
81
97
|
break;
|
package/bin/index.js
CHANGED
package/bin/util.js
CHANGED
|
@@ -3,6 +3,8 @@ import merge from 'deepmerge';
|
|
|
3
3
|
import si from 'systeminformation';
|
|
4
4
|
import * as dir from 'path';
|
|
5
5
|
import { svg } from 'font-awesome-assets';
|
|
6
|
+
import axios from 'axios';
|
|
7
|
+
import https from 'https';
|
|
6
8
|
|
|
7
9
|
import { loggerFactory } from '../src/server/logger.js';
|
|
8
10
|
import { shellCd, shellExec } from '../src/server/process.js';
|
|
@@ -12,6 +14,11 @@ import { Config } from '../src/server/conf.js';
|
|
|
12
14
|
import { FileFactory } from '../src/api/file/file.service.js';
|
|
13
15
|
import { buildTextImg, faBase64Png, getBufferPngText } from '../src/server/client-icons.js';
|
|
14
16
|
|
|
17
|
+
const httpsAgent = new https.Agent({
|
|
18
|
+
rejectUnauthorized: false,
|
|
19
|
+
});
|
|
20
|
+
axios.defaults.httpsAgent = httpsAgent;
|
|
21
|
+
|
|
15
22
|
const logger = loggerFactory(import.meta);
|
|
16
23
|
|
|
17
24
|
logger.info('argv', process.argv);
|
|
@@ -118,6 +125,10 @@ try {
|
|
|
118
125
|
break;
|
|
119
126
|
case 'delete-empty-folder':
|
|
120
127
|
function cleanEmptyFoldersRecursively(folder) {
|
|
128
|
+
if (!fs.existsSync(folder)) {
|
|
129
|
+
logger.warn('Does not exist', folder);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
121
132
|
const isDir = fs.statSync(folder).isDirectory();
|
|
122
133
|
if (!isDir) return;
|
|
123
134
|
|
|
@@ -135,7 +146,11 @@ try {
|
|
|
135
146
|
|
|
136
147
|
if (files.length === 0) {
|
|
137
148
|
console.log('removing: ', folder);
|
|
138
|
-
|
|
149
|
+
try {
|
|
150
|
+
fs.rmdirSync(folder);
|
|
151
|
+
} catch (error) {
|
|
152
|
+
logger.error(error);
|
|
153
|
+
}
|
|
139
154
|
return;
|
|
140
155
|
}
|
|
141
156
|
}
|
|
@@ -174,6 +189,21 @@ try {
|
|
|
174
189
|
fs.writeFileSync('b64-image', `data:image/jpg;base64,${fs.readFileSync(process.argv[3]).toString('base64')}`);
|
|
175
190
|
break;
|
|
176
191
|
|
|
192
|
+
case 'get-ip': {
|
|
193
|
+
const response = await axios.get(process.argv[3]);
|
|
194
|
+
logger.info(process.argv[3] + ' IP', response.request.socket.remoteAddress);
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
case 'clean-env': {
|
|
199
|
+
shellExec(`git checkout package.json`);
|
|
200
|
+
shellExec(`git checkout .env.production`);
|
|
201
|
+
shellExec(`git checkout .env.development`);
|
|
202
|
+
shellExec(`git checkout .env.test`);
|
|
203
|
+
shellExec(`git checkout jsdoc.json`);
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
|
|
177
207
|
default:
|
|
178
208
|
break;
|
|
179
209
|
}
|
package/conf.js
CHANGED
|
@@ -2,8 +2,14 @@ const DefaultConf = {
|
|
|
2
2
|
client: {
|
|
3
3
|
default: {
|
|
4
4
|
metadata: {
|
|
5
|
-
title: '
|
|
5
|
+
title: 'Demo App',
|
|
6
6
|
backgroundImage: './src/client/public/default/assets/background/white0-min.jpg',
|
|
7
|
+
description: 'Web application',
|
|
8
|
+
keywords: ['web', 'app', 'spa', 'demo', 'github-pages'],
|
|
9
|
+
author: 'https://github.com/underpostnet',
|
|
10
|
+
thumbnail: 'android-chrome-384x384.png',
|
|
11
|
+
themeColor: '#ececec',
|
|
12
|
+
pwaAssetsPath: '',
|
|
7
13
|
},
|
|
8
14
|
components: {
|
|
9
15
|
core: [
|
|
@@ -168,7 +174,7 @@ const DefaultConf = {
|
|
|
168
174
|
},
|
|
169
175
|
ssr: {
|
|
170
176
|
Default: {
|
|
171
|
-
head: ['
|
|
177
|
+
head: ['Seo', 'Pwa', 'Css', 'DefaultScripts', 'Production'],
|
|
172
178
|
body: ['CacheControl', 'DefaultSplashScreen'],
|
|
173
179
|
},
|
|
174
180
|
},
|
|
@@ -227,8 +233,6 @@ const DefaultConf = {
|
|
|
227
233
|
cron: {
|
|
228
234
|
ipDaemon: {
|
|
229
235
|
ip: null,
|
|
230
|
-
minutesTimeInterval: 3,
|
|
231
|
-
disabled: false,
|
|
232
236
|
},
|
|
233
237
|
records: {
|
|
234
238
|
A: [
|
|
@@ -245,6 +249,16 @@ const DefaultConf = {
|
|
|
245
249
|
deployGroupId: 'default-group',
|
|
246
250
|
},
|
|
247
251
|
],
|
|
252
|
+
jobs: {
|
|
253
|
+
dns: {
|
|
254
|
+
expression: '* * * * *',
|
|
255
|
+
enabled: true,
|
|
256
|
+
},
|
|
257
|
+
backups: {
|
|
258
|
+
expression: '0 1 * * *',
|
|
259
|
+
enabled: true,
|
|
260
|
+
},
|
|
261
|
+
},
|
|
248
262
|
},
|
|
249
263
|
};
|
|
250
264
|
|
package/docker-compose.yml
CHANGED
package/package.json
CHANGED
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
"type": "module",
|
|
3
3
|
"main": "src/index.js",
|
|
4
4
|
"name": "underpost",
|
|
5
|
-
"version": "2.7.
|
|
5
|
+
"version": "2.7.91",
|
|
6
6
|
"description": "pwa api rest template",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"start": "env-cmd -f .env.production node --max-old-space-size=8192 src/server",
|
|
9
9
|
"pm2": "env-cmd -f .env.production pm2 start src/server.js --node-args=\"--max-old-space-size=8192\" --name engine && pm2 logs",
|
|
10
10
|
"ssl": "env-cmd -f .env.production node bin/ssl",
|
|
11
11
|
"pm2-delete": "pm2 delete engine",
|
|
12
|
-
"build": "node bin/deploy build-full-client
|
|
12
|
+
"build": "node bin/deploy build-full-client",
|
|
13
|
+
"build-production": "env-cmd -f .env.production node bin/deploy build-full-client",
|
|
13
14
|
"dev": "env-cmd -f .env.development node src/client.dev --no-warnings",
|
|
14
15
|
"dev-api": "env-cmd -f .env.development nodemon --watch src --ignore src/client src/api",
|
|
15
16
|
"docs": "jsdoc -c jsdoc.json",
|
|
@@ -95,7 +96,6 @@
|
|
|
95
96
|
"marked": "^12.0.2",
|
|
96
97
|
"mongoose": "^8.0.1",
|
|
97
98
|
"morgan": "^1.10.0",
|
|
98
|
-
"node-cron": "^3.0.3",
|
|
99
99
|
"nodemailer": "^6.9.9",
|
|
100
100
|
"nodemon": "^3.0.1",
|
|
101
101
|
"pathfinding": "^0.4.18",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { authMiddleware } from '../../server/auth.js';
|
|
1
|
+
import { adminGuard, authMiddleware } from '../../server/auth.js';
|
|
2
2
|
import { loggerFactory } from '../../server/logger.js';
|
|
3
3
|
import { CoreController } from './core.controller.js';
|
|
4
4
|
import express from 'express';
|
|
@@ -7,14 +7,14 @@ const logger = loggerFactory(import.meta);
|
|
|
7
7
|
|
|
8
8
|
const CoreRouter = (options) => {
|
|
9
9
|
const router = express.Router();
|
|
10
|
-
router.post(`/:id`, async (req, res) => await CoreController.post(req, res, options));
|
|
11
|
-
router.post(`/`, async (req, res) => await CoreController.post(req, res, options));
|
|
12
|
-
router.get(`/:id`, async (req, res) => await CoreController.get(req, res, options));
|
|
13
|
-
router.get(`/`, async (req, res) => await CoreController.get(req, res, options));
|
|
14
|
-
router.put(`/:id`, async (req, res) => await CoreController.put(req, res, options));
|
|
15
|
-
router.put(`/`, async (req, res) => await CoreController.put(req, res, options));
|
|
16
|
-
router.delete(`/:id`, async (req, res) => await CoreController.delete(req, res, options));
|
|
17
|
-
router.delete(`/`, async (req, res) => await CoreController.delete(req, res, options));
|
|
10
|
+
router.post(`/:id`, authMiddleware, adminGuard, async (req, res) => await CoreController.post(req, res, options));
|
|
11
|
+
router.post(`/`, authMiddleware, adminGuard, async (req, res) => await CoreController.post(req, res, options));
|
|
12
|
+
router.get(`/:id`, authMiddleware, adminGuard, async (req, res) => await CoreController.get(req, res, options));
|
|
13
|
+
router.get(`/`, authMiddleware, adminGuard, async (req, res) => await CoreController.get(req, res, options));
|
|
14
|
+
router.put(`/:id`, authMiddleware, adminGuard, async (req, res) => await CoreController.put(req, res, options));
|
|
15
|
+
router.put(`/`, authMiddleware, adminGuard, async (req, res) => await CoreController.put(req, res, options));
|
|
16
|
+
router.delete(`/:id`, authMiddleware, adminGuard, async (req, res) => await CoreController.delete(req, res, options));
|
|
17
|
+
router.delete(`/`, authMiddleware, adminGuard, async (req, res) => await CoreController.delete(req, res, options));
|
|
18
18
|
return router;
|
|
19
19
|
};
|
|
20
20
|
|