Skip to content
Snippets Groups Projects
Commit 3e905fdf authored by Malin Haugland Høli's avatar Malin Haugland Høli
Browse files

Merge branch 'dev' of...

Merge branch 'dev' of https://gitlab.stud.idi.ntnu.no/idatt2106-gruppe-2/idatt2106_2024_02_frontend into enhancement/43/fix-confirmation-on-sent-email
parents d5960cdf d3348d53
No related branches found
No related tags found
3 merge requests!66Final merge,!38Confirmation when email is sent,!4Pipeline fix
Pipeline #280617 failed
src/assets/bioAuthFace.png

20.6 KiB

src/assets/bioAuthTouch.png

43.2 KiB

......@@ -23,6 +23,10 @@ const submitForm = () => {
userStore.login(username.value, password.value)
}
const bioLogin = () => {
userStore.bioLogin(username.value)
}
const toggleShowPassword = () => {
showPassword.value = !showPassword.value
}
......@@ -114,6 +118,7 @@ watch(
Logg inn
</button>
<p>{{ errorMessage }}</p>
<button @click="bioLogin">biologin</button>
</div>
</div>
<modal-component
......
......@@ -117,6 +117,11 @@ const router = createRouter({
path: '/:pathMatch(.*)*',
name: 'not-found',
component: () => import('@/views/NotFoundView.vue')
},
{
path: '/addAlternativeLogin',
name: 'addAlternativeLogin',
component: () => import('@/views/AddAlternativeLogin.vue')
}
],
scrollBehavior() {
......
......@@ -4,6 +4,10 @@ import type { User } from '@/types/user'
import router from '@/router'
import type { AxiosError } from 'axios'
import axios from 'axios'
import type { CredentialRequestOptions } from '@/types/CredentialRequestOptions'
import { base64urlToUint8array, initialCheckStatus, uint8arrayToBase64url } from '@/util'
import authInterceptor from '@/services/authInterceptor'
import type { CredentialCreationOptions } from '@/types/CredentialCreationOptions'
export const useUserStore = defineStore('user', () => {
const defaultUser: User = {
......@@ -38,7 +42,7 @@ export const useUserStore = defineStore('user', () => {
user.value.lastname = lastname
user.value.username = username
router.push({ name: 'configurations1' })
router.push({ name: 'addAlternativeLogin' })
})
.catch((error) => {
const axiosError = error as AxiosError
......@@ -76,10 +80,145 @@ export const useUserStore = defineStore('user', () => {
router.push({ name: 'login' })
}
const bioRegister = async () => {
try {
const response = await authInterceptor.post('/auth/bioRegistration')
initialCheckStatus(response)
const credentialCreateJson: CredentialCreationOptions = response.data
const credentialCreateOptions: CredentialCreationOptions = {
publicKey: {
...credentialCreateJson.publicKey,
challenge: base64urlToUint8array(
credentialCreateJson.publicKey.challenge as unknown as string
),
user: {
...credentialCreateJson.publicKey.user,
id: base64urlToUint8array(
credentialCreateJson.publicKey.user.id as unknown as string
)
},
excludeCredentials: credentialCreateJson.publicKey.excludeCredentials?.map(
(credential) => ({
...credential,
id: base64urlToUint8array(credential.id as unknown as string)
})
),
extensions: credentialCreateJson.publicKey.extensions
}
}
const publicKeyCredential = (await navigator.credentials.create(
credentialCreateOptions
)) as PublicKeyCredential
const publicKeyResponse =
publicKeyCredential.response as AuthenticatorAttestationResponse
const encodedResult = {
type: publicKeyCredential.type,
id: publicKeyCredential.id,
response: {
attestationObject: uint8arrayToBase64url(publicKeyResponse.attestationObject),
clientDataJSON: uint8arrayToBase64url(publicKeyResponse.clientDataJSON),
transports: publicKeyResponse.getTransports?.() || []
},
clientExtensionResults: publicKeyCredential.getClientExtensionResults()
}
await authInterceptor
.post('/auth/finishBioRegistration', { credential: JSON.stringify(encodedResult) })
.then((response) => {
router.push({ name: 'configurations1' })
})
} catch (error) {
router.push({ name: 'configurations1' })
console.error(error)
}
}
const bioLogin = async (username: string) => {
try {
const request = await axios.post(`http://localhost:8080/auth/bioLogin/${username}`)
initialCheckStatus(request)
console.log(request)
const credentialGetJson: CredentialRequestOptions = request.data
console.log(credentialGetJson)
const credentialGetOptions: CredentialRequestOptions = {
publicKey: {
...credentialGetJson.publicKey,
allowCredentials:
credentialGetJson.publicKey.allowCredentials &&
credentialGetJson.publicKey.allowCredentials.map((credential) => ({
...credential,
id: base64urlToUint8array(credential.id as unknown as string)
})),
challenge: base64urlToUint8array(
credentialGetJson.publicKey.challenge as unknown as string
),
extensions: credentialGetJson.publicKey.extensions
}
}
const publicKeyCredential = (await navigator.credentials.get(
credentialGetOptions
)) as PublicKeyCredential
// Extract response data based on the type of credential
const response = publicKeyCredential.response as AuthenticatorAssertionResponse
const encodedResult = {
type: publicKeyCredential.type,
id: publicKeyCredential.id,
response: {
authenticatorData:
response.authenticatorData &&
uint8arrayToBase64url(response.authenticatorData),
clientDataJSON:
response.clientDataJSON && uint8arrayToBase64url(response.clientDataJSON),
signature: response.signature && uint8arrayToBase64url(response.signature),
userHandle: response.userHandle && uint8arrayToBase64url(response.userHandle)
},
clientExtensionResults: publicKeyCredential.getClientExtensionResults()
}
console.log(encodedResult)
await axios
.post('http://localhost:8080/auth/finishBioLogin/katanta1', {
credential: JSON.stringify(encodedResult)
})
.then((response) => {
sessionStorage.setItem('accessToken', response.data.accessToken)
localStorage.setItem('refreshToken', response.data.refreshToken)
user.value.firstname = response.data.firstName
user.value.lastname = response.data.lastName
user.value.username = response.data.username
router.push({ name: 'home' })
})
.catch((error) => {
const axiosError = error as AxiosError
errorMessage.value =
(axiosError.response?.data as string) || 'An error occurred'
console.log('hei :' + errorMessage.value)
})
} catch (error) {
// Handle errors
console.log(error)
}
}
return {
register,
login,
logout,
bioLogin,
bioRegister,
errorMessage
}
})
export interface CredentialCreationOptions {
publicKey: PublicKeyCredentialCreationOptions
}
export interface CredentialRequestOptions {
publicKey: PublicKeyCredentialRequestOptions
}
import base64js from 'base64-js'
import { type AxiosResponse } from 'axios'
export function base64urlToUint8array(base64Bytes: string): Uint8Array {
const padding = '===='.substring(0, (4 - (base64Bytes.length % 4)) % 4)
return base64js.toByteArray((base64Bytes + padding).replace(/\//g, '_').replace(/\+/g, '-'))
}
export function uint8arrayToBase64url(bytes: Uint8Array | ArrayBuffer | number[]): string {
if (bytes instanceof Uint8Array) {
return base64js
.fromByteArray(bytes)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '')
} else {
return uint8arrayToBase64url(new Uint8Array(bytes))
}
}
export function checkStatus(response: AxiosResponse<any>): AxiosResponse<any> | undefined {
if (response.status !== 200) {
console.log('an error occurred: ', response.statusText)
return undefined
} else {
return response
}
}
export function initialCheckStatus(response: AxiosResponse<any>): any {
checkStatus(response)
return response.data
}
import base64js from 'base64-js'
export function base64urlToUint8array(base64Bytes) {
const padding = '===='.substring(0, (4 - (base64Bytes.length % 4)) % 4)
return base64js.toByteArray((base64Bytes + padding).replace(/\//g, '_').replace(/\+/g, '-'))
}
export function uint8arrayToBase64url(bytes) {
if (bytes instanceof Uint8Array) {
return base64js
.fromByteArray(bytes)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '')
} else {
return uint8arrayToBase64url(new Uint8Array(bytes))
}
}
export function checkStatus(response) {
if (response.status !== 200) {
console.log('an error occurred: ', response.body)
} else {
return response
}
}
export function initialCheckStatus(response) {
checkStatus(response)
return response.data
}
<template>
<div class="alt-login-main">
<h1>Alternativ innlogging</h1>
<div class="img-div">
<img src="@/assets/bioAuthTouch.png" alt="bioAuthTouch" />
<img src="@/assets/bioAuthFace.png" alt="bioAuthFace" />
</div>
<h2>Vil du logge på med touch eller face id?</h2>
<div class="btn-div">
<button @click="router.push('konfigurasjonSteg1')">Senere</button>
<button @click="userStore.bioRegister()">OK</button>
</div>
</div>
</template>
<script setup lang="ts">
import { useUserStore } from '@/stores/userStore'
import router from '@/router'
const userStore = useUserStore()
</script>
<style scoped>
.alt-login-main {
max-width: 800px;
display: flex;
flex-direction: column;
align-items: center;
}
.img-div {
display: flex;
justify-content: center;
}
img {
width: 30%;
}
img:first-child {
margin-right: 20px;
}
button {
margin: 10px;
width: 100px;
height: 40px;
}
</style>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment