underpost 2.8.877 → 2.8.878

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.
@@ -30,9 +30,8 @@ jobs:
30
30
  echo "Starting remote release deploy"
31
31
  cd /home/dd/engine
32
32
  npm install -g underpost
33
- underpost config set GITHUB_TOKEN ${{ secrets.GITHUB_TOKEN }}
33
+ underpost run secret
34
34
  node bin run --dev pull
35
35
  underpost run secret
36
36
  underpost run underpost-config
37
- node bin run --dev pull
38
37
  underpost run ssh-deploy engine-test
package/README.md CHANGED
@@ -55,13 +55,15 @@
55
55
 
56
56
 
57
57
 
58
+
59
+
58
60
 
59
61
 
60
62
 
61
63
  <!-- badges -->
62
64
 
63
65
 
64
- [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.yml) [![Downloads](https://img.shields.io/npm/dm/underpost.svg)](https://www.npmjs.com/package/underpost) [![Socket Badge](https://socket.dev/api/badge/npm/package/underpost/2.8.877)](https://socket.dev/npm/package/underpost/overview/2.8.877) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine/badge.svg?branch=master)](https://coveralls.io/github/underpostnet/engine?branch=master) [![Version](https://img.shields.io/npm/v/underpost.svg)](https://www.npmjs.org/package/underpost) [![License](https://img.shields.io/npm/l/underpost.svg)](https://www.npmjs.com/package/underpost)
66
+ [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.yml) [![Downloads](https://img.shields.io/npm/dm/underpost.svg)](https://www.npmjs.com/package/underpost) [![Socket Badge](https://socket.dev/api/badge/npm/package/underpost/2.8.878)](https://socket.dev/npm/package/underpost/overview/2.8.878) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine/badge.svg?branch=master)](https://coveralls.io/github/underpostnet/engine?branch=master) [![Version](https://img.shields.io/npm/v/underpost.svg)](https://www.npmjs.org/package/underpost) [![License](https://img.shields.io/npm/l/underpost.svg)](https://www.npmjs.com/package/underpost)
65
67
 
66
68
 
67
69
  <!-- end-badges -->
@@ -105,6 +107,8 @@
105
107
 
106
108
 
107
109
 
110
+
111
+
108
112
 
109
113
 
110
114
 
@@ -152,7 +156,7 @@ Run dev client server
152
156
  npm run dev
153
157
  ```
154
158
  <!-- -->
155
- ## underpost ci/cd cli v2.8.877
159
+ ## underpost ci/cd cli v2.8.878
156
160
 
157
161
  ### Usage: `underpost [options] [command]`
158
162
  ```
package/cli.md CHANGED
@@ -1,4 +1,4 @@
1
- ## underpost ci/cd cli v2.8.877
1
+ ## underpost ci/cd cli v2.8.878
2
2
 
3
3
  ### Usage: `underpost [options] [command]`
4
4
  ```
@@ -51,6 +51,7 @@ Arguments:
51
51
 
52
52
  Options:
53
53
  --deploy-id Crete deploy ID conf env files
54
+ --cluster Create deploy ID cluster files and sync to current cluster
54
55
  --dev Sets the development cli context
55
56
  -h, --help display help for command
56
57
 
@@ -17,7 +17,7 @@ spec:
17
17
  spec:
18
18
  containers:
19
19
  - name: dd-default-development-blue
20
- image: localhost/rockylinux9-underpost:v2.8.877
20
+ image: localhost/rockylinux9-underpost:v2.8.878
21
21
  # resources:
22
22
  # requests:
23
23
  # memory: "124Ki"
@@ -100,7 +100,7 @@ spec:
100
100
  spec:
101
101
  containers:
102
102
  - name: dd-default-development-green
103
- image: localhost/rockylinux9-underpost:v2.8.877
103
+ image: localhost/rockylinux9-underpost:v2.8.878
104
104
  # resources:
105
105
  # requests:
106
106
  # memory: "124Ki"
@@ -17,7 +17,7 @@ spec:
17
17
  spec:
18
18
  containers:
19
19
  - name: dd-test-development-blue
20
- image: localhost/rockylinux9-underpost:v2.8.877
20
+ image: localhost/rockylinux9-underpost:v2.8.878
21
21
  # resources:
22
22
  # requests:
23
23
  # memory: "94Ki"
@@ -104,7 +104,7 @@ spec:
104
104
  spec:
105
105
  containers:
106
106
  - name: dd-test-development-green
107
- image: localhost/rockylinux9-underpost:v2.8.877
107
+ image: localhost/rockylinux9-underpost:v2.8.878
108
108
  # resources:
109
109
  # requests:
110
110
  # memory: "94Ki"
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "main": "src/index.js",
4
4
  "name": "underpost",
5
- "version": "2.8.877",
5
+ "version": "2.8.878",
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",
@@ -20,7 +20,21 @@ const FileController = {
20
20
  get: async (req, res, options) => {
21
21
  try {
22
22
  const result = await FileService.get(req, res, options);
23
- if (result instanceof Buffer) return res.status(200).end(result);
23
+ if (result instanceof Buffer) {
24
+ if (
25
+ process.env.NODE_ENV === 'development' ||
26
+ req.hostname === options.host ||
27
+ (options.origins && options.origins.find((o) => o.match(req.hostname)))
28
+ ) {
29
+ res.set('Cross-Origin-Resource-Policy', 'cross-origin');
30
+ return res.status(200).end(result);
31
+ }
32
+ return res.status(403).json({
33
+ status: 'error',
34
+ message: 'Forbidden',
35
+ });
36
+ }
37
+
24
38
  return res.status(200).json({
25
39
  status: 'success',
26
40
  data: result,
@@ -48,9 +48,10 @@ const UserRouter = (options) => {
48
48
  check: fs.readFileSync(`./src/client/public/default/assets/mailer/api-user-check.png`),
49
49
  },
50
50
  header: (res) => {
51
- res.header('Access-Control-Allow-Origin', '*');
52
- res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
53
- res.header('Content-Type', 'image/png');
51
+ res.set('Cross-Origin-Resource-Policy', 'cross-origin');
52
+ res.set('Access-Control-Allow-Origin', '*');
53
+ res.set('Access-Control-Allow-Headers', '*');
54
+ res.set('Content-Type', 'image/png');
54
55
  },
55
56
  };
56
57
 
package/src/cli/index.js CHANGED
@@ -24,6 +24,7 @@ program
24
24
  .command('new')
25
25
  .argument('<app-name>', 'The name or deploy-id of the application to create.')
26
26
  .option('--deploy-id', 'Crete deploy ID conf env files')
27
+ .option('--cluster', 'Create deploy ID cluster files and sync to current cluster')
27
28
  .option('--dev', 'Sets the development cli context')
28
29
  .description('Initializes a new Underpost project with a predefined structure.')
29
30
  .action(Underpost.repo.new);
@@ -90,7 +90,7 @@ class UnderpostRepository {
90
90
  );
91
91
  },
92
92
 
93
- new(repositoryName, options = { dev: false, deployId: false }) {
93
+ new(repositoryName, options = { dev: false, deployId: false, cluster: false }) {
94
94
  return new Promise(async (resolve, reject) => {
95
95
  try {
96
96
  await logger.setUpInfo();
@@ -99,7 +99,7 @@ class UnderpostRepository {
99
99
  return resolve(
100
100
  await UnderpostStartUp.API.listenPortController(UnderpostStartUp.API.listenServerFactory(), ':'),
101
101
  );
102
- if (options.deployId === true) return Config.deployIdFactory(repositoryName);
102
+ if (options.deployId === true) return Config.deployIdFactory(repositoryName, options);
103
103
  const npmRoot = getNpmRootPath();
104
104
  const underpostRoot = options?.dev === true ? '.' : `${npmRoot}/underpost`;
105
105
  const destFolder = `./${repositoryName}`;
package/src/cli/run.js CHANGED
@@ -107,6 +107,8 @@ class UnderpostRun {
107
107
  },
108
108
  'template-deploy': (path, options = UnderpostRun.DEFAULT_OPTION) => {
109
109
  const baseCommand = options.dev || true ? 'node bin' : 'underpost';
110
+ shellExec(`${baseCommand} run clean`);
111
+ shellExec(`${baseCommand} push ./engine-private ${process.env.GITHUB_USERNAME}/engine-private`);
110
112
  shellCd('/home/dd/engine');
111
113
  shellExec(`git reset`);
112
114
  shellExec(`${baseCommand} cmt . --empty ci package-pwa-microservices-template`);
@@ -17,10 +17,6 @@ import { SocketIoDefault } from './components/default/SocketIoDefault.js';
17
17
  import { ElementsDefault } from './components/default/ElementsDefault.js';
18
18
  import { CssDefaultDark, CssDefaultLight } from './components/default/CssDefault.js';
19
19
 
20
- const htmlMainBody = async () => {
21
- return html`<span>Hello World!!</span>`;
22
- };
23
-
24
20
  window.onload = () =>
25
21
  Worker.instance({
26
22
  router: RouterDefault,
@@ -29,7 +25,7 @@ window.onload = () =>
29
25
  await TranslateCore.Init();
30
26
  await TranslateDefault.Init();
31
27
  await Responsive.Init();
32
- await MenuDefault.Render({ htmlMainBody });
28
+ await MenuDefault.Render();
33
29
  await SocketIo.Init({
34
30
  channels: ElementsDefault.Data,
35
31
  path: `/`,
@@ -137,11 +137,7 @@ const Content = {
137
137
  case 'svg':
138
138
  case 'gif':
139
139
  case 'png': {
140
- const url = options.url
141
- ? options.url
142
- : file._id
143
- ? getApiBaseUrl({ id: file._id, endpoint: 'file/blob' })
144
- : URL.createObjectURL(getBlobFromUint8ArrayFile(file.data.data, file.mimetype));
140
+ const url = Content.urlFactory(options);
145
141
  const imgRender = html`<img
146
142
  class="in ${options.class}"
147
143
  ${styleFactory(options.style, `${renderChessPattern(50)}`)}
@@ -151,11 +147,7 @@ const Content = {
151
147
  break;
152
148
  }
153
149
  case 'pdf': {
154
- const url = options.url
155
- ? options.url
156
- : file._id
157
- ? getApiBaseUrl({ id: file._id, endpoint: 'file/blob' })
158
- : URL.createObjectURL(getBlobFromUint8ArrayFile(file.data.data, file.mimetype));
150
+ const url = Content.urlFactory(options);
159
151
  render += html`<iframe
160
152
  class="in ${options.class} iframe-${options.idModal}"
161
153
  ${styleFactory(options.style)}
@@ -189,6 +181,15 @@ const Content = {
189
181
  if (options.raw) return render;
190
182
  append(container, render);
191
183
  },
184
+ urlFactory: function (options) {
185
+ return options.url
186
+ ? options.url
187
+ : options.file?.data?.data
188
+ ? URL.createObjectURL(getBlobFromUint8ArrayFile(options.file.data.data, options.file.mimetype))
189
+ : options.file._id
190
+ ? getApiBaseUrl({ id: options.file._id, endpoint: 'file/blob' })
191
+ : null;
192
+ },
192
193
  };
193
194
 
194
195
  export { Content };
@@ -88,6 +88,7 @@ const UserService = {
88
88
  fetch(getApiBaseUrl({ id: options.id, endpoint }), {
89
89
  method: 'PUT',
90
90
  headers: headersFactory(options.headerId),
91
+ credentials: 'include',
91
92
  body: payloadFactory(options.body),
92
93
  })
93
94
  .then(async (res) => {
package/src/index.js CHANGED
@@ -35,7 +35,7 @@ class Underpost {
35
35
  * @type {String}
36
36
  * @memberof Underpost
37
37
  */
38
- static version = 'v2.8.877';
38
+ static version = 'v2.8.878';
39
39
  /**
40
40
  * Repository cli API
41
41
  * @static
@@ -523,6 +523,7 @@ function applySecurity(app, opts = {}) {
523
523
 
524
524
  // Content-Security-Policy: include nonce from res.locals
525
525
  // Note: We avoid 'unsafe-inline' on script/style. Use nonces or hashes.
526
+ const httpDirective = process.env.NODE_ENV === 'production' ? 'https:' : 'http:';
526
527
  app.use(
527
528
  helmet.contentSecurityPolicy({
528
529
  useDefaults: true,
@@ -530,16 +531,16 @@ function applySecurity(app, opts = {}) {
530
531
  defaultSrc: ["'self'"],
531
532
  baseUri: ["'self'"],
532
533
  blockAllMixedContent: [],
533
- fontSrc: ["'self'", 'https:', 'data:'],
534
+ fontSrc: ["'self'", httpDirective, 'data:'],
534
535
  frameAncestors: frameAncestors,
535
- imgSrc: ["'self'", 'data:', 'https:'],
536
+ imgSrc: ["'self'", 'data:', httpDirective],
536
537
  objectSrc: ["'none'"],
537
538
  // script-src and script-src-elem include dynamic nonce
538
539
  scriptSrc: ["'self'", (req, res) => `'nonce-${res.locals.nonce}'`],
539
540
  scriptSrcElem: ["'self'", (req, res) => `'nonce-${res.locals.nonce}'`],
540
541
  // style-src: avoid 'unsafe-inline' when possible; if you must inline styles,
541
542
  // use a nonce for them too (or hash).
542
- styleSrc: ["'self'", 'https:', (req, res) => `'nonce-${res.locals.nonce}'`],
543
+ styleSrc: ["'self'", httpDirective, (req, res) => `'nonce-${res.locals.nonce}'`],
543
544
  // deny plugins
544
545
  objectSrc: ["'none'"],
545
546
  },
@@ -33,12 +33,13 @@ const Config = {
33
33
  else if (deployContext.startsWith('dd-')) return loadConf(deployContext, process.env.NODE_ENV, subConf);
34
34
  if (deployContext === 'proxy') Config.buildProxy(deployContext, deployList, subConf);
35
35
  },
36
- deployIdFactory: function (deployId = 'dd-default') {
36
+ deployIdFactory: function (deployId = 'dd-default', options = { cluster: false }) {
37
37
  if (!deployId.startsWith('dd-')) deployId = `dd-${deployId}`;
38
38
 
39
39
  logger.info('Build deployId', deployId);
40
40
 
41
41
  const folder = `./engine-private/conf/${deployId}`;
42
+ const repoName = `engine-${deployId.split('dd-')[1]}`;
42
43
 
43
44
  if (!fs.existsSync(folder)) fs.mkdirSync(folder, { recursive: true });
44
45
  fs.writeFileSync(
@@ -56,10 +57,44 @@ const Config = {
56
57
  fs.readFileSync('./.env.test', 'utf8').replaceAll('dd-default', deployId),
57
58
  'utf8',
58
59
  );
59
- fs.writeFileSync(`${folder}/package.json`, fs.readFileSync('./package.json', 'utf8'), 'utf8');
60
+ fs.writeFileSync(
61
+ `${folder}/package.json`,
62
+ fs.readFileSync('./package.json', 'utf8').replaceAll('dd-default', deployId),
63
+ 'utf8',
64
+ );
60
65
 
61
66
  this.buildTmpConf(folder);
62
67
 
68
+ if (options.cluster === true) {
69
+ fs.writeFileSync(
70
+ `./.github/workflows/${repoName}.cd.yml`,
71
+ fs.readFileSync(`./.github/workflows/engine-test.cd.yml`, 'utf8').replaceAll('test', deployId.split('dd-')[1]),
72
+ 'utf8',
73
+ );
74
+ fs.writeFileSync(
75
+ `./.github/workflows/${repoName}.ci.yml`,
76
+ fs.readFileSync(`./.github/workflows/engine-test.ci.yml`, 'utf8').replaceAll('test', deployId.split('dd-')[1]),
77
+ 'utf8',
78
+ );
79
+ shellExec(`node bin/deploy update-default-conf ${deployId}`);
80
+ fs.writeFileSync(
81
+ `./engine-private/deploy/dd.router`,
82
+ fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8').trim() + `,${deployId}`,
83
+ 'utf8',
84
+ );
85
+ const updateRepo = (stage = 1) => {
86
+ shellExec(`git add . && git commit -m "Add base deployId ${deployId} cluster files stage:${stage}"`);
87
+ shellExec(
88
+ `cd engine-private && git add . && git commit -m "Add base deployId ${deployId} cluster files stage:${stage}"`,
89
+ );
90
+ };
91
+ updateRepo(1);
92
+ shellExec(`node bin run --build --dev sync`);
93
+ updateRepo(2);
94
+ shellExec(`node bin run --build sync`);
95
+ updateRepo(3);
96
+ }
97
+
63
98
  return { deployIdFolder: folder, deployId };
64
99
  },
65
100
  buildTmpConf: function (folder = './conf') {
@@ -117,9 +117,6 @@ const buildRuntime = async () => {
117
117
  // set logger
118
118
  app.use(loggerMiddleware(import.meta));
119
119
 
120
- // instance public static
121
- app.use('/', express.static(directory ? directory : `.${rootHostPath}`));
122
-
123
120
  // js src compression
124
121
  app.use(compression({ filter: shouldCompress }));
125
122
  function shouldCompress(req, res) {
@@ -164,6 +161,9 @@ const buildRuntime = async () => {
164
161
  return next();
165
162
  });
166
163
 
164
+ // instance public static
165
+ app.use('/', express.static(directory ? directory : `.${rootHostPath}`));
166
+
167
167
  // security
168
168
  applySecurity(app, {
169
169
  origin: origins.concat(
@@ -235,17 +235,13 @@ const buildRuntime = async () => {
235
235
  for (const api of apis)
236
236
  await (async () => {
237
237
  const { ApiRouter } = await import(`../api/${api}/${api}.router.js`);
238
- const router = ApiRouter({ host, path, apiPath, mailer, db, authMiddleware });
238
+ const router = ApiRouter({ host, path, apiPath, mailer, db, authMiddleware, origins });
239
239
  // router.use(cors({ origin: origins }));
240
240
  // logger.info('Load api router', { host, path: apiPath, api });
241
241
  app.use(`${apiPath}/${api}`, router);
242
242
  })();
243
243
  }
244
244
 
245
- // load ssr
246
- const ssr = await ssrMiddlewareFactory({ app, directory, rootHostPath, path });
247
- for (const [_, ssrMiddleware] of Object.entries(ssr)) app.use(ssrMiddleware);
248
-
249
245
  if (ws)
250
246
  await (async () => {
251
247
  const { createIoServer } = await import(`../ws/${ws}/${ws}.ws.server.js`);
@@ -287,6 +283,10 @@ const buildRuntime = async () => {
287
283
  }
288
284
  }
289
285
 
286
+ // load ssr
287
+ const ssr = await ssrMiddlewareFactory({ app, directory, rootHostPath, path });
288
+ for (const [_, ssrMiddleware] of Object.entries(ssr)) app.use(ssrMiddleware);
289
+
290
290
  await UnderpostStartUp.API.listenPortController(server, port, runningData);
291
291
 
292
292
  break;