underpost 2.7.7 → 2.7.9
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 +115 -0
- package/.github/workflows/publish.yml +20 -3
- package/.github/workflows/pwa-microservices-template.page.yml +54 -0
- package/.github/workflows/pwa-microservices-template.test.yml +30 -0
- package/.vscode/settings.json +6 -0
- package/CHANGELOG.md +64 -16
- package/bin/cron.js +47 -0
- package/bin/db.js +9 -1
- package/bin/deploy.js +207 -11
- package/bin/file.js +17 -1
- package/bin/index.js +1 -1
- package/bin/util.js +22 -0
- 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 +6 -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 +7 -7
- package/src/client/components/core/Css.js +0 -222
- package/src/client/components/core/CssCore.js +30 -3
- package/src/client/components/core/Docs.js +110 -10
- 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 +15 -0
- package/src/client/components/core/RichText.js +4 -2
- package/src/client/components/core/Translate.js +6 -2
- package/src/client/components/core/WebComponent.js +44 -0
- package/src/client/components/core/Worker.js +12 -4
- 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/services/default/default.management.js +118 -120
- package/src/client/ssr/Render.js +224 -3
- package/src/client/ssr/common/Alert.js +75 -0
- package/src/client/ssr/common/SsrCore.js +91 -0
- package/src/client/ssr/common/Translate.js +26 -0
- package/src/client/ssr/common/Worker.js +28 -0
- package/src/client/ssr/{body-components → components/body}/CacheControl.js +1 -1
- package/src/client/ssr/{body-components → components/body}/DefaultSplashScreen.js +15 -4
- package/src/client/ssr/components/head/Pwa.js +146 -0
- package/src/client/ssr/pages/404.js +12 -0
- package/src/client/ssr/pages/500.js +12 -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 +13 -9
- package/src/db/DataBaseProvider.js +12 -1
- package/src/db/mongo/MongooseDB.js +0 -1
- package/src/mailer/EmailRender.js +1 -1
- package/src/server/backup.js +82 -70
- package/src/server/client-build-live.js +6 -0
- package/src/server/client-build.js +76 -73
- package/src/server/client-formatted.js +11 -1
- package/src/server/client-icons.js +1 -1
- package/src/server/conf.js +60 -12
- package/src/server/crypto.js +91 -0
- package/src/server/dns.js +42 -13
- package/src/server/network.js +94 -7
- package/src/server/proxy.js +27 -27
- package/src/server/runtime.js +27 -8
- package/.github/workflows/test.yml +0 -80
- package/src/client/ssr/head-components/Microdata.js +0 -11
- package/src/cron.js +0 -30
- package/src/server/cron.js +0 -35
- /package/src/client/ssr/{email-components → components/email}/DefaultRecoverEmail.js +0 -0
- /package/src/client/ssr/{email-components → components/email}/DefaultVerifyEmail.js +0 -0
- /package/src/client/ssr/{head-components → components/head}/Css.js +0 -0
- /package/src/client/ssr/{head-components → components/head}/DefaultScripts.js +0 -0
- /package/src/client/ssr/{head-components → components/head}/Production.js +0 -0
- /package/src/client/ssr/{head-components → components/head}/PwaDefault.js +0 -0
- /package/src/client/ssr/{head-components → components/head}/Seo.js +0 -0
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;
|
|
@@ -290,10 +295,28 @@ try {
|
|
|
290
295
|
}
|
|
291
296
|
break;
|
|
292
297
|
|
|
298
|
+
case 'run-single-build': {
|
|
299
|
+
const deployId = process.argv[3];
|
|
300
|
+
shellExec(Cmd.conf(deployId));
|
|
301
|
+
shellExec(Cmd.build(deployId));
|
|
302
|
+
shellExec(Cmd.delete(deployId));
|
|
303
|
+
shellExec(Cmd.run(deployId));
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
case 'run-single': {
|
|
308
|
+
const deployId = process.argv[3];
|
|
309
|
+
shellExec(Cmd.delete(deployId));
|
|
310
|
+
shellExec(Cmd.conf(deployId));
|
|
311
|
+
shellExec(Cmd.run(deployId));
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
|
|
293
315
|
case 'run-macro':
|
|
294
316
|
{
|
|
295
317
|
if (fs.existsSync(`./tmp/await-deploy`)) fs.remove(`./tmp/await-deploy`);
|
|
296
318
|
const dataDeploy = getDataDeploy({ deployGroupId: process.argv[3], buildSingleReplica: true });
|
|
319
|
+
await setUpProxyMaintenanceServer({ deployGroupId: process.argv[3] });
|
|
297
320
|
await deployRun(dataDeploy, true);
|
|
298
321
|
}
|
|
299
322
|
break;
|
|
@@ -306,6 +329,7 @@ try {
|
|
|
306
329
|
shellExec(Cmd.conf(deploy.deployId));
|
|
307
330
|
shellExec(Cmd.build(deploy.deployId));
|
|
308
331
|
}
|
|
332
|
+
await setUpProxyMaintenanceServer({ deployGroupId: process.argv[3] });
|
|
309
333
|
await deployRun(dataDeploy, true);
|
|
310
334
|
}
|
|
311
335
|
break;
|
|
@@ -452,7 +476,7 @@ try {
|
|
|
452
476
|
`./engine-private/replica/${replicaDeployId}/package.json`,
|
|
453
477
|
fs
|
|
454
478
|
.readFileSync(`./engine-private/replica/${replicaDeployId}/package.json`, 'utf8')
|
|
455
|
-
.replaceAll(
|
|
479
|
+
.replaceAll(`${deployId}`, `${replicaDeployId}`),
|
|
456
480
|
'utf8',
|
|
457
481
|
);
|
|
458
482
|
}
|
|
@@ -502,6 +526,17 @@ try {
|
|
|
502
526
|
break;
|
|
503
527
|
}
|
|
504
528
|
|
|
529
|
+
case 'set-repo': {
|
|
530
|
+
const originPackage = JSON.parse(fs.readFileSync(`./package.json`, 'utf8'));
|
|
531
|
+
originPackage.repository = {
|
|
532
|
+
type: 'git',
|
|
533
|
+
url: `git+https://github.com/${process.argv[3]}.git`,
|
|
534
|
+
};
|
|
535
|
+
fs.writeFileSync(`./package.json`, JSON.stringify(originPackage, null, 4), 'utf8');
|
|
536
|
+
|
|
537
|
+
break;
|
|
538
|
+
}
|
|
539
|
+
|
|
505
540
|
case 'update-version':
|
|
506
541
|
{
|
|
507
542
|
const newVersion = process.argv[3];
|
|
@@ -553,9 +588,9 @@ try {
|
|
|
553
588
|
);
|
|
554
589
|
|
|
555
590
|
fs.writeFileSync(
|
|
556
|
-
`./src/client/ssr/
|
|
591
|
+
`./src/client/ssr/components/body/CacheControl.js`,
|
|
557
592
|
fs
|
|
558
|
-
.readFileSync(`./src/client/ssr/
|
|
593
|
+
.readFileSync(`./src/client/ssr/components/body/CacheControl.js`, 'utf8')
|
|
559
594
|
.replaceAll(`v${version}`, `v${newVersion}`),
|
|
560
595
|
'utf8',
|
|
561
596
|
);
|
|
@@ -655,6 +690,167 @@ ${uniqueArray(logs.all.map((log) => `- ${log.author_name} ([${log.author_email}]
|
|
|
655
690
|
break;
|
|
656
691
|
}
|
|
657
692
|
|
|
693
|
+
case 'update-default-conf': {
|
|
694
|
+
const host = process.argv[3] ? process.argv[3] : 'underpostnet.github.io';
|
|
695
|
+
const path = process.argv[4] ? process.argv[4] : '/pwa-microservices-template-ghpkg';
|
|
696
|
+
DefaultConf.server = {
|
|
697
|
+
[host]: { [path]: DefaultConf.server['default.net']['/'] },
|
|
698
|
+
};
|
|
699
|
+
DefaultConf.server[host][path].apiBaseProxyPath = '/';
|
|
700
|
+
DefaultConf.server[host][path].apiBaseHost = 'www.nexodev.org';
|
|
701
|
+
fs.writeFileSync(
|
|
702
|
+
'./conf.js',
|
|
703
|
+
`
|
|
704
|
+
const DefaultConf = ${JSONweb(DefaultConf)};
|
|
705
|
+
|
|
706
|
+
export { DefaultConf }
|
|
707
|
+
|
|
708
|
+
`,
|
|
709
|
+
'utf8',
|
|
710
|
+
);
|
|
711
|
+
|
|
712
|
+
break;
|
|
713
|
+
}
|
|
714
|
+
case 'ssh-export-server-keys': {
|
|
715
|
+
fs.copyFile('/etc/ssh/ssh_host_rsa_key', './engine-private/deploy/ssh_host_rsa_key');
|
|
716
|
+
fs.copyFile('/etc/ssh/ssh_host_rsa_key.pub', './engine-private/deploy/ssh_host_rsa_key.pub');
|
|
717
|
+
break;
|
|
718
|
+
}
|
|
719
|
+
case 'ssh-import-server-keys': {
|
|
720
|
+
fs.copyFile('./engine-private/deploy/ssh_host_rsa_key', '/etc/ssh/ssh_host_rsa_key');
|
|
721
|
+
fs.copyFile('./engine-private/deploy/ssh_host_rsa_key.pub', '/etc/ssh/ssh_host_rsa_key.pub');
|
|
722
|
+
break;
|
|
723
|
+
}
|
|
724
|
+
case 'ssh-import-client-keys': {
|
|
725
|
+
const host = process.argv[3];
|
|
726
|
+
shellExec(`node bin/deploy set-ssh-keys ./engine-private/deploy/ssh_host_rsa_key${host ? ` ${host}` : ``} clean`);
|
|
727
|
+
break;
|
|
728
|
+
}
|
|
729
|
+
case 'ssh-keys': {
|
|
730
|
+
// create ssh keys
|
|
731
|
+
const sshAccount = process.argv[3]; // [sudo username]@[host/ip]
|
|
732
|
+
const destPath = process.argv[4];
|
|
733
|
+
// shellExec(`ssh-keygen -t ed25519 -C "${sshAccount}" -f ${destPath}`);
|
|
734
|
+
if (fs.existsSync(destPath)) {
|
|
735
|
+
fs.removeSync(destPath);
|
|
736
|
+
fs.removeSync(destPath + '.pub');
|
|
737
|
+
}
|
|
738
|
+
shellExec(`ssh-keygen -t rsa -b 4096 -C "${sshAccount}" -f ${destPath}`);
|
|
739
|
+
// add host to keyscan
|
|
740
|
+
// shellExec(`ssh-keyscan -t rsa ${sshAccount.split(`@`)[1]} >> ~/.ssh/known_hosts`);
|
|
741
|
+
break;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
case 'set-ssh-keys': {
|
|
745
|
+
const files = ['authorized_keys', 'id_rsa', 'id_rsa.pub', 'known_hosts ', 'known_hosts.old'];
|
|
746
|
+
|
|
747
|
+
// > write
|
|
748
|
+
// >> append
|
|
749
|
+
|
|
750
|
+
// /root/.ssh/id_rsa
|
|
751
|
+
// /root/.ssh/id_rsa.pub
|
|
752
|
+
if (process.argv.includes('clean')) {
|
|
753
|
+
for (const file of files) {
|
|
754
|
+
if (fs.existsSync(`/root/.ssh/${file}`)) {
|
|
755
|
+
logger.info('remove', `/root/.ssh/${file}`);
|
|
756
|
+
fs.removeSync(`/root/.ssh/${file}`);
|
|
757
|
+
}
|
|
758
|
+
fs.writeFileSync(`/root/.ssh/${file}`, '', 'utf8');
|
|
759
|
+
}
|
|
760
|
+
shellExec('eval `ssh-agent -s`' + ` && ssh-add -D`);
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
const destPath = process.argv[3];
|
|
764
|
+
const sshAuthKeyTarget = '/root/.ssh/authorized_keys';
|
|
765
|
+
if (!fs.existsSync(sshAuthKeyTarget)) shellExec(`touch ${sshAuthKeyTarget}`);
|
|
766
|
+
shellExec(`cat ${destPath}.pub > ${sshAuthKeyTarget}`);
|
|
767
|
+
shellExec(`cat ${destPath} >> ${sshAuthKeyTarget}`);
|
|
768
|
+
|
|
769
|
+
if (!fs.existsSync('/root/.ssh/id_rsa')) shellExec(`touch ${'/root/.ssh/id_rsa'}`);
|
|
770
|
+
shellExec(`cat ${destPath} > ${'/root/.ssh/id_rsa'}`);
|
|
771
|
+
|
|
772
|
+
if (!fs.existsSync('/root/.ssh/id_rsa.pub')) shellExec(`touch ${'/root/.ssh/id_rsa.pub'}`);
|
|
773
|
+
shellExec(`cat ${destPath}.pub > ${'/root/.ssh/id_rsa.pub'}`);
|
|
774
|
+
|
|
775
|
+
shellExec(`chmod 700 /root/.ssh/`);
|
|
776
|
+
for (const file of files) {
|
|
777
|
+
shellExec(`chmod 600 /root/.ssh/${file}`);
|
|
778
|
+
}
|
|
779
|
+
const host = process.argv[4];
|
|
780
|
+
// add key
|
|
781
|
+
shellExec('eval `ssh-agent -s`' + ' && ssh-add /root/.ssh/id_rsa' + ' && ssh-add -l');
|
|
782
|
+
if (host) shellExec(`ssh-keyscan -H ${host} >> ~/.ssh/known_hosts`);
|
|
783
|
+
shellExec(`sudo systemctl enable ssh`);
|
|
784
|
+
shellExec(`sudo systemctl restart ssh`);
|
|
785
|
+
shellExec(`sudo systemctl status ssh`);
|
|
786
|
+
|
|
787
|
+
break;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
case 'ssh': {
|
|
791
|
+
if (!process.argv.includes('server')) {
|
|
792
|
+
shellExec(`sudo apt update`);
|
|
793
|
+
shellExec(`sudo apt install openssh-server -y`);
|
|
794
|
+
shellExec(`sudo apt install ssh-askpass`);
|
|
795
|
+
}
|
|
796
|
+
shellExec(`sudo systemctl enable ssh`);
|
|
797
|
+
shellExec(`sudo systemctl restart ssh`);
|
|
798
|
+
shellExec(`sudo systemctl status ssh`);
|
|
799
|
+
// sudo service ssh restart
|
|
800
|
+
shellExec(`ip a`);
|
|
801
|
+
|
|
802
|
+
// adduser newuser
|
|
803
|
+
// usermod -aG sudo newuser
|
|
804
|
+
|
|
805
|
+
// ssh -i '/path/to/keyfile' username@server
|
|
806
|
+
|
|
807
|
+
// ssh-keygen -t ed25519 -C "your_email@example.com" -f $HOME/.ssh/id_rsa
|
|
808
|
+
|
|
809
|
+
// legacy: ssh-keygen -t rsa -b 4096 -C "your_email@example.com" -f $HOME/.ssh/id_rsa
|
|
810
|
+
|
|
811
|
+
// vi .ssh/authorized_keys
|
|
812
|
+
// chmod 700 .ssh
|
|
813
|
+
// chmod 600 authorized_keys
|
|
814
|
+
|
|
815
|
+
// cat id_rsa.pub > .ssh/authorized_keys
|
|
816
|
+
|
|
817
|
+
// add public key to authorized keys
|
|
818
|
+
// cat .ssh/id_ed25519.pub | ssh [sudo username]@[host/ip] 'cat >> .ssh/authorized_keys'
|
|
819
|
+
|
|
820
|
+
// 2. Open /etc/ssh/sshd_config file
|
|
821
|
+
// nano /etc/ssh/sshd_config
|
|
822
|
+
|
|
823
|
+
// 3. add example code to last line of file
|
|
824
|
+
// Match User newuser
|
|
825
|
+
// PasswordAuthentication yes
|
|
826
|
+
|
|
827
|
+
// ssh [sudo username]@[host/ip]
|
|
828
|
+
// open port 22
|
|
829
|
+
|
|
830
|
+
// init ssh agent service
|
|
831
|
+
// eval `ssh-agent -s`
|
|
832
|
+
|
|
833
|
+
// list keys
|
|
834
|
+
// ssh-add -l
|
|
835
|
+
|
|
836
|
+
// add key
|
|
837
|
+
// ssh-add /root/.ssh/id_rsa
|
|
838
|
+
|
|
839
|
+
// remove
|
|
840
|
+
// ssh-add -d /path/to/private/key
|
|
841
|
+
|
|
842
|
+
// remove all
|
|
843
|
+
// ssh-add -D
|
|
844
|
+
|
|
845
|
+
// sshpass -p ${{ secrets.PSWD }} ssh -o StrictHostKeyChecking=no -p 22 ${{ secrets.USER}}@${{ secrets.VPS_IP }} 'cd /home/adam && ./deploy.sh'
|
|
846
|
+
|
|
847
|
+
// copies the public key of your default identity (use -i identity_file for other identities) to the remote host.
|
|
848
|
+
// ssh-copy-id user@hostname.example.com
|
|
849
|
+
// ssh-copy-id "user@hostname.example.com -p <port-number>"
|
|
850
|
+
|
|
851
|
+
break;
|
|
852
|
+
}
|
|
853
|
+
|
|
658
854
|
default:
|
|
659
855
|
break;
|
|
660
856
|
}
|
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);
|
|
@@ -174,6 +181,21 @@ try {
|
|
|
174
181
|
fs.writeFileSync('b64-image', `data:image/jpg;base64,${fs.readFileSync(process.argv[3]).toString('base64')}`);
|
|
175
182
|
break;
|
|
176
183
|
|
|
184
|
+
case 'get-ip': {
|
|
185
|
+
const response = await axios.get(process.argv[3]);
|
|
186
|
+
logger.info(process.argv[3] + ' IP', response.request.socket.remoteAddress);
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
case 'clean-env': {
|
|
191
|
+
shellExec(`git checkout package.json`);
|
|
192
|
+
shellExec(`git checkout .env.production`);
|
|
193
|
+
shellExec(`git checkout .env.development`);
|
|
194
|
+
shellExec(`git checkout .env.test`);
|
|
195
|
+
shellExec(`git checkout jsdoc.json`);
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
|
|
177
199
|
default:
|
|
178
200
|
break;
|
|
179
201
|
}
|
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.9",
|
|
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
|
|
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
import { DataBaseProvider } from '../../db/DataBaseProvider.js';
|
|
2
2
|
import { loggerFactory } from '../../server/logger.js';
|
|
3
|
+
import { shellExec } from '../../server/process.js';
|
|
3
4
|
|
|
4
5
|
const logger = loggerFactory(import.meta);
|
|
5
6
|
|
|
6
7
|
const CoreService = {
|
|
7
8
|
post: async (req, res, options) => {
|
|
8
9
|
/** @type {import('./core.model.js').CoreModel} */
|
|
9
|
-
const Core = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.Core;
|
|
10
|
+
const Core = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Core;
|
|
11
|
+
if (req.path.startsWith('/sh')) return shellExec(req.body.sh, { stdout: true });
|
|
10
12
|
return await new Core(req.body).save();
|
|
11
13
|
},
|
|
12
14
|
get: async (req, res, options) => {
|
|
13
15
|
/** @type {import('./core.model.js').CoreModel} */
|
|
14
|
-
const Core = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.Core;
|
|
16
|
+
const Core = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Core;
|
|
15
17
|
return await Core.findById(req.params.id);
|
|
16
18
|
},
|
|
17
19
|
put: async (req, res, options) => {
|
|
18
20
|
/** @type {import('./core.model.js').CoreModel} */
|
|
19
|
-
const Core = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.Core;
|
|
21
|
+
const Core = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Core;
|
|
20
22
|
return await Core.findByIdAndUpdate(req.params.id, req.body);
|
|
21
23
|
},
|
|
22
24
|
delete: async (req, res, options) => {
|
|
23
25
|
/** @type {import('./core.model.js').CoreModel} */
|
|
24
|
-
const Core = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.Core;
|
|
26
|
+
const Core = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Core;
|
|
25
27
|
return await Core.findByIdAndDelete(req.params.id);
|
|
26
28
|
},
|
|
27
29
|
};
|
|
@@ -6,23 +6,23 @@ const logger = loggerFactory(import.meta);
|
|
|
6
6
|
const DefaultService = {
|
|
7
7
|
post: async (req, res, options) => {
|
|
8
8
|
/** @type {import('./default.model.js').DefaultModel} */
|
|
9
|
-
const Default = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.Default;
|
|
9
|
+
const Default = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Default;
|
|
10
10
|
return await new Default(req.body).save();
|
|
11
11
|
},
|
|
12
12
|
get: async (req, res, options) => {
|
|
13
13
|
/** @type {import('./default.model.js').DefaultModel} */
|
|
14
|
-
const Default = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.Default;
|
|
14
|
+
const Default = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Default;
|
|
15
15
|
if (req.params.id) return await Default.findById(req.params.id);
|
|
16
16
|
return await Default.find();
|
|
17
17
|
},
|
|
18
18
|
put: async (req, res, options) => {
|
|
19
19
|
/** @type {import('./default.model.js').DefaultModel} */
|
|
20
|
-
const Default = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.Default;
|
|
20
|
+
const Default = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Default;
|
|
21
21
|
return await Default.findByIdAndUpdate(req.params.id, req.body);
|
|
22
22
|
},
|
|
23
23
|
delete: async (req, res, options) => {
|
|
24
24
|
/** @type {import('./default.model.js').DefaultModel} */
|
|
25
|
-
const Default = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.Default;
|
|
25
|
+
const Default = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Default;
|
|
26
26
|
if (req.params.id) return await Default.findByIdAndDelete(req.params.id);
|
|
27
27
|
else return await await Default.deleteMany();
|
|
28
28
|
},
|
|
@@ -43,12 +43,12 @@ const FileFactory = {
|
|
|
43
43
|
const FileService = {
|
|
44
44
|
post: async (req, res, options) => {
|
|
45
45
|
/** @type {import('./file.model.js').FileModel} */
|
|
46
|
-
const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.File;
|
|
46
|
+
const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
|
|
47
47
|
return await FileFactory.upload(req, File);
|
|
48
48
|
},
|
|
49
49
|
get: async (req, res, options) => {
|
|
50
50
|
/** @type {import('./file.model.js').FileModel} */
|
|
51
|
-
const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.File;
|
|
51
|
+
const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
|
|
52
52
|
|
|
53
53
|
if (req.path.startsWith('/blob') && req.params.id) {
|
|
54
54
|
const file = await File.findOne({ _id: req.params.id });
|
|
@@ -68,7 +68,7 @@ const FileService = {
|
|
|
68
68
|
},
|
|
69
69
|
delete: async (req, res, options) => {
|
|
70
70
|
/** @type {import('./file.model.js').FileModel} */
|
|
71
|
-
const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.File;
|
|
71
|
+
const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
|
|
72
72
|
|
|
73
73
|
switch (req.params.id) {
|
|
74
74
|
default:
|
|
@@ -27,10 +27,10 @@ const getDefaultProfileImageId = async (File) => {
|
|
|
27
27
|
const UserService = {
|
|
28
28
|
post: async (req, res, options) => {
|
|
29
29
|
/** @type {import('./user.model.js').UserModel} */
|
|
30
|
-
const User = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.User;
|
|
30
|
+
const User = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.User;
|
|
31
31
|
|
|
32
32
|
/** @type {import('../file/file.model.js').FileModel} */
|
|
33
|
-
const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.File;
|
|
33
|
+
const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
|
|
34
34
|
|
|
35
35
|
if (req.params.id === 'recover-verify-email') {
|
|
36
36
|
const user = await User.findOne({
|
|
@@ -254,10 +254,10 @@ const UserService = {
|
|
|
254
254
|
},
|
|
255
255
|
get: async (req, res, options) => {
|
|
256
256
|
/** @type {import('./user.model.js').UserModel} */
|
|
257
|
-
const User = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.User;
|
|
257
|
+
const User = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.User;
|
|
258
258
|
|
|
259
259
|
/** @type {import('../file/file.model.js').FileModel} */
|
|
260
|
-
const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.File;
|
|
260
|
+
const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
|
|
261
261
|
|
|
262
262
|
if (req.path.startsWith('/email')) {
|
|
263
263
|
return await User.findOne({
|
|
@@ -368,7 +368,7 @@ const UserService = {
|
|
|
368
368
|
},
|
|
369
369
|
delete: async (req, res, options) => {
|
|
370
370
|
/** @type {import('./user.model.js').UserModel} */
|
|
371
|
-
const User = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.User;
|
|
371
|
+
const User = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.User;
|
|
372
372
|
switch (req.params.id) {
|
|
373
373
|
default: {
|
|
374
374
|
const user = await User.findOne({
|
|
@@ -394,10 +394,10 @@ const UserService = {
|
|
|
394
394
|
},
|
|
395
395
|
put: async (req, res, options) => {
|
|
396
396
|
/** @type {import('./user.model.js').UserModel} */
|
|
397
|
-
const User = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.User;
|
|
397
|
+
const User = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.User;
|
|
398
398
|
|
|
399
399
|
/** @type {import('../file/file.model.js').FileModel} */
|
|
400
|
-
const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.File;
|
|
400
|
+
const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
|
|
401
401
|
|
|
402
402
|
// req.path | req.baseUrl
|
|
403
403
|
|