underpost 2.8.881 → 2.8.883

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 (36) hide show
  1. package/.github/workflows/release.cd.yml +1 -2
  2. package/README.md +50 -36
  3. package/bin/db.js +1 -4
  4. package/cli.md +86 -86
  5. package/conf.js +1 -0
  6. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  7. package/manifests/deployment/dd-test-development/deployment.yaml +6 -6
  8. package/manifests/maas/device-scan.sh +1 -1
  9. package/package.json +1 -1
  10. package/src/api/document/document.service.js +9 -1
  11. package/src/cli/repository.js +2 -0
  12. package/src/client/components/core/Auth.js +258 -89
  13. package/src/client/components/core/BtnIcon.js +10 -1
  14. package/src/client/components/core/CssCore.js +36 -27
  15. package/src/client/components/core/Docs.js +188 -85
  16. package/src/client/components/core/LoadingAnimation.js +5 -10
  17. package/src/client/components/core/Modal.js +262 -120
  18. package/src/client/components/core/ObjectLayerEngine.js +154 -158
  19. package/src/client/components/core/Panel.js +2 -0
  20. package/src/client/components/core/PanelForm.js +94 -60
  21. package/src/client/components/core/Router.js +15 -15
  22. package/src/client/components/core/ToolTip.js +83 -19
  23. package/src/client/components/core/Translate.js +1 -1
  24. package/src/client/components/core/VanillaJs.js +4 -3
  25. package/src/client/components/core/windowGetDimensions.js +202 -0
  26. package/src/client/components/default/MenuDefault.js +11 -0
  27. package/src/client/ssr/Render.js +1 -1
  28. package/src/index.js +1 -1
  29. package/src/runtime/lampp/Lampp.js +253 -128
  30. package/src/server/auth.js +68 -17
  31. package/src/server/crypto.js +195 -76
  32. package/src/server/peer.js +47 -5
  33. package/src/server/process.js +85 -1
  34. package/src/server/runtime.js +13 -32
  35. package/test/crypto.test.js +117 -0
  36. package/src/runtime/xampp/Xampp.js +0 -83
@@ -0,0 +1,117 @@
1
+ /**
2
+ * @module crypto.test
3
+ * @description Unit tests for SymmetricCrypto and AsymmetricCrypto classes
4
+ * in the crypto module.
5
+ * * Uses 'chai' for assertions.
6
+ */
7
+
8
+ // Import Chai's assertion library
9
+ import { expect } from 'chai';
10
+
11
+ // Import the cryptographic classes from the Canvas's refactored module
12
+ import { SymmetricCrypto, AsymmetricCrypto } from '../src/server/crypto.js';
13
+
14
+ // Define a common plaintext message for testing
15
+ const plaintext = 'This is a secret message for testing cryptographic operations.';
16
+
17
+ // --- Main Test Suite ---
18
+
19
+ describe('Crypto Module Tests', () => {
20
+ // --- SymmetricCrypto Tests (AES-256-CBC) ---
21
+ describe('SymmetricCrypto (AES-256-CBC)', () => {
22
+ /**
23
+ * Test case: Verify that key and IV are automatically generated.
24
+ */
25
+ it('should generate new 32-byte key and 16-byte IV if none are provided', () => {
26
+ const symm = new SymmetricCrypto();
27
+ // Key should be 32 bytes (64 hex characters) and IV 16 bytes (32 hex characters)
28
+ expect(symm.encryptionKeyHex).to.be.a('string').and.have.lengthOf(64);
29
+ expect(symm.ivHex).to.be.a('string').and.have.lengthOf(32);
30
+ });
31
+
32
+ /**
33
+ * Test case: Encrypt data and ensure successful decryption back to the original plaintext.
34
+ */
35
+ it('should encrypt and successfully decrypt data', () => {
36
+ const symm = new SymmetricCrypto();
37
+ const ciphertext = symm.encryptData(plaintext);
38
+
39
+ // Ciphertext should contain IV and the encrypted data, separated by a colon
40
+ expect(ciphertext).to.include(':');
41
+
42
+ const decryptedText = symm.decryptData(ciphertext);
43
+ expect(decryptedText).to.equal(plaintext);
44
+ });
45
+
46
+ /**
47
+ * Test case: Verify that decryption fails gracefully if the ciphertext is tampered with (e.g., corrupting the encrypted payload).
48
+ *
49
+ * FIX: We now reliably tamper with the encrypted hex string by removing the last character.
50
+ * This ensures the underlying crypto operation fails due to invalid hex length or incomplete data,
51
+ * guaranteeing the try/catch block in the implementation is hit, and the expected error is thrown.
52
+ */
53
+ it('should fail decryption gracefully for tampered ciphertext (invalid payload)', () => {
54
+ const symm = new SymmetricCrypto();
55
+ const ciphertext = symm.encryptData(plaintext);
56
+
57
+ const [ivHex, encryptedHex] = ciphertext.split(':');
58
+
59
+ // Tamper with the encrypted content by cutting off the last character.
60
+ const tamperedEncryptedHex = encryptedHex.substring(0, encryptedHex.length - 1);
61
+
62
+ const tamperedCiphertext = `${ivHex}:${tamperedEncryptedHex}`;
63
+
64
+ // Expect the internal error handling to throw the generic error message
65
+ expect(() => symm.decryptData(tamperedCiphertext)).to.throw(
66
+ Error,
67
+ 'Decryption failed. Check key, IV, or ciphertext integrity.',
68
+ );
69
+ });
70
+ });
71
+
72
+ // --- AsymmetricCrypto Tests (RSA 2048) ---
73
+ describe('AsymmetricCrypto (RSA 2048)', () => {
74
+ /**
75
+ * Test case: Verify that RSA key pair is automatically generated.
76
+ */
77
+ it('should generate a new RSA key pair if none are provided', () => {
78
+ const asymm = new AsymmetricCrypto();
79
+ // Public and Private keys should be PEM strings
80
+ expect(asymm.publicKey).to.be.a('string').and.include('BEGIN PUBLIC KEY');
81
+ expect(asymm.privateKey).to.be.a('string').and.include('BEGIN PRIVATE KEY');
82
+ });
83
+
84
+ /**
85
+ * Test case: Encrypt with public key and decrypt with the corresponding private key.
86
+ */
87
+ it('should encrypt data with public key and decrypt with private key', () => {
88
+ const asymm = new AsymmetricCrypto();
89
+ const ciphertext = asymm.encryptData(plaintext);
90
+
91
+ // Ciphertext is a hex string
92
+ expect(ciphertext).to.be.a('string');
93
+
94
+ const decryptedText = asymm.decryptData(ciphertext);
95
+ expect(decryptedText).to.equal(plaintext);
96
+ });
97
+
98
+ /**
99
+ * Test case: Verify that decryption fails gracefully when using a mismatched private key.
100
+ */
101
+ it('should fail decryption gracefully when using the wrong private key', () => {
102
+ // 1. Generate the key pair and encrypt the data
103
+ const asymm1 = new AsymmetricCrypto();
104
+ const ciphertext = asymm1.encryptData(plaintext);
105
+
106
+ // 2. Generate a completely different key pair (wrong key)
107
+ const asymm2 = new AsymmetricCrypto();
108
+
109
+ // 3. Try to decrypt ciphertext from asymm1 using the private key from asymm2
110
+ // The implementation will log the 'oaep decoding error' and re-throw the generic message.
111
+ expect(() => asymm2.decryptData(ciphertext)).to.throw(
112
+ Error,
113
+ 'Decryption failed. Check private key or ciphertext integrity.',
114
+ );
115
+ });
116
+ });
117
+ });
@@ -1,83 +0,0 @@
1
- import fs from 'fs-extra';
2
- import { shellExec, getRootDirectory } from '../../server/process.js';
3
-
4
- const Xampp = {
5
- ports: [],
6
- initService: async function (options = { daemon: false }) {
7
- let cmd;
8
- // windows
9
- fs.writeFileSync(
10
- `C:/xampp/apache/conf/httpd.conf`,
11
- fs.readFileSync(`C:/xampp/apache/conf/httpd.template.conf`, 'utf8').replace(`Listen 80`, ``),
12
- 'utf8',
13
- );
14
- fs.writeFileSync(`C:/xampp/apache/conf/extra/httpd-ssl.conf`, this.router || '', 'utf8');
15
- cmd = `C:/xampp/xampp_stop.exe`;
16
- shellExec(cmd);
17
- cmd = `C:/xampp/xampp_start.exe`;
18
- if (this.router) fs.writeFileSync(`./tmp/xampp-router.conf`, this.router, 'utf-8');
19
- shellExec(cmd);
20
- },
21
- enabled: () => fs.existsSync(`C:/xampp/apache/conf/httpd.conf`),
22
- appendRouter: function (render) {
23
- if (!this.router) {
24
- if (fs.existsSync(`./tmp/xampp-router.conf`))
25
- return (this.router = fs.readFileSync(`./tmp/xampp-router.conf`, 'utf-8')) + render;
26
- return (this.router = render);
27
- }
28
- return (this.router += render);
29
- },
30
- removeRouter: function () {
31
- this.router = undefined;
32
- if (fs.existsSync(`./tmp/xampp-router.conf`)) fs.rmSync(`./tmp/xampp-router.conf`);
33
- },
34
- createApp: async ({ port, host, path, directory, rootHostPath, redirect, redirectTarget, resetRouter }) => {
35
- if (!Xampp.enabled()) {
36
- return { disabled: true };
37
- }
38
- if (!Xampp.ports.includes(port)) Xampp.ports.push(port);
39
- if (resetRouter) Xampp.removeRouter();
40
- Xampp.appendRouter(`
41
- Listen ${port}
42
-
43
- <VirtualHost *:${port}>
44
- DocumentRoot "${directory ? directory : `${getRootDirectory()}${rootHostPath}`}"
45
- ServerName ${host}:${port}
46
-
47
- <Directory "${directory ? directory : `${getRootDirectory()}${rootHostPath}`}">
48
- Options Indexes FollowSymLinks MultiViews
49
- AllowOverride All
50
- Require all granted
51
- </Directory>
52
-
53
- ${
54
- redirect
55
- ? `
56
- RewriteEngine on
57
-
58
- RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge
59
- RewriteRule ^(.*)$ ${redirectTarget}%{REQUEST_URI} [R=302,L]
60
- `
61
- : ''
62
- }
63
-
64
- ErrorDocument 400 ${path === '/' ? '' : path}/400.html
65
- ErrorDocument 404 ${path === '/' ? '' : path}/400.html
66
- ErrorDocument 500 ${path === '/' ? '' : path}/500.html
67
- ErrorDocument 502 ${path === '/' ? '' : path}/500.html
68
- ErrorDocument 503 ${path === '/' ? '' : path}/500.html
69
- ErrorDocument 504 ${path === '/' ? '' : path}/500.html
70
-
71
- </VirtualHost>
72
-
73
- `);
74
- // ERR too many redirects:
75
- // Check: SELECT * FROM database.wp_options where option_name = 'siteurl' or option_name = 'home';
76
- // Check: wp-config.php
77
- // if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
78
- // $_SERVER['HTTPS'] = 'on';
79
- // }
80
- },
81
- };
82
-
83
- export { Xampp };