Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/components/Login/Login.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<script setup lang="ts">
import { computed, ref } from 'vue';

import { useUserStore } from '@/stores/UserStore';
import { useAuthStore } from '@/stores/AuthStore';
import { osimRuntime } from '@/stores/osimRuntime';

// const router = useRouter();
const userStore = useUserStore();
const userStore = useAuthStore();
// const route = useRoute();

const username = ref('');
Expand Down
4 changes: 3 additions & 1 deletion src/components/Navbar/Navbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useElementBounding } from '@vueuse/core';
import { useSearchParams } from '@/composables/useSearchParams';

import { useUserStore } from '@/stores/UserStore';
import { useAuthStore } from '@/stores/AuthStore';
import router from '@/router';
import { useSettingsStore } from '@/stores/SettingsStore';
import { useToastStore } from '@/stores/ToastStore';
Expand All @@ -17,6 +18,7 @@ import { cveRegex } from '@/utils/helpers';
import RedHatIconSvg from '@/assets/Logo-Red_Hat-Hat_icon-Standard-RGB.svg';

const userStore = useUserStore();
const authStore = useAuthStore();
const { settings } = useSettingsStore();
const { toasts } = useToastStore();
const elHeader = ref<HTMLElement | null>(null);
Expand Down Expand Up @@ -166,7 +168,7 @@ const usernameDisplay = computed(() => {
<hr class="dropdown-divider">
</li>
<li>
<button class="dropdown-item" type="button" @click.prevent="userStore.logout">
<button class="dropdown-item" type="button" @click.prevent="authStore.logout">
Logout
</button>
</li>
Expand Down
12 changes: 6 additions & 6 deletions src/composables/__tests__/useSessionWarning.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createPinia, setActivePinia } from 'pinia';
import { DateTime } from 'luxon';

import { encodeJWT } from '@/__tests__/helpers';
import { useUserStore } from '@/stores/UserStore';
import { useAuthStore } from '@/stores/AuthStore';

import { useSessionWarning } from '../useSessionWarning';

Expand All @@ -29,17 +29,17 @@ const mockSessionData = {
// Create a shared login spy that can be accessed in tests
const mockLogin = vi.fn().mockResolvedValue(true);

vi.mock('@/stores/UserStore', () => ({
useUserStore: vi.fn(() => ({
get refreshToken() { return mockSessionData.refresh; },
vi.mock('@/stores/AuthStore', () => ({
useAuthStore: vi.fn(() => ({
get refreshToken() { return mockSessionData.refresh as any; },
set refreshToken(value: string) { mockSessionData.refresh = value; },
login: mockLogin,
logout: vi.fn(),
})),
}));

describe('useSessionWarning', () => {
let _userStore: any;
let _authStore: any;

beforeEach(() => {
setActivePinia(createPinia());
Expand All @@ -53,7 +53,7 @@ describe('useSessionWarning', () => {
mockSessionData.whoami = null;
mockSessionData.jiraUsername = '';

_userStore = useUserStore();
_authStore = useAuthStore();
vi.clearAllMocks();
mockLogin.mockClear();
});
Expand Down
12 changes: 6 additions & 6 deletions src/composables/useSessionWarning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import jwtDecode from 'jwt-decode';
import type { JwtPayload } from 'jwt-decode';
import { DateTime } from 'luxon';

import { useUserStore } from '@/stores/UserStore';
import { useAuthStore } from '@/stores/AuthStore';

export function useSessionWarning() {
const userStore = useUserStore();
const authStore = useAuthStore();
const isReauthenticating = ref(false);

const isRefreshTokenExpiringInOneHour = computed(() => {
try {
const refreshToken = userStore.refreshToken;
const refreshToken = authStore.refreshToken;
if (!refreshToken) return false;

const decoded = jwtDecode<JwtPayload>(refreshToken);
Expand All @@ -31,7 +31,7 @@ export function useSessionWarning() {

const timeUntilExpiration = computed(() => {
try {
const refreshToken = userStore.refreshToken;
const refreshToken = authStore.refreshToken;
if (!refreshToken) return null;

const decoded = jwtDecode<JwtPayload>(refreshToken);
Expand All @@ -55,9 +55,9 @@ export function useSessionWarning() {

try {
isReauthenticating.value = true;
await userStore.login();
await authStore.login();
} catch (error) {
userStore.logout();
authStore.logout();
throw error;
} finally {
isReauthenticating.value = false;
Expand Down
16 changes: 8 additions & 8 deletions src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
type RouteLocationNormalized,
} from 'vue-router';

import { useUserStore } from '@/stores/UserStore';
import { useAuthStore } from '@/stores/AuthStore';
import { useSettingsStore } from '@/stores/SettingsStore';
import { notifyApiKeyUnset } from '@/services/ApiKeyService';
import FlawCreateView from '@/views/FlawCreateView.vue';
Expand Down Expand Up @@ -79,8 +79,8 @@ export const routes = [
hideNavbar: true,
},
beforeEnter() {
const userStore = useUserStore();
if (userStore.isAuthenticated) {
const authStore = useAuthStore();
if (authStore.isAuthenticated) {
return { name: 'index' };
}
},
Expand Down Expand Up @@ -155,14 +155,14 @@ router.beforeEach(async (to, from) => {

// await workerReady;

const userStore = useUserStore();
const isAuthenticated = userStore.isAuthenticated;
const authStore = useAuthStore();
const isAuthenticated = authStore.isAuthenticated;

const { canVisitWithoutAuth } = to.meta;
const manualLocationNavigation = from.name === undefined;

if (
userStore.isLoggedIn
authStore.isLoggedIn
&& to.name !== 'logout'
&& to.name !== 'login'
) {
Expand All @@ -176,12 +176,12 @@ router.beforeEach(async (to, from) => {

if (!canVisitWithoutAuth && !isAuthenticated) {
// If user is logged in but token is expired/missing, try to refresh first
if (userStore.isLoggedIn) {
if (authStore.isLoggedIn) {
try {
console.debug('Router: Attempting token refresh for authenticated user');
await getNextAccessToken();
// If refresh succeeds, continue with navigation
if (userStore.isAuthenticated) {
if (authStore.isAuthenticated) {
return;
}
} catch (error) {
Expand Down
19 changes: 9 additions & 10 deletions src/services/OsidbAuthService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { z } from 'zod';

import { osimRuntime } from '@/stores/osimRuntime';
import { useToastStore } from '@/stores/ToastStore';

import { useUserStore } from '../stores/UserStore';
import { useAuthStore } from '@/stores/AuthStore';

const RefreshResponse = z.object({
access: z.string(),
Expand Down Expand Up @@ -133,16 +132,16 @@ export async function getNextAccessToken(forceRefresh: boolean = false) {
// Moving this to module scope results in "cannot access before initialization" -
// probably a vite or typescript bug
const url = `${osimRuntime.value.backends.osidb}/auth/token/refresh`;
const userStore = useUserStore();
const authStore = useAuthStore();
let response;
if (!forceRefresh && userStore.accessToken && !userStore.isAccessTokenExpired()) {
return userStore.accessToken;
if (!forceRefresh && authStore.accessToken && !authStore.isAccessTokenExpired()) {
return authStore.accessToken;
}

try {
if (osimRuntime.value.env === 'dev') {
// For local development: Use POST with refresh token from localStorage
const refreshToken = userStore.getDevRefreshToken();
const refreshToken = authStore.getDevRefreshToken();
if (!refreshToken) {
throw new Error('No refresh token available in localStorage for dev environment');
}
Expand Down Expand Up @@ -173,18 +172,18 @@ export async function getNextAccessToken(forceRefresh: boolean = false) {
const parsedResponse = RefreshResponse.parse(responseData);

// Update the access token in the store
userStore.accessToken = parsedResponse.access;
userStore.isLoggedIn = true;
authStore.accessToken = parsedResponse.access;
authStore.isLoggedIn = true;

// For dev environments, update the refresh token if provided
if (osimRuntime.value.env === 'dev' && parsedResponse.refresh) {
userStore.setDevRefreshToken(parsedResponse.refresh);
authStore.setDevRefreshToken(parsedResponse.refresh);
}

return parsedResponse.access;
} catch (e) {
console.error('OsidbAuthService::getNextAccessToken() Error refreshing access token', e);
return userStore.logout()
return authStore.logout()
.finally(() => {
throw new Error('Unable to refresh access token');
});
Expand Down
10 changes: 5 additions & 5 deletions src/services/__tests__/OsidbAuthService.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { http, HttpResponse } from 'msw';
import { createPinia, setActivePinia } from 'pinia';
import { DateTime } from 'luxon';

import { useUserStore } from '@/stores/UserStore';
import { useAuthStore } from '@/stores/AuthStore';
import { encodeJWT } from '@/__tests__/helpers';
import { server } from '@/__tests__/setup';

Expand Down Expand Up @@ -52,8 +52,8 @@ describe('osidbAuthService', () => {
jti: '1111',
user_id: 1337,
});
const userStore = useUserStore();
userStore.accessToken = accessToken;
const authStore = useAuthStore();
authStore.accessToken = accessToken;

const token = await getNextAccessToken();

Expand All @@ -68,8 +68,8 @@ describe('osidbAuthService', () => {
jti: '0000',
user_id: 1337,
});
const userStore = useUserStore();
userStore.accessToken = expiredAccessJWT;
const authStore = useAuthStore();
authStore.accessToken = expiredAccessJWT;

vi.advanceTimersByTime(4 * 60 * 1000);
const token = await getNextAccessToken();
Expand Down
Loading