import NavBar from "./partials/NavBar.vue";\r
import { getConfig } from "./api.js";\r
import { useGlobalStore } from "./globalStore.js";\r
+import { loadStoredToken } from "./tokenStorage.js";\r
\r
const globalStore = useGlobalStore();\r
const route = useRoute();\r
console.error(error);\r
}\r
});\r
+ loadStoredToken();\r
});\r
\r
const showNavBar = computed(() => {\r
import * as constants from "./constants.js";
import axios from "axios";
-import { getToken } from "./tokenStorage.js";
+import { getStoredToken } from "./tokenStorage.js";
import router from "./router.js";
const api = axios.create();
// If the request is not for the token endpoint, add the token to the headers.
function (config) {
if (config.url !== "/api/token") {
- const token = getToken();
+ const token = getStoredToken();
config.headers.Authorization = `Bearer ${token}`;
}
return config;
export function getConfig() {
return api.get("/api/config");
}
+
+export function getToken(username, password, totp) {
+ return api.post("/api/token", {
+ username: username,
+ password: totp ? password + totp : password,
+ });
+}
+
+export function getNotes(term, sort, order, limit) {
+ return api.get("/api/search", {
+ params: {
+ term: term,
+ sort: sort,
+ order: order,
+ limit: limit,
+ },
+ });
+}
type="text"
class="w-full rounded rounded-r-none border border-theme-border bg-theme-background-elevated px-3 py-2 focus:outline-none focus:ring-1"
placeholder="Search"
+ v-model="model"
/>
</template>
+
+<script setup>
+const model = defineModel()
+</script>
return `${tokenStorageKey}=${token}; path=/attachments; SameSite=Strict`;
}
-export function setToken(token, persist = false) {
+export function storeToken(token, persist = false) {
document.cookie = getCookieString(token);
sessionStorage.setItem(tokenStorageKey, token);
if (persist === true) {
}
}
-export function getToken() {
+export function getStoredToken() {
return sessionStorage.getItem(tokenStorageKey);
}
-export function loadToken() {
+export function loadStoredToken() {
const token = localStorage.getItem(tokenStorageKey);
if (token != null) {
- setToken(token, false);
+ storeToken(token, false);
}
}
-export function clearToken() {
+export function clearStoredToken() {
sessionStorage.removeItem(tokenStorageKey);
localStorage.removeItem(tokenStorageKey);
document.cookie =
<div class="h-full">
<div class="flex h-full flex-col items-center justify-center">
<Logo class="mb-5" />
- <SearchInput class="shadow-[0_0_20px] shadow-theme-shadow" />
+ <SearchInput class="mb-5 shadow-[0_0_20px] shadow-theme-shadow" />
+ <div class="flex flex-col items-center min-h-56">
+ <p
+ v-if="notes.length > 0"
+ class="mb-2 text-xs font-bold text-theme-text-very-muted"
+ >
+ RECENTLY MODIFIED
+ </p>
+ <CustomButton v-for="note in notes" :label="note.title" />
+ </div>
</div>
</div>
</template>
<script setup>
+import { ref } from "vue";
+
+import { getNotes } from "../api.js";
+import CustomButton from "../components/CustomButton.vue";
import Logo from "../components/Logo.vue";
import SearchInput from "../partials/SearchInput.vue";
+
+const notes = ref([]);
+
+getNotes("*", "lastModified", "desc", 5).then((response) => {
+ notes.value = response.data;
+});
</script>
<template>
<div class="flex h-full flex-col items-center justify-center">
<Logo class="mb-5" />
- <form @submit.prevent="login" class="flex max-w-80 flex-col items-center">
- <TextInput placeholder="Username" class="mb-1" required />
- <TextInput placeholder="Password" type="password" class="mb-1" required />
+ <form @submit.prevent="logIn" class="flex max-w-80 flex-col items-center">
+ <TextInput
+ v-model="username"
+ placeholder="Username"
+ class="mb-1"
+ required
+ />
+ <TextInput
+ v-model="password"
+ placeholder="Password"
+ type="password"
+ class="mb-1"
+ required
+ />
<TextInput
v-if="globalStore.authType == authTypes.totp"
+ v-model="totp"
placeholder="2FA Code"
class="mb-1"
required
<script setup>
import { mdilLogin } from "@mdi/light-js";
import { ref } from "vue";
-import { useRouter } from "vue-router";
+import { useRouter, useRoute } from "vue-router";
+import { getToken } from "../api.js";
import CustomButton from "../components/CustomButton.vue";
import Logo from "../components/Logo.vue";
import TextInput from "../components/TextInput.vue";
import { authTypes } from "../constants.js";
import { useGlobalStore } from "../globalStore.js";
+import { storeToken } from "../tokenStorage.js";
+import * as constants from "../constants.js";
const router = useRouter();
+const route = useRoute();
const globalStore = useGlobalStore();
+
+const username = ref("");
+const password = ref("");
+const totp = ref("");
const rememberMe = ref(false);
-function login() {
- router.push({ name: "home" });
- // TODO: Implement login functionality
+function logIn() {
+ getToken(username.value, password.value, totp.value)
+ .then((response) => {
+ storeToken(response.data.access_token, rememberMe.value);
+ const redirectPath = route.query[constants.params.redirect];
+ if (redirectPath) {
+ router.push(redirectPath);
+ } else {
+ router.push({ name: "home" });
+ }
+ })
+ .catch((error) => {
+ console.error(error);
+ // TODO: Trigger error toast
+ });
}
</script>