mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
fix(isa-app-store, core-storage): prevent caching of erroneous user state
Remove shareReplay(1) operator from user state observable to ensure fresh state retrieval on each request. This prevents the system from retaining and reusing failed or invalid state data across multiple operations. The current implementation now makes two API calls (GET + POST) per set operation to guarantee the latest state is always used, trading performance for reliability in error scenarios. Refs: #5270, #5249
This commit is contained in:
@@ -36,7 +36,10 @@ export class RootStateService {
|
||||
|
||||
async init() {
|
||||
await this.load();
|
||||
this._store.dispatch({ type: 'HYDRATE', payload: RootStateService.LoadFromLocalStorage() });
|
||||
this._store.dispatch({
|
||||
type: 'HYDRATE',
|
||||
payload: RootStateService.LoadFromLocalStorage(),
|
||||
});
|
||||
this.initSave();
|
||||
}
|
||||
|
||||
@@ -53,11 +56,7 @@ export class RootStateService {
|
||||
sub: this._authService.getClaimByKey('sub'),
|
||||
};
|
||||
RootStateService.SaveToLocalStorageRaw(JSON.stringify(data));
|
||||
return this.#storage.set('state', {
|
||||
...state,
|
||||
version: packageInfo.version,
|
||||
sub: this._authService.getClaimByKey('sub'),
|
||||
});
|
||||
return this.#storage.set('state', data);
|
||||
}),
|
||||
)
|
||||
.subscribe();
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { StorageProvider } from './storage-provider';
|
||||
import { UserStateService } from '@generated/swagger/isa-api';
|
||||
import { firstValueFrom, map, shareReplay } from 'rxjs';
|
||||
import { catchError, firstValueFrom, map, of } from 'rxjs';
|
||||
import { isEmpty } from 'lodash';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class UserStorageProvider implements StorageProvider {
|
||||
@@ -9,19 +10,33 @@ export class UserStorageProvider implements StorageProvider {
|
||||
|
||||
private state$ = this.#userStateService.UserStateGetUserState().pipe(
|
||||
map((res) => {
|
||||
if (res.result?.content) {
|
||||
if (res?.result?.content) {
|
||||
return JSON.parse(res.result.content);
|
||||
}
|
||||
return {};
|
||||
}),
|
||||
shareReplay(1),
|
||||
catchError((err) => {
|
||||
console.warn(
|
||||
'No UserStateGetUserState found, returning empty object:',
|
||||
err,
|
||||
);
|
||||
return of({}); // Return empty state fallback
|
||||
}),
|
||||
// shareReplay(1), #5249, #5270 Würde beim Fehlerfall den fehlerhaften Zustand behalten
|
||||
// Aktuell wird nun jedes mal 2 mal der UserState aufgerufen (GET + POST)
|
||||
// Damit bei der set Funktion immer der aktuelle Zustand verwendet wird
|
||||
);
|
||||
|
||||
async set(key: string, value: unknown): Promise<void> {
|
||||
async set(key: string, value: Record<string, unknown>): Promise<void> {
|
||||
const current = await firstValueFrom(this.state$);
|
||||
firstValueFrom(
|
||||
const content =
|
||||
current && !isEmpty(current)
|
||||
? { ...current, [key]: value }
|
||||
: { [key]: value };
|
||||
|
||||
await firstValueFrom(
|
||||
this.#userStateService.UserStateSetUserState({
|
||||
content: JSON.stringify({ ...current, [key]: value }),
|
||||
content: JSON.stringify(content),
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -32,7 +47,6 @@ export class UserStorageProvider implements StorageProvider {
|
||||
}
|
||||
|
||||
async clear(key: string): Promise<void> {
|
||||
|
||||
const current = await firstValueFrom(this.state$);
|
||||
delete current[key];
|
||||
firstValueFrom(this.#userStateService.UserStateResetUserState());
|
||||
|
||||
Reference in New Issue
Block a user