148 lines
5.2 KiB
JavaScript
148 lines
5.2 KiB
JavaScript
import { ref, computed, onMounted } from 'vue';
|
|
import axios from 'axios';
|
|
import { UserTypes } from '../../utils/UserTypes.js';
|
|
import { useUserStore } from '../../stores/user.js';
|
|
|
|
// Global reactive state to persist throughout the SPA session
|
|
const globalRole = ref(sessionStorage.getItem('user_acct_type') || UserTypes.PUBLIC);
|
|
const isFetching = ref(false);
|
|
|
|
/**
|
|
* Fetches the user account type from the server.
|
|
* Ensures only one request is made per session.
|
|
*/
|
|
async function fetchRole() {
|
|
if (isFetching.value) return;
|
|
|
|
// If we already have a specialized role in sessionStorage, don't fetch again
|
|
const cached = sessionStorage.getItem('user_acct_type');
|
|
if (cached && cached !== UserTypes.PUBLIC) {
|
|
return;
|
|
}
|
|
|
|
isFetching.value = true;
|
|
try {
|
|
const response = await axios.get('/get/user/acct-type');
|
|
let acctType = response.data?.acct_type;
|
|
|
|
// Handle case where acct_type might be an object (Enum serialization)
|
|
if (acctType && typeof acctType === 'object' && acctType.value) {
|
|
acctType = acctType.value;
|
|
}
|
|
|
|
if (acctType) {
|
|
globalRole.value = acctType;
|
|
sessionStorage.setItem('user_acct_type', acctType);
|
|
}
|
|
} catch (error) {
|
|
// If 401, we are likely a guest
|
|
if (error.response?.status === 401) {
|
|
globalRole.value = UserTypes.PUBLIC;
|
|
sessionStorage.setItem('user_acct_type', UserTypes.PUBLIC);
|
|
} else {
|
|
console.warn('Failed to fetch user acct type from server:', error);
|
|
}
|
|
} finally {
|
|
isFetching.value = false;
|
|
}
|
|
}
|
|
|
|
// Initial fetch attempt if we don't have a definitive role
|
|
if (!sessionStorage.getItem('user_acct_type') || sessionStorage.getItem('user_acct_type') === UserTypes.PUBLIC) {
|
|
fetchRole();
|
|
}
|
|
|
|
export function resetRole() {
|
|
globalRole.value = UserTypes.PUBLIC;
|
|
isFetching.value = false;
|
|
sessionStorage.removeItem('user_acct_type');
|
|
}
|
|
|
|
/**
|
|
* Composable for managing user roles and permissions in the frontend.
|
|
* @param {Object} [user] - Optional user object for legacy support or specific overrides
|
|
*/
|
|
export function useAuth(user = null) {
|
|
const userStore = useUserStore();
|
|
|
|
// Priority: Explicitly passed user prop > user store > sessionStorage fallback
|
|
const currentUser = computed(() => {
|
|
if (user?.value ?? user) return user?.value ?? user;
|
|
const storeUser = userStore.user;
|
|
if (storeUser && Object.keys(storeUser).length > 0) return storeUser;
|
|
|
|
try {
|
|
const stored = sessionStorage.getItem('currentUser');
|
|
return stored ? JSON.parse(stored) : null;
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
});
|
|
|
|
const role = computed(() => {
|
|
// Priority 1: User object passed directly or from store
|
|
const localRole = userStore.acctType || currentUser.value?.acct_type;
|
|
if (localRole) {
|
|
if (typeof localRole === 'object' && localRole.value) return localRole.value;
|
|
return localRole;
|
|
}
|
|
|
|
// Priority 2: Global fetched role
|
|
return globalRole.value;
|
|
});
|
|
|
|
const hasRole = (targetRole) => {
|
|
if (Array.isArray(targetRole)) {
|
|
return targetRole.some(r => role.value === r);
|
|
}
|
|
return role.value === targetRole;
|
|
};
|
|
|
|
// Role-specific helpers
|
|
const isUltimate = computed(() => role.value === UserTypes.ULTIMATE);
|
|
const isSuperOperator = computed(() => role.value === UserTypes.SUPER_OPERATOR);
|
|
const isOperator = computed(() => role.value === UserTypes.OPERATOR);
|
|
const isCoordinator = computed(() => role.value === UserTypes.COORDINATOR);
|
|
const isStoreOwner = computed(() => role.value === UserTypes.STORE_OWNER);
|
|
const isStoreManager = computed(() => role.value === UserTypes.STORE_MANAGER);
|
|
const isRider = computed(() => role.value === UserTypes.RIDER);
|
|
const isSupplier = computed(() => role.value === UserTypes.SUPPLIER);
|
|
const isSupplierOverseer = computed(() => role.value === UserTypes.SUPPLIER_OVERSEER);
|
|
const isWholesaleBuyer = computed(() => role.value === UserTypes.WHOLESALE_BUYER);
|
|
const isAudit = computed(() => role.value === UserTypes.AUDIT);
|
|
const isUser = computed(() => role.value === UserTypes.USER);
|
|
const isCoopOfficer = computed(() => role.value === UserTypes.COOP_OFFICER);
|
|
const isCoopMember = computed(() => role.value === UserTypes.COOP_MEMBER);
|
|
const isPOSTerminal = computed(() => role.value === UserTypes.POS_TERMINAL);
|
|
const isPublic = computed(() => role.value === UserTypes.PUBLIC || !userStore.isLoggedIn);
|
|
const isLoggedIn = computed(() => userStore.isLoggedIn);
|
|
|
|
return {
|
|
user: currentUser,
|
|
role,
|
|
hasRole,
|
|
isUltimate,
|
|
isSuperOperator,
|
|
isOperator,
|
|
isCoordinator,
|
|
isStoreOwner,
|
|
isStoreManager,
|
|
isRider,
|
|
isSupplier,
|
|
isSupplierOverseer,
|
|
isWholesaleBuyer,
|
|
isAudit,
|
|
isUser,
|
|
isCoopOfficer,
|
|
isCoopMember,
|
|
isPOSTerminal,
|
|
isPublic,
|
|
isLoggedIn,
|
|
UserTypes,
|
|
refreshRole: fetchRole,
|
|
// Expose the user store for direct access to user data
|
|
userStore
|
|
};
|
|
}
|
|
|