import { useUserStore } from '#lib/stores' import type { AppCookies, UserStore } from '#lib/types' import { useUser, useResetStore, useNadal, useAuthService, } from '#lib/composables' /** * Import types from Nadal. */ import type { ResetPasswordRequestPayload, UpdatePasswordRequestPayload, UpdateProfileRequestPayload, } from '@kira-dancer/nadal' import { ResponseStatus } from '#lib/enums/app' import { createError, useNuxtApp, useRoute } from 'nuxt/app' /** * Provides account-related methods to update the user's password and profile. * It also provides methods to send a password reset link and reset the password. * @returns An object containing the account-related methods. * @namespace */ export const useAccount = () => { /** * Nadal account instance. */ const { account } = useNadal() const route = useRoute() const resetStore = useResetStore() const store = useUserStore() const { user, token } = useUser() const $appCookies = useNuxtApp().$appCookies as AppCookies const { requestOTPCode, requestVerifyOTPCode, requestResetPassword, requestCheckUsername, } = useAuthService() /** * Updates the user's password using the provided data. * After updating the password, it clears the token cookie and resets the store. * * UpdatePasswordRequestPayload type is imported from the Nadal module. * * @param data - The payload containing the old and new passwords. * @returns A promise that resolves when the password is updated successfully. */ const onUpdatePassword = async ( data: UpdatePasswordRequestPayload, ): Promise => { await account.updatePassword(data, token.value!) $appCookies.token.value = null $appCookies.gpToken.value = null resetStore.resetAll() } /** * Check if fullname exists * @param payload * @returns A promise that resolves when the check fullname link is sent successfully. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any const checkFullnameExists = async (fullname: string): Promise => { return await account.checkFullNameExists({ fullname }) } /** * Check if fullname exists * @param payload * @returns A promise that resolves when the check fullname link is sent successfully. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any const checkUsernameExists = async (username: string): Promise => { const { data, error } = await requestCheckUsername(username) if (error.value) { throw error.value } return data } /** * Updates the user profile with the provided data. * If the email is provided, it checks if the email already exists and throws an error if it does. * Then, it updates the profile using the provided data and updates the user in the store. * * UpdateProfileRequestPayload type is imported from the Nadal module. * * @param data - The data to update the profile with. * @returns A promise that resolves when the profile is updated successfully. * @throws An error with the message 'EMAIL_ALREADY_EXIST' if the email already exists. */ const onUpdateProfile = async ( data: UpdateProfileRequestPayload, ): Promise => { if (data.email) { const isEmailExist = await account.checkEmail({ email: data.email }) if (isEmailExist) { throw createError({ statusCode: 400, statusMessage: ResponseStatus.EMAIL_ALREADY_EXIST, message: ResponseStatus.EMAIL_ALREADY_EXIST, }) } } const response = await account.updateProfile(data) if (response === ResponseStatus.OK) { store.setUser({ ...user.value, ...data, } as UserStore) } } /** * Sends a password reset link to the provided email. * @param email - The email to send the password reset link to. * @returns A promise that resolves when the password reset link is sent successfully. */ const onForgotPassword = async (email: string): Promise => { return account.sendPasswordResetLink({ email }) } /** * Resets the user's password using the provided token and new password. * * ResetPasswordRequestPayload type is imported from the Nadal module. * @param data - The payload containing the new password and token. * @returns A promise that resolves when the password is reset successfully. */ const onResetPassword = async ( payload: ResetPasswordRequestPayload, // eslint-disable-next-line @typescript-eslint/no-explicit-any ): Promise => { const token = route.query?.token ?? '' const { data, error } = await requestResetPassword( token.toString(), payload, ) if (error.value) { throw error.value } resetStore.resetAll() return data! } const fetchOTPCode = async (email: string) => { const { data, error } = await requestOTPCode(email) if (error.value) { throw error.value } return data } const verifyOTPCode = async (code: string) => { const { data, error } = await requestVerifyOTPCode(code) if (error.value) { throw error.value } return data } return { onResetPassword, onForgotPassword, onUpdatePassword, onUpdateProfile, fetchOTPCode, verifyOTPCode, checkFullnameExists, checkUsernameExists, } }