diff --git a/cypress/e2e/register.cy.ts b/cypress/e2e/register.cy.ts index 508e05569bccb1553a227967aad3bf9e55ee3625..44724e1d00affa893cc9760dcf64019c82f7bf77 100644 --- a/cypress/e2e/register.cy.ts +++ b/cypress/e2e/register.cy.ts @@ -5,8 +5,8 @@ describe('Register', () => { }) function fullInput() { - cy.get('input[name="firstname"]').type('firstname') - cy.get('input[name="lastname"]').type('lastname') + cy.get('input[name="firstName"]').type('firstName') + cy.get('input[name="lastName"]').type('lastName') cy.get('input[name="email"]').type('email@test.work') cy.get('input[name="username"]').type('username') cy.get('input[name="password"]').type('Password123!') diff --git a/src/components/FormLogin.vue b/src/components/FormLogin.vue index e676c6c6fec21252758cd1fe527d2c2985ecc01a..3295165e4da1d9b64376d364d468055a35d81452 100644 --- a/src/components/FormLogin.vue +++ b/src/components/FormLogin.vue @@ -16,8 +16,8 @@ const userStore = useUserStore() const isEmailValid = computed(() => emailRegex.test(resetEmail.value)) const isSendingEmail = ref(false) -const successMessage = ref<string>('') -const modalErrorMessage = ref<string>('') +const successMessage = ref<string | null>(null) +const modalErrorMessage = ref<string | null>(null) const submitForm = () => { userStore.login(username.value, password.value) @@ -27,42 +27,31 @@ const toggleShowPassword = () => { showPassword.value = !showPassword.value } -const openForgotPasswordModal = (event: MouseEvent) => { - event.preventDefault() - isModalOpen.value = true -} - const submitReset = async () => { isSendingEmail.value = true - modalErrorMessage.value = '' - successMessage.value = '' - try { - const response = await axios.post( - 'http://localhost:8080/forgotPassword/changePasswordRequest', - { - email: resetEmail.value - } - ) - successMessage.value = - 'E-posten er sendt. Vennligst sjekk innboksen din for instrukser. OBS: E-posten kan havne i spam-mappen' - isSendingEmail.value = false - setTimeout(() => { - isModalOpen.value = false - successMessage.value = '' - }, 5000) - } catch (error) { - console.error(error) - modalErrorMessage.value = 'Noe gikk galt. Vennligst prøv igjen.' - isSendingEmail.value = false - } + + await axios + .post('http://localhost:8080/forgotPassword/changePasswordRequest', { + email: resetEmail.value + }) + .then(() => { + successMessage.value = + 'E-posten er sendt. Vennligst sjekk innboksen din for instrukser. OBS: E-posten kan havne i spam-mappen' + }) + .catch((error) => { + console.error(error) + modalErrorMessage.value = 'Noe gikk galt. Vennligst prøv igjen.' + }) + + isSendingEmail.value = false } const closeModal = () => { isModalOpen.value = false isSendingEmail.value = false - modalErrorMessage.value = '' + modalErrorMessage.value = null resetEmail.value = '' - successMessage.value = '' + successMessage.value = null } watch( @@ -101,7 +90,7 @@ watch( {{ showPassword ? '🔓' : '🔒' }} </button> <a - @click="openForgotPasswordModal" + @click="isModalOpen = true" class="transition-none absolute right-3 top-10 hover:underline hover:bg-transparent text-[#ef9691] hover:transition-none hover:p-0 cursor-pointer" >Glemt passord?</a > @@ -120,54 +109,57 @@ watch( </div> </div> <modal-component + v-if="isModalOpen" :title="'Glemt passord'" :message="'Vennligst skriv inn e-posten din for å endre passordet.'" - :is-modal-open="isModalOpen" - @close="closeModal" > - <template v-slot:input> - <div v-if="isSendingEmail" class="flex justify-center items-center"> - <div - class="p-3 animate-spin drop-shadow-2xl bg-gradient-to-r from-lime-500 from-30% to-green-600 to-90% md:w-18 md:h-20 h-20 w-20 aspect-square rounded-full" - > - <div class="rounded-full h-full w-full bg-slate-100 background-blur-md"></div> - </div> - </div> - <div v-else-if="successMessage"> - <p class="text-green-500 text-center">{{ successMessage }}</p> + <div v-if="isSendingEmail" class="flex justify-center items-center"> + <div + class="p-3 animate-spin bg-gradient-to-r from-lime-500 from-30% to-green-600 to-90% md:w-18 md:h-20 h-20 w-20 aspect-square rounded-full" + > + <div class="rounded-full h-full w-full bg-slate-100"></div> </div> - <div v-else-if="modalErrorMessage"> - <p class="text-red-500 text-center">{{ modalErrorMessage }}</p> + </div> + <div v-else-if="successMessage"> + <p class="text-green-500 text-center">{{ successMessage }}</p> + <button + class="active-button font-bold py-2 px-4 w-1/2 mt-4 border-2 disabled:border-transparent" + @click="closeModal" + > + Lukk + </button> + </div> + <div v-else-if="modalErrorMessage"> + <p class="text-red-500 text-center">{{ modalErrorMessage }}</p> + <button + class="active-button font-bold py-2 px-4 w-1/2 mt-4 border-2 disabled:border-transparent" + @click="closeModal" + > + Lukk + </button> + </div> + <div v-else> + <input + v-model="resetEmail" + class="border border-gray-300 p-2 w-full mb-7" + placeholder="Skriv e-postadressen din her" + type="email" + /> + <div class="flex gap-5 mt-4"> <button + :disabled="!isEmailValid" + class="active-button font-bold py-2 px-4 w-1/2 border-2 disabled:border-transparent" + @click="submitReset" + > + Send mail + </button> + <button + class="active-button font-bold py-2 px-4 w-1/2 border-2 disabled:border-transparent" @click="closeModal" - class="active-button font-bold py-2 px-4 w-1/2 mt-4 border-2 disabled:border-transparent" > Lukk </button> </div> - <div v-else> - <input - type="email" - v-model="resetEmail" - class="border border-gray-300 p-2 w-full mb-7" - placeholder="Skriv e-postadressen din her" - /> - <div class="flex gap-5 mt-4"> - <button - :disabled="!isEmailValid" - @click="submitReset" - class="active-button font-bold py-2 px-4 w-1/2 border-2 disabled:border-transparent" - > - Send mail - </button> - <button - @click="closeModal" - class="active-button font-bold py-2 px-4 w-1/2 border-2 disabled:border-transparent" - > - Lukk - </button> - </div> - </div> - </template> + </div> </modal-component> </template> diff --git a/src/components/FormRegister.vue b/src/components/FormRegister.vue index 2863b6aa8d4f9fd47594ca36b2c5ba33d72bd2cc..f28be87ece27d5a2f706b421a457b01787c855b0 100644 --- a/src/components/FormRegister.vue +++ b/src/components/FormRegister.vue @@ -3,8 +3,8 @@ import { computed, ref, watch } from 'vue' import { useUserStore } from '@/stores/userStore' import ToolTip from '@/components/ToolTip.vue' -const firstname = ref<string>('') -const lastname = ref<string>('') +const firstName = ref<string>('') +const lastName = ref<string>('') const email = ref<string>('') const username = ref<string>('') const password = ref<string>('') @@ -21,8 +21,8 @@ const emailRegex = const usernameRegex = /^[ÆØÅæøåA-Za-z][æÆøØåÅA-Za-z0-9_]{2,29}$/ const passwordRegex = /^(?=.*[0-9])(?=.*[a-zæøå])(?=.*[ÆØÅA-Z])(?=.*[@#$%^&+=!])(?=\S+$).{8,30}$/ -const isFirstNameValid = computed(() => nameRegex.test(firstname.value) && firstname.value) -const isLastNameValid = computed(() => nameRegex.test(lastname.value) && lastname.value) +const isFirstNameValid = computed(() => nameRegex.test(firstName.value) && firstName.value) +const isLastNameValid = computed(() => nameRegex.test(lastName.value) && lastName.value) const isEmailValid = computed(() => emailRegex.test(email.value)) const isUsernameValid = computed(() => usernameRegex.test(username.value)) const isPasswordValid = computed(() => passwordRegex.test(password.value)) @@ -35,7 +35,7 @@ const isFormInvalid = computed( ) const submitForm = () => { - userStore.register(firstname.value, lastname.value, email.value, username.value, password.value) + userStore.register(firstName.value, lastName.value, email.value, username.value, password.value) } const toggleShowPassword = () => { @@ -60,8 +60,8 @@ watch( /> </div> <input - v-model="firstname" - name="firstname" + v-model="firstName" + name="firstName" :class="{ 'border-2 border-lime-400': isFirstNameValid }" placeholder="Skriv inn fornavn" type="text" @@ -75,8 +75,8 @@ watch( /> </div> <input - v-model="lastname" - name="lastname" + v-model="lastName" + name="lastName" :class="{ 'border-2 border-lime-400': isLastNameValid }" placeholder="Skriv inn etternavn" type="text" diff --git a/src/components/__tests__/FormRegisterTest.spec.ts b/src/components/__tests__/FormRegisterTest.spec.ts index 935801335b6ca43cd26082a3ea8a25d07a33a833..f3604b5c4a4351e9cc2f8cf781285983b102a679 100644 --- a/src/components/__tests__/FormRegisterTest.spec.ts +++ b/src/components/__tests__/FormRegisterTest.spec.ts @@ -24,8 +24,8 @@ describe('FormRegister', () => { }) function successfulFormFill() { - wrapper.find('input[name="firstname"]').setValue('firstname') - wrapper.find('input[name="lastname"]').setValue('lastname') + wrapper.find('input[name="firstName"]').setValue('firstName') + wrapper.find('input[name="lastName"]').setValue('lastName') wrapper.find('input[name="email"]').setValue('email@test.work') wrapper.find('input[name="username"]').setValue('username') wrapper.find('input[name="password"]').setValue('Password123!') @@ -37,15 +37,15 @@ describe('FormRegister', () => { expect(wrapper.text()).toContain('Passord') expect(wrapper.text()).toContain('Registrer deg') - expect(wrapper.find('input[name="firstname"]').exists()).toBe(true) - expect(wrapper.find('input[name="lastname"]').exists()).toBe(true) + expect(wrapper.find('input[name="firstName"]').exists()).toBe(true) + expect(wrapper.find('input[name="lastName"]').exists()).toBe(true) expect(wrapper.find('input[name="email"]').exists()).toBe(true) expect(wrapper.find('input[name="username"]').exists()).toBe(true) expect(wrapper.find('input[name="password"]').exists()).toBe(true) expect(wrapper.find('input[name="confirm"]').exists()).toBe(true) - expect((wrapper.find('input[name="firstname"]').element as HTMLInputElement).value).toBe('') - expect((wrapper.find('input[name="lastname"]').element as HTMLInputElement).value).toBe('') + expect((wrapper.find('input[name="firstName"]').element as HTMLInputElement).value).toBe('') + expect((wrapper.find('input[name="lastName"]').element as HTMLInputElement).value).toBe('') expect((wrapper.find('input[name="email"]').element as HTMLInputElement).value).toBe('') expect((wrapper.find('input[name="username"]').element as HTMLInputElement).value).toBe('') expect((wrapper.find('input[name="password"]').element as HTMLInputElement).value).toBe('') diff --git a/src/router/index.ts b/src/router/index.ts index 9bec3631e31d96d8c09d0ea0e33806acacd68f67..e440a314d843500378eb317a89cdaa2fbe1f0925 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -163,19 +163,16 @@ router.beforeEach(async (to, from, next) => { if (!loginCredentials) { if (bioCredentials && to.name !== 'login-bio') { - console.log('Bio login') await router.replace({ name: 'login-bio', params: { username: bioCredentials } }) return next({ name: 'login-bio', params: { username: bioCredentials } }) } else if (authRequired && !bioCredentials && to.name !== 'login') { - console.log('Normal login') await router.replace({ name: 'login' }) return next({ name: 'login' }) } else if (!authRequired) { - console.log('Public page') next() } } else { - if (userStore.user.isConfigured == false) { + if (!userStore.user.isConfigured) { await userStore.checkIfUserConfigured() } diff --git a/src/services/authInterceptor.ts b/src/services/authInterceptor.ts index 315aba21cbd30a1d992f735a58bcaf2e86aa1fe5..e9c604619f788cec3a46cf142af7a1a983cf9693 100644 --- a/src/services/authInterceptor.ts +++ b/src/services/authInterceptor.ts @@ -1,6 +1,7 @@ import type { AxiosResponse } from 'axios' import axios, { AxiosError } from 'axios' import router from '@/router' +import { useUserStore } from '@/stores/userStore' const authInterceptor = axios.create({ baseURL: 'http://localhost:8080', @@ -38,7 +39,7 @@ authInterceptor.interceptors.response.use( const username = localStorage.getItem('spareStiUsername') if (!username) { - await router.push({ name: 'login' }) + useUserStore().logout() } else { await router.push({ name: 'login-bio', params: { username: username } }) } diff --git a/src/stores/userConfigStore.ts b/src/stores/userConfigStore.ts index 9059f871fa3dde9522788c98f09673d4ac6300d5..2e562ca743a23ae5546c3e93e7af044434798ced 100644 --- a/src/stores/userConfigStore.ts +++ b/src/stores/userConfigStore.ts @@ -46,18 +46,12 @@ export const useUserConfigStore = defineStore('userConfig', () => { accNumber, balance } - await authInterceptor - .post('/accounts', payload) - .then((response) => { - console.log('Success:', response.data) - }) - .catch((error) => { - const axiosError = error as AxiosError - errorMessage.value = - (axiosError.response?.data as string) || - 'An error occurred while posting account' - console.error('Error posting account:', errorMessage.value) - }) + await authInterceptor.post('/accounts', payload).catch((error) => { + const axiosError = error as AxiosError + errorMessage.value = + (axiosError.response?.data as string) || 'An error occurred while posting account' + console.error('Error posting account:', errorMessage.value) + }) } const postUserConfig = async () => { @@ -66,18 +60,13 @@ export const useUserConfigStore = defineStore('userConfig', () => { motivation: motivation.value, challengeTypeConfigs: Array.from(challengeTypeConfigs.value) } - await authInterceptor - .post('/config/challenge', payload) - .then((response) => { - console.log('Success:', response.data) - }) - .catch((error) => { - const axiosError = error as AxiosError - errorMessage.value = - (axiosError.response?.data as string) || - 'An error occurred while updating configuration' - console.error('Error updating configuration:', errorMessage.value) - }) + await authInterceptor.post('/config/challenge', payload).catch((error) => { + const axiosError = error as AxiosError + errorMessage.value = + (axiosError.response?.data as string) || + 'An error occurred while updating configuration' + console.error('Error updating configuration:', errorMessage.value) + }) } return { diff --git a/src/stores/userStore.ts b/src/stores/userStore.ts index 35d6374e397c0c66a70dbe5abe36c30c5803fa9c..e94e85174e291497953345d1a89b5d2b39a1ba1f 100644 --- a/src/stores/userStore.ts +++ b/src/stores/userStore.ts @@ -11,28 +11,26 @@ import { base64urlToUint8array, initialCheckStatus, uint8arrayToBase64url } from import type { CredentialCreationOptions } from '@/types/CredentialCreationOptions' export const useUserStore = defineStore('user', () => { - const defaultUser: User = { - firstname: 'Firstname', - lastname: 'Lastname', - username: 'Username', + const user = ref<User>({ + firstName: '', + lastName: '', + username: '', isConfigured: false - } - - const user = ref<User>(defaultUser) + }) const errorMessage = ref<string>('') const streak = ref<Streak>() const register = async ( - firstname: string, - lastname: string, + firstName: string, + lastName: string, email: string, username: string, password: string ) => { await axios .post(`http://localhost:8080/auth/register`, { - firstName: firstname, - lastName: lastname, + firstName: firstName, + lastName: lastName, email: email, username: username, password: password @@ -40,8 +38,8 @@ export const useUserStore = defineStore('user', () => { .then((response) => { sessionStorage.setItem('accessToken', response.data.accessToken) - user.value.firstname = firstname - user.value.lastname = lastname + user.value.firstName = firstName + user.value.lastName = lastName user.value.username = username router.push({ name: 'configure-biometric' }) @@ -61,8 +59,8 @@ export const useUserStore = defineStore('user', () => { .then((response) => { sessionStorage.setItem('accessToken', response.data.accessToken) - user.value.firstname = response.data.firstName - user.value.lastname = response.data.lastName + user.value.firstName = response.data.firstName + user.value.lastName = response.data.lastName user.value.username = response.data.username return authInterceptor('/profile') @@ -87,10 +85,14 @@ export const useUserStore = defineStore('user', () => { } const logout = () => { - console.log('Logging out') sessionStorage.removeItem('accessToken') localStorage.removeItem('spareStiUsername') - user.value = defaultUser + + user.value.firstName = '' + user.value.lastName = '' + user.value.username = '' + user.value.isConfigured = false + router.push({ name: 'login' }) } @@ -172,10 +174,8 @@ export const useUserStore = defineStore('user', () => { .post(`http://localhost:8080/auth/bioLogin/${username}`) .then((request) => { initialCheckStatus(request) - console.log(request) const credentialGetJson: CredentialRequestOptions = request.data - console.log(credentialGetJson) const credentialGetOptions: CredentialRequestOptions = { publicKey: { @@ -216,7 +216,6 @@ export const useUserStore = defineStore('user', () => { }, clientExtensionResults: publicKeyCredential.getClientExtensionResults() } - console.log(encodedResult) return axios.post(`http://localhost:8080/auth/finishBioLogin/${username}`, { credential: JSON.stringify(encodedResult) @@ -225,8 +224,8 @@ export const useUserStore = defineStore('user', () => { .then((response) => { sessionStorage.setItem('accessToken', response.data.accessToken) - user.value.firstname = response.data.firstName - user.value.lastname = response.data.lastName + user.value.firstName = response.data.firstName + user.value.lastName = response.data.lastName user.value.username = response.data.username router.push({ name: 'home' }) diff --git a/src/types/user.ts b/src/types/user.ts index 624188688f1bec4c544ebf3b4d21d50f4a2d9be9..9fb1fe33d0d2e97d742cd7be056c18869668c44d 100644 --- a/src/types/user.ts +++ b/src/types/user.ts @@ -1,6 +1,6 @@ export interface User { - firstname: string - lastname: string + firstName: string + lastName: string username: string isConfigured: boolean isBiometric?: boolean diff --git a/src/views/ManageConfigView.vue b/src/views/ManageConfigView.vue index fac9e2fbdb3640b82088a70ac812ad5ad56a0b46..5e5f634de622323ebaae2fc6f5e0783b12b9d3c1 100644 --- a/src/views/ManageConfigView.vue +++ b/src/views/ManageConfigView.vue @@ -85,10 +85,9 @@ onMounted(() => { authInterceptor('/config/challenge') .then((response) => { configuration.value = response.data - console.log(configuration.value) }) .catch((error) => { - return console.log(error) + console.error(error) }) }) </script> diff --git a/src/views/ManageProfileView.vue b/src/views/ManageProfileView.vue index 867724633a526dde00d4a392db4c67bdfbbaa590..adc8b26a59ce9dabf1a9d7743bc760151bebf558 100644 --- a/src/views/ManageProfileView.vue +++ b/src/views/ManageProfileView.vue @@ -83,10 +83,9 @@ onMounted(async () => { await authInterceptor('/profile') .then((response) => { profile.value = response.data - console.log(profile.value) }) .catch((error) => { - return console.log(error) + console.error(error) }) }) @@ -135,7 +134,7 @@ const saveChanges = async () => { </div> <input v-model="profile.firstName" - name="firstname" + name="firstName" placeholder="Skriv inn fornavn" type="text" /> @@ -149,7 +148,7 @@ const saveChanges = async () => { </div> <input v-model="profile.lastName" - name="lastname" + name="lastName" placeholder="Skriv inn etternavn" type="text" />