Skip to content

Commit

Permalink
optimize login
Browse files Browse the repository at this point in the history
  • Loading branch information
tinohager committed Jun 17, 2024
1 parent fffec90 commit fcd7ee5
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 108 deletions.
63 changes: 37 additions & 26 deletions src/Frontend/src/components/MfaConfigurationBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const step = ref(1)
const stepper = ref<QStepper>()
const mfa = ref<MfaInformation>()
const token = ref('')
const processing = ref(false)
onMounted(async () => {
await getMfaStatus()
Expand All @@ -25,27 +26,30 @@ async function getMfaStatus () {
async function activate () {
try {
processing.value = true
const mfaResponse = await apiHelper.mfaActivate(token.value)
if (instanceOfMfaError(mfaResponse)) {
$q.notify({
type: 'negative',
caption: (mfaResponse as MfaError).error
})
return
}
} catch (e) {
console.error(e)
} finally {
processing.value = false
await getMfaStatus()
token.value = ''
step.value = 1
} catch (e) {
console.error(e)
}
await getMfaStatus()
}
async function deactivate () {
try {
processing.value = true
const mfaResponse = await apiHelper.mfaDeactivate(token.value)
if (instanceOfMfaError(mfaResponse)) {
Expand All @@ -58,6 +62,8 @@ async function deactivate () {
token.value = ''
} catch (e) {
console.error(e)
} finally {
processing.value = false
}
await getMfaStatus()
}
Expand Down Expand Up @@ -108,12 +114,14 @@ function stepperPrevious () {
icon="password"
:done="step > 2"
>
<q-input
v-model="token"
outlined
label="Activation code"
hint="Enter the code from your authenticator app"
/>
<q-form @submit.prevent="activate()">
<q-input
v-model="token"
outlined
label="Activation code"
hint="Enter the code from your authenticator app"
/>
</q-form>
</q-step>

<template #navigation>
Expand All @@ -130,11 +138,11 @@ function stepperPrevious () {
outline
color="black"
label="Activate"
:loading="processing"
@click="activate()"
/>
<q-btn
v-if="step > 1"

outline
color="black"
label="Back"
Expand All @@ -158,20 +166,23 @@ function stepperPrevious () {

<div class="q-mt-md">
To deactivate MFA, please provide another code.
<q-input
v-model="token"
outlined
dense
label="Deactivation code"
hint="Enter the code from your authenticator app"
/>
<q-btn
class="q-mt-md"
color="black"
outline
label="Deactivate"
@click="deactivate()"
/>
<q-form @submit.prevent="deactivate()">
<q-input
v-model="token"
outlined
dense
label="Deactivation code"
hint="Enter the code from your authenticator app"
/>
<q-btn
type="submit"
class="q-mt-md"
color="black"
outline
label="Deactivate"
:loading="processing"
/>
</q-form>
</div>
</div>
</div>
Expand Down
47 changes: 0 additions & 47 deletions src/Frontend/src/helpers/apiHelper.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { Notify } from 'quasar'

import { LoginAction } from 'src/models/LoginAction'
import { User } from 'src/models/User'
import { UserAdd } from 'src/models/UserAdd'
import { UserEdit } from 'src/models/UserEdit'
import { AuthenticationResponse } from 'src/models/AuthenticationResponse'

import { MfaError } from 'src/models/MfaError'
import { MfaSuccess } from 'src/models/MfaSuccess'
Expand All @@ -15,50 +13,6 @@ import { tokenHelper } from './tokenHelper'

const apiBaseUrl = process.env.NODE_ENV === 'development' ? '/api/v1/' : '/auth/api/v1/'

async function login (emailAddress : string, password : string) : Promise<LoginAction> {
const response = await fetch(`${apiBaseUrl}Authentication`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
emailAddress,
password
})
})

if (response.status === 200) {
const authenticationResponse = await response.json() as AuthenticationResponse
tokenHelper.setToken(authenticationResponse)

return LoginAction.Forward
}

if (response.status === 404) {
Notify.create({
type: 'negative',
message: 'Endpoint failure',
caption: 'Not Available'
})
return LoginAction.Failure
}

if (response.status === 504) {
Notify.create({
type: 'negative',
message: 'Endpoint failure',
caption: 'Timeout'
})
return LoginAction.Failure
}

Notify.create({
type: 'negative',
message: 'Request failure',
caption: 'Login not possible'
})

return LoginAction.ClearPassword
}

async function getUsers () : Promise<User[]> {
const token = tokenHelper.getToken()

Expand Down Expand Up @@ -306,7 +260,6 @@ async function mfaDeactivate (mfaToken: string) : Promise<MfaResponse> {
}

export const apiHelper = {
login,
getUsers,
createUser,
updateUser,
Expand Down
72 changes: 72 additions & 0 deletions src/Frontend/src/helpers/authenticationHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { LoginAction } from 'src/models/LoginAction'
import { AuthenticationResponse } from 'src/models/AuthenticationResponse'
import { AuthenticationMfaResponse } from 'src/models/AuthenticationMfaResponse'

import { tokenHelper } from './tokenHelper'

const apiBaseUrl = process.env.NODE_ENV === 'development' ? '/api/v1/' : '/auth/api/v1/'

export class AuthenticationHelper {
mfaIdentifier: string | undefined

constructor () {
this.mfaIdentifier = undefined
}

public async tokenLogin (token : string) : Promise<LoginAction> {
const response = await fetch(`${apiBaseUrl}Authentication/Token`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
mfaIdentifier: this.mfaIdentifier,
token
})
})

if (response.status === 200) {
const authenticationResponse = await response.json() as AuthenticationResponse
tokenHelper.setToken(authenticationResponse)

this.mfaIdentifier = undefined

return LoginAction.Forward
}

return LoginAction.ClearPassword
}

public async login (emailAddress : string, password : string) : Promise<LoginAction> {
const response = await fetch(`${apiBaseUrl}Authentication`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
emailAddress,
password
})
})

if (response.status === 200) {
const authenticationResponse = await response.json() as AuthenticationResponse
tokenHelper.setToken(authenticationResponse)

return LoginAction.Forward
}

if (response.status === 401) {
const authenticationMfaResponse = await response.json() as AuthenticationMfaResponse
this.mfaIdentifier = authenticationMfaResponse.mfaIdentifier

return LoginAction.TimeBasedOneTimePasswordRequired
}

if (response.status === 404) {
return LoginAction.Failure
}

if (response.status === 504) {
return LoginAction.Failure
}

return LoginAction.ClearPassword
}
}
4 changes: 4 additions & 0 deletions src/Frontend/src/models/AuthenticationMfaResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface AuthenticationMfaResponse {
mfaIdentifier: string
mfaType: string
}
3 changes: 2 additions & 1 deletion src/Frontend/src/models/LoginAction.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export enum LoginAction {
Forward,
ClearPassword,
Failure
Failure,
TimeBasedOneTimePasswordRequired
}
Loading

0 comments on commit fcd7ee5

Please sign in to comment.