Skip to content

Commit

Permalink
Merge branch 'main' of github.com:Amsterdam/mijn-amsterdam-frontend i…
Browse files Browse the repository at this point in the history
…nto test-acc-bff
  • Loading branch information
timvanoostrom committed Nov 30, 2023
2 parents 151617e + c2aef0f commit 684d6f0
Show file tree
Hide file tree
Showing 20 changed files with 546 additions and 169 deletions.
23 changes: 23 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"cookie-parser": "^1.4.6",
"cookie-session": "^2.0.0",
"cors": "^2.8.5",
"cron": "^3.1.6",
"cross-env": "^7.0.3",
"date-fns": "^2.27.0",
"dotenv": "^16.3.1",
Expand Down
7 changes: 6 additions & 1 deletion src/server/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ import { authRouterDevelopment, relayDevRouter } from './router-development';
import { router as oidcRouter } from './router-oidc';
import { router as protectedRouter } from './router-protected';
import { router as publicRouter } from './router-public';
import { adminRouter } from './router-admin';
import { cleanupSessionBlacklistTable } from './services/cron/jobs';

const sentryOptions: Sentry.NodeOptions = {
dsn: process.env.BFF_SENTRY_DSN,
Expand Down Expand Up @@ -152,7 +154,7 @@ if (IS_OT && !IS_AP) {
///// Generic Router Method for All environments
////////////////////////////////////////////////////////////////////////
// Mount the routers at the base path
app.use(BFF_BASE_PATH, nocache, protectedRouter);
app.use(BFF_BASE_PATH, nocache, protectedRouter, adminRouter);

app.get(BffEndpoints.ROOT, (req, res) => {
return res.redirect(`${BFF_BASE_PATH + BffEndpoints.ROOT}`);
Expand Down Expand Up @@ -197,3 +199,6 @@ const server = app.listen(BFF_PORT, () => {
// From https://shuheikagawa.com/blog/2019/04/25/keep-alive-timeout/
server.keepAliveTimeout = 60 * 1000;
server.headersTimeout = 65 * 1000; // This should be bigger than `keepAliveTimeout + your server's expected response time`

// Start Cron jobs
cleanupSessionBlacklistTable.start();
16 changes: 10 additions & 6 deletions src/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,11 @@ export interface DataRequestConfig extends AxiosRequestConfig {
maximumAmountOfPages?: number;
}

const ONE_SECOND_MS = 1000;
const ONE_MINUTE_MS = 60 * ONE_SECOND_MS;
const ONE_HOUR_MS = 60 * ONE_MINUTE_MS;
export const ONE_SECOND_MS = 1000;
export const ONE_MINUTE_MS = 60 * ONE_SECOND_MS;
export const ONE_HOUR_MS = 60 * ONE_MINUTE_MS;

export const OIDC_TOKEN_EXP = ONE_HOUR_MS * 24 * 3; // The TMA currently has a token expiration time of 3 hours

export const DEFAULT_API_CACHE_TTL_MS = (IS_OT ? 65 : 45) * ONE_SECOND_MS; // This means that every request that depends on the response of another will use the cached version of the response for a maximum of 45 seconds.
export const DEFAULT_CANCEL_TIMEOUT_MS = (IS_OT ? 60 : 20) * ONE_SECOND_MS; // This means a request will be aborted after 20 seconds without a response.
Expand Down Expand Up @@ -232,7 +234,9 @@ export const ApiConfig: ApiDataRequestConfig = {
httpsAgent: new https.Agent({
ca: IS_TAP ? getCert(process.env.BFF_SERVER_CLIENT_CERT) : [],
}),
postponeFetch: !FeatureToggle.erfpachtV2EndpointActive,
postponeFetch:
!FeatureToggle.erfpachtV2EndpointActive ||
!process.env.BFF_ERFPACHT_API_URL_ONT,
headers: {
'X-HERA-REQUESTORIGIN': 'MijnAmsterdam',
},
Expand Down Expand Up @@ -395,9 +399,10 @@ export const BffEndpoints = {
CACHE_OVERVIEW: '/status/cache',
LOGIN_STATS: '/status/logins/:authMethod?',
LOGIN_RAW: '/status/logins/table',
SESSION_BLACKLIST_RAW: '/status/session-blacklist/table',
STATUS_HEALTH: '/status/health',
STATUS_HEALTH2: '/bff/status/health',
USER_DATA_OVERVIEW: '/status/user-data-overview',
TEST_ACCOUNTS_OVERVIEW: '/status/user-data-overview',
LOODMETING_ATTACHMENTS: '/services/lood/:id/attachments',
};

Expand Down Expand Up @@ -428,7 +433,6 @@ const oidcConfigBase: ConfigParams = {
attemptSilentLogin: false,
authorizationParams: { prompt: 'login', response_type: 'code' },
clockTolerance: 120, // 2 minutes
// @ts-ignore
session: {
rolling: true,
rollingDuration: OIDC_SESSION_MAX_AGE_SECONDS,
Expand Down
30 changes: 8 additions & 22 deletions src/server/helpers/app.development.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,17 @@ import * as jose from 'jose';
import {
DEV_JWK_PRIVATE,
DEV_JWK_PUBLIC,
OIDC_COOKIE_ENCRYPTION_KEY,
OIDC_SESSION_MAX_AGE_SECONDS,
OIDC_TOKEN_AUD_ATTRIBUTE_VALUE,
TOKEN_ID_ATTRIBUTE,
} from '../config';
import type { AuthProfile } from './app';
import { createSecretKey } from 'node:crypto';

const { encryption: deriveKey } = require('express-openid-connect/lib/crypto');
import { encryptCookieValue, type AuthProfile } from './app';

/**
*
* Helpers for development
*/

async function encryptDevSessionCookieValue(payload: string, headers: object) {
const alg = 'dir';
const enc = 'A256GCM';
const keySource = deriveKey(OIDC_COOKIE_ENCRYPTION_KEY);
const key = await createSecretKey(keySource);

const jwe = await new jose.CompactEncrypt(new TextEncoder().encode(payload))
.setProtectedHeader({ alg, enc, ...headers })
.encrypt(key);

return jwe;
}

export async function getPrivateKeyForDevelopment() {
return jose.importJWK(DEV_JWK_PRIVATE);
}
Expand All @@ -40,11 +23,13 @@ export function getPublicKeyForDevelopment(): Promise<jose.KeyLike> {

export async function signDevelopmentToken(
authMethod: AuthProfile['authMethod'],
userID: string
userID: string,
sessionID: string
) {
const data = {
[TOKEN_ID_ATTRIBUTE[authMethod]]: userID,
aud: OIDC_TOKEN_AUD_ATTRIBUTE_VALUE[authMethod],
sid: sessionID,
};
const alg = 'RS256';
try {
Expand All @@ -61,15 +46,16 @@ export async function signDevelopmentToken(

export async function generateDevSessionCookieValue(
authMethod: AuthProfile['authMethod'],
userID: string
userID: string,
sessionID: string
) {
const uat = (Date.now() / 1000) | 0;
const iat = uat;
const exp = iat + OIDC_SESSION_MAX_AGE_SECONDS;

const value = await encryptDevSessionCookieValue(
const value = await encryptCookieValue(
JSON.stringify({
id_token: await signDevelopmentToken(authMethod, userID),
id_token: await signDevelopmentToken(authMethod, userID, sessionID),
}),
{
iat,
Expand Down
Loading

0 comments on commit 684d6f0

Please sign in to comment.