feat: (auth) switch to OTP code via e-mail
All checks were successful
Build BAB Application Deployment Artifact / build (push) Successful in 2m24s

This commit is contained in:
2024-06-14 16:23:48 -04:00
parent 1526a10630
commit 643d74e29d
3 changed files with 89 additions and 22 deletions

View File

@@ -14,7 +14,7 @@
<div class="col text-h6">Log in</div>
</div>
</q-card-section>
<q-form>
<q-form @keydown.enter.prevent="doTokenLogin">
<q-card-section class="q-gutter-md">
<q-input
v-model="email"
@@ -23,28 +23,21 @@
color="darkblue"
filled></q-input>
<q-input
v-model="password"
label="Password"
type="password"
v-if="userId"
v-model="token"
label="6-digit code"
type="number"
color="darkblue"
filled></q-input>
<q-card-actions>
<q-space />
<q-btn
type="button"
@click="doLogin"
label="Login"
color="primary"></q-btn>
</q-card-actions>
</q-card-section>
</q-form>
<q-card-section class="q-pa-none">
<div class="row justify-center q-ma-sm">
<q-btn
type="button"
:to="{ name: 'signup' }"
@click="doTokenLogin"
color="primary"
label="SignUp with E-mail"
label="Login with E-mail"
style="width: 300px" />
</div>
<div class="row justify-center q-ma-sm">
@@ -84,16 +77,75 @@
<script setup lang="ts">
import { ref } from 'vue';
import { login } from 'boot/appwrite';
import GoogleOauthComponent from 'src/components/GoogleOauthComponent.vue';
import DiscordOauthComponent from 'src/components/DiscordOauthComponent.vue';
import { Dialog, Notify } from 'quasar';
import { useAuthStore } from 'src/stores/auth';
import { useRouter } from 'vue-router';
import { AppwriteException } from 'appwrite';
const email = ref('');
const password = ref('');
const token = ref('');
const userId = ref();
console.log('version:' + process.env.VUE_APP_VERSION);
const doLogin = async () => {
login(email.value, password.value);
const doTokenLogin = async () => {
const authStore = useAuthStore();
if (!userId.value) {
try {
const sessionToken = await authStore.createTokenSession(email.value);
userId.value = sessionToken.userId;
Dialog.create({ message: 'Check your e-mail for your login code.' });
} catch (e) {
Dialog.create({
message: 'An error occurred. Please ask for help in Discord',
});
}
} else {
const notification = Notify.create({
type: 'primary',
position: 'top',
spinner: true,
message: 'Logging you in...',
timeout: 8000,
group: false,
});
try {
await authStore.tokenLogin(userId.value, token.value);
notification({
type: 'positive',
message: 'Logged in!',
timeout: 2000,
spinner: false,
icon: 'check_circle',
});
useRouter().replace({ name: 'index' });
} catch (error: unknown) {
if (error instanceof AppwriteException) {
if (error.type === 'user_session_already_exists') {
useRouter().replace({ name: 'index' });
notification({
type: 'positive',
message: 'Already Logged in!',
timeout: 2000,
spinner: false,
icon: 'check_circle',
});
return;
}
Dialog.create({
title: 'Login Error!',
message: error.message,
persistent: true,
});
}
notification({
type: 'negative',
message: 'Login failed.',
timeout: 2000,
});
}
}
};
</script>

View File

@@ -49,6 +49,10 @@ export default route(function (/* { store, ssrContext } */) {
return next('/login');
}
if (to.name === 'login' && currentUser) {
return next('/');
}
if (requiredRoles) {
if (!currentUser) {
return next('/login');

View File

@@ -45,22 +45,31 @@ export const useAuthStore = defineStore('auth', () => {
await init();
}
async function createTokenSession(email: string) {
return await account.createEmailToken(ID.unique(), email);
}
async function googleLogin() {
account.createOAuth2Session(
await account.createOAuth2Session(
OAuthProvider.Google,
'https://oys.undock.ca',
'https://oys.undock.ca/login'
);
currentUser.value = await account.get();
await init();
}
async function discordLogin() {
account.createOAuth2Session(
await account.createOAuth2Session(
OAuthProvider.Discord,
'https://oys.undock.ca',
'https://oys.undock.ca/login'
);
currentUser.value = await account.get();
await init();
}
async function tokenLogin(userId: string, token: string) {
await account.createSession(userId, token);
await init();
}
function getUserNameById(id: string | undefined | null): string {
@@ -102,6 +111,8 @@ export const useAuthStore = defineStore('auth', () => {
login,
googleLogin,
discordLogin,
createTokenSession,
tokenLogin,
logout,
init,
};