aboutsummaryrefslogtreecommitdiff
path: root/front-end/src
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2024-06-05 15:26:15 -0400
committerLibravatar vnugent <public@vaughnnugent.com>2024-06-05 15:26:15 -0400
commiteefba88ac4e2c70517aa71c79ed94c346f9de554 (patch)
tree3bfea4b8006b9b4a7e0985b34c3560597a133404 /front-end/src
parent9eed4022a79f2cba139c9f8a359bfc8c1f9c31c5 (diff)
chore: Package updates
Diffstat (limited to 'front-end/src')
-rw-r--r--front-end/src/bootstrap/components/Header.vue4
-rw-r--r--front-end/src/main.ts11
-rw-r--r--front-end/src/router/index.ts4
-rw-r--r--front-end/src/views/Login/components/UserPass.vue123
4 files changed, 71 insertions, 71 deletions
diff --git a/front-end/src/bootstrap/components/Header.vue b/front-end/src/bootstrap/components/Header.vue
index 25c857e..db004d8 100644
--- a/front-end/src/bootstrap/components/Header.vue
+++ b/front-end/src/bootstrap/components/Header.vue
@@ -1,7 +1,7 @@
<!-- eslint-disable vue/max-attributes-per-line -->
<script setup lang="ts">
-import { debounce, find } from 'lodash-es'
+import { debounce, find, isEqual, toLower } from 'lodash-es'
import { useElementSize, onClickOutside, useElementHover, get } from '@vueuse/core'
import { computed, ref, toRefs } from 'vue'
import { useEnvSize } from '@vnuge/vnlib.browser'
@@ -67,7 +67,7 @@ const gotoRoute = (route: string) => {
const allRoutes = router.getRoutes();
//Try to find the route by its path
- const goto = find(allRoutes, { path: route });
+ const goto = find(allRoutes, r => isEqual(toLower(r.path), toLower(route)));
if (goto) {
//navigate to the route manually
diff --git a/front-end/src/main.ts b/front-end/src/main.ts
index 3cc3bfa..40a9d2c 100644
--- a/front-end/src/main.ts
+++ b/front-end/src/main.ts
@@ -38,7 +38,7 @@ library.add(faSignInAlt, faGithub, faDiscord, faSpinner, faCertificate, faKey, f
);
//Add icons to library
-import router from './router'
+import router, { guardRoutes } from './router'
//Import nav components
import FooterNav1 from './components/FooterNav1.vue'
@@ -50,7 +50,6 @@ import { globalStatePlugin } from './store/globalState'
import { oauth2AppsPlugin } from './store/oauthAppsPlugin'
import { profilePlugin } from './store/userProfile'
import { mfaSettingsPlugin } from './store/mfaSettingsPlugin'
-import { pageProtectionPlugin } from './store/pageProtectionPlugin'
import { socialMfaPlugin } from './store/socialMfaPlugin'
import { cmnextAdminPlugin } from './store/cmnextAdminPlugin'
@@ -91,8 +90,6 @@ createVnApp({
app.use(router)
store.use(globalStatePlugin)
- //Add page protection plugin
- .use(pageProtectionPlugin(router))
//User-profile plugin
.use(profilePlugin('/account/profile'))
//Enable mfa with totp settings plugin (optional pki config)
@@ -117,6 +114,12 @@ createVnApp({
name: 'Account',
redirect: { path: '/account/profile' }
})
+
+ /**
+ * An array of named routes to protect from
+ * unauthenticated access.
+ */
+ guardRoutes(router, ['Account', 'account/:comp'])
//Add the footer nav components
app.component('FooterNav1', FooterNav1)
diff --git a/front-end/src/router/index.ts b/front-end/src/router/index.ts
index 2060965..4238621 100644
--- a/front-end/src/router/index.ts
+++ b/front-end/src/router/index.ts
@@ -5,9 +5,11 @@ import { includes, map, toLower } from 'lodash-es';
import { type Router } from 'vue-router';
import { createRouter, createWebHistory } from 'vue-router/auto'
+import { routes } from 'vue-router/auto-routes'
export default createRouter({
- history: createWebHistory(import.meta.env.BASE_URL)
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes
})
/**
diff --git a/front-end/src/views/Login/components/UserPass.vue b/front-end/src/views/Login/components/UserPass.vue
index bc9d8d1..16c8aab 100644
--- a/front-end/src/views/Login/components/UserPass.vue
+++ b/front-end/src/views/Login/components/UserPass.vue
@@ -1,67 +1,13 @@
-<template>
- <div class="">
- <h3>Login</h3>
- <div v-if="mfaUpgrade?.type === MfaMethod.TOTP">
- <Totp @clear="totpClear" :upgrade="mfaUpgrade" />
- </div>
-
- <form v-else id="user-pass-submit-form" method="post" action="/login" @submit.prevent="SubmitLogin">
- <fieldset class="" :disabled="waiting" >
- <div>
- <div class="float-label">
- <input
- id="username"
- v-model="v$.username.$model"
- type="email"
- class="w-full primary input"
- placeholder="Email"
- :class="{ 'data-invalid': v$.username.$invalid }"
- @input="onInput"
- >
- <label for="username">Email</label>
- </div>
- </div>
- <div class="py-3">
- <div class="mb-2 float-label">
- <input
- id="password"
- v-model="v$.password.$model"
- type="password"
- class="w-full primary input"
- placeholder="Password"
- :class="{ 'data-invalid': v$.password.$invalid }"
- @input="onInput"
- >
- <label for="password">Password</label>
- </div>
- </div>
- </fieldset>
- <button type="submit" form="user-pass-submit-form" class="btn primary" :disabled="waiting">
- <!-- Display spinner if waiting, otherwise the sign-in icon -->
- <fa-icon :class="{'animate-spin':waiting}" :icon="waiting ? 'spinner' : 'sign-in-alt'"/>
- Log-in
- </button>
- <div class="flex flex-row justify-between gap-3 pt-3 pb-2 form-links">
- <router-link to="/pwreset">
- Forgot password
- </router-link>
- <router-link to="/register">
- Register a new account
- </router-link>
- </div>
- </form>
- </div>
-</template>
<script setup lang="ts">
import { ref, shallowRef, reactive, defineAsyncComponent, Ref } from 'vue'
import { useTimeoutFn, set } from '@vueuse/core'
import { useVuelidate } from '@vuelidate/core'
-import { isEqual } from 'lodash-es'
+import { isEmpty } from 'lodash-es'
import { required, maxLength, minLength, email, helpers } from '@vuelidate/validators'
import {
- useVuelidateWrapper, useMfaLogin, totpMfaProcessor, IMfaFlowContinuiation, MfaMethod,
+ useVuelidateWrapper, useMfaLogin, totpMfaProcessor, IMfaFlowContinuiation,
apiCall, useMessage, useWait, debugLog, WebMessage,
type VuelidateInstance
} from '@vnuge/vnlib.browser'
@@ -126,12 +72,21 @@ const SubmitLogin = async () => {
//Try to get response as a flow continuation
const mfa = response as IMfaFlowContinuiation
- // Response is a totp upgrade request
- if (isEqual(mfa.type, MfaMethod.TOTP)) {
- //Store the upgrade message
+ // Response is an mfa upgrade
+ if (!isEmpty(mfa.type)) {
+
+ /**
+ * If mfa has a type assicated, then we should have a handler matched
+ * with it to continue the flow
+ *
+ * All mfa upgrades will have a token expiration, and an assoicated
+ * type string name (string)
+ */
+
set(mfaUpgrade, mfa);
- //Setup timeout timer
+
set(mfaTimeout, mfa.expires! * 1000);
+
mfaTimer.start();
}
//If login without mfa was successful
@@ -145,11 +100,51 @@ const SubmitLogin = async () => {
})
}
-const totpClear = () => {
- //Clear timer
+const mfaClear = () => {
mfaTimer.stop();
- //Clear upgrade message
set(mfaUpgrade, undefined);
}
-</script> \ No newline at end of file
+</script>
+
+<template>
+ <div class="">
+ <h3>Login</h3>
+
+ <div v-if="mfaUpgrade?.type === 'totp'">
+ <Totp @clear="mfaClear()" :upgrade="mfaUpgrade" />
+ </div>
+
+ <form v-else id="user-pass-submit-form" method="post" action="/login" @submit.prevent="SubmitLogin">
+ <fieldset class="" :disabled="waiting">
+ <div>
+ <div class="float-label">
+ <input id="username" v-model="v$.username.$model" type="email" class="w-full primary input"
+ placeholder="Email" :class="{ 'data-invalid': v$.username.$invalid }" @input="onInput">
+ <label for="username">Email</label>
+ </div>
+ </div>
+ <div class="py-3">
+ <div class="mb-2 float-label">
+ <input id="password" v-model="v$.password.$model" type="password" class="w-full primary input"
+ placeholder="Password" :class="{ 'data-invalid': v$.password.$invalid }" @input="onInput">
+ <label for="password">Password</label>
+ </div>
+ </div>
+ </fieldset>
+ <button type="submit" form="user-pass-submit-form" class="btn primary" :disabled="waiting">
+ <!-- Display spinner if waiting, otherwise the sign-in icon -->
+ <fa-icon :class="{ 'animate-spin': waiting }" :icon="waiting ? 'spinner' : 'sign-in-alt'" />
+ Log-in
+ </button>
+ <div class="flex flex-row justify-between gap-3 pt-3 pb-2 form-links">
+ <router-link to="/pwreset">
+ Forgot password
+ </router-link>
+ <router-link to="/register">
+ Register a new account
+ </router-link>
+ </div>
+ </form>
+ </div>
+</template> \ No newline at end of file