refs #6076 feat: init twoFactor section
gitea/salix-front/pipeline/head This commit looks good Details

This commit is contained in:
Alex Moreno 2023-08-03 15:56:55 +02:00
parent b55e216d6a
commit a554131d77
5 changed files with 203 additions and 4 deletions

View File

@ -58,6 +58,12 @@ const onResponseError = (error) => {
break;
}
if (response.data?.error?.code === 'REQUIRES_2FA') {
console.log(window.location.hash);
console.log(window.location.hash.slice(1));
return Router.push({ name: 'TwoFactor' });
}
if (session.isLoggedIn() && response.status === 401) {
session.destroy();
const hash = window.location.hash;

View File

@ -70,7 +70,7 @@ async function onSubmit() {
router.push({ name: 'Dashboard' });
}
} catch (e) {
//
console.log('LOGIN ERROR', e);
}
}
</script>

View File

@ -0,0 +1,187 @@
<script setup>
import { ref, computed } from 'vue';
import { Dark, Quasar, useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import axios from 'axios';
import { useSession } from 'src/composables/useSession';
const quasar = useQuasar();
const session = useSession();
const router = useRouter();
const { t, locale } = useI18n();
const userLocale = computed({
get() {
return locale.value;
},
set(value) {
locale.value = value;
if (value === 'en') value = 'en-GB';
// FIXME: Dynamic imports from absolute paths are not compatible with vite:
// https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations
try {
const langList = import.meta.glob('../../node_modules/quasar/lang/*.mjs');
langList[`../../node_modules/quasar/lang/${value}.mjs`]().then((lang) => {
Quasar.lang.set(lang.default);
});
} catch (error) {
//
}
},
});
const darkMode = computed({
get() {
return Dark.isActive;
},
set(value) {
Dark.set(value);
},
});
const username = ref('');
const password = ref('');
const keepLogin = ref(true);
async function onSubmit() {
// try {
// const { data } = await axios.post('Accounts/login', {
// user: username.value,
// password: password.value,
// });
// if (!data) return;
// await session.login(data.token, keepLogin.value);
// quasar.notify({
// message: t('login.loginSuccess'),
// type: 'positive',
// });
// const currentRoute = router.currentRoute.value;
// if (currentRoute.query && currentRoute.query.redirect) {
// router.push(currentRoute.query.redirect);
// } else {
// router.push({ name: 'Dashboard' });
// }
// } catch (e) {
// console.log('ENTRY');
// console.log(e);
// }
}
</script>
<template>
<QLayout>
<QPageContainer>
<QPage id="login">
<QPageSticky position="top-right">
<QToolbar>
<QBtn
id="switchLanguage"
:label="t('globals.language')"
icon="translate"
color="primary"
size="sm"
flat
rounded
>
<QMenu auto-close>
<QList dense>
<QItem
@click="userLocale = 'en'"
:active="userLocale == 'en'"
v-ripple
clickable
>
{{ t('globals.lang.en') }}
</QItem>
<QItem
@click="userLocale = 'es'"
:active="userLocale == 'es'"
v-ripple
clickable
>
{{ t('globals.lang.es') }}
</QItem>
</QList>
</QMenu>
</QBtn>
<QList>
<QItem>
<QItemSection>
<QItemLabel caption>
{{ t(`globals.darkMode`) }}
</QItemLabel>
</QItemSection>
<QItemSection side>
<QToggle
v-model="darkMode"
checked-icon="dark_mode"
unchecked-icon="light_mode"
/>
</QItemSection>
</QItem>
</QList>
</QToolbar>
</QPageSticky>
<div class="login-form q-pa-xl">
<QImg
src="~/assets/logo.svg"
alt="Logo"
fit="contain"
:ratio="16 / 9"
class="q-mb-md"
/>
<QForm @submit="onSubmit" class="q-gutter-md">
<QInput
v-model="username"
:label="t('login.username')"
lazy-rules
:rules="[
(val) =>
(val && val.length > 0) || t('login.fieldRequired'),
]"
/>
<QInput
type="password"
v-model="password"
:label="t('login.password')"
lazy-rules
:rules="[
(val) =>
(val && val.length > 0) || t('login.fieldRequired'),
]"
/>
<QToggle v-model="keepLogin" :label="t('login.keepLogin')" />
<div>
<QBtn
:label="t('login.submit')"
type="submit"
color="primary"
class="full-width"
rounded
unelevated
/>
</div>
</QForm>
</div>
</QPage>
</QPageContainer>
</QLayout>
</template>
<style lang="scss" scoped>
#login {
display: flex;
align-items: center;
justify-content: center;
min-height: inherit;
}
.login-form {
width: 400px;
}
</style>

View File

@ -45,8 +45,8 @@ export { Router };
export default route(function (/* { store, ssrContext } */) {
Router.beforeEach(async (to, from, next) => {
const { isLoggedIn } = session;
if (!isLoggedIn() && to.name !== 'Login') {
const outLayout = ['Login', 'TwoFactor'];
if (!isLoggedIn() && !outLayout.includes(to.name)) {
return next({ name: 'Login', query: { redirect: to.fullPath } });
}

View File

@ -12,6 +12,12 @@ const routes = [
meta: { title: 'logIn' },
component: () => import('../pages/Login/LoginMain.vue'),
},
{
path: '/twoFactor',
name: 'TwoFactor',
meta: { title: 'twoFactor' },
component: () => import('../pages/Login/TwoFactor.vue'),
},
{
path: '/',
name: 'Main',
@ -35,7 +41,7 @@ const routes = [
name: 'NotFound',
component: () => import('../pages/NotFound.vue'),
},
wagon
wagon,
],
},
];