Skip to content

Commit

Permalink
👽 Setter opp oasis for innsending av søknad og mellomlagring
Browse files Browse the repository at this point in the history
  • Loading branch information
mrbjoern committed Mar 13, 2024
1 parent 6106595 commit 77138d8
Show file tree
Hide file tree
Showing 10 changed files with 235 additions and 58 deletions.
22 changes: 22 additions & 0 deletions lib/utils/api/ErrorMedStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// TODO: Errorcode og developerMessage vil returneres fra innsending og oppslag etterhvert.
// Her må vi støtte begge deler parallelt i en periode.

export class ErrorMedStatus extends Error {
status: number;
developerMessage?: string;
errorCode?: string;
navCallId?: string;
constructor(
message: string,
status: number,
navCallId = '',
developerMessage = '',
errorCode = '',
) {
super(message);
this.status = status;
this.developerMessage = developerMessage;
this.errorCode = errorCode;
this.navCallId = navCallId;
}
}
86 changes: 86 additions & 0 deletions lib/utils/api/simpleTokenXProxy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { validateToken, requestOboToken, getToken } from '@navikt/oasis';
import { logError, logInfo } from '@navikt/aap-felles-utils';
import { randomUUID } from 'crypto';
import { IncomingMessage } from 'http';
import { ErrorMedStatus } from 'lib/utils/api/ErrorMedStatus';

export const getOnBefalfOfToken = async (
audience: string,
url: string,
req: IncomingMessage,
): Promise<string> => {
const token = getToken(req);
if (!token) {
logError(`Token for ${url} er undefined`);
throw new Error('Token for simpleTokenXProxy is undefined');
}

const validation = await validateToken(token);
if (!validation.ok) {
logError(`Token for ${url} validerte ikke`);
throw new Error('Token for simpleTokenXProxy didnt validate');
}

const onBehalfOf = await requestOboToken(token, audience);
if (!onBehalfOf.ok) {
logError(`Henting av oboToken for ${url} feilet`);
throw new Error('Request oboToken for simpleTokenXProxy failed');
}

return onBehalfOf.token;
};

interface Opts {
url: string;
method?: 'GET' | 'POST' | 'DELETE';
audience: string;
body?: object;
req?: IncomingMessage;
}

export const simpleTokenXProxy = async <T>({
url,
audience,
req,
method = 'GET',
body,
}: Opts): Promise<T> => {
if (!req) {
logError(`Request for ${url} er undefined`);
throw new Error('Request for simpleTokenXProxy is undefined');
}
const onBehalfOfToken = await getOnBefalfOfToken(audience, url, req);
const navCallId = randomUUID();

logInfo(`${req.method} ${url}, callId ${navCallId}`);

const response = await fetch(url, {
method: method,
headers: {
Authorization: `Bearer ${onBehalfOfToken}`,
'Content-Type': 'application/json',
'Nav-CallId': navCallId,
},
body: method === 'POST' ? JSON.stringify(body) : undefined,
});

try {
if (response.ok) {
logInfo(`OK ${url}, status ${response.status}, callId ${navCallId}`);
const headers = response.headers.get('content-type');
const isJson = headers?.includes('application/json');

// TODO: Midlertidig, til innsending returnerer json på alle OK-responser
if (!isJson) {
return (await response.text()) as T;
}
return await response.json();
}
} catch (error) {
logError(`Unable to parse response for ${url}`, error);
}
logError(
`Error fetching simpleTokenXProxy. Fikk responskode ${response.status} fra ${url} med navCallId: ${navCallId}`,
);
throw new ErrorMedStatus('Error fetching simpleTokenXProxy', response.status, navCallId);
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@navikt/ds-react": "^5.17.4",
"@navikt/nav-dekoratoren-moduler": "^2.1.5",
"@navikt/next-api-proxy": "3.4.0",
"@navikt/oasis": "^3.2.2",
"@ungap/structured-clone": "^1.2.0",
"@vercel/otel": "1.2.1",
"cross-fetch": "^4.0.0",
Expand Down
2 changes: 1 addition & 1 deletion pages/[step].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ export const getServerSideProps = beskyttetSide(
let mellomlagretSøknad: SoknadContextState | undefined;

try {
mellomlagretSøknad = await hentMellomlagring(bearerToken);
mellomlagretSøknad = await hentMellomlagring(ctx.req);
} catch (e) {
logError('Noe gikk galt i innhenting av mellomlagret søknad', e);
}
Expand Down
35 changes: 19 additions & 16 deletions pages/api/innsending/soknadinnsending.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import { getYrkesskadeSchema } from 'components/pageComponents/standard/Yrkesska
import { getAccessTokenFromRequest } from 'auth/accessToken';
import { AttachmentType, RequiredVedlegg } from 'types/SoknadContext';
import { SOKNAD_VERSION } from 'context/soknadcontext/soknadContext';
import { deleteCache } from 'mock/mellomlagringsCache';
import { simpleTokenXProxy } from 'lib/utils/api/simpleTokenXProxy';
import { IncomingMessage } from 'http';

// TODO: Sjekke om vi må generere pdf på samme språk som bruker har valgt når de fyller ut søknaden
function getIntl() {
Expand Down Expand Up @@ -67,8 +70,6 @@ const søknadIsValid = (søknad: Soknad) => {
};

const handler = beskyttetApi(async (req: NextApiRequest, res: NextApiResponse) => {
const accessToken = getAccessTokenFromRequest(req);

const { søknad, requiredVedlegg } = req.body as {
søknad: Soknad;
requiredVedlegg: RequiredVedlegg[];
Expand Down Expand Up @@ -106,7 +107,7 @@ const handler = beskyttetApi(async (req: NextApiRequest, res: NextApiResponse) =
kvittering: søknadPdf,
filer,
},
accessToken,
req,
);

metrics.sendSoknadCounter.inc({ type: 'STANDARD' });
Expand Down Expand Up @@ -145,26 +146,28 @@ function mapVedleggTypeTilVedleggTekst(vedleggType: AttachmentType): string {

export const sendSoknadViaAapInnsending = async (
innsending: SoknadInnsendingRequestBody,
accessToken?: string,
req: IncomingMessage,
) => {
if (isFunctionalTest()) {
return 'Vi har mottat søknaden din.';
}
if (isMock()) {
await deleteCache();
return 'Vi har mottat søknaden din.';
}
const søknad = await tokenXApiProxy({
url: `${process.env.INNSENDING_URL}/innsending`,
prometheusPath: 'innsending/soknad',
method: 'POST',
data: JSON.stringify(innsending),
audience: process.env.INNSENDING_AUDIENCE!,
bearerToken: accessToken,
metricsStatusCodeCounter: metrics.backendApiStatusCodeCounter,
metricsTimer: metrics.backendApiDurationHistogram,
noResponse: true,
});
return søknad;
try {
const søknad = await simpleTokenXProxy({
url: `${process.env.INNSENDING_URL}/innsending`,
audience: process.env.INNSENDING_AUDIENCE!,
method: 'POST',
body: innsending,
req,
});
return søknad;
} catch (error) {
logError('Noe gikk galt ved innsending av søknad', error);
throw new Error('Error sending søknad via aap-innsending');
}
};

export default handler;
35 changes: 18 additions & 17 deletions pages/api/mellomlagring/lagre.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import metrics from 'utils/metrics';

import { StepType } from 'components/StepWizard/Step';
import { hentMellomlagring } from 'pages/api/mellomlagring/les';
import { simpleTokenXProxy } from 'lib/utils/api/simpleTokenXProxy';
import { IncomingMessage } from 'http';

const handler = beskyttetApi(async (req: NextApiRequest, res: NextApiResponse) => {
const accessToken = getAccessTokenFromRequest(req);

const eksisterendeSøknad = await hentMellomlagring(accessToken);
const eksisterendeSøknad = await hentMellomlagring(req);
if (
eksisterendeSøknad &&
eksisterendeSøknad.søknad &&
Expand All @@ -27,25 +27,26 @@ const handler = beskyttetApi(async (req: NextApiRequest, res: NextApiResponse) =
`Overskriver eksisterende søknad med en tom søknad på side ${activeStepIndex ?? 'ukjent'}`,
);
}
await lagreBucket(req.body, accessToken);
await mellomlagreSøknad(req.body, req);
res.status(201).json({});
});

export const lagreBucket = async (data: string, accessToken?: string) => {
export const mellomlagreSøknad = async (data: object, req: IncomingMessage) => {
if (isFunctionalTest()) return;
if (isMock()) return await lagreCache(JSON.stringify(data));
await tokenXApiProxy({
url: `${process.env.INNSENDING_URL}/mellomlagring/søknad`,
prometheusPath: `mellomlagring`,
method: 'POST',
data: JSON.stringify(data),
audience: process.env.INNSENDING_AUDIENCE!,
noResponse: true,
bearerToken: accessToken,
metricsStatusCodeCounter: metrics.backendApiStatusCodeCounter,
metricsTimer: metrics.backendApiDurationHistogram,
});
return;
try {
await simpleTokenXProxy({
url: `${process.env.INNSENDING_URL}/mellomlagring/søknad`,
method: 'POST',
audience: process.env.INNSENDING_AUDIENCE!,
body: data,
req,
});
return;
} catch (error) {
logError('Noe gikk galt ved mellomlagring av søknad', error);
throw new Error('Error saving søknad via aap-innsending');
}
};

export default handler;
14 changes: 6 additions & 8 deletions pages/api/mellomlagring/les.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ import { lesCache } from 'mock/mellomlagringsCache';
import { isFunctionalTest, isMock } from 'utils/environments';
import { defaultStepList } from 'pages';
import { SOKNAD_VERSION, SoknadContextState } from 'context/soknadcontext/soknadContext';
import { simpleTokenXProxy } from 'lib/utils/api/simpleTokenXProxy';
import { IncomingMessage } from 'http';

const handler = beskyttetApi(async (req: NextApiRequest, res: NextApiResponse) => {
const accessToken = getAccessTokenFromRequest(req);
const result = await hentMellomlagring(accessToken);
const result = await hentMellomlagring(req);
res.status(200).json(result);
});

export const hentMellomlagring = async (
accessToken?: string,
req?: IncomingMessage,
): Promise<SoknadContextState | undefined> => {
if (isFunctionalTest()) {
return {
Expand All @@ -30,14 +31,11 @@ export const hentMellomlagring = async (
return result ? JSON.parse(result) : {};
}
try {
const mellomlagretSøknad = await tokenXApiProxy({
const mellomlagretSøknad = await simpleTokenXProxy<SoknadContextState>({
url: `${process.env.INNSENDING_URL}/mellomlagring/søknad`,
prometheusPath: `mellomlagring`,
method: 'GET',
audience: process.env.INNSENDING_AUDIENCE!,
bearerToken: accessToken,
metricsStatusCodeCounter: metrics.backendApiStatusCodeCounter,
metricsTimer: metrics.backendApiDurationHistogram,
req,
});

return mellomlagretSøknad;
Expand Down
32 changes: 18 additions & 14 deletions pages/api/mellomlagring/slett.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,37 @@
import { NextApiRequest, NextApiResponse } from 'next';
import { getAccessTokenFromRequest } from 'auth/accessToken';
import { beskyttetApi } from 'auth/beskyttetApi';
import { tokenXApiProxy } from '@navikt/aap-felles-utils';
import { logError, tokenXApiProxy } from '@navikt/aap-felles-utils';
import metrics from 'utils/metrics';
import { deleteCache } from 'mock/mellomlagringsCache';
import { isMock } from 'utils/environments';
import { simpleTokenXProxy } from 'lib/utils/api/simpleTokenXProxy';
import { IncomingMessage } from 'http';
import { ca } from 'date-fns/locale';

const handler = beskyttetApi(async (req: NextApiRequest, res: NextApiResponse) => {
const accessToken = getAccessTokenFromRequest(req);
await slettBucket(accessToken);
await slettBucket(req);
res.status(204).json({});
});

export const slettBucket = async (accessToken?: string) => {
export const slettBucket = async (req: IncomingMessage) => {
if (isMock()) {
await deleteCache();
return;
}

await tokenXApiProxy({
url: `${process.env.INNSENDING_URL}/mellomlagring/søknad`,
prometheusPath: `mellomlagring`,
method: 'DELETE',
noResponse: true,
audience: process.env.INNSENDING_AUDIENCE!,
bearerToken: accessToken,
metricsStatusCodeCounter: metrics.backendApiStatusCodeCounter,
metricsTimer: metrics.backendApiDurationHistogram,
});
try {
await simpleTokenXProxy({
url: `${process.env.INNSENDING_URL}/mellomlagring/søknad`,
method: 'DELETE',
audience: process.env.INNSENDING_AUDIENCE!,
req,
});
return;
} catch (error) {
logError('Noe gikk galt ved sletting av søknad', error);
throw new Error('Error deleting søknad via aap-innsending');
}
};

export default handler;
2 changes: 1 addition & 1 deletion pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export const getServerSideProps = beskyttetSide(
let mellomlagretSøknad: SoknadContextState | undefined;

try {
mellomlagretSøknad = await hentMellomlagring(bearerToken);
mellomlagretSøknad = await hentMellomlagring(ctx.req);
} catch (e) {
logError('Noe gikk galt i innhenting av mellomlagret søknad', e);
}
Expand Down
Loading

0 comments on commit 77138d8

Please sign in to comment.