Handle auth type of none in the frontend
authorAdam Dullage <redacted>
Wed, 12 Oct 2022 12:13:05 +0000 (13:13 +0100)
committerAdam Dullage <redacted>
Wed, 12 Oct 2022 12:13:05 +0000 (13:13 +0100)
flatnotes/auth_type.py
flatnotes/main.py
flatnotes/models.py
flatnotes/src/components/App.js
flatnotes/src/components/App.vue
flatnotes/src/components/Login.vue
flatnotes/src/components/NavBar.vue
flatnotes/src/constants.js

index c3ad9583a3d1cc7ee178068ec483fd8e47462f51..5644d89e88510f67e1cffbd06423adc7c6110ce1 100644 (file)
@@ -1,7 +1,7 @@
 from enum import Enum
 
 
-class AuthType(Enum):
+class AuthType(str, Enum):
     NONE = "none"
     PASSWORD = "password"
     # TOTP = "totp"  # Not yet implemented
index 63dbe1fe4a0ace9acdb754cccc7de7352b041b0f..ddeb1f49708e5d0f8ec52288e6f53eb67aa68c2a 100644 (file)
@@ -13,7 +13,13 @@ from error_responses import (
     title_exists_response,
 )
 from flatnotes import Flatnotes, InvalidTitleError, Note
-from models import LoginModel, NoteModel, NotePatchModel, SearchResultModel
+from models import (
+    ConfigModel,
+    LoginModel,
+    NoteModel,
+    NotePatchModel,
+    SearchResultModel,
+)
 
 app = FastAPI()
 flatnotes = Flatnotes(config.data_path)
@@ -128,4 +134,10 @@ async def search(
     ]
 
 
+@app.get("/api/config", response_model=ConfigModel)
+async def get_config():
+    """Retrieve server-side config required for the UI."""
+    return ConfigModel.dump(config)
+
+
 app.mount("/", StaticFiles(directory="flatnotes/dist"), name="dist")
index 348a7f14307fe08848c800485edddc274ab9e67b..fac37526398387ad825993177b46037a285ef9d5 100644 (file)
@@ -1,8 +1,9 @@
 from typing import Dict, List, Optional
 
-from helpers import CamelCaseBaseModel
-
+from config import Config
 from flatnotes import Note, SearchResult
+from helpers import CamelCaseBaseModel
+from auth_type import AuthType
 
 
 class LoginModel(CamelCaseBaseModel):
@@ -47,3 +48,13 @@ class SearchResultModel(CamelCaseBaseModel):
             "contentHighlights": search_result.content_highlights,
             "tagMatches": search_result.tag_matches,
         }
+
+
+class ConfigModel(CamelCaseBaseModel):
+    auth_type: AuthType
+
+    @classmethod
+    def dump(self, config: Config) -> Dict:
+        return {
+            "authType": config.auth_type.value,
+        }
index 0553ed9eaf43c005e17d2022cd4ef450293d4ab2..fb7087fafd995b3e265470ba302598dd5ab84278 100644 (file)
@@ -8,9 +8,10 @@ import Logo from "./Logo";
 import Mousetrap from "mousetrap";
 import NavBar from "./NavBar";
 import NoteViewerEditor from "./NoteViewerEditor";
-import RecentlyModified from "./RecentlyModified"
+import RecentlyModified from "./RecentlyModified";
 import SearchInput from "./SearchInput";
 import SearchResults from "./SearchResults";
+import api from "../api";
 
 export default {
   name: "App",
@@ -28,6 +29,8 @@ export default {
 
   data: function() {
     return {
+      authType: null,
+
       views: {
         login: 0,
         home: 1,
@@ -42,6 +45,13 @@ export default {
   },
 
   methods: {
+    loadConfig: function() {
+      let parent = this;
+      api.get("/api/config").then(function(response) {
+        parent.authType = constants.authTypes[response.data.authType];
+      });
+    },
+
     route: function() {
       let path = window.location.pathname.split("/");
       let basePath = `/${path[1]}`;
@@ -155,6 +165,8 @@ export default {
       return false;
     });
 
+    this.loadConfig();
+
     let token = localStorage.getItem("token");
     if (token != null) {
       sessionStorage.setItem("token", token);
index 25654a09c53baa014d903acf221bc9f0246d8a2c..f8216095231e5aef8b9a46328ed3fcebdf4fe6bb 100644 (file)
       v-if="currentView != views.login"
       class="w-100 mb-5"
       :show-logo="currentView != views.home"
+      :show-log-out="authType != null && authType != constants.authTypes.none"
       @logout="logout()"
       @search="openSearch()"
     ></NavBar>
 
     <!-- Login -->
-    <Login v-if="currentView == views.login" class="flex-grow-1"></Login>
+    <Login
+      v-if="currentView == views.login"
+      class="flex-grow-1"
+      :auth-type="authType"
+    ></Login>
 
     <!-- Home -->
     <div
index b7f4f1f15923658f11aaa3683120336f76cb37eb..11a3f6872219c4b99b36a3ae36e5dca0570a9e75 100644 (file)
@@ -66,6 +66,10 @@ export default {
     Logo,
   },
 
+  props: {
+    authType: { type: Number, default: null },
+  },
+
   data: function () {
     return {
       usernameInput: null,
@@ -74,7 +78,20 @@ export default {
     };
   },
 
+  watch: {
+    authType: function () {
+      this.skipIfNoneAuthType();
+    },
+  },
+
   methods: {
+    skipIfNoneAuthType: function () {
+      // Skip past the login page if authentication is disabled
+      if (this.authType == constants.authTypes.none) {
+        EventBus.$emit("navigate", constants.basePaths.home);
+      }
+    },
+
     login: function () {
       let parent = this;
       api
@@ -113,5 +130,9 @@ export default {
         });
     },
   },
+
+  created: function () {
+    this.skipIfNoneAuthType();
+  },
 };
 </script>
index 1d3186f8015b565773fefef5da48a73955378b93..6a939cc395686869b5e7387a800325829e8b017b 100644 (file)
@@ -5,14 +5,21 @@
       :href="constants.basePaths.home"
       @click.prevent="navigate(constants.basePaths.home, $event)"
     >
-      <Logo
-        :class="{ invisible: !showLogo }"
-        responsive
-      ></Logo>
+      <Logo :class="{ invisible: !showLogo }" responsive></Logo>
     </a>
 
     <!-- Buttons -->
     <div class="d-flex">
+      <!-- Log Out -->
+      <button
+        v-if="showLogOut"
+        type="button"
+        class="bttn"
+        @click="$emit('logout')"
+      >
+        <b-icon icon="box-arrow-right"></b-icon> Log Out
+      </button>
+
       <!-- New Note -->
       <a
         :href="constants.basePaths.new"
         <b-icon icon="plus-circle"></b-icon> New
       </a>
 
-      <!-- Log Out -->
-      <button type="button" class="bttn" @click="$emit('logout')">
-        <b-icon icon="box-arrow-right"></b-icon> Log Out
-      </button>
-
       <!-- A-Z -->
       <a :href="azHref" class="bttn" @click.prevent="navigate(azHref, $event)"
         >A-Z</a
@@ -70,6 +72,7 @@ export default {
       type: Boolean,
       default: true,
     },
+    showLogOut: { type: Boolean, default: false },
   },
 
   computed: {
index 55476e48418c54a2d07932ceb1c4018010534709..5934fd45f3cf9cec99fe48a7233cc6c7a9348cd5 100644 (file)
@@ -46,3 +46,5 @@ export const alphabet = [
 ];
 
 export const searchSortOptions = { score: 0, title: 1, lastModified: 2 };
+
+export const authTypes = { none: 0, password: 1 };
git clone https://git.99rst.org/PROJECT