@automattic/vip 4.0.9 → 4.0.11
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/dist/bin/vip-defensive-mode-configure.js +216 -0
- package/dist/bin/vip-defensive-mode-disable.js +42 -0
- package/dist/bin/vip-defensive-mode-enable.js +45 -0
- package/dist/bin/vip-defensive-mode.js +21 -0
- package/dist/bin/vip.js +6 -1
- package/dist/lib/api/constants.js +7 -0
- package/dist/lib/api/feature-flags.js +17 -4
- package/dist/lib/api/http.js +3 -3
- package/dist/lib/api.js +23 -8
- package/dist/lib/cli/internal-bin-loader.js +4 -0
- package/dist/lib/defensive-mode/api.js +106 -0
- package/dist/lib/defensive-mode/cli-helpers.js +60 -0
- package/dist/lib/dev-environment/dev-environment-configuration-file.js +19 -14
- package/dist/lib/keychain/insecure.js +2 -2
- package/dist/lib/keychain/secure.js +2 -2
- package/dist/lib/keychain.js +20 -15
- package/dist/lib/logout.js +9 -4
- package/dist/lib/rechallenge/client.js +55 -0
- package/dist/lib/rechallenge/errors.js +55 -0
- package/dist/lib/rechallenge/flow.js +145 -0
- package/dist/lib/rechallenge/index.js +27 -0
- package/dist/lib/rechallenge/link.js +167 -0
- package/dist/lib/rechallenge/open-browser.js +21 -0
- package/dist/lib/rechallenge/token-cache.js +113 -0
- package/dist/lib/rechallenge/types.js +15 -0
- package/dist/lib/token.js +18 -14
- package/docs/SETUP.md +7 -6
- package/docs/decisions/0001-operation-scoped-elevated-token-reuse.md +87 -0
- package/npm-shrinkwrap.json +18 -18
- package/package.json +6 -2
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
var _debug = _interopRequireDefault(require("debug"));
|
|
6
|
+
var _constants = require("../api/constants");
|
|
7
|
+
var _keychain = require("../keychain");
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
const debug = (0, _debug.default)('@automattic/vip:rechallenge:cache');
|
|
10
|
+
// Storage strategy: a single keychain entry holds a JSON map { [scope]: ElevatedToken }.
|
|
11
|
+
// The vip-cli Keychain interface (src/lib/keychain/keychain.ts) is service-only — there
|
|
12
|
+
// is no separate account argument — so per-scope entries under the keytar model would
|
|
13
|
+
// require a different keying scheme. The single-blob approach also keeps clearAll() cheap.
|
|
14
|
+
// This is marked subject-to-change in the spec pending security review.
|
|
15
|
+
const BASE_SERVICE = 'vip-go-cli:elevated';
|
|
16
|
+
function serviceName() {
|
|
17
|
+
if (_constants.API_HOST === _constants.PRODUCTION_API_HOST) {
|
|
18
|
+
return BASE_SERVICE;
|
|
19
|
+
}
|
|
20
|
+
const sanitized = _constants.API_HOST.replace(/[^a-z0-9]/gi, '-');
|
|
21
|
+
return `${BASE_SERVICE}:${sanitized}`;
|
|
22
|
+
}
|
|
23
|
+
let inMemory = null;
|
|
24
|
+
async function read() {
|
|
25
|
+
if (inMemory) {
|
|
26
|
+
return inMemory;
|
|
27
|
+
}
|
|
28
|
+
const keychain = await (0, _keychain.getKeychain)();
|
|
29
|
+
const raw = await keychain.getPassword(serviceName());
|
|
30
|
+
if (!raw) {
|
|
31
|
+
inMemory = {};
|
|
32
|
+
return inMemory;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const parsed = JSON.parse(raw);
|
|
36
|
+
if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
|
|
37
|
+
inMemory = parsed;
|
|
38
|
+
} else {
|
|
39
|
+
debug('Elevated token blob had unexpected shape; resetting');
|
|
40
|
+
inMemory = {};
|
|
41
|
+
await keychain.deletePassword(serviceName());
|
|
42
|
+
}
|
|
43
|
+
} catch (err) {
|
|
44
|
+
debug('Failed to parse elevated token blob; resetting (%o)', err);
|
|
45
|
+
inMemory = {};
|
|
46
|
+
await keychain.deletePassword(serviceName());
|
|
47
|
+
}
|
|
48
|
+
return inMemory;
|
|
49
|
+
}
|
|
50
|
+
async function write(blob) {
|
|
51
|
+
inMemory = blob;
|
|
52
|
+
const keychain = await (0, _keychain.getKeychain)();
|
|
53
|
+
if (Object.keys(blob).length === 0) {
|
|
54
|
+
await keychain.deletePassword(serviceName());
|
|
55
|
+
} else {
|
|
56
|
+
await keychain.setPassword(serviceName(), JSON.stringify(blob));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function isExpired(token) {
|
|
60
|
+
const exp = Date.parse(token.expiresAt);
|
|
61
|
+
if (Number.isNaN(exp)) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
// Treat tokens within the next 5 seconds as effectively expired.
|
|
65
|
+
return Date.now() >= exp - 5_000;
|
|
66
|
+
}
|
|
67
|
+
async function get(scope) {
|
|
68
|
+
const blob = await read();
|
|
69
|
+
const token = blob[scope];
|
|
70
|
+
if (!token) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
if (isExpired(token)) {
|
|
74
|
+
debug('Cached elevated token for %s is expired; evicting', scope);
|
|
75
|
+
const {
|
|
76
|
+
[scope]: _evicted,
|
|
77
|
+
...rest
|
|
78
|
+
} = blob;
|
|
79
|
+
await write(rest);
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
return token;
|
|
83
|
+
}
|
|
84
|
+
async function set(scope, token) {
|
|
85
|
+
const blob = await read();
|
|
86
|
+
blob[scope] = token;
|
|
87
|
+
await write(blob);
|
|
88
|
+
}
|
|
89
|
+
async function clearScope(scope) {
|
|
90
|
+
const blob = await read();
|
|
91
|
+
if (scope in blob) {
|
|
92
|
+
const {
|
|
93
|
+
[scope]: _removed,
|
|
94
|
+
...rest
|
|
95
|
+
} = blob;
|
|
96
|
+
await write(rest);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async function clearAll() {
|
|
100
|
+
inMemory = {};
|
|
101
|
+
const keychain = await (0, _keychain.getKeychain)();
|
|
102
|
+
await keychain.deletePassword(serviceName());
|
|
103
|
+
}
|
|
104
|
+
function _resetInMemoryForTests() {
|
|
105
|
+
inMemory = null;
|
|
106
|
+
}
|
|
107
|
+
var _default = exports.default = {
|
|
108
|
+
get,
|
|
109
|
+
set,
|
|
110
|
+
clearScope,
|
|
111
|
+
clearAll,
|
|
112
|
+
_resetInMemoryForTests
|
|
113
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.RECHALLENGE_VERSION = exports.ELEVATED_PERMISSION_ERROR_CODE = exports.CLIENT_TYPE = void 0;
|
|
5
|
+
const ELEVATED_PERMISSION_ERROR_CODE = exports.ELEVATED_PERMISSION_ERROR_CODE = 'elevated-permission-required';
|
|
6
|
+
const RECHALLENGE_VERSION = exports.RECHALLENGE_VERSION = 'v2';
|
|
7
|
+
const CLIENT_TYPE = exports.CLIENT_TYPE = 'cli';
|
|
8
|
+
|
|
9
|
+
/** Shape of `errors[0].extensions.rechallenge` from the API. */
|
|
10
|
+
|
|
11
|
+
/** Response from POST {createSessionPath}. */
|
|
12
|
+
|
|
13
|
+
/** Response from GET {statusPathTemplate}. */
|
|
14
|
+
|
|
15
|
+
/** Response from POST {exchangePathTemplate}. */
|
package/dist/lib/token.js
CHANGED
|
@@ -4,9 +4,8 @@ exports.__esModule = true;
|
|
|
4
4
|
exports.default = exports.SERVICE = void 0;
|
|
5
5
|
var _jwtDecode = require("jwt-decode");
|
|
6
6
|
var _nodeCrypto = require("node:crypto");
|
|
7
|
-
var
|
|
8
|
-
var _keychain =
|
|
9
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
var _constants = require("./api/constants");
|
|
8
|
+
var _keychain = require("./keychain");
|
|
10
9
|
// Config
|
|
11
10
|
const SERVICE = exports.SERVICE = 'vip-go-cli';
|
|
12
11
|
class Token {
|
|
@@ -62,34 +61,39 @@ class Token {
|
|
|
62
61
|
}
|
|
63
62
|
static async uuid() {
|
|
64
63
|
const service = Token.getServiceName('-uuid');
|
|
65
|
-
|
|
64
|
+
const keychain = await (0, _keychain.getKeychain)();
|
|
65
|
+
let _uuid = await keychain.getPassword(service);
|
|
66
66
|
if (!_uuid) {
|
|
67
67
|
_uuid = (0, _nodeCrypto.randomUUID)();
|
|
68
|
-
await
|
|
68
|
+
await keychain.setPassword(service, _uuid);
|
|
69
69
|
}
|
|
70
70
|
return _uuid;
|
|
71
71
|
}
|
|
72
72
|
static async setUuid(_uuid) {
|
|
73
73
|
const service = Token.getServiceName('-uuid');
|
|
74
|
-
await
|
|
74
|
+
const keychain = await (0, _keychain.getKeychain)();
|
|
75
|
+
await keychain.setPassword(service, _uuid);
|
|
75
76
|
}
|
|
76
|
-
static set(token) {
|
|
77
|
+
static async set(token) {
|
|
77
78
|
const service = Token.getServiceName();
|
|
78
|
-
|
|
79
|
+
const keychain = await (0, _keychain.getKeychain)();
|
|
80
|
+
return keychain.setPassword(service, token);
|
|
79
81
|
}
|
|
80
82
|
static async get() {
|
|
81
83
|
const service = Token.getServiceName();
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
+
const keychain = await (0, _keychain.getKeychain)();
|
|
85
|
+
const token = await keychain.getPassword(service);
|
|
86
|
+
return new Token(token ?? '');
|
|
84
87
|
}
|
|
85
|
-
static purge() {
|
|
88
|
+
static async purge() {
|
|
86
89
|
const service = Token.getServiceName();
|
|
87
|
-
|
|
90
|
+
const keychain = await (0, _keychain.getKeychain)();
|
|
91
|
+
return keychain.deletePassword(service);
|
|
88
92
|
}
|
|
89
93
|
static getServiceName(modifier = '') {
|
|
90
94
|
let service = SERVICE;
|
|
91
|
-
if (
|
|
92
|
-
const sanitized =
|
|
95
|
+
if (_constants.PRODUCTION_API_HOST !== _constants.API_HOST) {
|
|
96
|
+
const sanitized = _constants.API_HOST.replace(/[^a-z0-9]/gi, '-');
|
|
93
97
|
service = `${SERVICE}:${sanitized}`;
|
|
94
98
|
}
|
|
95
99
|
return `${service}${modifier}`;
|
package/docs/SETUP.md
CHANGED
|
@@ -63,7 +63,7 @@ npm run build
|
|
|
63
63
|
|
|
64
64
|
## Usage
|
|
65
65
|
|
|
66
|
-
The software runs as standalone CLI and relies on
|
|
66
|
+
The software runs as standalone CLI and relies on environment variables for configuration and a few configuration files.
|
|
67
67
|
|
|
68
68
|
### Starting up locally
|
|
69
69
|
|
|
@@ -85,15 +85,15 @@ By default, we record information about the usage of this tool using an in-house
|
|
|
85
85
|
|
|
86
86
|
Install the software locally, run and follow the instructions to configure the access token.
|
|
87
87
|
|
|
88
|
-
###
|
|
88
|
+
### Environment variables
|
|
89
89
|
|
|
90
|
-
#### Configuring
|
|
90
|
+
#### Configuring environment variables
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
Environment variables are configured in the shell. Use normal shell commands to set them.
|
|
93
93
|
|
|
94
|
-
#### List of
|
|
94
|
+
#### List of environment variables
|
|
95
95
|
|
|
96
|
-
This application uses
|
|
96
|
+
This application uses environment variables for vital configuration information. Find a partial list below.
|
|
97
97
|
|
|
98
98
|
TODO: Update description of the variables.
|
|
99
99
|
|
|
@@ -108,6 +108,7 @@ TODO: Update description of the variables.
|
|
|
108
108
|
- `HTTP_PROXY`:
|
|
109
109
|
- `NO_PROXY`:
|
|
110
110
|
- `VIP_PROXY`: [For internal VIP use](TESTING.md#local-testing).
|
|
111
|
+
- `VIP_RECHALLENGE_WAIT`: set to `1` to print the verification URL and wait for rechallenge completion on another device.
|
|
111
112
|
- `VIP_USE_SYSTEM_PROXY`:
|
|
112
113
|
- `WPVIP_DEPLOY_TOKEN`: For use with `vip app deploy` on sites that have custom deploys enabled.
|
|
113
114
|
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: accepted
|
|
3
|
+
date: 2026-07-01
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Accept Operation-Scoped Elevated Token Reuse
|
|
7
|
+
|
|
8
|
+
## Context and Problem Statement
|
|
9
|
+
|
|
10
|
+
Step-up rechallenge currently issues elevated tokens scoped by GraphQL `requestedOperation` (mutation field name or operation domain), not by app, environment, or payload details.
|
|
11
|
+
|
|
12
|
+
The team must decide whether this behavior should be treated as a defect that requires per-resource rebinding, or as intended product behavior.
|
|
13
|
+
|
|
14
|
+
Primary workflow motivation: users may need to perform the same protected operation repeatedly across many targets, such as adding many domains to multiple environments. Requiring a new rechallenge for every target would add significant friction.
|
|
15
|
+
|
|
16
|
+
## Decision Drivers
|
|
17
|
+
|
|
18
|
+
- Reduce repeated operator friction in bulk workflows.
|
|
19
|
+
- Preserve baseline authorization enforcement at resolver level.
|
|
20
|
+
- Keep step-up semantics understandable: user confirms an operation class, not one specific payload.
|
|
21
|
+
- Avoid unnecessary complexity in token minting, validation, and client caching.
|
|
22
|
+
- Keep room for future hardening if product intent changes.
|
|
23
|
+
|
|
24
|
+
## Considered Options
|
|
25
|
+
|
|
26
|
+
- Option 1: Keep operation-scoped elevated token reuse.
|
|
27
|
+
- Option 2: Require per-resource scoped elevated tokens (bind to app/environment/payload).
|
|
28
|
+
- Option 3: Disable reuse and force fresh rechallenge on every protected mutation.
|
|
29
|
+
|
|
30
|
+
## Decision Outcome
|
|
31
|
+
|
|
32
|
+
Chosen option: Option 1, keep operation-scoped elevated token reuse.
|
|
33
|
+
|
|
34
|
+
Accepted behavior: a valid elevated token for a protected operation may be reused across app/environment targets while token validity holds.
|
|
35
|
+
|
|
36
|
+
This is intentional because it removes repeated rechallenge prompts in high-volume administrative workflows, including adding many domains across multiple environments.
|
|
37
|
+
|
|
38
|
+
### Consequences
|
|
39
|
+
|
|
40
|
+
Good, because:
|
|
41
|
+
|
|
42
|
+
- Bulk operations become materially faster and less error-prone for users.
|
|
43
|
+
- Behavior aligns with current implementation and avoids disruptive contract changes.
|
|
44
|
+
- Security posture remains layered: resolver authorization still enforces target access for the authenticated user.
|
|
45
|
+
|
|
46
|
+
Bad, because:
|
|
47
|
+
|
|
48
|
+
- Some readers may incorrectly assume step-up approval is resource-bound.
|
|
49
|
+
- If future product intent requires per-resource confirmation, this decision will need to be superseded and implementation changed.
|
|
50
|
+
|
|
51
|
+
Neutral, because:
|
|
52
|
+
|
|
53
|
+
- This decision does not change which mutations are protected; it defines scope behavior once a mutation is protected.
|
|
54
|
+
|
|
55
|
+
### Confirmation
|
|
56
|
+
|
|
57
|
+
The decision is considered correctly implemented when all of the following hold:
|
|
58
|
+
|
|
59
|
+
- Rechallenge token scope is derived from `requestedOperation`.
|
|
60
|
+
- Elevated token validation checks operation/operationDomain compatibility.
|
|
61
|
+
- Resolver-level authorization remains enforced independently of elevated token scope.
|
|
62
|
+
- Documentation and support guidance describe operation-scoped reuse as intended behavior.
|
|
63
|
+
|
|
64
|
+
## Pros and Cons of the Options
|
|
65
|
+
|
|
66
|
+
### Option 1: Keep operation-scoped elevated token reuse
|
|
67
|
+
|
|
68
|
+
- Good, because it optimizes repeated protected actions across many targets.
|
|
69
|
+
- Good, because it matches existing VIP CLI and GOOP behavior.
|
|
70
|
+
- Bad, because it may be perceived as broader than least-privilege if readers expect resource scoping.
|
|
71
|
+
|
|
72
|
+
### Option 2: Require per-resource scoped elevated tokens
|
|
73
|
+
|
|
74
|
+
- Good, because it enforces tighter binding between step-up and target resource.
|
|
75
|
+
- Bad, because it increases user friction and rechallenge frequency in bulk workflows.
|
|
76
|
+
- Bad, because it introduces higher implementation and rollout complexity.
|
|
77
|
+
|
|
78
|
+
### Option 3: Disable reuse and force fresh rechallenge every time
|
|
79
|
+
|
|
80
|
+
- Good, because the model is simple and strict.
|
|
81
|
+
- Bad, because it has the worst user experience for repetitive operations.
|
|
82
|
+
- Bad, because it provides limited practical security gain beyond existing authorization checks.
|
|
83
|
+
|
|
84
|
+
## More Information
|
|
85
|
+
|
|
86
|
+
- Source validation and rationale: https://github.com/Automattic/vip-cli/pull/2869
|
|
87
|
+
- Revisit trigger: if product/security policy explicitly requires per-resource step-up approval, supersede this ADR with a new decision and migration plan.
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/vip",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.11",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@automattic/vip",
|
|
9
|
-
"version": "4.0.
|
|
9
|
+
"version": "4.0.11",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@apollo/client": "4.2.
|
|
13
|
+
"@apollo/client": "4.2.5",
|
|
14
14
|
"@automattic/vip-search-replace": "^2.0.0",
|
|
15
15
|
"@json2csv/plainjs": "^7.0.3",
|
|
16
16
|
"@wwa/single-line-log": "^1.1.4",
|
|
@@ -145,9 +145,9 @@
|
|
|
145
145
|
}
|
|
146
146
|
},
|
|
147
147
|
"node_modules/@apollo/client": {
|
|
148
|
-
"version": "4.2.
|
|
149
|
-
"resolved": "https://registry.npmjs.org/@apollo/client/-/client-4.2.
|
|
150
|
-
"integrity": "sha512
|
|
148
|
+
"version": "4.2.5",
|
|
149
|
+
"resolved": "https://registry.npmjs.org/@apollo/client/-/client-4.2.5.tgz",
|
|
150
|
+
"integrity": "sha512-1VyJ4eAriUFCfK2Btc09PQtxxgrnmoO1Dbg2A1O7MQbsK1ri5GSWBzc7/P6A0KJrkWll/Ojf9HC6ptIET8yv3g==",
|
|
151
151
|
"license": "MIT",
|
|
152
152
|
"dependencies": {
|
|
153
153
|
"@graphql-typed-document-node/core": "^3.1.1",
|
|
@@ -4594,9 +4594,9 @@
|
|
|
4594
4594
|
"license": "MIT"
|
|
4595
4595
|
},
|
|
4596
4596
|
"node_modules/@types/node": {
|
|
4597
|
-
"version": "26.
|
|
4598
|
-
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.
|
|
4599
|
-
"integrity": "sha512-
|
|
4597
|
+
"version": "26.1.0",
|
|
4598
|
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.0.tgz",
|
|
4599
|
+
"integrity": "sha512-O0A1G3xPGy4w7AgQdAQYUlQ+BKk2Oovw8eRpofyp5KdBZULnbe+WqaOVNrm705SHphCiG4XHsACrSmPu1f+Kgw==",
|
|
4600
4600
|
"license": "MIT",
|
|
4601
4601
|
"dependencies": {
|
|
4602
4602
|
"undici-types": "~8.3.0"
|
|
@@ -6914,9 +6914,9 @@
|
|
|
6914
6914
|
}
|
|
6915
6915
|
},
|
|
6916
6916
|
"node_modules/dockerode": {
|
|
6917
|
-
"version": "5.0.
|
|
6918
|
-
"resolved": "https://registry.npmjs.org/dockerode/-/dockerode-5.0.
|
|
6919
|
-
"integrity": "sha512-
|
|
6917
|
+
"version": "5.0.1",
|
|
6918
|
+
"resolved": "https://registry.npmjs.org/dockerode/-/dockerode-5.0.1.tgz",
|
|
6919
|
+
"integrity": "sha512-avsq/xk4YPIrn0CgleX5bjT9Y8IT1p9PxrNQ++RBQ2WEyFfHCTDsT9kmyxz+H/axnjAwg8wJWEIuPGOUuNupiA==",
|
|
6920
6920
|
"license": "Apache-2.0",
|
|
6921
6921
|
"dependencies": {
|
|
6922
6922
|
"@balena/dockerignore": "^1.0.2",
|
|
@@ -11418,9 +11418,9 @@
|
|
|
11418
11418
|
"license": "MIT"
|
|
11419
11419
|
},
|
|
11420
11420
|
"node_modules/js-yaml": {
|
|
11421
|
-
"version": "5.1
|
|
11422
|
-
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.1.
|
|
11423
|
-
"integrity": "sha512-
|
|
11421
|
+
"version": "5.2.1",
|
|
11422
|
+
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.2.1.tgz",
|
|
11423
|
+
"integrity": "sha512-zfLtNfQqxVqq3uaTqSkh4x4hZw3KHobGUA0fJUj4wawW8bsQLTVqpHdXSIzidh7o+4lEW36tANuAGdaFx6Zgnw==",
|
|
11424
11424
|
"funding": [
|
|
11425
11425
|
{
|
|
11426
11426
|
"type": "github",
|
|
@@ -14172,9 +14172,9 @@
|
|
|
14172
14172
|
}
|
|
14173
14173
|
},
|
|
14174
14174
|
"node_modules/tar": {
|
|
14175
|
-
"version": "7.5.
|
|
14176
|
-
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.
|
|
14177
|
-
"integrity": "sha512-
|
|
14175
|
+
"version": "7.5.19",
|
|
14176
|
+
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.19.tgz",
|
|
14177
|
+
"integrity": "sha512-4LeEWl96twnS2Q7Bz4MGqgazLqO+hJN63GZxXoIqh1T3VweYD997gbU1ItNsQafqqXTXd5WFyFdReLtwvRBNiw==",
|
|
14178
14178
|
"license": "BlueOak-1.0.0",
|
|
14179
14179
|
"dependencies": {
|
|
14180
14180
|
"@isaacs/fs-minipass": "^4.0.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/vip",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.11",
|
|
4
4
|
"description": "The VIP Javascript library & CLI",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -27,6 +27,10 @@
|
|
|
27
27
|
"vip-config-software-update": "dist/bin/vip-config-software-update.js",
|
|
28
28
|
"vip-db": "dist/bin/vip-db.js",
|
|
29
29
|
"vip-db-phpmyadmin": "dist/bin/vip-db-phpmyadmin.js",
|
|
30
|
+
"vip-defensive-mode": "dist/bin/vip-defensive-mode.js",
|
|
31
|
+
"vip-defensive-mode-configure": "dist/bin/vip-defensive-mode-configure.js",
|
|
32
|
+
"vip-defensive-mode-disable": "dist/bin/vip-defensive-mode-disable.js",
|
|
33
|
+
"vip-defensive-mode-enable": "dist/bin/vip-defensive-mode-enable.js",
|
|
30
34
|
"vip-dev-env": "dist/bin/vip-dev-env.js",
|
|
31
35
|
"vip-dev-env-create": "dist/bin/vip-dev-env-create.js",
|
|
32
36
|
"vip-dev-env-update": "dist/bin/vip-dev-env-update.js",
|
|
@@ -141,7 +145,7 @@
|
|
|
141
145
|
"typescript": "^6.0.2"
|
|
142
146
|
},
|
|
143
147
|
"dependencies": {
|
|
144
|
-
"@apollo/client": "4.2.
|
|
148
|
+
"@apollo/client": "4.2.5",
|
|
145
149
|
"@automattic/vip-search-replace": "^2.0.0",
|
|
146
150
|
"@json2csv/plainjs": "^7.0.3",
|
|
147
151
|
"@wwa/single-line-log": "^1.1.4",
|