diff --git a/src/App.vue b/src/App.vue
index 7dd64f3..ad1f234 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,8 +1,11 @@
-
-
+
+
+
+ Loading
+
diff --git a/src/api/index.ts b/src/api/index.ts
index 45fbe74..17e082d 100644
--- a/src/api/index.ts
+++ b/src/api/index.ts
@@ -1,6 +1,13 @@
-import { LoginResponse, token } from "./types";
-import { get, set } from "idb-keyval";
-import { unref } from "vue";
+import { cSite, LoginResponse, Site, token } from "./types";
+import { get as idbGet, set as idbSet, del as idbDel } from "idb-keyval";
+
+export * from "./types";
+
+const enum HTTPMethod {
+ GET = "GET",
+ POST = "POST",
+ PATCH = "PATCH",
+}
const url = "http://192.168.178.5:8080/api";
let token: token;
@@ -9,7 +16,7 @@ let ready = false;
export async function init() {
if (ready) return;
- await get("token").then((val: token) => {
+ await idbGet("token").then((val: token) => {
if (val !== undefined) {
token = val;
}
@@ -17,36 +24,80 @@ export async function init() {
ready = true;
}
+export async function logout(): Promise {
+ token = { jwt: "", expiration: 0 };
+ await idbDel("token");
+}
+
export async function isLoggedIn(): Promise {
await init();
- return token !== undefined && token.expiration > Date.now();
+ return token?.expiration > Date.now();
}
-export async function login(user: string, password: string): Promise {
- await init();
- let response = await fetch(`${url}/auth`, {
- method: "POST",
- headers: {
- Accept: "application/json",
- "Content-Type": "application/json",
- },
- body: JSON.stringify({ username: user, password: password }),
- });
- const login: LoginResponse = await response.json();
+interface ReqOptions extends RequestInit {
+ method: HTTPMethod;
+ auth?: boolean;
+}
- if (response.ok) {
- if (login.success) {
- token = {
- jwt: login.token,
- expiration: Date.parse(login.expiration),
- };
- set("token", token).catch((error) => console.error(error));
- return true;
- } else {
- return Promise.reject(new Error(login.message));
- }
- } else {
- const error = new Error(login.message);
- return Promise.reject(error);
+async function request(
+ endpoint: string,
+ options: ReqOptions,
+ data?: any
+): Promise {
+ if (options.auth) {
+ await init();
+ options.headers = {
+ ...options.headers,
+ Authorization: `Bearer ${token.jwt}`,
+ };
}
+ if (
+ options.method === HTTPMethod.POST ||
+ options.method === HTTPMethod.PATCH
+ ) {
+ options.headers = {
+ ...options.headers,
+ "Content-Type": "application/json",
+ };
+ options.body = JSON.stringify(data);
+ }
+
+ const response = await fetch(`${url}${endpoint}`, {
+ ...options,
+ headers: { ...options.headers, Accept: "application/json" },
+ });
+ if (!response.ok) {
+ throw new Error(response.statusText);
+ }
+ return response.json();
+}
+
+export async function login(
+ username: string,
+ password: string
+): Promise {
+ const login = await request(
+ "/auth",
+ { method: HTTPMethod.POST },
+ { username, password }
+ );
+
+ if (!login.success) {
+ throw new Error(login.message);
+ }
+ token = {
+ jwt: login.token,
+ expiration: Date.parse(login.expiration),
+ };
+ idbSet("token", token).catch((error) => console.error(error));
+
+ return true;
+}
+
+export async function getSites(): Promise {
+ return request("/sites", { auth: true, method: HTTPMethod.GET });
+}
+
+export async function createSite(site: Site) {
+ return request("/sites", { auth: true, method: HTTPMethod.POST });
}
diff --git a/src/api/types.ts b/src/api/types.ts
index 9fc9390..13e4541 100644
--- a/src/api/types.ts
+++ b/src/api/types.ts
@@ -9,3 +9,13 @@ export interface LoginResponse {
success: boolean;
token: string;
}
+
+export interface Site {
+ default_prefix: string;
+ id: number;
+ name: string;
+}
+
+export interface cSite {
+ "site-id": number;
+}
diff --git a/src/components/VNav.vue b/src/components/VNav.vue
index 7480f25..b3bccd9 100644
--- a/src/components/VNav.vue
+++ b/src/components/VNav.vue
@@ -88,9 +88,9 @@
class="absolute inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0"
>
Logout{{ isLoggedIn ? "Logout" : "Login" }}
@@ -124,8 +124,9 @@
diff --git a/src/router/index.ts b/src/router/index.ts
index e15d33a..dd2cb9b 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -2,6 +2,7 @@ import { createWebHistory, createRouter } from "vue-router";
import Home from "../views/Home.vue";
const Settings = () => import("../views/Settings.vue");
const Login = () => import("../views/Login.vue");
+const Sites = () => import("../views/Sites.vue");
import { isLoggedIn } from "../api";
const routes = [
@@ -15,10 +16,16 @@ const routes = [
name: "Settings",
component: Settings,
},
+ {
+ path: "/sites",
+ name: "Sites",
+ component: Sites,
+ },
{
path: "/login",
name: "Login",
component: Login,
+ props: (route) => ({ logout: route.query.logout }),
},
];
diff --git a/src/views/Login.vue b/src/views/Login.vue
index 7ea86c5..99994d6 100644
--- a/src/views/Login.vue
+++ b/src/views/Login.vue
@@ -1,11 +1,12 @@
-
+
-
+
+