client/web: pull SynoToken logic into apiFetch

Updates tailscale/corp#13775
This commit is contained in:
Sonia Appasamy 2023-08-29 13:20:25 -04:00 committed by Sonia Appasamy
parent 6b882a1511
commit 7aea219a0f
2 changed files with 36 additions and 35 deletions

View File

@ -1,12 +1,26 @@
let csrfToken: string let csrfToken: string
// apiFetch wraps the standard JS fetch function // apiFetch wraps the standard JS fetch function with csrf header
// with csrf header management. // 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( export function apiFetch(
input: RequestInfo | URL, endpoint: string,
init?: RequestInit | undefined init?: RequestInit | undefined,
addURLParams?: Record<string, string>
): Promise<Response> { ): Promise<Response> {
return fetch(input, { const urlParams = new URLSearchParams(window.location.search)
const nextParams = new URLSearchParams(addURLParams)
const token = urlParams.get("SynoToken")
if (token) {
nextParams.set("SynoToken", token)
}
const search = nextParams.toString()
const url = `api${endpoint}${search ? `?${search}` : ""}`
return fetch(url, {
...init, ...init,
headers: withCsrfToken(init?.headers), headers: withCsrfToken(init?.headers),
}).then((r) => { }).then((r) => {

View File

@ -35,21 +35,14 @@ export default function useNodeData() {
const [data, setData] = useState<NodeData>() const [data, setData] = useState<NodeData>()
const [isPosting, setIsPosting] = useState<boolean>(false) const [isPosting, setIsPosting] = useState<boolean>(false)
const fetchNodeData = useCallback(() => { const fetchNodeData = useCallback(
const urlParams = new URLSearchParams(window.location.search) () =>
const nextParams = new URLSearchParams() apiFetch("/data")
const token = urlParams.get("SynoToken")
if (token) {
nextParams.set("SynoToken", token)
}
const search = nextParams.toString()
const url = `api/data${search ? `?${search}` : ""}`
apiFetch(url)
.then((r) => r.json()) .then((r) => r.json())
.then((d) => setData(d)) .then((d) => setData(d))
.catch((error) => console.error(error)) .catch((error) => console.error(error)),
}, [setData]) [setData]
)
const updateNode = useCallback( const updateNode = useCallback(
(update: NodeUpdate) => { (update: NodeUpdate) => {
@ -77,17 +70,7 @@ export default function useNodeData() {
: data.AdvertiseExitNode, : data.AdvertiseExitNode,
} }
const urlParams = new URLSearchParams(window.location.search)
const nextParams = new URLSearchParams({ up: "true" })
const token = urlParams.get("SynoToken")
if (token) {
nextParams.set("SynoToken", token)
}
const search = nextParams.toString()
const url = `api/data${search ? `?${search}` : ""}`
var body, contentType: string var body, contentType: string
if (data.IsUnraid) { if (data.IsUnraid) {
const params = new URLSearchParams() const params = new URLSearchParams()
params.append("csrf_token", data.UnraidToken) params.append("csrf_token", data.UnraidToken)
@ -99,11 +82,15 @@ export default function useNodeData() {
contentType = "application/json" contentType = "application/json"
} }
apiFetch(url, { apiFetch(
"/data",
{
method: "POST", method: "POST",
headers: { Accept: "application/json", "Content-Type": contentType }, headers: { Accept: "application/json", "Content-Type": contentType },
body: body, body: body,
}) },
{ up: "true" }
)
.then((r) => r.json()) .then((r) => r.json())
.then((r) => { .then((r) => {
setIsPosting(false) setIsPosting(false)