@wppconnect/server-cli 1.3.56 → 1.3.57
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/CHANGELOG.md +8 -0
- package/Dockerfile +1 -0
- package/SECURITY_BACKPORTS.md +17 -0
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/program.js +2 -2
- package/dist/program.js.map +1 -1
- package/dist/security.js +48 -0
- package/dist/security.js.map +1 -0
- package/package.json +26 -20
- package/test/auth.test.js +14 -6
- package/test/deepmerge-security.test.js +76 -0
- package/test/dependency-globs.test.js +74 -0
- package/test/helpers/assert-packed-merger.cjs +48 -0
- package/test/packed-runtime-security.cjs +75 -0
- package/vendor/deepmerge/LICENSE +21 -0
- package/vendor/deepmerge/README.md +3 -0
- package/vendor/deepmerge/index.cjs +113 -0
- package/vendor/deepmerge/index.d.ts +20 -0
- package/vendor/deepmerge/is-mergeable-object.cjs +24 -0
- package/vendor/deepmerge/package.json +19 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [1.3.57](https://github.com/wppconnect-team/server-cli/compare/v1.3.56...v1.3.57) (2026-10-30)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
- complete Babel 8 migration and preserve CommonJS CLI ([#844](https://github.com/wppconnect-team/server-cli/issues/844)) ([a91dd3e](https://github.com/wppconnect-team/server-cli/commit/a91dd3e9cfedf1c97ae65ec1e4fa590c0ec8ab59))
|
|
6
|
+
- **deps:** resolve remaining CLI security alerts ([#876](https://github.com/wppconnect-team/server-cli/issues/876)) ([57ee10d](https://github.com/wppconnect-team/server-cli/commit/57ee10dcacb27f74101494a2f04743fcc3b242f5))
|
|
7
|
+
- protect browser option merging in installed CLI packages ([#877](https://github.com/wppconnect-team/server-cli/issues/877)) ([a61a8e2](https://github.com/wppconnect-team/server-cli/commit/a61a8e2f16e70d6daf3f9da9e07d039b074cd42f))
|
|
8
|
+
|
|
1
9
|
## [1.3.56](https://github.com/wppconnect-team/server-cli/compare/v1.3.55...v1.3.56) (2026-10-27)
|
|
2
10
|
|
|
3
11
|
### Bug Fixes
|
package/Dockerfile
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Private deepmerge backport
|
|
2
|
+
|
|
3
|
+
This repository-maintained artifact is based on deepmerge4.3.1 and the prototype-poisoning fix from upstream PR274, commit c5ad573121574db1c625b0aabcc6114ed7df6c5a. Its local version4.3.2+wppconnect.1 identifies our security patch and preserves4.x dependency compatibility. It is not a published upstream release. The package is private and must not be published to a registry.
|
|
4
|
+
|
|
5
|
+
Both copy loops reject the **proto** key before assigning properties. Other merging behavior is preserved. The is-mergeable-object1.1.0 helper is included locally because the original Git source declares it only as a development dependency. Original MIT notices are retained.
|
|
6
|
+
|
|
7
|
+
Source references:
|
|
8
|
+
|
|
9
|
+
- https://github.com/TehShrike/deepmerge/tree/5b87756a5671635679001cbac72aa42f23472c81
|
|
10
|
+
- https://github.com/TehShrike/deepmerge/pull/274/commits/c5ad573121574db1c625b0aabcc6114ed7df6c5a
|
|
11
|
+
- https://github.com/TehShrike/is-mergeable-object/tree/v1.1.0
|
|
12
|
+
|
|
13
|
+
The readable files in vendor/deepmerge and the local tarball represent the same runtime implementation. Native installed-package tests compare their contents. No install scripts, registry publication or changes to unrelated installed dependencies are needed.
|
|
14
|
+
|
|
15
|
+
For the CLI, the repository resolution selects the private artifact. The startup protection also uses Node's synchronous module-resolution hooks for affected deepmerge requests from Puppeteer Extra consumers, before loading the server dependencies. This covers registry installations where repository resolutions are not inherited and npm can install a separate original copy. Unrelated packages and already-fixed versions retain normal resolution. The CLI's required Node range already follows Babel8: ^22.18.0 or >=24.11.0.
|
|
16
|
+
|
|
17
|
+
Keep the regression tests when removing this backport after a validated upstream release is available.
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports, "__esModule", { value: true });exports.run = run;
|
|
1
|
+
"use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;Object.defineProperty(exports, "__esModule", { value: true });exports.run = run;
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
@@ -13,12 +13,13 @@
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
|
|
16
|
+
require("./security");
|
|
16
17
|
var _server = require("@wppconnect/server");
|
|
17
18
|
var express = _interopRequireWildcard(require("express"));
|
|
18
19
|
var fs = _interopRequireWildcard(require("fs"));
|
|
19
20
|
var path = _interopRequireWildcard(require("path"));
|
|
20
21
|
var _mergeDeep = _interopRequireDefault(require("merge-deep"));
|
|
21
|
-
var _program = require("./program");
|
|
22
|
+
var _program = require("./program"); /*
|
|
22
23
|
* Copyright 2021 WPPConnect Team
|
|
23
24
|
*
|
|
24
25
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["
|
|
1
|
+
{"version":3,"file":"index.js","names":["program","mergeDeep","initServer"],"sources":["../src/index.js"],"sourcesContent":["/*\n * Copyright 2021 WPPConnect Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport './security';\nimport { initServer } from '@wppconnect/server';\nimport * as express from 'express';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport mergeDeep from 'merge-deep';\nimport { program } from './program';\n\nconst DEFAULT_SECRET_KEY = 'THISISMYSECURETOKEN';\n\nexport function run() {\n let serverOptions = {};\n\n program.parse();\n const commandOptions = program.opts();\n\n if (commandOptions.config) {\n try {\n const json = fs.readFileSync(commandOptions.config, { encoding: 'utf8' });\n const configOptions = JSON.parse(json);\n\n serverOptions = mergeDeep({}, serverOptions, configOptions);\n } catch (error) {\n console.log(error);\n process.exit(1);\n }\n\n delete commandOptions.config;\n }\n\n const subOptions = ['webhook', 'archive', 'log', 'createOptions'];\n\n for (const key in commandOptions) {\n const opt = subOptions.find((opt) => key.startsWith(opt));\n\n if (opt) {\n commandOptions[opt] = commandOptions[opt] || {};\n\n const name = key.substr(opt.length);\n const newName = name[0].toLowerCase() + name.slice(1);\n\n commandOptions[opt][newName] = commandOptions[key];\n delete commandOptions[key];\n }\n }\n\n serverOptions = mergeDeep({}, serverOptions, commandOptions);\n\n // @wppconnect/server signs tokens with `secretKey` and otherwise falls back to\n // the public default, which would let anyone mint valid tokens. An explicit\n // empty/null value would also override that fallback (mergeDeep keeps it), so\n // blank values count as unset and the validated secret is passed explicitly.\n const isUsable = (value) => typeof value === 'string' && value.trim() !== '';\n const secretKey = isUsable(serverOptions.secretKey) ? serverOptions.secretKey : process.env.SECRET_KEY;\n\n if (!isUsable(secretKey) || secretKey === DEFAULT_SECRET_KEY) {\n console.error(\n 'Erro: nenhuma \"secretKey\" segura foi definida. Configure --secretKey, \"secretKey\" no arquivo de configuração ou a variável SECRET_KEY (o valor padrão público não é aceito).'\n );\n process.exit(1);\n }\n\n serverOptions.secretKey = secretKey;\n\n const { app } = initServer(serverOptions);\n\n if (commandOptions.frontend) {\n let frontendPath = commandOptions.frontendPath;\n\n if (!frontendPath) {\n try {\n const frontendPackage = require.resolve('@wppconnect/frontend/package.json');\n frontendPath = path.join(path.dirname(frontendPackage), 'build');\n } catch (error) {\n console.error(\n 'Não foi encontrado o caminho para o frontend, por favor defina com --frontend-path ou instale o pacote @wppconnect/frontend'\n );\n process.exit(1);\n }\n }\n\n if (frontendPath) {\n // Requisição de configuração do frontend\n app.use('/config.js', (req, res) => {\n res.set({\n 'Content-Type': 'application/javascript; charset=UTF-8',\n });\n res.send(`\n// Arquivo gerado automaticamente\nwindow.IP_SERVER = location.protocol + \"//\" + location.host + '/api/';\nwindow.IP_SOCKET_IO = ((location.protocol === 'https:') ? 'wss:' : 'ws:') + \"//\" + location.host;\n`);\n });\n\n app.use(express.static(frontendPath));\n\n app.get('*', function (req, res, next) {\n // Força a renderização do react para requisições do browser\n if (req.accepts('html')) {\n return res.sendfile(path.join(frontendPath, 'index.html'));\n }\n next();\n });\n }\n }\n}\n\nif (process.env['RUN_SERVER']) {\n run();\n}\n"],"mappings":"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","ignoreList":[]}
|
package/dist/program.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.program = void 0;
|
|
1
|
+
"use strict";var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;Object.defineProperty(exports, "__esModule", { value: true });exports.program = void 0;
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
var packageJSON = _interopRequireWildcard(require("../package.json"));
|
|
17
|
-
var _commander = require("commander");
|
|
17
|
+
var _commander = require("commander"); /*
|
|
18
18
|
* Copyright 2021 WPPConnect Team
|
|
19
19
|
*
|
|
20
20
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
package/dist/program.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"program.js","names":["
|
|
1
|
+
{"version":3,"file":"program.js","names":["Command"],"sources":["../src/program.js"],"sourcesContent":["/*\n * Copyright 2021 WPPConnect Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport * as packageJSON from '../package.json';\nimport { Command } from 'commander';\nexport const program = new Command();\n\nprogram.version(packageJSON.version);\n\n//#region frontend\nprogram.option('--frontend', 'Habilita o frontend');\nprogram.option('--frontend-path <path>', 'Caminho dos arquivos de frontend (pasta dist)');\n//#endregion\n\n//#region comum\nprogram.option('-c, --config <path>', 'Arquivo JSON de configuração para inicialização');\n\n// Host\nprogram.option('-h, --host <host>', 'Host de execução');\nprogram.option('-p, --port <numero>', 'Porta de execução');\nprogram.option('-k, --secretKey <chave>', 'Chave secreta para validação de tokens');\nprogram.option('--startAllSession', 'Habilita a auto inicialização das sessões');\nprogram.option('--no-startAllSession', 'Desabilita a auto inicialização das sessões');\n//#endregion\n\n//#region webhook\nprogram.option('--webhook-url <url>', 'URL para as chamadas de webhook');\nprogram.option('--webhook-autoDownload', 'Habilita o auto download de arquivo');\nprogram.option('--no-webhook-autoDownload', 'Desabilita o auto download de arquivo');\nprogram.option('--webhook-readMessage', 'Habilita a marcação automática de lido');\nprogram.option('--no-webhook-readMessage', 'Desabilita a marcação automática de lido');\nprogram.option('--webhook-allUnreadOnStart', 'Envia no webhook todas as mensagens não lidas na inicialização');\nprogram.option('--no-webhook-listenAcks', 'Desabilita o envio de ACKs no webhook');\nprogram.option('--no-webhook-onPresenceChanged', 'Desabilita o envio do onPresenceChanged no webhook');\nprogram.option('--no-webhook-onParticipantsChanged', 'Desabilita o envio do onParticipantsChanged no webhook');\n//#endregion\n\n//#region archive\nprogram.option('--archive-enable', 'Habilita o auto-arquivamento');\nprogram.option('--no-archive-enable', 'Desabilita o auto-arquivamento');\nprogram.option('--archive-waitTime <milisegundos>', 'Tempo de espera de arquivamento entre chats');\nprogram.option('--archive-daysToArchive <dias>', 'Dias de inatividade para arquivar');\n//#endregion\n\n//#region log\nprogram.option('--log-level <level>', 'Nível de detalhe de log');\nprogram.option('--log-logger <saidas...>', 'Opções de saída de LOG');\n//#endregion\n\n//#region createOptions\nprogram.option('--createOptions-browserArgs <opcoes...>', 'Opções para serem passadas na inicialização do browser');\n//#endregion\n"],"mappings":";;;;;;;;;;;;;;;AAeA;AACA,sCAAoC,CAhBpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAGO,MAAM,OAAO,qBAAG,IAAIA,WAAA,OAAO,CAAC,CAAC,CAEpC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAErC;AACA,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,qBAAqB,CAAC,CACnD,OAAO,CAAC,MAAM,CAAC,wBAAwB,EAAE,+CAA+C,CAAC,CAAC,CAC1F;AAEA;AACA,OAAO,CAAC,MAAM,CAAC,qBAAqB,EAAE,iDAAiD,CAAC,CAAC,CAEzF;AACA,OAAO,CAAC,MAAM,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CACvD,OAAO,CAAC,MAAM,CAAC,qBAAqB,EAAE,mBAAmB,CAAC,CAC1D,OAAO,CAAC,MAAM,CAAC,yBAAyB,EAAE,wCAAwC,CAAC,CACnF,OAAO,CAAC,MAAM,CAAC,mBAAmB,EAAE,2CAA2C,CAAC,CAChF,OAAO,CAAC,MAAM,CAAC,sBAAsB,EAAE,6CAA6C,CAAC;AACrF;;AAEA;AACA,OAAO,CAAC,MAAM,CAAC,qBAAqB,EAAE,iCAAiC,CAAC;AACxE,OAAO,CAAC,MAAM,CAAC,wBAAwB,EAAE,qCAAqC,CAAC;AAC/E,OAAO,CAAC,MAAM,CAAC,2BAA2B,EAAE,uCAAuC,CAAC;AACpF,OAAO,CAAC,MAAM,CAAC,uBAAuB,EAAE,wCAAwC,CAAC;AACjF,OAAO,CAAC,MAAM,CAAC,0BAA0B,EAAE,0CAA0C,CAAC;AACtF,OAAO,CAAC,MAAM,CAAC,4BAA4B,EAAE,gEAAgE,CAAC;AAC9G,OAAO,CAAC,MAAM,CAAC,yBAAyB,EAAE,uCAAuC,CAAC;AAClF,OAAO,CAAC,MAAM,CAAC,gCAAgC,EAAE,oDAAoD,CAAC;AACtG,OAAO,CAAC,MAAM,CAAC,oCAAoC,EAAE,wDAAwD,CAAC;AAC9G;;AAEA;AACA,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,8BAA8B,CAAC;AAClE,OAAO,CAAC,MAAM,CAAC,qBAAqB,EAAE,gCAAgC,CAAC;AACvE,OAAO,CAAC,MAAM,CAAC,mCAAmC,EAAE,6CAA6C,CAAC;AAClG,OAAO,CAAC,MAAM,CAAC,gCAAgC,EAAE,mCAAmC,CAAC;AACrF;;AAEA;AACA,OAAO,CAAC,MAAM,CAAC,qBAAqB,EAAE,yBAAyB,CAAC;AAChE,OAAO,CAAC,MAAM,CAAC,0BAA0B,EAAE,wBAAwB,CAAC;AACpE;;AAEA;AACA,OAAO,CAAC,MAAM,CAAC,yCAAyC,EAAE,wDAAwD,CAAC;AACnH","ignoreList":[]}
|
package/dist/security.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict"; /*
|
|
2
|
+
* Copyright 2026 WPPConnect Team
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
// Keep the browser option merger protected in registry installations too.
|
|
17
|
+
// Package-manager overrides apply to the repository root, not its consumers.
|
|
18
|
+
const fs = require('node:fs');
|
|
19
|
+
const path = require('node:path');
|
|
20
|
+
const { createRequire, registerHooks } = require('node:module');
|
|
21
|
+
const { pathToFileURL } = require('node:url');
|
|
22
|
+
|
|
23
|
+
if (typeof registerHooks !== 'function') {
|
|
24
|
+
throw new Error('WPPConnect CLI requires Node 22.18 or a supported newer version.');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const patched = pathToFileURL(path.resolve(__dirname, '../vendor/deepmerge/index.cjs')).href;
|
|
28
|
+
const affected = new Set(['4.2.0', '4.2.1', '4.2.2', '4.3.0', '4.3.1']);
|
|
29
|
+
const versions = new Map();
|
|
30
|
+
const browserConsumer = /\/node_modules\/puppeteer-extra(?:-plugin(?:-[^/]+)?)?\//;
|
|
31
|
+
|
|
32
|
+
registerHooks({
|
|
33
|
+
resolve(specifier, context, nextResolve) {
|
|
34
|
+
if (specifier !== 'deepmerge' || !context.parentURL || !browserConsumer.test(context.parentURL)) {
|
|
35
|
+
return nextResolve(specifier, context);
|
|
36
|
+
}
|
|
37
|
+
const metadata = createRequire(context.parentURL).resolve('deepmerge/package.json');
|
|
38
|
+
if (!versions.has(metadata)) {
|
|
39
|
+
const manifest = JSON.parse(fs.readFileSync(metadata, 'utf8'));
|
|
40
|
+
versions.set(metadata, manifest.name === 'deepmerge' && affected.has(manifest.version));
|
|
41
|
+
}
|
|
42
|
+
if (versions.get(metadata)) {
|
|
43
|
+
return { url: patched, shortCircuit: true };
|
|
44
|
+
}
|
|
45
|
+
return nextResolve(specifier, context);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=security.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.js","names":[],"sources":["../src/security.js"],"sourcesContent":["/*\n * Copyright 2026 WPPConnect Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n// Keep the browser option merger protected in registry installations too.\n// Package-manager overrides apply to the repository root, not its consumers.\nconst fs = require('node:fs');\nconst path = require('node:path');\nconst { createRequire, registerHooks } = require('node:module');\nconst { pathToFileURL } = require('node:url');\n\nif (typeof registerHooks !== 'function') {\n throw new Error('WPPConnect CLI requires Node 22.18 or a supported newer version.');\n}\n\nconst patched = pathToFileURL(path.resolve(__dirname, '../vendor/deepmerge/index.cjs')).href;\nconst affected = new Set(['4.2.0', '4.2.1', '4.2.2', '4.3.0', '4.3.1']);\nconst versions = new Map();\nconst browserConsumer = /\\/node_modules\\/puppeteer-extra(?:-plugin(?:-[^/]+)?)?\\//;\n\nregisterHooks({\n resolve(specifier, context, nextResolve) {\n if (specifier !== 'deepmerge' || !context.parentURL || !browserConsumer.test(context.parentURL)) {\n return nextResolve(specifier, context);\n }\n const metadata = createRequire(context.parentURL).resolve('deepmerge/package.json');\n if (!versions.has(metadata)) {\n const manifest = JSON.parse(fs.readFileSync(metadata, 'utf8'));\n versions.set(metadata, manifest.name === 'deepmerge' && affected.has(manifest.version));\n }\n if (versions.get(metadata)) {\n return { url: patched, shortCircuit: true };\n }\n return nextResolve(specifier, context);\n },\n});\n"],"mappings":"cAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC;AAC7B,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC;AACjC,MAAM,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC;AAC/D,MAAM,EAAE,aAAa,CAAC,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;;AAE7C,IAAI,OAAO,aAAa,KAAK,UAAU,EAAE;EACvC,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC;AACrF;;AAEA,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,+BAA+B,CAAC,CAAC,CAAC,IAAI;AAC5F,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACvE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC;AAC1B,MAAM,eAAe,GAAG,0DAA0D;;AAElF,aAAa,CAAC;EACZ,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE;IACvC,IAAI,SAAS,KAAK,WAAW,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;MAC/F,OAAO,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC;IACxC;IACA,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,wBAAwB,CAAC;IACnF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;MAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;MAC9D,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,KAAK,WAAW,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACzF;IACA,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;MAC1B,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;IAC7C;IACA,OAAO,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC;EACxC;AACF,CAAC,CAAC","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wppconnect/server-cli",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.57",
|
|
4
4
|
"description": "Servidor de WPPConnect com frontend para ser executado a partir de uma linha de comando",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
"release": "release-it",
|
|
26
26
|
"start": "cross-env RUN_SERVER=1 babel-node src",
|
|
27
27
|
"watch": "nodemon -w src --exec \"babel-node src\"",
|
|
28
|
-
"test": "node --require @babel/register --test --test-force-exit \"test/**/*.test.js\""
|
|
28
|
+
"test": "node --require @babel/register --test --test-force-exit \"test/**/*.test.js\"",
|
|
29
|
+
"test:packed-security": "node test/packed-runtime-security.cjs"
|
|
29
30
|
},
|
|
30
31
|
"config": {
|
|
31
32
|
"commitizen": {
|
|
@@ -33,7 +34,7 @@
|
|
|
33
34
|
}
|
|
34
35
|
},
|
|
35
36
|
"dependencies": {
|
|
36
|
-
"@babel/runtime": "^
|
|
37
|
+
"@babel/runtime": "^8.0.8",
|
|
37
38
|
"@wppconnect/server": "2.10.68",
|
|
38
39
|
"commander": "^14.0.3",
|
|
39
40
|
"merge-deep": "^3.0.3",
|
|
@@ -41,13 +42,11 @@
|
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
43
44
|
"@aws-sdk/client-s3": "^3.1156.0",
|
|
44
|
-
"@babel/cli": "^
|
|
45
|
-
"@babel/core": "^
|
|
46
|
-
"@babel/
|
|
47
|
-
"@babel/
|
|
48
|
-
"@babel/
|
|
49
|
-
"@babel/plugin-transform-runtime": "^7.29.7",
|
|
50
|
-
"@babel/preset-env": "^7.29.7",
|
|
45
|
+
"@babel/cli": "^8.0.6",
|
|
46
|
+
"@babel/core": "^8.0.9",
|
|
47
|
+
"@babel/node": "^8.0.6",
|
|
48
|
+
"@babel/plugin-transform-runtime": "^8.0.6",
|
|
49
|
+
"@babel/preset-env": "^8.0.7",
|
|
51
50
|
"@commitlint/cli": "^20.5.3",
|
|
52
51
|
"@commitlint/config-conventional": "^20.5.3",
|
|
53
52
|
"@commitlint/cz-commitlint": "^20.5.3",
|
|
@@ -83,32 +82,39 @@
|
|
|
83
82
|
"@commitlint/**/ajv": "8.18.0",
|
|
84
83
|
"commitizen/**/ajv": "8.18.0",
|
|
85
84
|
"eslint/**/ajv": "6.15.0",
|
|
86
|
-
"basic-ftp": "
|
|
85
|
+
"basic-ftp": "6.2.1",
|
|
87
86
|
"fast-xml-parser": "5.11.2",
|
|
88
87
|
"flatted": "3.4.4",
|
|
89
88
|
"handlebars": "4.7.10",
|
|
90
89
|
"@wppconnect/server/**/body-parser": "1.20.9",
|
|
91
|
-
"@wppconnect/server/**/brace-expansion": "1.1.21",
|
|
92
90
|
"@wppconnect/server/**/engine.io": "6.6.11",
|
|
93
91
|
"@wppconnect/server/**/form-data": "4.0.6",
|
|
94
92
|
"@wppconnect/server/**/multer": "2.5.0",
|
|
95
|
-
"@wppconnect/server/**/path-to-regexp": "0.2.5",
|
|
96
93
|
"@wppconnect/server/**/qs": "6.16.1",
|
|
97
94
|
"@wppconnect/server/**/tmp": "0.2.7",
|
|
98
|
-
"@wppconnect/server/**/ws": "8.
|
|
95
|
+
"@wppconnect/server/**/ws": "8.22.0",
|
|
99
96
|
"**/package-json/got": "11.8.6",
|
|
100
97
|
"**/sharp": "0.35.5",
|
|
101
|
-
"@wppconnect-team/wppconnect/**/ws": "8.
|
|
98
|
+
"@wppconnect-team/wppconnect/**/ws": "8.22.0",
|
|
102
99
|
"@types/minimatch/**/minimatch": "10.2.5",
|
|
103
|
-
"archiver-utils/**/minimatch": "9.0.
|
|
104
|
-
"nodemon/**/brace-expansion": "5.0.9",
|
|
100
|
+
"**/archiver-utils/**/minimatch": "9.0.9",
|
|
105
101
|
"nodemon/**/minimatch": "10.2.5",
|
|
106
102
|
"pretty-quick/**/picomatch": "3.0.2",
|
|
107
103
|
"readdir-glob/**/minimatch": "5.1.9",
|
|
108
|
-
"rimraf/**/minimatch": "9.0.
|
|
104
|
+
"**/rimraf/**/minimatch": "9.0.9",
|
|
105
|
+
"**/nodemon/**/brace-expansion": "5.0.12",
|
|
106
|
+
"**/readdir-glob/**/brace-expansion": "2.1.7",
|
|
107
|
+
"puppeteer": "25.13.0",
|
|
108
|
+
"http-cache-semantics": "4.3.0",
|
|
109
|
+
"browserslist": "4.28.9",
|
|
110
|
+
"baseline-browser-mapping": "2.11.34",
|
|
109
111
|
"**/lodash": "4.18.1",
|
|
110
112
|
"tar": "7.5.22",
|
|
111
|
-
"tmp": "0.2.7"
|
|
113
|
+
"tmp": "0.2.7",
|
|
114
|
+
"deepmerge": "file:vendor/deepmerge-4.3.2+wppconnect.1.tgz"
|
|
112
115
|
},
|
|
113
|
-
"packageManager": "yarn@1.22.22"
|
|
116
|
+
"packageManager": "yarn@1.22.22",
|
|
117
|
+
"engines": {
|
|
118
|
+
"node": "^22.18.0 || >=24.11.0"
|
|
119
|
+
}
|
|
114
120
|
}
|
package/test/auth.test.js
CHANGED
|
@@ -17,7 +17,11 @@ const bcrypt = require(require.resolve('bcrypt', {
|
|
|
17
17
|
const DEFAULT_SECRET = 'THISISMYSECURETOKEN';
|
|
18
18
|
const SESSION = 'regression';
|
|
19
19
|
const ROOT = path.resolve(__dirname, '..');
|
|
20
|
-
const
|
|
20
|
+
const COMPILED = process.env.WPP_CLI_TEST_COMPILED === '1';
|
|
21
|
+
const babelManifest = require.resolve('@babel/node/package.json');
|
|
22
|
+
const CLI_ENTRY = COMPILED
|
|
23
|
+
? path.join(ROOT, 'bin', 'wppserver.js')
|
|
24
|
+
: path.resolve(path.dirname(babelManifest), require(babelManifest).bin['babel-node']);
|
|
21
25
|
|
|
22
26
|
const children = new Set();
|
|
23
27
|
const tmpDirs = new Set();
|
|
@@ -50,15 +54,19 @@ async function startCli(args = [], env = {}, config) {
|
|
|
50
54
|
fs.writeFileSync(file, JSON.stringify(config));
|
|
51
55
|
args = [...args, '--config', file];
|
|
52
56
|
}
|
|
53
|
-
const childEnv = { ...process.env, RUN_SERVER: '1', PORT: String(port), ...env };
|
|
57
|
+
const childEnv = { ...process.env, RUN_SERVER: COMPILED ? '' : '1', PORT: String(port), ...env };
|
|
54
58
|
for (const key of Object.keys(childEnv)) {
|
|
55
59
|
if (childEnv[key] === undefined) delete childEnv[key];
|
|
56
60
|
}
|
|
57
61
|
|
|
58
|
-
const child = spawn(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
const child = spawn(
|
|
63
|
+
process.execPath,
|
|
64
|
+
[CLI_ENTRY, ...(COMPILED ? [] : ['src']), '--port', String(port), '--no-startAllSession', ...args],
|
|
65
|
+
{
|
|
66
|
+
cwd: ROOT,
|
|
67
|
+
env: childEnv,
|
|
68
|
+
}
|
|
69
|
+
);
|
|
62
70
|
children.add(child);
|
|
63
71
|
|
|
64
72
|
let output = '';
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 WPPConnect Team
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
const assert = require('node:assert/strict');
|
|
17
|
+
const { createRequire } = require('node:module');
|
|
18
|
+
const { test } = require('node:test');
|
|
19
|
+
const owner = createRequire(require.resolve('puppeteer-extra'));
|
|
20
|
+
const merge = owner('deepmerge');
|
|
21
|
+
|
|
22
|
+
const malicious = () => JSON.parse('{"__proto__":{"isAdmin":true}}');
|
|
23
|
+
function assertSafe(value) {
|
|
24
|
+
assert.equal(Object.getPrototypeOf(value), Object.prototype);
|
|
25
|
+
assert.equal(value.isAdmin, undefined);
|
|
26
|
+
assert.equal(Object.hasOwn(value, '__proto__'), false);
|
|
27
|
+
assert.equal({}.isAdmin, undefined);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
test('browser options cannot inherit attacker values from a null-prototype target', () => {
|
|
31
|
+
const target = Object.assign(Object.create(null), { debug: false });
|
|
32
|
+
const result = merge(target, malicious());
|
|
33
|
+
assertSafe(result);
|
|
34
|
+
assert.equal(result.debug, false);
|
|
35
|
+
});
|
|
36
|
+
test('browser options cannot inherit attacker values through a null placeholder', () => {
|
|
37
|
+
const input = { session: malicious() };
|
|
38
|
+
assertSafe(merge({ session: null }, input).session);
|
|
39
|
+
});
|
|
40
|
+
test('browser options reject a proto key already present in the defaults', () => {
|
|
41
|
+
const result = merge(malicious(), { debug: false });
|
|
42
|
+
assertSafe(result);
|
|
43
|
+
assert.equal(result.debug, false);
|
|
44
|
+
});
|
|
45
|
+
test('browser options cannot inherit attacker values through a primitive placeholder', () => {
|
|
46
|
+
assertSafe(merge({ session: 1 }, { session: malicious() }).session);
|
|
47
|
+
});
|
|
48
|
+
test('cloned browser option arrays retain safe element prototypes', () => {
|
|
49
|
+
const result = merge({ list: [] }, { list: [malicious()] });
|
|
50
|
+
assertSafe(result.list[0]);
|
|
51
|
+
});
|
|
52
|
+
test('browser option merging retains arrays, symbols, custom merging and source objects', () => {
|
|
53
|
+
const key = Symbol('option');
|
|
54
|
+
const first = { args: ['--one'], nested: { a: 1 }, [key]: 1 };
|
|
55
|
+
const second = { args: ['--two'], nested: { b: 2 } };
|
|
56
|
+
assert.deepEqual(merge.all([first, second]).args, ['--one', '--two']);
|
|
57
|
+
assert.deepEqual(first.args, ['--one']);
|
|
58
|
+
assert.equal(merge(first, second)[key], 1);
|
|
59
|
+
assert.deepEqual(merge(first, second, { arrayMerge: (_a, b) => b }).args, ['--two']);
|
|
60
|
+
assert.deepEqual(
|
|
61
|
+
merge(first, second, { customMerge: (name) => (name === 'nested' ? (a, b) => ({ a: a.a + b.b }) : undefined) })
|
|
62
|
+
.nested,
|
|
63
|
+
{ a: 3 }
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const fs = require('node:fs');
|
|
68
|
+
const path = require('node:path');
|
|
69
|
+
test('installed browser merger matches the reviewed private runtime files', () => {
|
|
70
|
+
const installed = path.dirname(owner.resolve('deepmerge'));
|
|
71
|
+
for (const file of ['index.cjs', 'is-mergeable-object.cjs']) {
|
|
72
|
+
const actual = fs.readFileSync(path.join(installed, file), 'utf8').replace(/\r\n/g, '\n');
|
|
73
|
+
const expected = fs.readFileSync(path.join(__dirname, '../vendor/deepmerge', file), 'utf8').replace(/\r\n/g, '\n');
|
|
74
|
+
assert.equal(actual, expected);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 WPPConnect Team
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
const assert = require('node:assert/strict');
|
|
17
|
+
const { execFileSync } = require('node:child_process');
|
|
18
|
+
const fs = require('node:fs');
|
|
19
|
+
const { createRequire } = require('node:module');
|
|
20
|
+
const os = require('node:os');
|
|
21
|
+
const path = require('node:path');
|
|
22
|
+
const { test } = require('node:test');
|
|
23
|
+
|
|
24
|
+
test('rimraf ESM executable loads brace expansion and removes its target', () => {
|
|
25
|
+
const owner = createRequire(require.resolve('rimraf'));
|
|
26
|
+
const globOwner = createRequire(owner.resolve('glob'));
|
|
27
|
+
assert.equal(globOwner('minimatch/package.json').version, '9.0.9');
|
|
28
|
+
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'wppcli-rimraf-'));
|
|
29
|
+
try {
|
|
30
|
+
const target = path.join(directory, 'output');
|
|
31
|
+
fs.mkdirSync(target);
|
|
32
|
+
fs.writeFileSync(path.join(target, 'fixture.txt'), 'fixture');
|
|
33
|
+
const manifest = require.resolve('rimraf/package.json');
|
|
34
|
+
const executable = path.resolve(path.dirname(manifest), require(manifest).bin);
|
|
35
|
+
execFileSync(process.execPath, [executable, target], { encoding: 'utf8' });
|
|
36
|
+
assert.equal(fs.existsSync(target), false);
|
|
37
|
+
assert.equal(fs.existsSync(directory), true);
|
|
38
|
+
} finally {
|
|
39
|
+
fs.rmSync(directory, { recursive: true, force: true });
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('archiver glob expands braces and exclusions through its own minimatch', () => {
|
|
44
|
+
const owner = createRequire(require.resolve('archiver-utils'));
|
|
45
|
+
const globOwner = createRequire(owner.resolve('glob'));
|
|
46
|
+
assert.equal(globOwner('minimatch/package.json').version, '9.0.9');
|
|
47
|
+
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'wppcli-glob-'));
|
|
48
|
+
try {
|
|
49
|
+
for (const name of ['first.txt', 'second.txt', 'ignored.txt']) {
|
|
50
|
+
fs.writeFileSync(path.join(directory, name), 'fixture');
|
|
51
|
+
}
|
|
52
|
+
const glob = require('archiver-utils/file').expand;
|
|
53
|
+
assert.deepEqual(glob({ cwd: directory }, ['{first,second,ignored}.txt', '!ignored.txt']).sort(), [
|
|
54
|
+
'first.txt',
|
|
55
|
+
'second.txt',
|
|
56
|
+
]);
|
|
57
|
+
} finally {
|
|
58
|
+
fs.rmSync(directory, { recursive: true, force: true });
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('legacy glob retains its callable minimatch and brace expansion APIs', () => {
|
|
63
|
+
const owner = createRequire(require.resolve('glob'));
|
|
64
|
+
const minimatch = owner('minimatch');
|
|
65
|
+
assert.equal(minimatch('first.txt', '{first,second}.txt'), true);
|
|
66
|
+
assert.equal(minimatch('third.txt', '{first,second}.txt'), false);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('nodemon retains its named minimatch API for watched file patterns', () => {
|
|
70
|
+
const owner = createRequire(require.resolve('nodemon'));
|
|
71
|
+
const { minimatch } = owner('minimatch');
|
|
72
|
+
assert.equal(minimatch('src/index.js', 'src/{index,config}.js'), true);
|
|
73
|
+
assert.equal(minimatch('src/ignored.js', 'src/{index,config}.js'), false);
|
|
74
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 WPPConnect Team
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
const assert = require('node:assert/strict');
|
|
17
|
+
const path = require('node:path');
|
|
18
|
+
const { createRequire } = require('node:module');
|
|
19
|
+
|
|
20
|
+
delete process.env.RUN_SERVER;
|
|
21
|
+
const root = path.resolve(process.argv[2]);
|
|
22
|
+
const project = createRequire(path.join(root, 'package.json'));
|
|
23
|
+
project(root);
|
|
24
|
+
const server = createRequire(project.resolve('@wppconnect/server'));
|
|
25
|
+
const core = createRequire(server.resolve('@wppconnect-team/wppconnect'));
|
|
26
|
+
const extra = createRequire(core.resolve('puppeteer-extra'));
|
|
27
|
+
const merge = extra('deepmerge');
|
|
28
|
+
const privateRuntime = path.join(root, 'vendor', 'deepmerge', 'index.cjs');
|
|
29
|
+
assert.equal(merge, project(privateRuntime));
|
|
30
|
+
const payload = JSON.parse('{"__proto__":{"isAdmin":true}}');
|
|
31
|
+
for (const result of [
|
|
32
|
+
merge(Object.create(null), payload),
|
|
33
|
+
merge({ session: null }, { session: payload }).session,
|
|
34
|
+
merge(payload, {}),
|
|
35
|
+
]) {
|
|
36
|
+
assert.equal(Object.getPrototypeOf(result), Object.prototype);
|
|
37
|
+
assert.equal(result.isAdmin, undefined);
|
|
38
|
+
}
|
|
39
|
+
assert.deepEqual(merge.all([{ args: ['a'] }, { args: ['b'] }]), { args: ['a', 'b'] });
|
|
40
|
+
assert.equal({}.isAdmin, undefined);
|
|
41
|
+
console.log(
|
|
42
|
+
JSON.stringify({
|
|
43
|
+
publicEntryLoaded: true,
|
|
44
|
+
privateRuntime,
|
|
45
|
+
dependencyMetadataVersion: extra('deepmerge/package.json').version,
|
|
46
|
+
prototypeCasesPassed: 3,
|
|
47
|
+
})
|
|
48
|
+
);
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 WPPConnect Team
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
// Run with npm run test:packed-security so npm_execpath is the native npm CLI.
|
|
17
|
+
const assert = require('node:assert/strict');
|
|
18
|
+
const fs = require('node:fs');
|
|
19
|
+
const os = require('node:os');
|
|
20
|
+
const path = require('node:path');
|
|
21
|
+
const { spawnSync } = require('node:child_process');
|
|
22
|
+
|
|
23
|
+
const root = path.resolve(__dirname, '..');
|
|
24
|
+
const scratch = fs.mkdtempSync(path.join(os.tmpdir(), 'wpp-cli-package-security-'));
|
|
25
|
+
const npm = process.env.npm_execpath;
|
|
26
|
+
assert(npm && /npm-cli\.js$/.test(npm), 'Run this check using npm run test:packed-security');
|
|
27
|
+
const env = { ...process.env, PUPPETEER_SKIP_DOWNLOAD: 'true', RUN_SERVER: '' };
|
|
28
|
+
function run(args, cwd) {
|
|
29
|
+
const result = spawnSync(process.execPath, args, {
|
|
30
|
+
cwd,
|
|
31
|
+
env,
|
|
32
|
+
encoding: 'utf8',
|
|
33
|
+
timeout: 300000,
|
|
34
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
35
|
+
});
|
|
36
|
+
assert.equal(result.status, 0, result.stdout + result.stderr + (result.error?.message || ''));
|
|
37
|
+
return result.stdout;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
const packed = JSON.parse(run([npm, 'pack', '--ignore-scripts', '--json', '--pack-destination', scratch], root))[0];
|
|
41
|
+
const files = new Set(packed.files.map((file) => file.path));
|
|
42
|
+
for (const file of [
|
|
43
|
+
'dist/security.js',
|
|
44
|
+
'vendor/deepmerge/index.cjs',
|
|
45
|
+
'vendor/deepmerge/is-mergeable-object.cjs',
|
|
46
|
+
'vendor/deepmerge/LICENSE',
|
|
47
|
+
]) {
|
|
48
|
+
assert(files.has(file), `Runtime security file missing from packed CLI: ${file}`);
|
|
49
|
+
}
|
|
50
|
+
const artifact = path.join(scratch, packed.filename);
|
|
51
|
+
const helper = path.join(__dirname, 'helpers', 'assert-packed-merger.cjs');
|
|
52
|
+
for (const mode of ['local', 'global']) {
|
|
53
|
+
const prefix = path.join(scratch, mode);
|
|
54
|
+
fs.mkdirSync(prefix);
|
|
55
|
+
fs.writeFileSync(
|
|
56
|
+
path.join(prefix, 'package.json'),
|
|
57
|
+
JSON.stringify({ name: 'wpp-cli-security-consumer', version: '0.0.0', private: true })
|
|
58
|
+
);
|
|
59
|
+
const install = [npm, 'install', '--ignore-scripts', '--no-audit', '--no-fund'];
|
|
60
|
+
if (mode === 'global') install.push('--global', '--prefix', prefix);
|
|
61
|
+
install.push(artifact);
|
|
62
|
+
run(install, prefix);
|
|
63
|
+
const installed = path.join(
|
|
64
|
+
prefix,
|
|
65
|
+
process.platform === 'win32' || mode === 'local' ? 'node_modules' : 'lib/node_modules',
|
|
66
|
+
'@wppconnect/server-cli'
|
|
67
|
+
);
|
|
68
|
+
process.stdout.write(run([helper, installed], prefix));
|
|
69
|
+
const help = run([path.join(installed, 'bin', 'wppserver.js'), '--help'], prefix);
|
|
70
|
+
assert.match(help, /Usage:/);
|
|
71
|
+
}
|
|
72
|
+
} finally {
|
|
73
|
+
assert.equal(path.dirname(path.resolve(scratch)), path.resolve(os.tmpdir()));
|
|
74
|
+
fs.rmSync(scratch, { recursive: true, force: true });
|
|
75
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2012 James Halliday, Josh Duff, and other contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# Private local security backport
|
|
2
|
+
|
|
3
|
+
This package contains deepmerge4.3.1 plus the prototype-poisoning fix from upstream PR274, commit c5ad573121574db1c625b0aabcc6114ed7df6c5a. Version4.3.2+wppconnect.1 identifies this private local patch and its4.x compatibility; it is not an upstream release and is never published to a registry. The original package name is preserved for transitive dependency matching. The is-mergeable-object1.1.0 helper is included locally. Both libraries are MIT-licensed; original notices are preserved.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
var defaultIsMergeableObject = require('./is-mergeable-object.cjs')
|
|
2
|
+
|
|
3
|
+
function emptyTarget(val) {
|
|
4
|
+
return Array.isArray(val) ? [] : {}
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function cloneUnlessOtherwiseSpecified(value, options) {
|
|
8
|
+
return (options.clone !== false && options.isMergeableObject(value))
|
|
9
|
+
? deepmerge(emptyTarget(value), value, options)
|
|
10
|
+
: value
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function defaultArrayMerge(target, source, options) {
|
|
14
|
+
return target.concat(source).map(function(element) {
|
|
15
|
+
return cloneUnlessOtherwiseSpecified(element, options)
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getMergeFunction(key, options) {
|
|
20
|
+
if (!options.customMerge) {
|
|
21
|
+
return deepmerge
|
|
22
|
+
}
|
|
23
|
+
var customMerge = options.customMerge(key)
|
|
24
|
+
return typeof customMerge === 'function' ? customMerge : deepmerge
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getEnumerableOwnPropertySymbols(target) {
|
|
28
|
+
return Object.getOwnPropertySymbols
|
|
29
|
+
? Object.getOwnPropertySymbols(target).filter(function(symbol) {
|
|
30
|
+
return Object.propertyIsEnumerable.call(target, symbol)
|
|
31
|
+
})
|
|
32
|
+
: []
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function getKeys(target) {
|
|
36
|
+
return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function propertyIsOnObject(object, property) {
|
|
40
|
+
try {
|
|
41
|
+
return property in object
|
|
42
|
+
} catch(_) {
|
|
43
|
+
return false
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function propertyIsForbidden(key) {
|
|
48
|
+
return key === '__proto__'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Protects from prototype poisoning and unexpected merging up the prototype chain.
|
|
52
|
+
function propertyIsUnsafe(target, key) {
|
|
53
|
+
return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,
|
|
54
|
+
&& !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,
|
|
55
|
+
&& Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function mergeObject(target, source, options) {
|
|
59
|
+
var destination = {}
|
|
60
|
+
if (options.isMergeableObject(target)) {
|
|
61
|
+
getKeys(target).forEach(function(key) {
|
|
62
|
+
if (propertyIsForbidden(key)) {
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
destination[key] = cloneUnlessOtherwiseSpecified(target[key], options)
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
getKeys(source).forEach(function(key) {
|
|
69
|
+
if (propertyIsForbidden(key) || propertyIsUnsafe(target, key)) {
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {
|
|
74
|
+
destination[key] = getMergeFunction(key, options)(target[key], source[key], options)
|
|
75
|
+
} else {
|
|
76
|
+
destination[key] = cloneUnlessOtherwiseSpecified(source[key], options)
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
return destination
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function deepmerge(target, source, options) {
|
|
83
|
+
options = options || {}
|
|
84
|
+
options.arrayMerge = options.arrayMerge || defaultArrayMerge
|
|
85
|
+
options.isMergeableObject = options.isMergeableObject || defaultIsMergeableObject
|
|
86
|
+
// cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()
|
|
87
|
+
// implementations can use it. The caller may not replace it.
|
|
88
|
+
options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified
|
|
89
|
+
|
|
90
|
+
var sourceIsArray = Array.isArray(source)
|
|
91
|
+
var targetIsArray = Array.isArray(target)
|
|
92
|
+
var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray
|
|
93
|
+
|
|
94
|
+
if (!sourceAndTargetTypesMatch) {
|
|
95
|
+
return cloneUnlessOtherwiseSpecified(source, options)
|
|
96
|
+
} else if (sourceIsArray) {
|
|
97
|
+
return options.arrayMerge(target, source, options)
|
|
98
|
+
} else {
|
|
99
|
+
return mergeObject(target, source, options)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
deepmerge.all = function deepmergeAll(array, options) {
|
|
104
|
+
if (!Array.isArray(array)) {
|
|
105
|
+
throw new Error('first argument should be an array')
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return array.reduce(function(prev, next) {
|
|
109
|
+
return deepmerge(prev, next, options)
|
|
110
|
+
}, {})
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module.exports = deepmerge
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
declare function deepmerge<T>(x: Partial<T>, y: Partial<T>, options?: deepmerge.Options): T;
|
|
2
|
+
declare function deepmerge<T1, T2>(x: Partial<T1>, y: Partial<T2>, options?: deepmerge.Options): T1 & T2;
|
|
3
|
+
|
|
4
|
+
declare namespace deepmerge {
|
|
5
|
+
export interface Options {
|
|
6
|
+
arrayMerge?(target: any[], source: any[], options?: ArrayMergeOptions): any[];
|
|
7
|
+
clone?: boolean;
|
|
8
|
+
customMerge?: (key: string, options?: Options) => ((x: any, y: any) => any) | undefined;
|
|
9
|
+
isMergeableObject?(value: object): boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface ArrayMergeOptions {
|
|
12
|
+
isMergeableObject(value: object): boolean;
|
|
13
|
+
cloneUnlessOtherwiseSpecified(value: object, options?: Options): object;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function all (objects: object[], options?: Options): object;
|
|
17
|
+
export function all<T> (objects: Partial<T>[], options?: Options): T;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export = deepmerge;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module.exports = function isMergeableObject(value) {
|
|
2
|
+
return isNonNullObject(value)
|
|
3
|
+
&& !isSpecial(value)
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function isNonNullObject(value) {
|
|
7
|
+
return !!value && typeof value === 'object'
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function isSpecial(value) {
|
|
11
|
+
var stringValue = Object.prototype.toString.call(value)
|
|
12
|
+
|
|
13
|
+
return stringValue === '[object RegExp]'
|
|
14
|
+
|| stringValue === '[object Date]'
|
|
15
|
+
|| isReactElement(value)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25
|
|
19
|
+
var canUseSymbol = typeof Symbol === 'function' && Symbol.for
|
|
20
|
+
var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7
|
|
21
|
+
|
|
22
|
+
function isReactElement(value) {
|
|
23
|
+
return value.$$typeof === REACT_ELEMENT_TYPE
|
|
24
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "deepmerge",
|
|
3
|
+
"version": "4.3.2+wppconnect.1",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "Private unpublished WPPConnect patch of deepmerge4.3.1. This version is local, not an upstream registry release.",
|
|
6
|
+
"main": "index.cjs",
|
|
7
|
+
"types": "index.d.ts",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"files": [
|
|
10
|
+
"index.cjs",
|
|
11
|
+
"is-mergeable-object.cjs",
|
|
12
|
+
"index.d.ts",
|
|
13
|
+
"LICENSE",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=0.10.0"
|
|
18
|
+
}
|
|
19
|
+
}
|