import fetch, { RequestInit } from "node-fetch";
import { ApiError } from "./util";
import { StatusCodes } from "http-status-codes";
import { DISPLAY_ERRORS } from "./env";
export const url = (u: string) => {
return __RAVEN__.config.wildduck_api_url.replace(/\/$/, "") + u;
}
const Requester =
(method: string) => {
return async (u: string, accessToken: string, body?: Body) => {
const init: RequestInit = { method }
if(body != null) {
init.headers = {
"x-access-token": accessToken,
"content-type": "application/json",
}
init.body = JSON.stringify(body);
} else {
init.headers = { "x-access-token": accessToken }
}
const res = await fetch(url(u), init).catch(e => {
throw new ApiError(StatusCodes.BAD_GATEWAY, DISPLAY_ERRORS ? String(e?.message) : "Bad Gateway");
})
if(res.status === StatusCodes.FORBIDDEN) {
throw new ApiError(StatusCodes.FORBIDDEN, "The session has expired");
}
const json = await res.json().catch(e => {
throw new ApiError(StatusCodes.BAD_GATEWAY, "Invalid JSON from backend");
})
if(json?.error) {
throw new ApiError(res.ok ? StatusCodes.INTERNAL_SERVER_ERROR : res.status, String(json.error))
}
return json;
}
}
export const get = Requester("GET");
export const del = Requester("DELETE");
export const post = Requester("POST");
export const put = Requester("PUT");
export type Authentication = {
success: boolean
id: string
username: string
scope: string
require2fa: string[]
requirePasswordChange: boolean
token: string
}
export const authenticate = async (username: string, password: string): Promise => {
const res = await fetch(url("/authenticate"), {
method: "POST",
headers: {
"content-type": "application/json",
"x-access-token": __RAVEN__.config.wildduck_api_token,
},
body: JSON.stringify({
token: true,
scope: "master",
username,
password,
})
}).catch(e => {
throw new ApiError(StatusCodes.BAD_GATEWAY, DISPLAY_ERRORS ? String(e?.message) : "Bad Gateway");
})
const json: any = await res.json().catch(e => {
throw new ApiError(StatusCodes.BAD_GATEWAY, "Invalid JSON body from backend")
});
if(json?.error) {
throw new ApiError(res.ok ? StatusCodes.INTERNAL_SERVER_ERROR : res.status, String(json.error));
}
return json;
}
export const watch = async (userId: string, accessToken: string): Promise => {
const res = await fetch(url(`/users/${userId}/updates`), {
headers: { "x-access-token": accessToken },
}).catch(e => {
throw new ApiError(502, DISPLAY_ERRORS ? String(e?.message) : "Bad Gateway");
})
if(res.ok) {
return res.body;
}
if(res.status === StatusCodes.FORBIDDEN) {
throw new ApiError(StatusCodes.FORBIDDEN, "Session has expired");
}
const json = await res.json().catch(() => {
throw new ApiError(502, "Invalid JSON body from backend");
})
throw new ApiError(res.status, String(json?.error || "JSON error without message"));
}