This repository has been archived on 2022-05-05. You can view files and clone it, but cannot push or open issues or pull requests.
userausfall/src/api.ts

101 lines
2.7 KiB
TypeScript
Raw Normal View History

import Cookies from "js-cookie";
import Vue from "vue";
2021-04-15 16:04:22 +02:00
type HTTPMethod = "GET" | "POST" | "PUT" | "PATCH";
2021-05-18 11:06:02 +02:00
export class APIError extends Error {
constructor(message: string, public readonly errors: unknown) {
super(message);
}
}
2021-08-02 10:14:38 +02:00
async function api_request(
2021-04-15 16:04:22 +02:00
method: HTTPMethod,
endpoint: string,
successStatus: number,
data?: any,
2021-04-15 16:04:22 +02:00
authToken?: string
) {
const init = {
headers: new Headers(),
method: method,
body: JSON.stringify(data),
};
const csrfToken = Cookies.get("csrftoken");
if (csrfToken != undefined) {
init.headers.set("X-CSRFToken", csrfToken);
}
2021-04-15 16:04:22 +02:00
if (authToken != undefined) {
2021-04-16 11:31:11 +02:00
init.headers.set("Authorization", `Token ${authToken}`);
}
2021-04-15 16:04:22 +02:00
init.headers.set("Accept", "application/json");
init.headers.set("Content-Type", "application/json");
2021-08-02 10:14:38 +02:00
const response = await fetch(`/api/${endpoint}/`, init);
if (response.status !== 204) {
if (response.status === successStatus) {
return await response.json();
} else {
throw new APIError(response.statusText, await response.json());
}
2021-04-15 14:24:55 +02:00
}
}
2021-04-15 16:04:22 +02:00
export class User {
pk: number | undefined;
2021-04-16 10:36:52 +02:00
password: string | undefined;
2021-05-18 11:06:02 +02:00
username: string | null = null;
2021-04-16 10:36:52 +02:00
isAuthenticated = false;
isTrusted = false;
2021-04-15 10:05:54 +02:00
/**
* Activate the corresponding LDAP account.
*/
async activate(): Promise<void> {
2021-08-03 12:38:34 +02:00
await api_request("POST", `users/${this.pk}/activate`, 204, {
password: this.password,
});
2021-04-15 09:31:03 +02:00
}
2021-04-14 11:21:39 +02:00
async login(): Promise<void> {
2021-08-02 10:14:38 +02:00
if (!this.username || !this.password) throw new APIError("", "");
2021-05-18 12:07:03 +02:00
// logout any existing sessions
//await logout()
// fetch the login endpoint we use for authentication
const loginEndpoint = "/api-auth/login/";
// fetch the login page, so it sets csrf cookies
await window.fetch(loginEndpoint);
// authenticate us
const body = new window.FormData();
2021-08-02 10:14:38 +02:00
body.append("username", this.username);
2021-05-18 12:07:03 +02:00
body.append("password", this.password);
const csrf_token = Cookies.get("csrftoken");
if (csrf_token) body.append("csrfmiddlewaretoken", csrf_token);
const res = await window.fetch(loginEndpoint, { method: "post", body });
// successful logins are followed by a redirect
if (res.redirected && res.status === 200) {
this.isAuthenticated = true;
await this.retrieve();
2021-05-18 12:07:03 +02:00
} else {
throw new APIError("", "");
}
2021-04-14 11:21:39 +02:00
}
async retrieve(): Promise<void> {
const data = await api_request("GET", "users/me", 200);
this.pk = data.pk;
this.isTrusted = data.trust_bridge.is_trusted;
2021-04-15 14:24:55 +02:00
}
async signup(): Promise<void> {
2021-05-18 12:07:03 +02:00
await api_request("POST", "users", 201, {
2021-08-02 10:14:38 +02:00
username: this.username,
2021-04-15 16:04:22 +02:00
password: this.password,
});
}
}
export const user = Vue.observable(new User());