Skip to content

Commit 012c67b

Browse files
authored
Merge pull request #6382 from espoon-voltti/reduce-apigw-noise
Vähennetään apigw:stä tulevia turhia virhehälyjä
2 parents 80433d2 + a46eef2 commit 012c67b

File tree

3 files changed

+34
-24
lines changed

3 files changed

+34
-24
lines changed

apigw/src/app.ts

+5
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ export function apiRouter(config: Config, redisClient: RedisClient) {
321321
redisClient
322322
)
323323
)
324+
router.all('/citizen/auth/*', (_, res) => res.redirect('/'))
324325
router.use('/citizen/public/map-api', mapRoutes)
325326
router.all('/citizen/public/*', citizenProxy)
326327
router.all('/citizen/*', citizenSessions.requireAuthentication, citizenProxy)
@@ -341,6 +342,7 @@ export function apiRouter(config: Config, redisClient: RedisClient) {
341342

342343
router.use('/employee/', employeeSessions.middleware)
343344
router.get('/employee/auth/status', internalAuthStatus(employeeSessions))
345+
router.all('/employee/auth/*', (_, res) => res.redirect('/employee'))
344346
router.all('/employee/public/*', employeeProxy)
345347
router.all(
346348
'/employee/*',
@@ -376,6 +378,9 @@ export function apiRouter(config: Config, redisClient: RedisClient) {
376378
express.json(),
377379
pinLogoutRequestHandler(employeeMobileSessions, redisClient)
378380
)
381+
router.all('/employee-mobile/auth/*', (_, res) =>
382+
res.redirect('/employee/mobile')
383+
)
379384
router.all('/employee-mobile/public/*', employeeMobileProxy)
380385
router.all(
381386
'/employee-mobile/*',

apigw/src/shared/middleware/error-handler.ts

-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ interface LogResponse {
1919
export const errorHandler: (v: boolean) => ErrorRequestHandler =
2020
(includeErrorMessage: boolean) => (error, req, res, next) => {
2121
if (error instanceof InvalidAntiCsrfToken) {
22-
logError('Anti-CSRF token error', req, undefined, error)
2322
if (!res.headersSent) {
2423
res
2524
.status(403)

apigw/src/shared/routes/saml.ts

+29-23
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,30 @@ export function createSamlIntegration<T extends SessionType>(
104104
return samlMessage.profile
105105
}
106106

107+
const validateSamlLogoutMessage = async (
108+
req: express.Request
109+
): Promise<Profile | null> => {
110+
let samlMessage: { profile: Profile | null; loggedOut: boolean }
111+
if (req.method === 'GET') {
112+
const originalQuery = url.parse(req.url).query ?? ''
113+
samlMessage = await saml.validateRedirectAsync(req.query, originalQuery)
114+
} else if (req.method === 'POST') {
115+
samlMessage = isSamlPostRequest(req)
116+
? // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
117+
await saml.validatePostRequestAsync(req.body)
118+
: // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
119+
await saml.validatePostResponseAsync(req.body)
120+
} else {
121+
throw new SamlError(`Unsupported HTTP method ${req.method}`)
122+
}
123+
if (!samlMessage.loggedOut) {
124+
throw new SamlError(
125+
'Invalid SAML message type: expected logout request/response'
126+
)
127+
}
128+
return samlMessage.profile
129+
}
130+
107131
const login: AsyncRequestHandler = async (req, res) => {
108132
logAuditEvent(eventCode('sign_in_started'), req, 'Login endpoint called')
109133
try {
@@ -234,33 +258,15 @@ export function createSamlIntegration<T extends SessionType>(
234258
const logoutCallback: AsyncRequestHandler = async (req, res) => {
235259
logAuditEvent(eventCode('sign_out'), req, 'Logout callback called')
236260

237-
let samlMessage: { profile: Profile | null; loggedOut: boolean }
238-
if (req.method === 'GET') {
239-
const originalQuery = url.parse(req.url).query ?? ''
240-
samlMessage = await saml.validateRedirectAsync(req.query, originalQuery)
241-
} else if (req.method === 'POST') {
242-
samlMessage = isSamlPostRequest(req)
243-
? // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
244-
await saml.validatePostRequestAsync(req.body)
245-
: // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
246-
await saml.validatePostResponseAsync(req.body)
247-
} else {
248-
throw new SamlError(`Unsupported HTTP method ${req.method}`)
249-
}
250-
if (!samlMessage.loggedOut) {
251-
throw new SamlError(
252-
'Invalid SAML message type: expected logout request/response'
253-
)
254-
}
255-
256261
try {
262+
const profile = await validateSamlLogoutMessage(req)
257263
let url: string
258264
// There are two scenarios:
259265
// 1. IDP-initiated logout, and we've just received a logout request -> profile is not null, the SAML transaction
260266
// is still in progress, and we should redirect the user back to the IDP
261267
// 2. SP-initiated logout, and we've just received a logout response -> profile is null, the SAML transaction
262268
// is complete, and we should redirect the user to some meaningful page
263-
if (samlMessage.profile) {
269+
if (profile) {
264270
let user: unknown
265271
const sessionUser = sessions.getUser(req)
266272
if (sessionUser) {
@@ -271,16 +277,16 @@ export function createSamlIntegration<T extends SessionType>(
271277
} else {
272278
// We're possibly doing SLO without a real session (e.g. browser has
273279
// 3rd party cookies disabled)
274-
const logoutToken = createLogoutToken(samlMessage.profile)
280+
const logoutToken = createLogoutToken(profile)
275281
const sessionUser = await sessions.logoutWithToken(logoutToken)
276282
const userId = SamlProfileIdSchema.safeParse(sessionUser)
277283
user = userId.success ? userId.data : undefined
278284
}
279-
const profileId = SamlProfileIdSchema.safeParse(samlMessage.profile)
285+
const profileId = SamlProfileIdSchema.safeParse(profile)
280286
const success = profileId.success && _.isEqual(user, profileId.data)
281287

282288
url = await saml.getLogoutResponseUrlAsync(
283-
samlMessage.profile,
289+
profile,
284290
// not validated, because the value and its format are specified by the IDP and we're supposed to
285291
// just pass it back
286292
getRawUnvalidatedRelayState(req) ?? '',

0 commit comments

Comments
 (0)