소스 검색

[ui-core] upgrade axios from 0.28.0 to 1.8.2 to fix CVE-2025-27152 (#4283)

Bjorn Alm - personal 1 개월 전
부모
커밋
3fd79018a1

+ 24 - 11
desktop/core/src/desktop/js/api/utils.ts

@@ -20,7 +20,7 @@ import axios, {
   AxiosRequestConfig,
   AxiosResponse,
   AxiosResponseTransformer,
-  CancelToken
+  InternalAxiosRequestConfig
 } from 'axios';
 import qs from 'qs';
 
@@ -48,6 +48,13 @@ export enum HttpMethod {
   PATCH = 'patch'
 }
 
+/**
+ * Options for API fetch functions.
+ *
+ * Note: This extends AxiosRequestConfig (not InternalAxiosRequestConfig) because it's the
+ * public API for users to pass options to axios requests. InternalAxiosRequestConfig is
+ * only used for the internal config object inside interceptors.
+ */
 export interface ApiFetchOptions<T, E = AxiosError<DefaultApiResponse>> extends AxiosRequestConfig {
   silenceErrors?: boolean;
   ignoreSuccessErrors?: boolean;
@@ -71,7 +78,7 @@ const axiosInstance = axios.create({ withCredentials: true });
 let baseUrl = (window as hueWindow).HUE_BASE_URL;
 let bearerToken: string | undefined;
 
-axiosInstance.interceptors.request.use(config => {
+axiosInstance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
   if (baseUrl) {
     config.baseURL = baseUrl;
   }
@@ -194,9 +201,15 @@ const handleResponse = <T, E = unknown>(
   }
 };
 
-const getCancelToken = (): { cancelToken: CancelToken; cancel: () => void } => {
-  const cancelTokenSource = axios.CancelToken.source();
-  return { cancelToken: cancelTokenSource.token, cancel: cancelTokenSource.cancel };
+/**
+ * Creates an AbortController for cancelling axios requests.
+ * This replaces the deprecated CancelToken API with the standard AbortController API.
+ *
+ * @returns An object containing the AbortSignal and abort function
+ */
+const getAbortController = (): { signal: AbortSignal; abort: () => void } => {
+  const controller = new AbortController();
+  return { signal: controller.signal, abort: () => controller.abort() };
 };
 
 // Shared HTTP method for post, put, patch requests
@@ -207,13 +220,13 @@ export const sendApiRequest = <T, U = unknown, E = AxiosError>(
   options?: ApiFetchOptions<T, E>
 ): CancellablePromise<T> =>
   new CancellablePromise((resolve, reject, onCancel) => {
-    const { cancelToken, cancel } = getCancelToken();
+    const { signal, abort } = getAbortController();
     let completed = false;
 
     const encodeData = options?.qsEncodeData == undefined || options?.qsEncodeData;
 
     axiosInstance[method]<T & DefaultApiResponse>(url, encodeData ? qs.stringify(data) : data, {
-      cancelToken,
+      signal,
       ...options
     })
       .then(response => {
@@ -235,7 +248,7 @@ export const sendApiRequest = <T, U = unknown, E = AxiosError>(
 
     onCancel(() => {
       if (!completed) {
-        cancel();
+        abort();
       }
     });
   });
@@ -264,12 +277,12 @@ export const get = <T, U = unknown, E = AxiosError<DefaultApiResponse>>(
   options?: ApiFetchOptions<T, E>
 ): CancellablePromise<T> =>
   new CancellablePromise((resolve, reject, onCancel) => {
-    const { cancelToken, cancel } = getCancelToken();
+    const { signal, abort } = getAbortController();
     let completed = false;
 
     axiosInstance
       .get<T & DefaultApiResponse>(url, {
-        cancelToken,
+        signal,
         params: data
       })
       .then(response => {
@@ -284,7 +297,7 @@ export const get = <T, U = unknown, E = AxiosError<DefaultApiResponse>>(
 
     onCancel(() => {
       if (!completed) {
-        cancel();
+        abort();
       }
     });
   });

+ 5 - 0
desktop/core/src/desktop/js/jest/jest.init.js

@@ -111,6 +111,11 @@ $.ajaxSetup({
   }
 });
 
+/**
+ * Interceptor for axios requests in tests
+ * @param {import('axios').InternalAxiosRequestConfig} config
+ * @returns {import('axios').InternalAxiosRequestConfig}
+ */
 const axiosConfigInterceptor = config => {
   console.warn('Actual axios ajax request made to url: ' + config.url);
   console.trace();

+ 1 - 1
docs/designs/hue5.md

@@ -98,7 +98,7 @@ A live demo with the SQL Scratchpad is coming. In the meantime:
         // Util to check if cached token is still valid before asking to auth for a new one
         axios.post('v1/iam/verify/auth-token/', {token: data['data']['token']});
 
-        axios.defaults.headers.common['Authorization'] = 'JWT ' + data['data']['token'];
+        axios.defaults.headers['Authorization'] = 'JWT ' + data['data']['token'];
       }).then(function() {
         axios.post('/v1/editor/query/sqlite', {snippet: "{\"statement\":\"SELECT 1000, 1001\""}).then(function(data) {
           console.log(data['data']);

+ 1 - 1
docs/docs-site/content/developer/api/rest/_index.md

@@ -96,7 +96,7 @@ In the meantime, with Axios:
         // Util to check if cached token is still valid before asking to auth for a new one
         axios.post('api/v1/token/verify/', {token: data['access']});
 
-        axios.defaults.headers.common['Authorization'] = 'Bearer ' + data['access'];
+        axios.defaults.headers['Authorization'] = 'Bearer ' + data['access'];
       }).then(function() {
         axios.post('api/v1/query/sqlite', {statement:"SELECT 1000, 1001"}).then(function(data) {
           console.log(data['data']);

+ 6 - 5
package-lock.json

@@ -14,7 +14,7 @@
         "@gethue/sql-formatter": "4.0.3",
         "@selectize/selectize": "0.14.0",
         "antd": "4.24.5",
-        "axios": "0.28.0",
+        "axios": "1.8.2",
         "classnames": "2.3.2",
         "clipboard": "1.7.1",
         "copy-to-clipboard": "3.3.3",
@@ -5596,11 +5596,12 @@
       }
     },
     "node_modules/axios": {
-      "version": "0.28.0",
-      "resolved": "https://registry.npmjs.org/axios/-/axios-0.28.0.tgz",
-      "integrity": "sha512-Tu7NYoGY4Yoc7I+Npf9HhUMtEEpV7ZiLH9yndTCoNhcpBH0kwcvFbzYN9/u5QKI5A6uefjsNNWaz5olJVYS62Q==",
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.2.tgz",
+      "integrity": "sha512-ls4GYBm5aig9vWx8AWDSGLpnpDQRtWAfrjU+EuytuODrFBkqesN2RkOQCBzrA1RQNHw1SmRMSDDDSwzNAYQ6Rg==",
+      "license": "MIT",
       "dependencies": {
-        "follow-redirects": "^1.15.0",
+        "follow-redirects": "^1.15.6",
         "form-data": "^4.0.0",
         "proxy-from-env": "^1.1.0"
       }

+ 1 - 1
package.json

@@ -35,7 +35,7 @@
     "@gethue/sql-formatter": "4.0.3",
     "@selectize/selectize": "0.14.0",
     "antd": "4.24.5",
-    "axios": "0.28.0",
+    "axios": "1.8.2",
     "classnames": "2.3.2",
     "clipboard": "1.7.1",
     "copy-to-clipboard": "3.3.3",