mirror of
https://github.com/tailscale/tailscale.git
synced 2024-12-02 06:25:37 +00:00
9a3bc9049c
We already had a path on the web client server struct, but hadn't plumbed it through to the CLI. Add that now and use it for Synology and QNAP instead of hard-coding the path. (Adding flag for QNAP is tailscale/tailscale-qpkg#112) This will allow supporting other environments (like unraid) without additional changes to the client/web package. Also fix a small bug in unraid handling to only include the csrf token on POST requests. Updates tailscale/corp#13775 Signed-off-by: Will Norris <will@tailscale.com>
68 lines
1.8 KiB
TypeScript
68 lines
1.8 KiB
TypeScript
let csrfToken: string
|
|
let unraidCsrfToken: string | undefined // required for unraid POST requests (#8062)
|
|
|
|
// apiFetch wraps the standard JS fetch function with csrf header
|
|
// management and param additions specific to the web client.
|
|
//
|
|
// apiFetch adds the `api` prefix to the request URL,
|
|
// so endpoint should be provided without the `api` prefix
|
|
// (i.e. provide `/data` rather than `api/data`).
|
|
export function apiFetch(
|
|
endpoint: string,
|
|
method: "GET" | "POST",
|
|
body?: any,
|
|
params?: Record<string, string>
|
|
): Promise<Response> {
|
|
const urlParams = new URLSearchParams(window.location.search)
|
|
const nextParams = new URLSearchParams(params)
|
|
const token = urlParams.get("SynoToken")
|
|
if (token) {
|
|
nextParams.set("SynoToken", token)
|
|
}
|
|
const search = nextParams.toString()
|
|
const url = `api${endpoint}${search ? `?${search}` : ""}`
|
|
|
|
var contentType: string
|
|
if (unraidCsrfToken && method === "POST") {
|
|
const params = new URLSearchParams()
|
|
params.append("csrf_token", unraidCsrfToken)
|
|
if (body) {
|
|
params.append("ts_data", JSON.stringify(body))
|
|
}
|
|
body = params.toString()
|
|
contentType = "application/x-www-form-urlencoded;charset=UTF-8"
|
|
} else {
|
|
body = body ? JSON.stringify(body) : undefined
|
|
contentType = "application/json"
|
|
}
|
|
|
|
return fetch(url, {
|
|
method: method,
|
|
headers: {
|
|
Accept: "application/json",
|
|
"Content-Type": contentType,
|
|
"X-CSRF-Token": csrfToken,
|
|
},
|
|
body,
|
|
}).then((r) => {
|
|
updateCsrfToken(r)
|
|
if (!r.ok) {
|
|
return r.text().then((err) => {
|
|
throw new Error(err)
|
|
})
|
|
}
|
|
return r
|
|
})
|
|
}
|
|
|
|
function updateCsrfToken(r: Response) {
|
|
const tok = r.headers.get("X-CSRF-Token")
|
|
if (tok) {
|
|
csrfToken = tok
|
|
}
|
|
}
|
|
|
|
export function setUnraidCsrfToken(token?: string) {
|
|
unraidCsrfToken = token
|
|
}
|