Skip to content

Commit 32d29f8

Browse files
authored
Saksbehandler innlogget + autentisering for nye javascript klienter (#7965)
* Introduserer InnloggetAnsattContext og RootSuspense. InnloggetAnsattContext er ein global context som blir initialisert av InnloggetAnsattProvider i AppConfigResolver. Den er ein erstatning for bruken av restApiHooks.useGlobalStateRestApiData(K9sakApiKeys.NAV_ANSATT), og returnerer samme data som det kallet. Med InnloggetAnsattContext har vi ein måte å få info om innlogga saksbehandler uavhengig av om ein er i k9 eller ung. Innfører her også bruk av Suspense med RootSuspense. Det er tenkt at anna innhenting av data på toppnivå, feks kodeverkoppslag, featuretoggles og liknande også skal bruke denne på sikt. * AuthFixApi og relatert kode som kan køyre autentiseringsflyt for backends. For å (re-)autentisere for kommunikasjon med servere via popup som køyre redirect til innlogging når det trengs legger vi til AuthFixApi og kode som implementerer dette. Dette skal brukast i request og response interceptor for genererte typescript klienter, slik at dei mest mulig automatisk og transparent for bruker kan autentisere klienten for kommunikasjon med server. * Modernisering av app bootstrapping. Ta i bruk AuthFixApi i genererte klienter slik at autentiseringsfeil blir fiksa. Bruk layouts i react router oppsett for felles grunnleggande oppsettskode. Legg til RootLayout med øverste ErrorBoundary, RootSuspense og andre fellestjenester for grunnleggande app initialisering både for k9 og ung. Dette oppsett muliggjer bruk av useSuspenseQuery, så ein kan sleppe å manuelt sjekke om data er lasta eller om forespørsel feila over alt i applikasjonskoden. Tek i bruk dette for å forenkle henting av grunnleggande systemdata som innlogget ansatt og kodeverkoppslag. * Krympa og tydleggjort AuthFixApi litt. * Storybook test fix. * Aktiver prefetch av innlogget ansatt. Så InnloggetAnsattProvider har data tilgjengeleg raskast mulig. * Litt betre typing. * Fjern unødvendig promise handtering. Trengs ikkje lenger etter at api vart endra. * Fiks manglande /
1 parent ce4e29c commit 32d29f8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1686
-293
lines changed

loosely-type-checked-files.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,6 @@
339339
"packages/rest-api/src/requestApi/error/RequestErrorEventHandler.ts",
340340
"packages/rest-api/src/requestApi/requestApi.spec.ts",
341341
"packages/rest-api/src/requestApi/requestRunner.spec.ts",
342-
"packages/sak-app/src/app/components/Dekorator.tsx",
343342
"packages/sak-app/src/app/useTrackRouteParam.tsx",
344343
"packages/sak-app/src/behandling/BehandlingEventHandler.ts",
345344
"packages/sak-app/src/behandling/BehandlingIndex.tsx",
@@ -381,7 +380,6 @@
381380
"packages/tidslinje/src/Timeline.tsx",
382381
"packages/tidslinje/src/components/pleiepenger/Tidslinje.spec.tsx",
383382
"packages/tidslinje/src/components/pleiepenger/Tidslinje.tsx",
384-
"packages/ung/sak-app/app/components/Dekorator.tsx",
385383
"packages/ung/sak-app/app/useTrackRouteParam.tsx",
386384
"packages/ung/sak-app/behandling/BehandlingEventHandler.ts",
387385
"packages/ung/sak-app/behandling/BehandlingIndex.tsx",

packages/sak-app/src/app/AppConfigResolver.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import { useK9Kodeverkoppslag } from '@k9-sak-web/gui/kodeverk/oppslag/useK9Kode
1313
import { K9KodeverkoppslagContext } from '@k9-sak-web/gui/kodeverk/oppslag/K9KodeverkoppslagContext.jsx';
1414
import useGetEnabledApplikasjonContext from './useGetEnabledApplikasjonContext';
1515
import ApplicationContextPath from './ApplicationContextPath';
16+
import { InnloggetAnsattProvider } from '@k9-sak-web/gui/saksbehandler/InnloggetAnsattProvider.js';
17+
import { K9SakInnloggetAnsattBackendClient } from '@k9-sak-web/gui/saksbehandler/K9SakInnloggetAnsattBackendClient.js';
1618

1719
interface OwnProps {
1820
children: ReactElement<any>;
@@ -56,13 +58,14 @@ const AppConfigResolver = ({ children }: OwnProps) => {
5658
harHentetFerdigKodeverk &&
5759
navAnsattState === RestApiState.SUCCESS &&
5860
sprakFilState === RestApiState.SUCCESS &&
59-
!k9KodeverkOppslag.isPending &&
6061
!!featureToggles; // <- sjekker at feature toggles er lasta
6162

6263
return (
6364
<FeatureTogglesContext.Provider value={featureToggles ?? prodFeatureToggles}>
6465
<K9KodeverkoppslagContext value={k9KodeverkOppslag}>
65-
{harFeilet || erFerdig ? children : <LoadingPanel />}
66+
<InnloggetAnsattProvider api={new K9SakInnloggetAnsattBackendClient()}>
67+
{harFeilet || erFerdig ? children : <LoadingPanel />}
68+
</InnloggetAnsattProvider>
6669
</K9KodeverkoppslagContext>
6770
</FeatureTogglesContext.Provider>
6871
);

packages/sak-app/src/app/AppIndex.tsx

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useLocation } from 'react-router';
44

55
import { parseQueryString } from '@fpsak-frontend/utils';
66
import ForbiddenPage from '@k9-sak-web/gui/app/feilmeldinger/ForbiddenPage.js';
7-
import UnauthorizedPage from '@k9-sak-web/gui/app/feilmeldinger/UnauthorizedPage.js';
7+
import UnauthorizedPage, { k9LoginResourcePath } from '@k9-sak-web/gui/app/feilmeldinger/UnauthorizedPage.js';
88
import { useRestApiError, useRestApiErrorDispatcher } from '@k9-sak-web/rest-api-hooks';
99
import EventType from '@k9-sak-web/rest-api/src/requestApi/eventType';
1010
import { NavAnsatt } from '@k9-sak-web/types';
@@ -18,29 +18,24 @@ import Home from './components/Home';
1818

1919
import '@fpsak-frontend/assets/styles/global.css';
2020
import '@navikt/ds-css/darkside';
21-
import { Theme } from '@navikt/ds-react/Theme';
2221
import '@navikt/ft-fakta-beregning/dist/style.css';
2322
import '@navikt/ft-form-hooks/dist/style.css';
2423
import '@navikt/ft-plattform-komponenter/dist/style.css';
2524
import '@navikt/ft-prosess-beregningsgrunnlag/dist/style.css';
2625
import '@navikt/ft-ui-komponenter/dist/style.css';
27-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
26+
import { RootSuspense } from '@k9-sak-web/gui/app/root/suspense/RootSuspense.js';
27+
import { usePrefetchQuery } from '@tanstack/react-query';
28+
import { kodeverkOppslagQueryOptions } from '@k9-sak-web/gui/kodeverk/oppslag/useK9Kodeverkoppslag.js';
29+
import { innloggetAnsattQueryOptions } from '@k9-sak-web/gui/saksbehandler/InnloggetAnsattProvider.js';
30+
import { K9SakInnloggetAnsattBackendClient } from '@k9-sak-web/gui/saksbehandler/K9SakInnloggetAnsattBackendClient.js';
2831

2932
const EMPTY_ARRAY = [];
3033

31-
const queryClient = new QueryClient({
32-
defaultOptions: {
33-
queries: {
34-
refetchOnWindowFocus: false,
35-
},
36-
},
37-
});
38-
3934
/**
4035
* AppIndex
4136
*
42-
* Container komponent. Dette er toppkomponenten i applikasjonen. Denne vil rendre header
43-
* og home-komponentene. Home-komponenten vil rendre barn-komponenter via ruter.
37+
* Container komponent. Dette er toppkomponenten i den ytelsespesifikke applikasjonen (felles RootLayout er over her).
38+
* Denne vil rendre header og home-komponentene. Home-komponenten vil rendre barn-komponenter via ruter.
4439
*/
4540
const AppIndex = () => {
4641
const location = useLocation();
@@ -79,30 +74,32 @@ const AppIndex = () => {
7974
const hasForbiddenOrUnauthorizedErrors = forbiddenErrors.length > 0 || unauthorizedErrors.length > 0;
8075
const shouldRenderHome = !hasCrashed && !hasForbiddenOrUnauthorizedErrors;
8176

77+
// Start forhåndslasting av kodeverk oppslag data
78+
usePrefetchQuery(kodeverkOppslagQueryOptions.k9sak);
79+
usePrefetchQuery(kodeverkOppslagQueryOptions.k9tilbake(true));
80+
usePrefetchQuery(kodeverkOppslagQueryOptions.k9klage(true));
81+
// Start forhåndslasting av nav ansatt data
82+
usePrefetchQuery(innloggetAnsattQueryOptions(new K9SakInnloggetAnsattBackendClient()));
83+
84+
// Sjå bootstrap for å sjå kva som er lenger oppe i hierarkiet.
8285
return (
83-
// Ytterste feilgrense viser alltid separat feil-side, fordi viss feil har skjedd i AppConfigResolver eller lenger ute
84-
// er det sannsynlegvis så grunnleggande at ingenting vil fungere.
85-
<ErrorBoundary>
86-
<Theme theme="light">
87-
<QueryClientProvider client={queryClient}>
88-
<AppConfigResolver>
89-
<ErrorBoundary errorMessageCallback={addErrorMessageAndSetAsCrashed} doNotShowErrorPage>
90-
<LanguageProvider>
91-
<Dekorator
92-
hideErrorMessages={hasForbiddenOrUnauthorizedErrors}
93-
queryStrings={queryStrings}
94-
setSiteHeight={setSiteHeight}
95-
pathname={location.pathname}
96-
/>
97-
{shouldRenderHome && <Home headerHeight={headerHeight} />}
98-
{forbiddenErrors.length > 0 && <ForbiddenPage />}
99-
{unauthorizedErrors.length > 0 && <UnauthorizedPage />}
100-
</LanguageProvider>
101-
</ErrorBoundary>
102-
</AppConfigResolver>
103-
</QueryClientProvider>
104-
</Theme>
105-
</ErrorBoundary>
86+
<RootSuspense heading="Laster grunnleggende systemdata">
87+
<AppConfigResolver>
88+
<ErrorBoundary errorMessageCallback={addErrorMessageAndSetAsCrashed} doNotShowErrorPage>
89+
<LanguageProvider>
90+
<Dekorator
91+
hideErrorMessages={hasForbiddenOrUnauthorizedErrors}
92+
queryStrings={queryStrings}
93+
setSiteHeight={setSiteHeight}
94+
pathname={location.pathname}
95+
/>
96+
{shouldRenderHome && <Home headerHeight={headerHeight} />}
97+
{forbiddenErrors.length > 0 && <ForbiddenPage />}
98+
{unauthorizedErrors.length > 0 && <UnauthorizedPage loginUrl={k9LoginResourcePath} />}
99+
</LanguageProvider>
100+
</ErrorBoundary>
101+
</AppConfigResolver>
102+
</RootSuspense>
106103
);
107104
};
108105

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { RestApiErrorProvider, RestApiProvider } from '@k9-sak-web/rest-api-hooks';
2+
import { Outlet } from 'react-router';
3+
4+
/** Denne brukast på tvers av k9 og ung for å tilby globale data frå legacy rest api mekanisme til rutene som treng det */
5+
export const RestApiProviderLayout = () => {
6+
return (
7+
<RestApiProvider>
8+
<RestApiErrorProvider>
9+
<Outlet />
10+
</RestApiErrorProvider>
11+
</RestApiProvider>
12+
);
13+
};

packages/sak-app/src/app/components/Dekorator.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ import { Feilmelding } from '@k9-sak-web/gui/sak/dekoratør/feilmeldingTsType.js
22
import HeaderWithErrorPanel from '@k9-sak-web/gui/sak/dekoratør/HeaderWithErrorPanel.js';
33
import { AAREG_URL, AINNTEKT_URL } from '@k9-sak-web/konstanter';
44
import { useRestApiError, useRestApiErrorDispatcher } from '@k9-sak-web/rest-api-hooks';
5-
import { NavAnsatt } from '@k9-sak-web/types';
6-
import { useMemo } from 'react';
5+
import { use, useMemo } from 'react';
76
import { injectIntl, IntlShape, WrappedComponentProps } from 'react-intl';
8-
import { K9sakApiKeys, restApiHooks } from '../../data/k9sakApi';
97
import ErrorFormatter from '../feilhandtering/ErrorFormatter';
108
import ErrorMessage from '../feilhandtering/ErrorMessage';
119
import { getPathToK9Los, getPathToK9Punsj } from '../paths';
10+
import { InnloggetAnsattContext } from '@k9-sak-web/gui/saksbehandler/InnloggetAnsattContext.js';
1211

1312
type QueryStrings = {
1413
errorcode?: string;
@@ -59,7 +58,7 @@ const Dekorator = ({
5958
pathname,
6059
hideErrorMessages = false,
6160
}: OwnProps & WrappedComponentProps) => {
62-
const navAnsatt = restApiHooks.useGlobalStateRestApiData<NavAnsatt>(K9sakApiKeys.NAV_ANSATT);
61+
const navAnsatt = use(InnloggetAnsattContext);
6362
const fagsakFraUrl = pathname.split('/fagsak/')[1]?.split('/')[0];
6463
const isFagsakFraUrlValid = fagsakFraUrl?.match(/^[a-zA-Z0-9]{1,19}$/);
6564

packages/sak-app/src/bootstrap.tsx

Lines changed: 52 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1-
/* eslint-disable @typescript-eslint/no-var-requires */
2-
import { RestApiErrorProvider, RestApiProvider } from '@k9-sak-web/rest-api-hooks';
31
import { init } from '@sentry/browser';
42
import * as Sentry from '@sentry/react';
53
import React from 'react';
64
import { createRoot } from 'react-dom/client';
75
import { Provider } from 'react-redux';
8-
import { BrowserRouter, createRoutesFromChildren, matchRoutes, useLocation, useNavigationType } from 'react-router';
6+
import {
7+
BrowserRouter,
8+
createRoutesFromChildren,
9+
matchRoutes,
10+
Route,
11+
Routes,
12+
useLocation,
13+
useNavigationType,
14+
} from 'react-router';
915

1016
import { ExtendedApiError } from '@k9-sak-web/backend/shared/errorhandling/ExtendedApiError.js';
11-
import AppIndex from './app/AppIndex';
1217
import configureStore from './configureStore';
1318
import { IS_DEV, VITE_SENTRY_RELEASE } from './constants';
1419

@@ -17,6 +22,12 @@ import { AxiosError } from 'axios';
1722
import { configureK9KlageClient } from '@k9-sak-web/backend/k9klage/configureK9KlageClient.js';
1823
import { configureK9SakClient } from '@k9-sak-web/backend/k9sak/configureK9SakClient.js';
1924
import { configureK9TilbakeClient } from '@k9-sak-web/backend/k9tilbake/configureK9TilbakeClient.js';
25+
import { RootLayout } from '@k9-sak-web/gui/app/root/RootLayout.js';
26+
import { AuthRedirectDoneWindow, authRedirectDoneWindowPath } from '@k9-sak-web/gui/app/auth/AuthRedirectDoneWindow.js';
27+
import AppIndex from './app/AppIndex';
28+
import { RestApiProviderLayout } from './app/RestApiProviderLayout.js';
29+
import { AuthFixer } from '@k9-sak-web/gui/app/auth/AuthFixer.js';
30+
import { sequentialAuthFixerSetup } from '@k9-sak-web/gui/app/auth/ThisOrOtherAuthFixer.js';
2031

2132
/* eslint no-undef: "error" */
2233
const isDevelopment = IS_DEV;
@@ -77,13 +88,22 @@ init({
7788
},
7889
});
7990

80-
configureK9SakClient();
81-
configureK9KlageClient();
82-
configureK9TilbakeClient();
91+
const basePath = '/k9/web';
92+
93+
const [sakAuthFixer, klageAuthFixer, tilbakeAuthFixer] = sequentialAuthFixerSetup(
94+
new AuthFixer(`${basePath}${authRedirectDoneWindowPath}`),
95+
new AuthFixer(`${basePath}${authRedirectDoneWindowPath}`),
96+
new AuthFixer(`${basePath}${authRedirectDoneWindowPath}`),
97+
);
98+
configureK9SakClient(sakAuthFixer);
99+
configureK9KlageClient(klageAuthFixer);
100+
configureK9TilbakeClient(tilbakeAuthFixer);
83101

84102
const store = configureStore();
85103

86-
const renderFunc = async Component => {
104+
const SentryRoutes = Sentry.withSentryReactRouterV6Routing(Routes);
105+
106+
const renderFunc = () => {
87107
/**
88108
* Redirecte til riktig basename om man kommer hit uten
89109
* Vil kunne forekomme lokalt og i tester
@@ -105,19 +125,29 @@ const renderFunc = async Component => {
105125
}
106126
};
107127

108-
await prepare();
109-
const root = createRoot(app);
110-
root.render(
111-
<Provider store={store}>
112-
<BrowserRouter basename="/k9/web">
113-
<RestApiProvider>
114-
<RestApiErrorProvider>
115-
<Component />
116-
</RestApiErrorProvider>
117-
</RestApiProvider>
118-
</BrowserRouter>
119-
</Provider>,
120-
);
128+
const run = () => {
129+
const root = createRoot(app);
130+
root.render(
131+
<Provider store={store}>
132+
<BrowserRouter basename={basePath}>
133+
<SentryRoutes>
134+
<Route element={<RootLayout />}>
135+
<Route path={authRedirectDoneWindowPath} element={<AuthRedirectDoneWindow />} />
136+
<Route element={<RestApiProviderLayout />}>
137+
<Route path="*" element={<AppIndex />} />
138+
</Route>
139+
</Route>
140+
</SentryRoutes>
141+
</BrowserRouter>
142+
</Provider>,
143+
);
144+
};
145+
prepare()
146+
.then(run)
147+
.catch(err => {
148+
console.error(`bootstrap prepare failed, will start running anyways`, err);
149+
run();
150+
});
121151
};
122152

123-
void renderFunc(AppIndex);
153+
renderFunc();

packages/ung/sak-app/app/AppConfigResolver.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { useFeatureToggles } from '@k9-sak-web/gui/featuretoggles/useFeatureTogg
99
import { UngSakApiKeys, requestApi, restApiHooks } from '../data/ungsakApi';
1010
import useHentInitLenker from './useHentInitLenker';
1111
import useHentKodeverk from './useHentKodeverk';
12+
import { InnloggetAnsattProvider } from '@k9-sak-web/gui/saksbehandler/InnloggetAnsattProvider.js';
13+
import { UngSakInnloggetAnsattBackendClient } from '@k9-sak-web/gui/saksbehandler/UngSakInnloggetAnsattBackendClient.js';
1214

1315
interface OwnProps {
1416
children: ReactElement<any>;
@@ -50,7 +52,9 @@ const AppConfigResolver = ({ children }: OwnProps) => {
5052

5153
return (
5254
<FeatureTogglesContext.Provider value={featureToggles ?? qFeatureToggles}>
53-
{harFeilet || erFerdig ? children : <LoadingPanel />}
55+
<InnloggetAnsattProvider api={new UngSakInnloggetAnsattBackendClient()}>
56+
{harFeilet || erFerdig ? children : <LoadingPanel />}
57+
</InnloggetAnsattProvider>
5458
</FeatureTogglesContext.Provider>
5559
);
5660
};

0 commit comments

Comments
 (0)