fleet/frontend/services/index.ts
Gabriel Hernandez 084ebe6e16 update auth token storage (#40504)
**Related issue:** Resolves #14401

this updates the mechanism of storing the auth token for a user that is
used for making requests and validating a user session. We change the
storage from local storage to a cookie. This allow a bit more security
and prepares for a future change where we will allow the browser to
handle setting and passing the auth token in the request.

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
- [x] QA'd all new/changed functionality manually
2026-02-27 12:36:42 -06:00

229 lines
5.2 KiB
TypeScript

import axios, {
isAxiosError,
ResponseType as AxiosResponseType,
AxiosProgressEvent,
} from "axios";
import URL_PREFIX from "router/url_prefix";
import authToken from "utilities/auth_token";
export const sendRequestWithProgress = async ({
method,
path,
data,
responseType = "json",
timeout,
skipParseError,
returnRaw,
onDownloadProgress,
onUploadProgress,
signal,
}: {
method: "GET" | "POST" | "PATCH" | "DELETE" | "HEAD";
path: string;
data?: unknown;
responseType?: AxiosResponseType;
timeout?: number;
skipParseError?: boolean;
returnRaw?: boolean;
onDownloadProgress?: (progressEvent: AxiosProgressEvent) => void;
onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;
signal?: AbortSignal;
}) => {
const { origin } = global.window.location;
const url = `${origin}${URL_PREFIX}/api${path}`;
try {
const response = await axios({
method,
url,
data,
responseType,
timeout,
headers: {
Authorization: `Bearer ${authToken.get()}`,
},
onDownloadProgress,
onUploadProgress,
signal,
});
if (returnRaw) {
return response;
}
return response.data;
} catch (error) {
if (skipParseError) {
return Promise.reject(error);
}
let reason: unknown | undefined;
if (isAxiosError(error)) {
reason = error.response || error.message || error.code;
}
return Promise.reject(
reason || `send request: parse server error: ${error}`
);
}
};
export const sendRequest = async (
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD",
path: string,
data?: unknown,
responseType: AxiosResponseType = "json",
timeout?: number,
skipParseError?: boolean,
returnRaw?: boolean
) => {
const { origin } = global.window.location;
const url = `${origin}${URL_PREFIX}/api${path}`;
try {
const response = await axios({
method,
url,
data,
responseType,
timeout,
headers: {
Authorization: `Bearer ${authToken.get()}`,
},
});
if (returnRaw) {
return response;
}
return response.data;
} catch (error) {
if (skipParseError) {
return Promise.reject(error);
}
let reason: unknown | undefined;
if (isAxiosError(error)) {
reason = error.response || error.message || error.code;
}
return Promise.reject(
reason || `send request: parse server error: ${error}`
);
}
};
/**
* Send a request with custom headers. Used for requests that need to signal
* special handling (e.g., base64-encoded scripts to bypass WAF rules).
*/
export const sendRequestWithHeaders = async (
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD",
path: string,
data?: unknown,
customHeaders?: Record<string, string>,
responseType: AxiosResponseType = "json",
timeout?: number,
skipParseError?: boolean,
returnRaw?: boolean
) => {
const { origin } = global.window.location;
const url = `${origin}${URL_PREFIX}/api${path}`;
try {
const response = await axios({
method,
url,
data,
responseType,
timeout,
headers: {
Authorization: `Bearer ${authToken.get()}`,
...customHeaders,
},
});
if (returnRaw) {
return response;
}
return response.data;
} catch (error) {
if (skipParseError) {
return Promise.reject(error);
}
let reason: unknown | undefined;
if (isAxiosError(error)) {
reason = error.response || error.message || error.code;
}
return Promise.reject(
reason || `send request: parse server error: ${error}`
);
}
};
/**
* Send a request with progress tracking and custom headers. Used for file uploads
* that need to signal special handling (e.g., base64-encoded scripts to bypass WAF rules).
*/
export const sendRequestWithProgressAndHeaders = async ({
method,
path,
data,
customHeaders,
responseType = "json",
timeout,
skipParseError,
returnRaw,
onDownloadProgress,
onUploadProgress,
signal,
}: {
method: "GET" | "POST" | "PATCH" | "DELETE" | "HEAD";
path: string;
data?: unknown;
customHeaders?: Record<string, string>;
responseType?: AxiosResponseType;
timeout?: number;
skipParseError?: boolean;
returnRaw?: boolean;
onDownloadProgress?: (progressEvent: AxiosProgressEvent) => void;
onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;
signal?: AbortSignal;
}) => {
const { origin } = global.window.location;
const url = `${origin}${URL_PREFIX}/api${path}`;
try {
const response = await axios({
method,
url,
data,
responseType,
timeout,
headers: {
Authorization: `Bearer ${authToken.get()}`,
...customHeaders,
},
onDownloadProgress,
onUploadProgress,
signal,
});
if (returnRaw) {
return response;
}
return response.data;
} catch (error) {
if (skipParseError) {
return Promise.reject(error);
}
let reason: unknown | undefined;
if (isAxiosError(error)) {
reason = error.response || error.message || error.code;
}
return Promise.reject(
reason || `send request: parse server error: ${error}`
);
}
};
export default sendRequest;