chore: remove user and session id from JS use cookie and withcredentials#101
chore: remove user and session id from JS use cookie and withcredentials#101sandragjacinto wants to merge 2 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR migrates the frontend away from persisting/passing userId and sessionId in JS (localStorage/headers/query params) toward cookie-based session handling by enabling credentialed requests (withCredentials / credentials: 'include') in the shared fetch utilities.
Changes:
- Rename
getAxios/postAxiostobaseGetAxios/basePostAxiosand enable credentialed requests; addbaseDeleteAxios. - Remove the user/session Pinia state and initialization logic; update bookmarks/auth flows to no longer require user/session IDs from JS.
- Adjust various stores/components to use the new fetch helpers; remove the workshop form link from the nav.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/views/MicroLearning.vue | Switch micro-learning fetch to baseGetAxios. |
| src/utils/metrics.ts | Use basePostAxios for metric event posting. |
| src/utils/fetch.ts | Introduce credentialed base Axios helpers; adjust bookmark APIs; add baseDeleteAxios; include credentials for streaming fetch. |
| src/utils/auth.ts | Replace user+session retrieval flow with a single /user/user_and_session call. |
| src/utils/tests/fetch.spec.ts | Update unit tests for renamed helpers and credentialed config. |
| src/stores/user.ts | Remove persisted userId/sessionId state and initialization method. |
| src/stores/tutor.ts | Swap tutor API calls to basePostAxios (incl. file upload). |
| src/stores/sources.ts | Swap corpus/metrics fetches to baseGetAxios. |
| src/stores/search.ts | Increase search nb_results parameter from 1 to 100. |
| src/stores/metrics.ts | Remove userId/workshop URL logic; keep click-tracking wrapper. |
| src/stores/chat.ts | Swap chat API calls to basePostAxios. |
| src/stores/bookmarks.ts | Remove dependency on useUserStore and call bookmark utils without userId. |
| src/components/nav/NavComponent.vue | Remove workshop form link and metrics store usage. |
| src/components/dropdowns/SubjectSelector.vue | Switch subject list fetch to baseGetAxios. |
| src/App.vue | Replace user-store initialization with getUserAndSession call on mount. |
| e2e/base.ts | Update bookmark route matching in Playwright network mocks. |
Comments suppressed due to low confidence (3)
src/stores/metrics.ts:16
if (await !getCampaignStatus())is logically incorrect:!getCampaignStatus()negates the Promise (always truthy) before awaiting, so the condition will never be true. This should await first and then negate (e.g.,if (!(await getCampaignStatus()))).
if (await !getCampaignStatus()) {
return;
src/stores/tutor.ts:121
- This call relies on passing a multipart/form-data header via the
configargument, butbasePostAxioscurrently replacesconfig.headerswith its own headers object. As a result the multipart header won’t be sent, which can break file upload handling on the backend. FixbasePostAxiosto merge headers (or adjust this call accordingly).
const resp = await basePostAxios(
`/tutor/files/content?lang=${syllabusLanguage.value}`,
formData,
{
headers: { 'content-type': 'multipart/form-data' }
}
);
src/stores/search.ts:46
- This changes
nb_resultsfrom 1 to 100, which can significantly increase payload size and latency for every search. If the UI only needs a small preview, keep this low or make it a configurable constant/pagination; otherwise please confirm the backend and UI are intended to handle 100 results here.
getSDGsFromQuery(searchInput.value),
getSearch(100, {
query: searchInput.value,
lang: languageFilters,
sdg_filter: sdgFilters,
corpora: sourcesFilters,
relevance_factor: RELEVANCE_FACTOR
})
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export const baseDeleteAxios = async (endpoint: string, config?: AxiosRequestConfig) => { | ||
| if (!API_BASE) throw new Error('API_BASE not defined'); | ||
|
|
There was a problem hiding this comment.
baseDeleteAxios is newly introduced but isn’t covered by unit tests (unlike baseGetAxios/basePostAxios). Adding a small vitest case for success + error paths would help prevent regressions in credentials/headers/status handling.
| await page.route('**/**/user/**', async (route) => { | ||
| const url = route.request().url(); | ||
| if (url.includes('user/user')) { | ||
| await route.fulfill({ status: 200, body: JSON.stringify({ user_id: 'fake_user_id' }) }); | ||
| } else if (url.includes('session')) { | ||
| await route.fulfill({ | ||
| status: 200, | ||
| body: JSON.stringify({ session_id: 'fake_session_id', referer: 'toto' }) | ||
| }); | ||
| } else if (url.includes('/:user_id/bookmarks?user_id=')) { | ||
| } else if (url.includes('/bookmarks')) { |
There was a problem hiding this comment.
The auth/session mock in this route handler still fulfills /user/user and /user/session responses, but App.vue now calls /user/user_and_session. As written, url.includes('user/user') will also match user_and_session and return a payload with user_id instead of the expected { message: ... }, likely breaking E2E. Update the mock to explicitly handle user_and_session and return the shape expected by getUserAndSession.
| const enhancedConfig = { | ||
| ...config, | ||
| withCredentials: true, | ||
| headers: { |
There was a problem hiding this comment.
basePostAxios overwrites any config.headers passed by callers (it sets headers to only X-API-Key). This breaks call sites that rely on custom headers (e.g., multipart upload in tutor store). Merge config.headers into the generated headers instead of replacing them.
| headers: { | |
| headers: { | |
| ...(config?.headers || {}), |
| if (!(response.status >= 200) && !(response.status <= 300)) { | ||
| throw new Error('Error deleting data'); | ||
| } |
There was a problem hiding this comment.
baseDeleteAxios has the same status-range bug as basePostAxios: if (!(status >= 200) && !(status <= 300)) will incorrectly accept 1xx responses. Use a standard 2xx check (status < 200 || status >= 300) to ensure errors are thrown consistently.
| const enhancedConfig = { | ||
| ...config, | ||
| withCredentials: true, | ||
| headers: { | ||
| 'X-API-Key': WL_API_KEY | ||
| } | ||
| }; |
There was a problem hiding this comment.
baseDeleteAxios also overwrites any caller-provided config.headers by replacing headers entirely. Merge config.headers with X-API-Key (and keep withCredentials) so per-call headers aren't dropped.
Description
Why?
How?
Screenshots (if appropriate):
Types of changes
Checklist: