Skip to content

Commit 7ebd2d6

Browse files
committed
prevent non staff access
1 parent 790052c commit 7ebd2d6

File tree

6 files changed

+57
-13
lines changed

6 files changed

+57
-13
lines changed

src/client/util/apiClient.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable no-console */
12
import axios from 'axios'
23

34
import { PUBLIC_URL } from '@config'
@@ -6,4 +7,18 @@ const baseURL = `${PUBLIC_URL}/api`
67

78
const apiClient = axios.create({ baseURL })
89

10+
// Intercept 401 and 500 responses and let them bubble up to error boundary
11+
apiClient.interceptors.response.use(
12+
response => response,
13+
error => {
14+
if (error.response?.status === 401) {
15+
console.warn('Unauthorized request:', error.config?.url)
16+
} else if (error.response?.status === 500) {
17+
console.error('Server error:', error.config?.url)
18+
}
19+
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
20+
return Promise.reject(error)
21+
}
22+
)
23+
924
export default apiClient

src/client/util/queryClient.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ const queryClient = new QueryClient({
44
defaultOptions: {
55
queries: {
66
refetchOnWindowFocus: false,
7+
// Throw errors to error boundary for 401 and 500 errors
8+
useErrorBoundary: (error: any) => {
9+
return error?.response?.status === 401 || error?.response?.status === 500
10+
},
711
},
812
},
913
})

src/server/middleware/mockUser.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { getMockUser } from '../mocs/user'
2+
3+
const mockUserMiddleware = (req, _, next) => {
4+
if (req.path.includes('/login')) {
5+
return next()
6+
}
7+
8+
req.user = getMockUser()
9+
10+
return next()
11+
}
12+
13+
export default mockUserMiddleware

src/server/middleware/user.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
import { getMockUser } from '../mocs/user'
1+
import { NextFunction, Response } from 'express'
2+
import UnauthorizedError from '../errors/UnauthorizedError'
23

3-
const userMiddleware = (req, _, next) => {
4-
if (req.path.includes('/login')) {
5-
return next()
4+
const userAccessHandler = (req, res: Response, next: NextFunction) => {
5+
if (!req?.user?.iamGroups?.includes('hy-employees')) {
6+
throw new UnauthorizedError('Unauthorized')
67
}
78

8-
req.user = getMockUser()
9-
109
return next()
1110
}
1211

13-
export default userMiddleware
12+
export default userAccessHandler

src/server/mocs/user.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const mockUsers = {
99
email: 'grp-toska@helsinki.fi',
1010
language: 'fi',
1111
isAdmin: true,
12-
iamGroups: ['grp-toska', 'hy-mltdk-employees'],
12+
iamGroups: ['grp-toska', 'hy-employees'],
1313
},
1414
normal: {
1515
id: 'normaltestuser',
@@ -19,7 +19,17 @@ const mockUsers = {
1919
email: 'matti.luukkainen@helsinki.fi',
2020
language: 'fi',
2121
isAdmin: false,
22-
iamGroups: ['hy-mltdk-employees'],
22+
iamGroups: ['hy-employees'],
23+
},
24+
student: {
25+
id: 'student',
26+
username: 'hy-hlo-221212',
27+
firstName: 'Matti',
28+
lastName: 'Meikäläinen',
29+
email: 'matti.meikalainen@helsinki.fi',
30+
language: 'fi',
31+
isAdmin: false,
32+
iamGroups: [],
2333
},
2434
}
2535

src/server/routes/index.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import * as Sentry from '@sentry/node'
44

55
import { inDevelopment, inE2EMode, inAcualStaging } from '@config'
66
import initializeSentry from '../util/sentry'
7-
import userMiddleware from '../middleware/user'
7+
import mockUserMiddleware from '../middleware/mockUser'
8+
import userAccessMiddleware from '../middleware/user'
89
import sentryUserMiddleware from '../middleware/sentry'
910
import errorHandler from '../middleware/error'
1011
import accessLogger from '../middleware/access'
@@ -32,10 +33,9 @@ router.use(cors())
3233
router.use(express.json())
3334

3435
if (inDevelopment || inE2EMode || inAcualStaging) {
35-
router.use(userMiddleware)
36+
router.use(mockUserMiddleware)
3637
}
3738

38-
// Set Sentry user context after user middleware
3939
router.use(sentryUserMiddleware)
4040

4141
router.use(accessLogger)
@@ -58,13 +58,16 @@ router.post('/seed', adminHandler, async (_, res) => {
5858
res.send('Database seeded successfully')
5959
})
6060

61+
router.use('/login', loginRouter)
62+
63+
router.use(userAccessMiddleware)
64+
6165
router.use('/faculties', facultyRouter)
6266
router.use('/surveys', surveyRouter)
6367
router.use('/questions', questionRouter)
6468
router.use('/results', resultRouter)
6569
router.use('/entries', entryRouter)
6670
router.use('/users', userRouter)
67-
router.use('/login', loginRouter)
6871
router.use('/countries', countryRouter)
6972
router.use('/organizations', organizationRouter)
7073
router.use('/warnings', warningsRouter)

0 commit comments

Comments
 (0)