groove-dev 0.27.143 → 0.27.145
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/CLAUDE.md +0 -7
- package/node_modules/@groove-dev/cli/package.json +1 -1
- package/node_modules/@groove-dev/daemon/package.json +1 -1
- package/node_modules/@groove-dev/daemon/src/api.js +1086 -6532
- package/node_modules/@groove-dev/daemon/src/conversations.js +18 -48
- package/node_modules/@groove-dev/daemon/src/gateways/manager.js +35 -1
- package/node_modules/@groove-dev/daemon/src/index.js +3 -0
- package/node_modules/@groove-dev/daemon/src/journalist.js +23 -13
- package/node_modules/@groove-dev/daemon/src/mlx-server.js +365 -0
- package/node_modules/@groove-dev/daemon/src/model-lab.js +308 -12
- package/node_modules/@groove-dev/daemon/src/pm.js +1 -1
- package/node_modules/@groove-dev/daemon/src/process.js +2 -2
- package/node_modules/@groove-dev/daemon/src/providers/local.js +36 -8
- package/node_modules/@groove-dev/daemon/src/registry.js +21 -5
- package/node_modules/@groove-dev/daemon/src/routes/agents.js +812 -0
- package/node_modules/@groove-dev/daemon/src/routes/coordination.js +318 -0
- package/node_modules/@groove-dev/daemon/src/routes/files.js +751 -0
- package/node_modules/@groove-dev/daemon/src/routes/integrations.js +485 -0
- package/node_modules/@groove-dev/daemon/src/routes/network.js +1784 -0
- package/node_modules/@groove-dev/daemon/src/routes/providers.js +755 -0
- package/node_modules/@groove-dev/daemon/src/routes/schedules.js +110 -0
- package/node_modules/@groove-dev/daemon/src/routes/teams.js +650 -0
- package/node_modules/@groove-dev/daemon/src/scheduler.js +456 -24
- package/node_modules/@groove-dev/daemon/src/teams.js +1 -1
- package/node_modules/@groove-dev/daemon/src/validate.js +38 -1
- package/node_modules/@groove-dev/daemon/templates/mlx-setup.json +12 -0
- package/node_modules/@groove-dev/daemon/templates/tgi-setup.json +1 -1
- package/node_modules/@groove-dev/daemon/templates/vllm-setup.json +1 -1
- package/node_modules/@groove-dev/daemon/test/introducer.test.js +3 -3
- package/node_modules/@groove-dev/daemon/test/journalist.test.js +7 -10
- package/node_modules/@groove-dev/daemon/test/registry.test.js +38 -0
- package/node_modules/@groove-dev/gui/dist/assets/index-Bxc0gU06.js +1006 -0
- package/node_modules/@groove-dev/gui/dist/assets/index-C0pztKBn.css +1 -0
- package/node_modules/@groove-dev/gui/dist/index.html +2 -2
- package/node_modules/@groove-dev/gui/package.json +1 -1
- package/node_modules/@groove-dev/gui/src/{app.jsx → App.jsx} +0 -2
- package/node_modules/@groove-dev/gui/src/app.css +35 -0
- package/node_modules/@groove-dev/gui/src/components/agents/agent-config.jsx +1 -128
- package/node_modules/@groove-dev/gui/src/components/agents/agent-feed.jsx +210 -112
- package/node_modules/@groove-dev/gui/src/components/agents/agent-node.jsx +8 -13
- package/node_modules/@groove-dev/gui/src/components/agents/agent-panel.jsx +2 -70
- package/node_modules/@groove-dev/gui/src/components/agents/code-review.jsx +159 -122
- package/node_modules/@groove-dev/gui/src/components/agents/diff-viewer.jsx +23 -23
- package/node_modules/@groove-dev/gui/src/components/agents/journalist-panel.jsx +1 -1
- package/node_modules/@groove-dev/gui/src/components/agents/spawn-wizard.jsx +2 -135
- package/node_modules/@groove-dev/gui/src/components/automations/automation-card.jsx +274 -0
- package/node_modules/@groove-dev/gui/src/components/automations/automation-wizard.jsx +1136 -0
- package/node_modules/@groove-dev/gui/src/components/chat/chat-header.jsx +2 -0
- package/node_modules/@groove-dev/gui/src/components/chat/chat-input.jsx +68 -66
- package/node_modules/@groove-dev/gui/src/components/chat/chat-view.jsx +4 -8
- package/node_modules/@groove-dev/gui/src/components/dashboard/activity-feed.jsx +3 -3
- package/node_modules/@groove-dev/gui/src/components/dashboard/cache-ring.jsx +5 -5
- package/node_modules/@groove-dev/gui/src/components/dashboard/context-gauges.jsx +6 -8
- package/node_modules/@groove-dev/gui/src/components/dashboard/fleet-panel.jsx +8 -14
- package/node_modules/@groove-dev/gui/src/components/dashboard/intel-panel.jsx +238 -656
- package/node_modules/@groove-dev/gui/src/components/dashboard/kpi-card.jsx +3 -3
- package/node_modules/@groove-dev/gui/src/components/dashboard/routing-chart.jsx +3 -3
- package/node_modules/@groove-dev/gui/src/components/dashboard/team-burn-panel.jsx +1 -1
- package/node_modules/@groove-dev/gui/src/components/dashboard/token-chart.jsx +4 -4
- package/node_modules/@groove-dev/gui/src/components/lab/chat-playground.jsx +39 -31
- package/node_modules/@groove-dev/gui/src/components/lab/lab-assistant.jsx +316 -82
- package/node_modules/@groove-dev/gui/src/components/lab/metrics-panel.jsx +187 -32
- package/node_modules/@groove-dev/gui/src/components/lab/parameter-panel.jsx +200 -18
- package/node_modules/@groove-dev/gui/src/components/lab/preset-manager.jsx +17 -14
- package/node_modules/@groove-dev/gui/src/components/lab/runtime-config.jsx +335 -152
- package/node_modules/@groove-dev/gui/src/components/lab/system-prompt-editor.jsx +10 -8
- package/node_modules/@groove-dev/gui/src/components/layout/activity-bar.jsx +2 -4
- package/node_modules/@groove-dev/gui/src/components/layout/terminal-panel.jsx +4 -2
- package/node_modules/@groove-dev/gui/src/components/layout/welcome-splash.jsx +137 -108
- package/node_modules/@groove-dev/gui/src/components/network/network-health.jsx +2 -2
- package/node_modules/@groove-dev/gui/src/components/network/performance-dashboard.jsx +4 -4
- package/node_modules/@groove-dev/gui/src/components/settings/ssh-wizard.jsx +81 -99
- package/node_modules/@groove-dev/gui/src/components/ui/sheet.jsx +5 -2
- package/node_modules/@groove-dev/gui/src/components/ui/slider.jsx +8 -8
- package/node_modules/@groove-dev/gui/src/lib/cron.js +64 -0
- package/node_modules/@groove-dev/gui/src/lib/status.js +25 -24
- package/node_modules/@groove-dev/gui/src/lib/theme-hex.js +1 -0
- package/node_modules/@groove-dev/gui/src/stores/groove.js +51 -3144
- package/node_modules/@groove-dev/gui/src/stores/helpers.js +10 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/agents-slice.js +459 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/automations-slice.js +96 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/chat-slice.js +226 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/editor-slice.js +285 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/marketplace-slice.js +461 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/network-slice.js +361 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/preview-slice.js +109 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/providers-slice.js +897 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/teams-slice.js +413 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/ui-slice.js +98 -0
- package/node_modules/@groove-dev/gui/src/views/agents.jsx +5 -5
- package/node_modules/@groove-dev/gui/src/views/dashboard.jsx +12 -13
- package/node_modules/@groove-dev/gui/src/views/marketplace.jsx +191 -3
- package/node_modules/@groove-dev/gui/src/views/model-lab.jsx +54 -12
- package/node_modules/@groove-dev/gui/src/views/models.jsx +419 -496
- package/node_modules/@groove-dev/gui/src/views/network.jsx +3 -3
- package/node_modules/@groove-dev/gui/src/views/settings.jsx +81 -94
- package/node_modules/@groove-dev/gui/src/views/teams.jsx +40 -483
- package/node_modules/axios/CHANGELOG.md +260 -0
- package/node_modules/axios/README.md +595 -223
- package/node_modules/axios/dist/axios.js +1460 -1090
- package/node_modules/axios/dist/axios.js.map +1 -1
- package/node_modules/axios/dist/axios.min.js +3 -3
- package/node_modules/axios/dist/axios.min.js.map +1 -1
- package/node_modules/axios/dist/browser/axios.cjs +1560 -1132
- package/node_modules/axios/dist/browser/axios.cjs.map +1 -1
- package/node_modules/axios/dist/esm/axios.js +1557 -1128
- package/node_modules/axios/dist/esm/axios.js.map +1 -1
- package/node_modules/axios/dist/esm/axios.min.js +2 -2
- package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
- package/node_modules/axios/dist/node/axios.cjs +1594 -1057
- package/node_modules/axios/dist/node/axios.cjs.map +1 -1
- package/node_modules/axios/index.d.cts +40 -41
- package/node_modules/axios/index.d.ts +151 -227
- package/node_modules/axios/index.js +2 -0
- package/node_modules/axios/lib/adapters/adapters.js +4 -2
- package/node_modules/axios/lib/adapters/fetch.js +147 -16
- package/node_modules/axios/lib/adapters/http.js +306 -58
- package/node_modules/axios/lib/adapters/xhr.js +6 -2
- package/node_modules/axios/lib/core/Axios.js +7 -3
- package/node_modules/axios/lib/core/AxiosError.js +120 -34
- package/node_modules/axios/lib/core/AxiosHeaders.js +27 -25
- package/node_modules/axios/lib/core/buildFullPath.js +1 -1
- package/node_modules/axios/lib/core/dispatchRequest.js +19 -7
- package/node_modules/axios/lib/core/mergeConfig.js +21 -4
- package/node_modules/axios/lib/core/settle.js +7 -11
- package/node_modules/axios/lib/defaults/index.js +14 -9
- package/node_modules/axios/lib/env/data.js +1 -1
- package/node_modules/axios/lib/helpers/AxiosURLSearchParams.js +1 -2
- package/node_modules/axios/lib/helpers/buildURL.js +1 -1
- package/node_modules/axios/lib/helpers/cookies.js +14 -2
- package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +28 -1
- package/node_modules/axios/lib/helpers/formDataToJSON.js +3 -1
- package/node_modules/axios/lib/helpers/formDataToStream.js +3 -2
- package/node_modules/axios/lib/helpers/parseProtocol.js +1 -1
- package/node_modules/axios/lib/helpers/progressEventReducer.js +5 -5
- package/node_modules/axios/lib/helpers/resolveConfig.js +54 -18
- package/node_modules/axios/lib/helpers/shouldBypassProxy.js +74 -2
- package/node_modules/axios/lib/helpers/toFormData.js +10 -2
- package/node_modules/axios/lib/helpers/validator.js +3 -1
- package/node_modules/axios/lib/utils.js +33 -21
- package/node_modules/axios/package.json +17 -24
- package/node_modules/follow-redirects/README.md +7 -5
- package/node_modules/follow-redirects/index.js +24 -1
- package/node_modules/follow-redirects/package.json +1 -1
- package/package.json +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/daemon/package.json +1 -1
- package/packages/daemon/src/api.js +1086 -6532
- package/packages/daemon/src/conversations.js +18 -48
- package/packages/daemon/src/gateways/manager.js +35 -1
- package/packages/daemon/src/index.js +3 -0
- package/packages/daemon/src/journalist.js +23 -13
- package/packages/daemon/src/mlx-server.js +365 -0
- package/packages/daemon/src/model-lab.js +308 -12
- package/packages/daemon/src/pm.js +1 -1
- package/packages/daemon/src/process.js +2 -2
- package/packages/daemon/src/providers/local.js +36 -8
- package/packages/daemon/src/registry.js +21 -5
- package/packages/daemon/src/routes/agents.js +812 -0
- package/packages/daemon/src/routes/coordination.js +318 -0
- package/packages/daemon/src/routes/files.js +751 -0
- package/packages/daemon/src/routes/integrations.js +485 -0
- package/packages/daemon/src/routes/network.js +1784 -0
- package/packages/daemon/src/routes/providers.js +755 -0
- package/packages/daemon/src/routes/schedules.js +110 -0
- package/packages/daemon/src/routes/teams.js +650 -0
- package/packages/daemon/src/scheduler.js +456 -24
- package/packages/daemon/src/teams.js +1 -1
- package/packages/daemon/src/validate.js +38 -1
- package/packages/daemon/templates/mlx-setup.json +12 -0
- package/packages/daemon/templates/tgi-setup.json +1 -1
- package/packages/daemon/templates/vllm-setup.json +1 -1
- package/packages/gui/dist/assets/index-Bxc0gU06.js +1006 -0
- package/packages/gui/dist/assets/index-C0pztKBn.css +1 -0
- package/packages/gui/dist/index.html +2 -2
- package/packages/gui/package.json +1 -1
- package/packages/gui/src/{app.jsx → App.jsx} +0 -2
- package/packages/gui/src/app.css +35 -0
- package/packages/gui/src/components/agents/agent-config.jsx +1 -128
- package/packages/gui/src/components/agents/agent-feed.jsx +210 -112
- package/packages/gui/src/components/agents/agent-node.jsx +8 -13
- package/packages/gui/src/components/agents/agent-panel.jsx +2 -70
- package/packages/gui/src/components/agents/code-review.jsx +159 -122
- package/packages/gui/src/components/agents/diff-viewer.jsx +23 -23
- package/packages/gui/src/components/agents/journalist-panel.jsx +1 -1
- package/packages/gui/src/components/agents/spawn-wizard.jsx +2 -135
- package/packages/gui/src/components/automations/automation-card.jsx +274 -0
- package/packages/gui/src/components/automations/automation-wizard.jsx +1136 -0
- package/packages/gui/src/components/chat/chat-header.jsx +2 -0
- package/packages/gui/src/components/chat/chat-input.jsx +68 -66
- package/packages/gui/src/components/chat/chat-view.jsx +4 -8
- package/packages/gui/src/components/dashboard/activity-feed.jsx +3 -3
- package/packages/gui/src/components/dashboard/cache-ring.jsx +5 -5
- package/packages/gui/src/components/dashboard/context-gauges.jsx +6 -8
- package/packages/gui/src/components/dashboard/fleet-panel.jsx +8 -14
- package/packages/gui/src/components/dashboard/intel-panel.jsx +238 -656
- package/packages/gui/src/components/dashboard/kpi-card.jsx +3 -3
- package/packages/gui/src/components/dashboard/routing-chart.jsx +3 -3
- package/packages/gui/src/components/dashboard/team-burn-panel.jsx +1 -1
- package/packages/gui/src/components/dashboard/token-chart.jsx +4 -4
- package/packages/gui/src/components/lab/chat-playground.jsx +39 -31
- package/packages/gui/src/components/lab/lab-assistant.jsx +316 -82
- package/packages/gui/src/components/lab/metrics-panel.jsx +187 -32
- package/packages/gui/src/components/lab/parameter-panel.jsx +200 -18
- package/packages/gui/src/components/lab/preset-manager.jsx +17 -14
- package/packages/gui/src/components/lab/runtime-config.jsx +335 -152
- package/packages/gui/src/components/lab/system-prompt-editor.jsx +10 -8
- package/packages/gui/src/components/layout/activity-bar.jsx +2 -4
- package/packages/gui/src/components/layout/terminal-panel.jsx +4 -2
- package/packages/gui/src/components/layout/welcome-splash.jsx +137 -108
- package/packages/gui/src/components/network/network-health.jsx +2 -2
- package/packages/gui/src/components/network/performance-dashboard.jsx +4 -4
- package/packages/gui/src/components/settings/ssh-wizard.jsx +81 -99
- package/packages/gui/src/components/ui/sheet.jsx +5 -2
- package/packages/gui/src/components/ui/slider.jsx +8 -8
- package/packages/gui/src/lib/cron.js +64 -0
- package/packages/gui/src/lib/status.js +25 -24
- package/packages/gui/src/lib/theme-hex.js +1 -0
- package/packages/gui/src/stores/groove.js +51 -3144
- package/packages/gui/src/stores/helpers.js +10 -0
- package/packages/gui/src/stores/slices/agents-slice.js +459 -0
- package/packages/gui/src/stores/slices/automations-slice.js +96 -0
- package/packages/gui/src/stores/slices/chat-slice.js +226 -0
- package/packages/gui/src/stores/slices/editor-slice.js +285 -0
- package/packages/gui/src/stores/slices/marketplace-slice.js +461 -0
- package/packages/gui/src/stores/slices/network-slice.js +361 -0
- package/packages/gui/src/stores/slices/preview-slice.js +109 -0
- package/packages/gui/src/stores/slices/providers-slice.js +897 -0
- package/packages/gui/src/stores/slices/teams-slice.js +413 -0
- package/packages/gui/src/stores/slices/ui-slice.js +98 -0
- package/packages/gui/src/views/agents.jsx +5 -5
- package/packages/gui/src/views/dashboard.jsx +12 -13
- package/packages/gui/src/views/marketplace.jsx +191 -3
- package/packages/gui/src/views/model-lab.jsx +54 -12
- package/packages/gui/src/views/models.jsx +419 -496
- package/packages/gui/src/views/network.jsx +3 -3
- package/packages/gui/src/views/settings.jsx +81 -94
- package/packages/gui/src/views/teams.jsx +40 -483
- package/SECURITY_SWEEP.md +0 -228
- package/TRAINING_DATA_v4.md +0 -6
- package/node_modules/@groove-dev/gui/dist/assets/index-CCVvAoQn.css +0 -1
- package/node_modules/@groove-dev/gui/dist/assets/index-DGIv_TRm.js +0 -984
- package/node_modules/@groove-dev/gui/src/components/agents/agent-chat.jsx +0 -379
- package/node_modules/@groove-dev/gui/src/views/preview.jsx +0 -6
- package/node_modules/@groove-dev/gui/src/views/subscription-panel.jsx +0 -327
- package/packages/gui/dist/assets/index-CCVvAoQn.css +0 -1
- package/packages/gui/dist/assets/index-DGIv_TRm.js +0 -984
- package/packages/gui/src/components/agents/agent-chat.jsx +0 -379
- package/packages/gui/src/views/preview.jsx +0 -6
- package/packages/gui/src/views/subscription-panel.jsx +0 -327
- package/test.py +0 -571
|
@@ -7,15 +7,55 @@ import mergeConfig from '../core/mergeConfig.js';
|
|
|
7
7
|
import AxiosHeaders from '../core/AxiosHeaders.js';
|
|
8
8
|
import buildURL from './buildURL.js';
|
|
9
9
|
|
|
10
|
+
const FORM_DATA_CONTENT_HEADERS = ['content-type', 'content-length'];
|
|
11
|
+
|
|
12
|
+
function setFormDataHeaders(headers, formHeaders, policy) {
|
|
13
|
+
if (policy !== 'content-only') {
|
|
14
|
+
headers.set(formHeaders);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
Object.entries(formHeaders).forEach(([key, val]) => {
|
|
19
|
+
if (FORM_DATA_CONTENT_HEADERS.includes(key.toLowerCase())) {
|
|
20
|
+
headers.set(key, val);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Encode a UTF-8 string to a Latin-1 byte string for use with btoa().
|
|
27
|
+
* This is a modern replacement for the deprecated unescape(encodeURIComponent(str)) pattern.
|
|
28
|
+
*
|
|
29
|
+
* @param {string} str The string to encode
|
|
30
|
+
*
|
|
31
|
+
* @returns {string} UTF-8 bytes as a Latin-1 string
|
|
32
|
+
*/
|
|
33
|
+
const encodeUTF8 = (str) =>
|
|
34
|
+
encodeURIComponent(str).replace(/%([0-9A-F]{2})/gi, (_, hex) =>
|
|
35
|
+
String.fromCharCode(parseInt(hex, 16))
|
|
36
|
+
);
|
|
37
|
+
|
|
10
38
|
export default (config) => {
|
|
11
39
|
const newConfig = mergeConfig({}, config);
|
|
12
40
|
|
|
13
|
-
|
|
41
|
+
// Read only own properties to prevent prototype pollution gadgets
|
|
42
|
+
// (e.g. Object.prototype.baseURL = 'https://evil.com').
|
|
43
|
+
const own = (key) => (utils.hasOwnProp(newConfig, key) ? newConfig[key] : undefined);
|
|
44
|
+
|
|
45
|
+
const data = own('data');
|
|
46
|
+
let withXSRFToken = own('withXSRFToken');
|
|
47
|
+
const xsrfHeaderName = own('xsrfHeaderName');
|
|
48
|
+
const xsrfCookieName = own('xsrfCookieName');
|
|
49
|
+
let headers = own('headers');
|
|
50
|
+
const auth = own('auth');
|
|
51
|
+
const baseURL = own('baseURL');
|
|
52
|
+
const allowAbsoluteUrls = own('allowAbsoluteUrls');
|
|
53
|
+
const url = own('url');
|
|
14
54
|
|
|
15
55
|
newConfig.headers = headers = AxiosHeaders.from(headers);
|
|
16
56
|
|
|
17
57
|
newConfig.url = buildURL(
|
|
18
|
-
buildFullPath(
|
|
58
|
+
buildFullPath(baseURL, url, allowAbsoluteUrls),
|
|
19
59
|
config.params,
|
|
20
60
|
config.paramsSerializer
|
|
21
61
|
);
|
|
@@ -25,11 +65,7 @@ export default (config) => {
|
|
|
25
65
|
headers.set(
|
|
26
66
|
'Authorization',
|
|
27
67
|
'Basic ' +
|
|
28
|
-
btoa(
|
|
29
|
-
(auth.username || '') +
|
|
30
|
-
':' +
|
|
31
|
-
(auth.password ? unescape(encodeURIComponent(auth.password)) : '')
|
|
32
|
-
)
|
|
68
|
+
btoa((auth.username || '') + ':' + (auth.password ? encodeUTF8(auth.password) : ''))
|
|
33
69
|
);
|
|
34
70
|
}
|
|
35
71
|
|
|
@@ -38,14 +74,7 @@ export default (config) => {
|
|
|
38
74
|
headers.setContentType(undefined); // browser handles it
|
|
39
75
|
} else if (utils.isFunction(data.getHeaders)) {
|
|
40
76
|
// Node.js FormData (like form-data package)
|
|
41
|
-
|
|
42
|
-
// Only set safe headers to avoid overwriting security headers
|
|
43
|
-
const allowedHeaders = ['content-type', 'content-length'];
|
|
44
|
-
Object.entries(formHeaders).forEach(([key, val]) => {
|
|
45
|
-
if (allowedHeaders.includes(key.toLowerCase())) {
|
|
46
|
-
headers.set(key, val);
|
|
47
|
-
}
|
|
48
|
-
});
|
|
77
|
+
setFormDataHeaders(headers, data.getHeaders(), own('formDataHeaderPolicy'));
|
|
49
78
|
}
|
|
50
79
|
}
|
|
51
80
|
|
|
@@ -54,10 +83,17 @@ export default (config) => {
|
|
|
54
83
|
// Specifically not if we're in a web worker, or react-native.
|
|
55
84
|
|
|
56
85
|
if (platform.hasStandardBrowserEnv) {
|
|
57
|
-
|
|
86
|
+
if (utils.isFunction(withXSRFToken)) {
|
|
87
|
+
withXSRFToken = withXSRFToken(newConfig);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Strict boolean check — prevents proto-pollution gadgets (e.g. Object.prototype.withXSRFToken = 1)
|
|
91
|
+
// and misconfigurations (e.g. "false") from short-circuiting the same-origin check and leaking
|
|
92
|
+
// the XSRF token cross-origin.
|
|
93
|
+
const shouldSendXSRF =
|
|
94
|
+
withXSRFToken === true || (withXSRFToken == null && isURLSameOrigin(newConfig.url));
|
|
58
95
|
|
|
59
|
-
if (
|
|
60
|
-
// Add xsrf header
|
|
96
|
+
if (shouldSendXSRF) {
|
|
61
97
|
const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName);
|
|
62
98
|
|
|
63
99
|
if (xsrfValue) {
|
|
@@ -1,3 +1,50 @@
|
|
|
1
|
+
const LOOPBACK_HOSTNAMES = new Set(['localhost']);
|
|
2
|
+
|
|
3
|
+
const isIPv4Loopback = (host) => {
|
|
4
|
+
const parts = host.split('.');
|
|
5
|
+
if (parts.length !== 4) return false;
|
|
6
|
+
if (parts[0] !== '127') return false;
|
|
7
|
+
return parts.every((p) => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255);
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const isIPv6Loopback = (host) => {
|
|
11
|
+
// Collapse all-zero groups: any form of ::1 / 0:0:...:0:1
|
|
12
|
+
// First, strip any leading "::" by normalising with Set lookup of common forms,
|
|
13
|
+
// then fall back to structural check.
|
|
14
|
+
if (host === '::1') return true;
|
|
15
|
+
|
|
16
|
+
// Check IPv4-mapped IPv6 loopback: ::ffff:<v4-loopback> or ::ffff:<hex-v4-loopback>
|
|
17
|
+
// Node's URL parser normalises ::ffff:127.0.0.1 → ::ffff:7f00:1
|
|
18
|
+
const v4MappedDotted = host.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/i);
|
|
19
|
+
if (v4MappedDotted) return isIPv4Loopback(v4MappedDotted[1]);
|
|
20
|
+
|
|
21
|
+
const v4MappedHex = host.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);
|
|
22
|
+
if (v4MappedHex) {
|
|
23
|
+
const high = parseInt(v4MappedHex[1], 16);
|
|
24
|
+
// High 16 bits must start with 127 (0x7f) — i.e. 0x7f00..0x7fff
|
|
25
|
+
return high >= 0x7f00 && high <= 0x7fff;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Full-form ::1 variants: any number of zero groups followed by trailing 1
|
|
29
|
+
// e.g. 0:0:0:0:0:0:0:1, 0000:...:0001
|
|
30
|
+
const groups = host.split(':');
|
|
31
|
+
if (groups.length === 8) {
|
|
32
|
+
for (let i = 0; i < 7; i++) {
|
|
33
|
+
if (!/^0+$/.test(groups[i])) return false;
|
|
34
|
+
}
|
|
35
|
+
return /^0*1$/.test(groups[7]);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return false;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const isLoopback = (host) => {
|
|
42
|
+
if (!host) return false;
|
|
43
|
+
if (LOOPBACK_HOSTNAMES.has(host)) return true;
|
|
44
|
+
if (isIPv4Loopback(host)) return true;
|
|
45
|
+
return isIPv6Loopback(host);
|
|
46
|
+
};
|
|
47
|
+
|
|
1
48
|
const DEFAULT_PORTS = {
|
|
2
49
|
http: 80,
|
|
3
50
|
https: 443,
|
|
@@ -40,6 +87,31 @@ const parseNoProxyEntry = (entry) => {
|
|
|
40
87
|
return [entryHost, entryPort];
|
|
41
88
|
};
|
|
42
89
|
|
|
90
|
+
// Convert IPv4-mapped IPv6 (::ffff:0:0/96 prefix) to IPv4 dotted form so both
|
|
91
|
+
// sides of a NO_PROXY comparison see the same canonical address. Without this,
|
|
92
|
+
// `NO_PROXY=192.168.1.5` would not match a request to `http://[::ffff:192.168.1.5]/`
|
|
93
|
+
// (Node's URL parser normalises that to `[::ffff:c0a8:105]`), and vice-versa,
|
|
94
|
+
// allowing the proxy-bypass policy to be circumvented by using the alternate
|
|
95
|
+
// representation. Returns the input unchanged when not IPv4-mapped.
|
|
96
|
+
const IPV4_MAPPED_DOTTED_RE = /^(?:::|(?:0{1,4}:){1,4}:|(?:0{1,4}:){5})ffff:(\d+\.\d+\.\d+\.\d+)$/i;
|
|
97
|
+
const IPV4_MAPPED_HEX_RE = /^(?:::|(?:0{1,4}:){1,4}:|(?:0{1,4}:){5})ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i;
|
|
98
|
+
|
|
99
|
+
const unmapIPv4MappedIPv6 = (host) => {
|
|
100
|
+
if (typeof host !== 'string' || host.indexOf(':') === -1) return host;
|
|
101
|
+
|
|
102
|
+
const dotted = host.match(IPV4_MAPPED_DOTTED_RE);
|
|
103
|
+
if (dotted) return dotted[1];
|
|
104
|
+
|
|
105
|
+
const hex = host.match(IPV4_MAPPED_HEX_RE);
|
|
106
|
+
if (hex) {
|
|
107
|
+
const high = parseInt(hex[1], 16);
|
|
108
|
+
const low = parseInt(hex[2], 16);
|
|
109
|
+
return `${high >> 8}.${high & 0xff}.${low >> 8}.${low & 0xff}`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return host;
|
|
113
|
+
};
|
|
114
|
+
|
|
43
115
|
const normalizeNoProxyHost = (hostname) => {
|
|
44
116
|
if (!hostname) {
|
|
45
117
|
return hostname;
|
|
@@ -49,7 +121,7 @@ const normalizeNoProxyHost = (hostname) => {
|
|
|
49
121
|
hostname = hostname.slice(1, -1);
|
|
50
122
|
}
|
|
51
123
|
|
|
52
|
-
return hostname.replace(/\.+$/, '');
|
|
124
|
+
return unmapIPv4MappedIPv6(hostname.replace(/\.+$/, ''));
|
|
53
125
|
};
|
|
54
126
|
|
|
55
127
|
export default function shouldBypassProxy(location) {
|
|
@@ -101,6 +173,6 @@ export default function shouldBypassProxy(location) {
|
|
|
101
173
|
return hostname.endsWith(entryHost);
|
|
102
174
|
}
|
|
103
175
|
|
|
104
|
-
return hostname === entryHost;
|
|
176
|
+
return hostname === entryHost || (isLoopback(hostname) && isLoopback(entryHost));
|
|
105
177
|
});
|
|
106
178
|
}
|
|
@@ -115,6 +115,7 @@ function toFormData(obj, formData, options) {
|
|
|
115
115
|
const dots = options.dots;
|
|
116
116
|
const indexes = options.indexes;
|
|
117
117
|
const _Blob = options.Blob || (typeof Blob !== 'undefined' && Blob);
|
|
118
|
+
const maxDepth = options.maxDepth === undefined ? 100 : options.maxDepth;
|
|
118
119
|
const useBlob = _Blob && utils.isSpecCompliantForm(formData);
|
|
119
120
|
|
|
120
121
|
if (!utils.isFunction(visitor)) {
|
|
@@ -207,9 +208,16 @@ function toFormData(obj, formData, options) {
|
|
|
207
208
|
isVisitable,
|
|
208
209
|
});
|
|
209
210
|
|
|
210
|
-
function build(value, path) {
|
|
211
|
+
function build(value, path, depth = 0) {
|
|
211
212
|
if (utils.isUndefined(value)) return;
|
|
212
213
|
|
|
214
|
+
if (depth > maxDepth) {
|
|
215
|
+
throw new AxiosError(
|
|
216
|
+
'Object is too deeply nested (' + depth + ' levels). Max depth: ' + maxDepth,
|
|
217
|
+
AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
213
221
|
if (stack.indexOf(value) !== -1) {
|
|
214
222
|
throw Error('Circular reference detected in ' + path.join('.'));
|
|
215
223
|
}
|
|
@@ -222,7 +230,7 @@ function toFormData(obj, formData, options) {
|
|
|
222
230
|
visitor.call(formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers);
|
|
223
231
|
|
|
224
232
|
if (result === true) {
|
|
225
|
-
build(el, path ? path.concat(key) : [key]);
|
|
233
|
+
build(el, path ? path.concat(key) : [key], depth + 1);
|
|
226
234
|
}
|
|
227
235
|
});
|
|
228
236
|
|
|
@@ -86,7 +86,9 @@ function assertOptions(options, schema, allowUnknown) {
|
|
|
86
86
|
let i = keys.length;
|
|
87
87
|
while (i-- > 0) {
|
|
88
88
|
const opt = keys[i];
|
|
89
|
-
|
|
89
|
+
// Use hasOwnProperty so a polluted Object.prototype.<opt> cannot supply
|
|
90
|
+
// a non-function validator and cause a TypeError.
|
|
91
|
+
const validator = Object.prototype.hasOwnProperty.call(schema, opt) ? schema[opt] : undefined;
|
|
90
92
|
if (validator) {
|
|
91
93
|
const value = options[opt];
|
|
92
94
|
const result = value === undefined || validator(value, opt, options);
|
|
@@ -192,21 +192,21 @@ const isFile = kindOfTest('File');
|
|
|
192
192
|
* also have a `name` and `type` attribute to specify filename and content type
|
|
193
193
|
*
|
|
194
194
|
* @see https://github.com/facebook/react-native/blob/26684cf3adf4094eb6c405d345a75bf8c7c0bf88/Libraries/Network/FormData.js#L68-L71
|
|
195
|
-
*
|
|
195
|
+
*
|
|
196
196
|
* @param {*} value The value to test
|
|
197
|
-
*
|
|
197
|
+
*
|
|
198
198
|
* @returns {boolean} True if value is a React Native Blob, otherwise false
|
|
199
199
|
*/
|
|
200
200
|
const isReactNativeBlob = (value) => {
|
|
201
201
|
return !!(value && typeof value.uri !== 'undefined');
|
|
202
|
-
}
|
|
202
|
+
};
|
|
203
203
|
|
|
204
204
|
/**
|
|
205
205
|
* Determine if environment is React Native
|
|
206
206
|
* ReactNative `FormData` has a non-standard `getParts()` method
|
|
207
|
-
*
|
|
207
|
+
*
|
|
208
208
|
* @param {*} formData The formData to test
|
|
209
|
-
*
|
|
209
|
+
*
|
|
210
210
|
* @returns {boolean} True if environment is React Native, otherwise false
|
|
211
211
|
*/
|
|
212
212
|
const isReactNative = (formData) => formData && typeof formData.getParts !== 'undefined';
|
|
@@ -225,7 +225,7 @@ const isBlob = kindOfTest('Blob');
|
|
|
225
225
|
*
|
|
226
226
|
* @param {*} val The value to test
|
|
227
227
|
*
|
|
228
|
-
* @returns {boolean} True if value is a
|
|
228
|
+
* @returns {boolean} True if value is a FileList, otherwise false
|
|
229
229
|
*/
|
|
230
230
|
const isFileList = kindOfTest('FileList');
|
|
231
231
|
|
|
@@ -257,15 +257,17 @@ const G = getGlobal();
|
|
|
257
257
|
const FormDataCtor = typeof G.FormData !== 'undefined' ? G.FormData : undefined;
|
|
258
258
|
|
|
259
259
|
const isFormData = (thing) => {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
260
|
+
if (!thing) return false;
|
|
261
|
+
if (FormDataCtor && thing instanceof FormDataCtor) return true;
|
|
262
|
+
// Reject plain objects inheriting directly from Object.prototype so prototype-pollution gadgets can't spoof FormData.
|
|
263
|
+
const proto = getPrototypeOf(thing);
|
|
264
|
+
if (!proto || proto === Object.prototype) return false;
|
|
265
|
+
if (!isFunction(thing.append)) return false;
|
|
266
|
+
const kind = kindOf(thing);
|
|
267
|
+
return (
|
|
268
|
+
kind === 'formdata' ||
|
|
269
|
+
// detect form-data instance
|
|
270
|
+
(kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')
|
|
269
271
|
);
|
|
270
272
|
};
|
|
271
273
|
|
|
@@ -401,7 +403,7 @@ const isContextDefined = (context) => !isUndefined(context) && context !== _glob
|
|
|
401
403
|
*
|
|
402
404
|
* @returns {Object} Result of all merge properties
|
|
403
405
|
*/
|
|
404
|
-
function merge(
|
|
406
|
+
function merge(...objs) {
|
|
405
407
|
const { caseless, skipUndefined } = (isContextDefined(this) && this) || {};
|
|
406
408
|
const result = {};
|
|
407
409
|
const assignValue = (val, key) => {
|
|
@@ -411,8 +413,12 @@ function merge(/* obj1, obj2, obj3, ... */) {
|
|
|
411
413
|
}
|
|
412
414
|
|
|
413
415
|
const targetKey = (caseless && findKey(result, key)) || key;
|
|
414
|
-
|
|
415
|
-
|
|
416
|
+
// Read via own-prop only — a bare `result[targetKey]` walks the prototype
|
|
417
|
+
// chain, so a polluted Object.prototype value could surface here and get
|
|
418
|
+
// copied into the merged result.
|
|
419
|
+
const existing = hasOwnProperty(result, targetKey) ? result[targetKey] : undefined;
|
|
420
|
+
if (isPlainObject(existing) && isPlainObject(val)) {
|
|
421
|
+
result[targetKey] = merge(existing, val);
|
|
416
422
|
} else if (isPlainObject(val)) {
|
|
417
423
|
result[targetKey] = merge({}, val);
|
|
418
424
|
} else if (isArray(val)) {
|
|
@@ -422,8 +428,8 @@ function merge(/* obj1, obj2, obj3, ... */) {
|
|
|
422
428
|
}
|
|
423
429
|
};
|
|
424
430
|
|
|
425
|
-
for (let i = 0, l =
|
|
426
|
-
|
|
431
|
+
for (let i = 0, l = objs.length; i < l; i++) {
|
|
432
|
+
objs[i] && forEach(objs[i], assignValue);
|
|
427
433
|
}
|
|
428
434
|
return result;
|
|
429
435
|
}
|
|
@@ -445,6 +451,9 @@ const extend = (a, b, thisArg, { allOwnKeys } = {}) => {
|
|
|
445
451
|
(val, key) => {
|
|
446
452
|
if (thisArg && isFunction(val)) {
|
|
447
453
|
Object.defineProperty(a, key, {
|
|
454
|
+
// Null-proto descriptor so a polluted Object.prototype.get cannot
|
|
455
|
+
// hijack defineProperty's accessor-vs-data resolution.
|
|
456
|
+
__proto__: null,
|
|
448
457
|
value: bind(val, thisArg),
|
|
449
458
|
writable: true,
|
|
450
459
|
enumerable: true,
|
|
@@ -452,6 +461,7 @@ const extend = (a, b, thisArg, { allOwnKeys } = {}) => {
|
|
|
452
461
|
});
|
|
453
462
|
} else {
|
|
454
463
|
Object.defineProperty(a, key, {
|
|
464
|
+
__proto__: null,
|
|
455
465
|
value: val,
|
|
456
466
|
writable: true,
|
|
457
467
|
enumerable: true,
|
|
@@ -490,12 +500,14 @@ const stripBOM = (content) => {
|
|
|
490
500
|
const inherits = (constructor, superConstructor, props, descriptors) => {
|
|
491
501
|
constructor.prototype = Object.create(superConstructor.prototype, descriptors);
|
|
492
502
|
Object.defineProperty(constructor.prototype, 'constructor', {
|
|
503
|
+
__proto__: null,
|
|
493
504
|
value: constructor,
|
|
494
505
|
writable: true,
|
|
495
506
|
enumerable: false,
|
|
496
507
|
configurable: true,
|
|
497
508
|
});
|
|
498
509
|
Object.defineProperty(constructor, 'super', {
|
|
510
|
+
__proto__: null,
|
|
499
511
|
value: superConstructor.prototype,
|
|
500
512
|
});
|
|
501
513
|
props && Object.assign(constructor.prototype, props);
|
|
@@ -677,7 +689,7 @@ const reduceDescriptors = (obj, reducer) => {
|
|
|
677
689
|
const freezeMethods = (obj) => {
|
|
678
690
|
reduceDescriptors(obj, (descriptor, name) => {
|
|
679
691
|
// skip restricted props in strict mode
|
|
680
|
-
if (isFunction(obj) && ['arguments', 'caller', 'callee'].
|
|
692
|
+
if (isFunction(obj) && ['arguments', 'caller', 'callee'].includes(name)) {
|
|
681
693
|
return false;
|
|
682
694
|
}
|
|
683
695
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "axios",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"description": "Promise based HTTP client for the browser and node.js",
|
|
5
5
|
"main": "./dist/node/axios.cjs",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -86,10 +86,10 @@
|
|
|
86
86
|
"Justin Beckwith (https://github.com/JustinBeckwith)",
|
|
87
87
|
"Martti Laine (https://github.com/codeclown)",
|
|
88
88
|
"Xianming Zhong (https://github.com/chinesedfan)",
|
|
89
|
-
"Remco Haszing (https://github.com/remcohaszing)",
|
|
90
89
|
"Willian Agostini (https://github.com/WillianAgostini)",
|
|
91
|
-
"
|
|
92
|
-
"
|
|
90
|
+
"Shaan Majid (https://github.com/shaanmajid)",
|
|
91
|
+
"Remco Haszing (https://github.com/remcohaszing)",
|
|
92
|
+
"Rikki Gibson (https://github.com/RikkiGibson)"
|
|
93
93
|
],
|
|
94
94
|
"sideEffects": false,
|
|
95
95
|
"license": "MIT",
|
|
@@ -121,15 +121,15 @@
|
|
|
121
121
|
"prepare": "husky"
|
|
122
122
|
},
|
|
123
123
|
"dependencies": {
|
|
124
|
-
"follow-redirects": "^1.
|
|
124
|
+
"follow-redirects": "^1.16.0",
|
|
125
125
|
"form-data": "^4.0.5",
|
|
126
126
|
"proxy-from-env": "^2.1.0"
|
|
127
127
|
},
|
|
128
128
|
"devDependencies": {
|
|
129
129
|
"@babel/core": "^7.29.0",
|
|
130
|
-
"@babel/preset-env": "^7.29.
|
|
131
|
-
"@commitlint/cli": "^20.
|
|
132
|
-
"@commitlint/config-conventional": "^20.
|
|
130
|
+
"@babel/preset-env": "^7.29.2",
|
|
131
|
+
"@commitlint/cli": "^20.5.0",
|
|
132
|
+
"@commitlint/config-conventional": "^20.5.0",
|
|
133
133
|
"@eslint/js": "^10.0.1",
|
|
134
134
|
"@rollup/plugin-alias": "^6.0.0",
|
|
135
135
|
"@rollup/plugin-babel": "^7.0.0",
|
|
@@ -137,40 +137,33 @@
|
|
|
137
137
|
"@rollup/plugin-json": "^6.1.0",
|
|
138
138
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
139
139
|
"@rollup/plugin-terser": "^1.0.0",
|
|
140
|
-
"@vitest/browser": "^4.1.
|
|
141
|
-
"@vitest/browser-playwright": "^4.1.
|
|
140
|
+
"@vitest/browser": "^4.1.5",
|
|
141
|
+
"@vitest/browser-playwright": "^4.1.5",
|
|
142
142
|
"abortcontroller-polyfill": "^1.7.8",
|
|
143
|
-
"auto-changelog": "^2.5.0",
|
|
144
143
|
"body-parser": "^2.2.2",
|
|
145
144
|
"chalk": "^5.6.2",
|
|
146
145
|
"cross-env": "^10.1.0",
|
|
147
146
|
"dev-null": "^0.1.1",
|
|
148
|
-
"eslint": "^10.1
|
|
147
|
+
"eslint": "^10.2.1",
|
|
149
148
|
"express": "^5.2.1",
|
|
150
149
|
"formdata-node": "^6.0.3",
|
|
151
|
-
"formidable": "^3.
|
|
150
|
+
"formidable": "^3.5.4",
|
|
152
151
|
"fs-extra": "^11.3.4",
|
|
153
152
|
"get-stream": "^9.0.1",
|
|
154
|
-
"globals": "^17.
|
|
153
|
+
"globals": "^17.5.0",
|
|
155
154
|
"gulp": "^5.0.1",
|
|
156
|
-
"handlebars": "^4.7.8",
|
|
157
155
|
"husky": "^9.1.7",
|
|
158
156
|
"lint-staged": "^16.4.0",
|
|
159
|
-
"memoizee": "^0.4.17",
|
|
160
157
|
"minimist": "^1.2.8",
|
|
161
158
|
"multer": "^2.1.1",
|
|
162
|
-
"
|
|
163
|
-
"
|
|
164
|
-
"
|
|
165
|
-
"pretty-bytes": "^7.1.0",
|
|
166
|
-
"rollup": "^4.60.0",
|
|
159
|
+
"playwright": "^1.59.1",
|
|
160
|
+
"prettier": "^3.8.3",
|
|
161
|
+
"rollup": "^4.60.2",
|
|
167
162
|
"rollup-plugin-bundle-size": "^1.0.3",
|
|
168
163
|
"selfsigned": "^5.5.0",
|
|
169
164
|
"stream-throttle": "^0.1.3",
|
|
170
|
-
"string-replace-async": "^3.0.2",
|
|
171
|
-
"tar-stream": "^3.1.8",
|
|
172
165
|
"typescript": "^5.9.3",
|
|
173
|
-
"vitest": "^4.1.
|
|
166
|
+
"vitest": "^4.1.5"
|
|
174
167
|
},
|
|
175
168
|
"commitlint": {
|
|
176
169
|
"rules": {
|
|
@@ -15,7 +15,7 @@ Drop-in replacement for Node's `http` and `https` modules that automatically fol
|
|
|
15
15
|
```javascript
|
|
16
16
|
const { http, https } = require('follow-redirects');
|
|
17
17
|
|
|
18
|
-
http.get('http://
|
|
18
|
+
http.get('http://en.wikipedia.org/', response => {
|
|
19
19
|
response.on('data', chunk => {
|
|
20
20
|
console.log(chunk);
|
|
21
21
|
});
|
|
@@ -29,8 +29,8 @@ If no redirection happened, `responseUrl` is the original request URL.
|
|
|
29
29
|
|
|
30
30
|
```javascript
|
|
31
31
|
const request = https.request({
|
|
32
|
-
host: '
|
|
33
|
-
path: '/
|
|
32
|
+
host: 'en.wikipedia.org',
|
|
33
|
+
path: '/',
|
|
34
34
|
}, response => {
|
|
35
35
|
console.log(response.responseUrl);
|
|
36
36
|
// 'http://duckduckgo.com/robots.txt'
|
|
@@ -61,7 +61,7 @@ Per-request options are set by passing an `options` object:
|
|
|
61
61
|
const url = require('url');
|
|
62
62
|
const { http, https } = require('follow-redirects');
|
|
63
63
|
|
|
64
|
-
const options = url.parse('http://
|
|
64
|
+
const options = url.parse('http://en.wikipedia.org/');
|
|
65
65
|
options.maxRedirects = 10;
|
|
66
66
|
options.beforeRedirect = (options, response, request) => {
|
|
67
67
|
// Use this to adjust the request options upon redirecting,
|
|
@@ -74,7 +74,7 @@ options.beforeRedirect = (options, response, request) => {
|
|
|
74
74
|
// request.url = the requested URL that resulted in a redirect
|
|
75
75
|
// request.headers = the headers in the request that resulted in a redirect
|
|
76
76
|
// request.method = the method of the request that resulted in a redirect
|
|
77
|
-
if (options.hostname === "example.
|
|
77
|
+
if (options.hostname === "example.org") {
|
|
78
78
|
options.auth = "user:password";
|
|
79
79
|
}
|
|
80
80
|
};
|
|
@@ -95,6 +95,8 @@ the following per-request options are supported:
|
|
|
95
95
|
|
|
96
96
|
- `trackRedirects` (default: `false`) – whether to store the redirected response details into the `redirects` array on the response object.
|
|
97
97
|
|
|
98
|
+
- `sensitiveHeaders` (default: `[]`) – names of headers to omit when making redirected requests (such as `X-API-Key`, `X-Auth-Token`…)
|
|
99
|
+
|
|
98
100
|
|
|
99
101
|
### Advanced usage
|
|
100
102
|
By default, `follow-redirects` will use the Node.js default implementations
|
|
@@ -26,6 +26,13 @@ catch (error) {
|
|
|
26
26
|
useNativeURL = error.code === "ERR_INVALID_URL";
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
// HTTP headers to drop across HTTP/HTTPS and domain boundaries
|
|
30
|
+
var sensitiveHeaders = [
|
|
31
|
+
"Authorization",
|
|
32
|
+
"Proxy-Authorization",
|
|
33
|
+
"Cookie",
|
|
34
|
+
];
|
|
35
|
+
|
|
29
36
|
// URL fields to preserve in copy operations
|
|
30
37
|
var preservedUrlFields = [
|
|
31
38
|
"auth",
|
|
@@ -107,6 +114,11 @@ function RedirectableRequest(options, responseCallback) {
|
|
|
107
114
|
}
|
|
108
115
|
};
|
|
109
116
|
|
|
117
|
+
// Create filter for sensitive HTTP headers
|
|
118
|
+
this._headerFilter = new RegExp("^(?:" +
|
|
119
|
+
sensitiveHeaders.concat(options.sensitiveHeaders).map(escapeRegex).join("|") +
|
|
120
|
+
")$", "i");
|
|
121
|
+
|
|
110
122
|
// Perform the first request
|
|
111
123
|
this._performRequest();
|
|
112
124
|
}
|
|
@@ -290,6 +302,9 @@ RedirectableRequest.prototype._sanitizeOptions = function (options) {
|
|
|
290
302
|
if (!options.headers) {
|
|
291
303
|
options.headers = {};
|
|
292
304
|
}
|
|
305
|
+
if (!isArray(options.sensitiveHeaders)) {
|
|
306
|
+
options.sensitiveHeaders = [];
|
|
307
|
+
}
|
|
293
308
|
|
|
294
309
|
// Since http.request treats host as an alias of hostname,
|
|
295
310
|
// but the url module interprets host as hostname plus port,
|
|
@@ -472,7 +487,7 @@ RedirectableRequest.prototype._processResponse = function (response) {
|
|
|
472
487
|
redirectUrl.protocol !== "https:" ||
|
|
473
488
|
redirectUrl.host !== currentHost &&
|
|
474
489
|
!isSubdomain(redirectUrl.host, currentHost)) {
|
|
475
|
-
removeMatchingHeaders(
|
|
490
|
+
removeMatchingHeaders(this._headerFilter, this._options.headers);
|
|
476
491
|
}
|
|
477
492
|
|
|
478
493
|
// Evaluate the beforeRedirect callback
|
|
@@ -665,6 +680,10 @@ function isSubdomain(subdomain, domain) {
|
|
|
665
680
|
return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain);
|
|
666
681
|
}
|
|
667
682
|
|
|
683
|
+
function isArray(value) {
|
|
684
|
+
return value instanceof Array;
|
|
685
|
+
}
|
|
686
|
+
|
|
668
687
|
function isString(value) {
|
|
669
688
|
return typeof value === "string" || value instanceof String;
|
|
670
689
|
}
|
|
@@ -681,6 +700,10 @@ function isURL(value) {
|
|
|
681
700
|
return URL && value instanceof URL;
|
|
682
701
|
}
|
|
683
702
|
|
|
703
|
+
function escapeRegex(regex) {
|
|
704
|
+
return regex.replace(/[\]\\/()*+?.$]/g, "\\$&");
|
|
705
|
+
}
|
|
706
|
+
|
|
684
707
|
// Exports
|
|
685
708
|
module.exports = wrap({ http: http, https: https });
|
|
686
709
|
module.exports.wrap = wrap;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "groove-dev",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.145",
|
|
4
4
|
"description": "Open-source agent orchestration layer — the AI company OS. Local model agent engine (GGUF/Ollama/llama-server), HuggingFace model browser, MCP integrations (Slack, Gmail, Stripe, 15+), agent scheduling (cron), business roles (CMO, CFO, EA). GUI dashboard, multi-agent coordination, zero cold-start, infinite sessions. Works with Claude Code, Codex, Gemini CLI, Ollama, any local model.",
|
|
5
5
|
"license": "FSL-1.1-Apache-2.0",
|
|
6
6
|
"author": "Groove Dev <hello@groovedev.ai> (https://groovedev.ai)",
|