aktueller stand
This commit is contained in:
@@ -13,13 +13,15 @@ const client = axios.create({
|
||||
});
|
||||
|
||||
client.interceptors.request.use((config) => {
|
||||
config.metadata = { startedAt: Date.now() };
|
||||
const metadata = config.metadata && typeof config.metadata === 'object' ? config.metadata : {};
|
||||
config.metadata = { ...metadata, startedAt: Date.now() };
|
||||
return config;
|
||||
});
|
||||
|
||||
client.interceptors.response.use(
|
||||
(response) => {
|
||||
const startedAt = response?.config?.metadata?.startedAt || Date.now();
|
||||
const metadata = response?.config?.metadata || {};
|
||||
try {
|
||||
requestLogStore.add({
|
||||
direction: 'outgoing',
|
||||
@@ -28,6 +30,9 @@ client.interceptors.response.use(
|
||||
path: response.config?.url || '',
|
||||
status: response.status,
|
||||
durationMs: Date.now() - startedAt,
|
||||
sessionId: metadata.sessionId ?? null,
|
||||
profileId: metadata.profileId ?? null,
|
||||
profileName: metadata.profileName ?? null,
|
||||
responseBody: response.data
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -37,6 +42,7 @@ client.interceptors.response.use(
|
||||
},
|
||||
(error) => {
|
||||
const startedAt = error?.config?.metadata?.startedAt || Date.now();
|
||||
const metadata = error?.config?.metadata || {};
|
||||
try {
|
||||
requestLogStore.add({
|
||||
direction: 'outgoing',
|
||||
@@ -45,6 +51,9 @@ client.interceptors.response.use(
|
||||
path: error.config?.url || '',
|
||||
status: error?.response?.status || null,
|
||||
durationMs: Date.now() - startedAt,
|
||||
sessionId: metadata.sessionId ?? null,
|
||||
profileId: metadata.profileId ?? null,
|
||||
profileName: metadata.profileName ?? null,
|
||||
error: error?.message || 'Unbekannter Fehler',
|
||||
responseBody: error?.response?.data
|
||||
});
|
||||
@@ -55,7 +64,7 @@ client.interceptors.response.use(
|
||||
}
|
||||
);
|
||||
|
||||
const CSRF_COOKIE_NAMES = ['CSRF_TOKEN', 'CSRF-TOKEN', 'XSRF-TOKEN', 'XSRF_TOKEN'];
|
||||
const CSRF_COOKIE_NAMES = ['FS_CSRF_TOKEN', 'CSRF_TOKEN', 'CSRF-TOKEN', 'XSRF-TOKEN', 'XSRF_TOKEN'];
|
||||
|
||||
function extractCookieValue(cookies = [], name) {
|
||||
if (!Array.isArray(cookies) || !name) {
|
||||
@@ -114,10 +123,46 @@ function buildHeaders(cookieHeader, csrfToken) {
|
||||
return headers;
|
||||
}
|
||||
|
||||
async function getCurrentUserDetails(cookieHeader) {
|
||||
const response = await client.get('/api/user/current/details', {
|
||||
headers: buildHeaders(cookieHeader)
|
||||
});
|
||||
function buildRequestMetadata(context) {
|
||||
if (!context) {
|
||||
return {};
|
||||
}
|
||||
if (context.sessionId || context.profileId) {
|
||||
return {
|
||||
sessionId: context.sessionId ?? null,
|
||||
profileId: context.profileId ?? null,
|
||||
profileName: context.profileName ?? null
|
||||
};
|
||||
}
|
||||
if (context.id || context.profile?.id) {
|
||||
return {
|
||||
sessionId: context.id ?? null,
|
||||
profileId: context.profile?.id ?? null,
|
||||
profileName: context.profile?.name ?? null
|
||||
};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
function buildRequestConfig({ cookieHeader, csrfToken, context, params } = {}) {
|
||||
const metadata = buildRequestMetadata(context);
|
||||
const config = {
|
||||
headers: buildHeaders(cookieHeader, csrfToken)
|
||||
};
|
||||
if (Object.keys(metadata).length > 0) {
|
||||
config.metadata = metadata;
|
||||
}
|
||||
if (params) {
|
||||
config.params = params;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
async function getCurrentUserDetails(cookieHeader, context) {
|
||||
const response = await client.get(
|
||||
'/api/user/current/details',
|
||||
buildRequestConfig({ cookieHeader, context })
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
@@ -165,9 +210,9 @@ async function login(email, password) {
|
||||
};
|
||||
}
|
||||
|
||||
async function fetchProfile(cookieHeader, { throwOnError = false } = {}) {
|
||||
async function fetchProfile(cookieHeader, { throwOnError = false } = {}, context) {
|
||||
try {
|
||||
return await getCurrentUserDetails(cookieHeader);
|
||||
return await getCurrentUserDetails(cookieHeader, context);
|
||||
} catch (error) {
|
||||
if (throwOnError) {
|
||||
throw error;
|
||||
@@ -181,7 +226,7 @@ function wait(ms = 0) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
async function fetchStores(cookieHeader, profileId, options = {}) {
|
||||
async function fetchStores(cookieHeader, profileId, options = {}, context) {
|
||||
if (!profileId) {
|
||||
return [];
|
||||
}
|
||||
@@ -193,10 +238,10 @@ async function fetchStores(cookieHeader, profileId, options = {}) {
|
||||
? options.onStoreCheck
|
||||
: null;
|
||||
try {
|
||||
const response = await client.get(`/api/user/${profileId}/stores`, {
|
||||
headers: buildHeaders(cookieHeader),
|
||||
params: { activeStores: 1 }
|
||||
});
|
||||
const response = await client.get(
|
||||
`/api/user/${profileId}/stores`,
|
||||
buildRequestConfig({ cookieHeader, params: { activeStores: 1 }, context })
|
||||
);
|
||||
const stores = Array.isArray(response.data) ? response.data : [];
|
||||
const normalized = stores.map((store) => ({
|
||||
id: String(store.id),
|
||||
@@ -209,14 +254,26 @@ async function fetchStores(cookieHeader, profileId, options = {}) {
|
||||
zip: store.zip || ''
|
||||
}));
|
||||
|
||||
return annotateStoresWithPickupSlots(normalized, cookieHeader, delayBetweenRequestsMs, onStoreCheck);
|
||||
return annotateStoresWithPickupSlots(
|
||||
normalized,
|
||||
cookieHeader,
|
||||
delayBetweenRequestsMs,
|
||||
onStoreCheck,
|
||||
context
|
||||
);
|
||||
} catch (error) {
|
||||
console.warn('Stores konnten nicht geladen werden:', error.message);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async function annotateStoresWithPickupSlots(stores, cookieHeader, delayBetweenRequestsMs = 0, onStoreCheck) {
|
||||
async function annotateStoresWithPickupSlots(
|
||||
stores,
|
||||
cookieHeader,
|
||||
delayBetweenRequestsMs = 0,
|
||||
onStoreCheck,
|
||||
context
|
||||
) {
|
||||
if (!Array.isArray(stores) || stores.length === 0) {
|
||||
return [];
|
||||
}
|
||||
@@ -238,7 +295,7 @@ async function annotateStoresWithPickupSlots(stores, cookieHeader, delayBetweenR
|
||||
}
|
||||
let hasPickupSlots = null;
|
||||
try {
|
||||
const pickups = await fetchPickups(store.id, cookieHeader);
|
||||
const pickups = await fetchPickups(store.id, cookieHeader, context);
|
||||
hasPickupSlots = Array.isArray(pickups) && pickups.length > 0;
|
||||
} catch (error) {
|
||||
const status = error?.response?.status;
|
||||
@@ -255,50 +312,59 @@ async function annotateStoresWithPickupSlots(stores, cookieHeader, delayBetweenR
|
||||
return annotated;
|
||||
}
|
||||
|
||||
async function fetchPickups(storeId, cookieHeader) {
|
||||
const response = await client.get(`/api/stores/${storeId}/pickups`, {
|
||||
headers: buildHeaders(cookieHeader)
|
||||
});
|
||||
async function fetchPickups(storeId, cookieHeader, context) {
|
||||
const response = await client.get(
|
||||
`/api/stores/${storeId}/pickups`,
|
||||
buildRequestConfig({ cookieHeader, context })
|
||||
);
|
||||
return response.data?.pickups || [];
|
||||
}
|
||||
|
||||
async function fetchRegionStores(regionId, cookieHeader) {
|
||||
async function fetchRegionStores(regionId, cookieHeader, context) {
|
||||
if (!regionId) {
|
||||
return { total: 0, stores: [] };
|
||||
}
|
||||
const response = await client.get(`/api/region/${regionId}/stores`, {
|
||||
headers: buildHeaders(cookieHeader)
|
||||
});
|
||||
const response = await client.get(
|
||||
`/api/region/${regionId}/stores`,
|
||||
buildRequestConfig({ cookieHeader, context })
|
||||
);
|
||||
return {
|
||||
total: Number(response.data?.total) || 0,
|
||||
stores: Array.isArray(response.data?.stores) ? response.data.stores : []
|
||||
};
|
||||
}
|
||||
|
||||
async function fetchStoreDetails(storeId, cookieHeader) {
|
||||
async function fetchStoreDetails(storeId, cookieHeader, context) {
|
||||
if (!storeId) {
|
||||
return null;
|
||||
}
|
||||
const response = await client.get(`/api/map/stores/${storeId}`, {
|
||||
headers: buildHeaders(cookieHeader)
|
||||
});
|
||||
const response = await client.get(
|
||||
`/api/map/stores/${storeId}`,
|
||||
buildRequestConfig({ cookieHeader, context })
|
||||
);
|
||||
return response.data || null;
|
||||
}
|
||||
|
||||
async function pickupRuleCheck(storeId, utcDate, profileId, session) {
|
||||
const response = await client.get(`/api/stores/${storeId}/pickupRuleCheck/${utcDate}/${profileId}`, {
|
||||
headers: buildHeaders(session.cookieHeader, session.csrfToken)
|
||||
});
|
||||
const response = await client.get(
|
||||
`/api/stores/${storeId}/pickupRuleCheck/${utcDate}/${profileId}`,
|
||||
buildRequestConfig({
|
||||
cookieHeader: session.cookieHeader,
|
||||
csrfToken: session.csrfToken,
|
||||
context: session
|
||||
})
|
||||
);
|
||||
return response.data?.result === true;
|
||||
}
|
||||
|
||||
async function fetchStoreMembers(storeId, cookieHeader) {
|
||||
async function fetchStoreMembers(storeId, cookieHeader, context) {
|
||||
if (!storeId) {
|
||||
return [];
|
||||
}
|
||||
const response = await client.get(`/api/stores/${storeId}/member`, {
|
||||
headers: buildHeaders(cookieHeader)
|
||||
});
|
||||
const response = await client.get(
|
||||
`/api/stores/${storeId}/member`,
|
||||
buildRequestConfig({ cookieHeader, context })
|
||||
);
|
||||
return Array.isArray(response.data) ? response.data : [];
|
||||
}
|
||||
|
||||
@@ -307,7 +373,11 @@ async function bookSlot(storeId, utcDate, profileId, session) {
|
||||
`/api/stores/${storeId}/pickups/${utcDate}/${profileId}`,
|
||||
{},
|
||||
{
|
||||
headers: buildHeaders(session.cookieHeader, session.csrfToken)
|
||||
...buildRequestConfig({
|
||||
cookieHeader: session.cookieHeader,
|
||||
csrfToken: session.csrfToken,
|
||||
context: session
|
||||
})
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user