Skip to content
49 changes: 43 additions & 6 deletions src/features/auth/controllers/AuthController.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
reauthenticateWithCredential,
reauthenticateWithPopup,
EmailAuthProvider,
sendEmailVerification
} from 'firebase/auth'
import { auth } from '@/app/plugins/firebase'
import axios from 'axios'
Expand All @@ -27,7 +28,15 @@ export default class AuthController {
* @returns {Promise} - Firebase auth user credential
*/
async signUp(email, password) {
return createUserWithEmailAndPassword(auth, email, password)
const userCredential = await createUserWithEmailAndPassword(auth, email, password)

if (userCredential?.user) {
sendEmailVerification(userCredential.user).catch(() => {
// Verification email failed, but account creation succeeded
})
}

return userCredential
}

/**
Expand All @@ -37,11 +46,17 @@ export default class AuthController {
* @returns {Promise} - Firebase auth user credential
*/
async signIn(email, password, rememberMe) {
await setPersistence(
auth,
rememberMe ? browserLocalPersistence : browserSessionPersistence,
)
return signInWithEmailAndPassword(auth, email, password)
await setPersistence(auth, rememberMe ? browserLocalPersistence : browserSessionPersistence)
const userCredential = await signInWithEmailAndPassword(auth, email, password)

// Check if email is verified
if (userCredential.user && !userCredential.user.emailVerified) {
const error = new Error('Email not verified')
error.code = 'auth/email-not-verified'
throw error
}

return userCredential
}

/**
Expand All @@ -65,6 +80,28 @@ export default class AuthController {
return auth.currentUser
}

/**
* Refreshes current user data (including emailVerified status)
* @returns {Promise<void>}
*/
async reloadCurrentUser() {
const currentUser = auth.currentUser
if (currentUser) {
await currentUser.reload()
}
}

/**
* Sends verification email to user
* @param {Object} user - Firebase auth user
* @returns {Promise<void>}
*/
async sendVerificationEmail(user) {
if (user) {
await sendEmailVerification(user)
}
}

/**
* Signs out the current user
* @returns {Promise} - Firebase auth signOut promise
Expand Down
13 changes: 10 additions & 3 deletions src/features/auth/store/Auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export default {
payload.email,
payload.password,
)
await userController.create({ id: user.uid, email: user.email })
await userController.create({ id: user.uid, email: user.email, emailVerified: false })
commit('SET_TOAST', {
message: i18n.global.t('auth.signupSuccess'),
type: 'success',
Expand Down Expand Up @@ -102,8 +102,15 @@ export default {
type: 'success',
})
} catch (err) {
showError('errors.incorrectCredential')
return err
if (err.code === 'auth/email-not-verified') {
commit('SET_TOAST', {
message: i18n.global.t('emailNotVerified'),
type: 'warning',
})
} else {
showError('errors.incorrectCredential')
}
throw err
} finally {
commit('setLoading', false)
}
Expand Down
22 changes: 19 additions & 3 deletions src/features/auth/views/SignUpView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,24 @@ const onSignUp = async () => {
email: email.value,
password: password.value,
})
await router.push('/admin')
sessionStorage.setItem('signupEmail', email.value)
await router.push({ name: 'verify-email', params: { email: email.value } })
} catch (error) {
return error
store.commit('setLoading', false)
// Handle email already in use error
if (error.code === 'auth/email-already-in-use') {
store.commit('setSnackbar', {
show: true,
message: t('errors.emailAlreadyInUse'),
type: 'error'
})
} else {
store.commit('setSnackbar', {
show: true,
message: error.message || t('errors.signupFailed'),
type: 'error'
})
}
} finally {
store.commit('setLoading', false)
}
Expand All @@ -171,7 +186,8 @@ const onGoogleSignInSuccess = async () => {
await router.push('/admin')
store.commit('setLoading', false)
}
const onGoogleSignInError = (error) => {

const onGoogleSignInError = () => {
store.commit('setLoading', false)
return error
}
Expand Down
Loading
Loading