Features: 1) Add error handling for invalid token scenarios with isTokenInvalidError in useRefresh; 2) Integrate useLogout logic in useRefresh for improved redirection after token expiration; 3) Optimize server-side refresh operations with conditional execution in app.vue; 4) Enhance form behavior in input.vue with dynamic autocapitalize attribute.
Fixes: 1) Improve error notification handling in `useRefresh` with detailed GraphQL message extraction; 2) Address missing token reassignments for `refreshToken` and `accessToken` in `useRefresh`; 3) Resolve redundant refresh execution in non-server environments of `app.vue`. Extra: 1) Refactor `useRefresh` for cleaner error handling and better modularity; 2) Cleanup unused comments and enhance log messages for easier debugging; 3) Organize imports across updated files for standardization.
This commit is contained in:
parent
85ec39255b
commit
f370c0872f
3 changed files with 73 additions and 30 deletions
|
|
@ -59,12 +59,14 @@ const { isSupportedLocale } = useLocaleRedirect();
|
|||
|
||||
let refreshInterval: NodeJS.Timeout;
|
||||
|
||||
await Promise.all([
|
||||
refresh(),
|
||||
useLanguages(),
|
||||
useCompanyInfo(),
|
||||
getCategories()
|
||||
]);
|
||||
if (import.meta.server) {
|
||||
await Promise.all([
|
||||
refresh(),
|
||||
useLanguages(),
|
||||
useCompanyInfo(),
|
||||
getCategories()
|
||||
]);
|
||||
}
|
||||
|
||||
watch(
|
||||
() => appStore.activeState,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
@keydown="numberOnly ? onlyNumbersKeydown($event) : null"
|
||||
class="block__input"
|
||||
:inputmode="inputMode || 'text'"
|
||||
:autocapitalize="type === 'input' ? 'off' : 'on'"
|
||||
>
|
||||
<button
|
||||
@click.prevent="togglePasswordVisible"
|
||||
|
|
|
|||
|
|
@ -6,15 +6,31 @@ import { isGraphQLError } from '~/utils/error';
|
|||
import {DEFAULT_LOCALE} from "~/config/constants";
|
||||
import {useNotification} from "~/composables/notification";
|
||||
import {useUserBaseData} from "~/composables/user";
|
||||
import {useLogout} from "~/composables/auth/useLogout";
|
||||
|
||||
export function useRefresh() {
|
||||
const { t } = useI18n();
|
||||
const router = useRouter();
|
||||
const localePath = useLocalePath();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const { COOKIES_REFRESH_TOKEN_KEY, COOKIES_LOCALE_KEY, COOKIES_ACCESS_TOKEN_KEY } = useAppConfig();
|
||||
const { checkAndRedirect } = useLocaleRedirect();
|
||||
const { logout } = useLogout();
|
||||
|
||||
const { mutate, loading, error } = useMutation(REFRESH);
|
||||
|
||||
function isTokenInvalidError(error: any): boolean {
|
||||
if (isGraphQLError(error)) {
|
||||
const message = error.graphQLErrors?.[0]?.message?.toLowerCase() || '';
|
||||
return message.includes('invalid refresh token') ||
|
||||
message.includes('blacklist') ||
|
||||
message.includes('expired') ||
|
||||
message.includes('revoked');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async function refresh() {
|
||||
const cookieRefresh = useCookie(
|
||||
COOKIES_REFRESH_TOKEN_KEY,
|
||||
|
|
@ -42,33 +58,57 @@ export function useRefresh() {
|
|||
return;
|
||||
}
|
||||
|
||||
const result = await mutate({ refreshToken: cookieRefresh.value });
|
||||
const data = result?.data?.refreshJwtToken;
|
||||
if (!data) {
|
||||
try {
|
||||
const result = await mutate({ refreshToken: cookieRefresh.value });
|
||||
const data = result?.data?.refreshJwtToken;
|
||||
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
userStore.setUser(data.user);
|
||||
cookieRefresh.value = data.refreshToken;
|
||||
cookieAccess.value = data.accessToken;
|
||||
|
||||
if (data.user.language !== cookieLocale.value) {
|
||||
await checkAndRedirect(data.user.language);
|
||||
}
|
||||
|
||||
await useUserBaseData(data.user.email);
|
||||
} catch (err) {
|
||||
if (isTokenInvalidError(err)) {
|
||||
await logout();
|
||||
await router.push(localePath('/'));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let message = t('popup.errors.defaultError');
|
||||
if (isGraphQLError(err)) {
|
||||
message = err.graphQLErrors?.[0]?.message || message;
|
||||
} else if (err instanceof Error) {
|
||||
message = err.message;
|
||||
} else if (typeof err === 'string') {
|
||||
message = err;
|
||||
}
|
||||
|
||||
useNotification({
|
||||
message,
|
||||
type: 'error',
|
||||
title: t('popup.errors.main')
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
watch(error, async (err) => {
|
||||
if (!err) return;
|
||||
|
||||
if (isTokenInvalidError(err)) {
|
||||
await logout();
|
||||
await router.push(localePath('/'));
|
||||
return;
|
||||
}
|
||||
|
||||
userStore.setUser(data.user);
|
||||
cookieAccess.value = data.accessToken;
|
||||
|
||||
if (data.user.language !== cookieLocale.value) {
|
||||
await checkAndRedirect(data.user.language);
|
||||
}
|
||||
|
||||
cookieRefresh.value = data.refreshToken;
|
||||
|
||||
// await useWishlist();
|
||||
// await useOrders({
|
||||
// userEmail: data.user.email,
|
||||
// status: "PENDING"
|
||||
// });
|
||||
// await usePromocodes();
|
||||
|
||||
await useUserBaseData(data.user.email);
|
||||
}
|
||||
|
||||
watch(error, (err) => {
|
||||
if (!err) return;
|
||||
console.error('useRefresh error:', err);
|
||||
let message = t('popup.errors.defaultError');
|
||||
if (isGraphQLError(err)) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue