mirror of
https://github.com/sasjs/server.git
synced 2025-12-11 03:34:35 +00:00
chore: conditionally call authorize middleware from authenticateToken
This commit is contained in:
@@ -550,12 +550,12 @@ components:
|
|||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
AuthorizedRoutesResponse:
|
AuthorizedRoutesResponse:
|
||||||
properties:
|
properties:
|
||||||
routes:
|
URIs:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
required:
|
required:
|
||||||
- routes
|
- URIs
|
||||||
type: object
|
type: object
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
ExecuteReturnJsonPayload:
|
ExecuteReturnJsonPayload:
|
||||||
@@ -1615,7 +1615,7 @@ paths:
|
|||||||
$ref: '#/components/schemas/AuthorizedRoutesResponse'
|
$ref: '#/components/schemas/AuthorizedRoutesResponse'
|
||||||
examples:
|
examples:
|
||||||
'Example 1':
|
'Example 1':
|
||||||
value: {routes: [/AppStream, /SASjsApi/stp/execute]}
|
value: {URIs: [/AppStream, /SASjsApi/stp/execute]}
|
||||||
summary: 'Get authorized routes.'
|
summary: 'Get authorized routes.'
|
||||||
tags:
|
tags:
|
||||||
- Info
|
- Info
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
import { RequestHandler, Request, Response, NextFunction } from 'express'
|
import { RequestHandler, Request, Response, NextFunction } from 'express'
|
||||||
import jwt from 'jsonwebtoken'
|
import jwt from 'jsonwebtoken'
|
||||||
import { csrfProtection } from '../app'
|
import { csrfProtection } from '../app'
|
||||||
import { fetchLatestAutoExec, ModeType, verifyTokenInDB } from '../utils'
|
import {
|
||||||
|
fetchLatestAutoExec,
|
||||||
|
ModeType,
|
||||||
|
verifyTokenInDB,
|
||||||
|
getAuthorizedRoutes
|
||||||
|
} from '../utils'
|
||||||
import { desktopUser } from './desktop'
|
import { desktopUser } from './desktop'
|
||||||
|
import { authorize } from './authorize'
|
||||||
|
|
||||||
export const authenticateAccessToken: RequestHandler = async (
|
export const authenticateAccessToken: RequestHandler = async (
|
||||||
req,
|
req,
|
||||||
@@ -15,6 +21,12 @@ export const authenticateAccessToken: RequestHandler = async (
|
|||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const authorizedRoutes = getAuthorizedRoutes()
|
||||||
|
const uri = req.baseUrl + req.path
|
||||||
|
const nextFunction = authorizedRoutes.includes(uri)
|
||||||
|
? () => authorize(req, res, next)
|
||||||
|
: next
|
||||||
|
|
||||||
// if request is coming from web and has valid session
|
// if request is coming from web and has valid session
|
||||||
// it can be validated.
|
// it can be validated.
|
||||||
if (req.session?.loggedIn) {
|
if (req.session?.loggedIn) {
|
||||||
@@ -24,7 +36,7 @@ export const authenticateAccessToken: RequestHandler = async (
|
|||||||
if (user) {
|
if (user) {
|
||||||
if (user.isActive) {
|
if (user.isActive) {
|
||||||
req.user = user
|
req.user = user
|
||||||
return csrfProtection(req, res, next)
|
return csrfProtection(req, res, nextFunction)
|
||||||
} else return res.sendStatus(401)
|
} else return res.sendStatus(401)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,7 +46,7 @@ export const authenticateAccessToken: RequestHandler = async (
|
|||||||
authenticateToken(
|
authenticateToken(
|
||||||
req,
|
req,
|
||||||
res,
|
res,
|
||||||
next,
|
nextFunction,
|
||||||
process.env.ACCESS_TOKEN_SECRET as string,
|
process.env.ACCESS_TOKEN_SECRET as string,
|
||||||
'accessToken'
|
'accessToken'
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import express from 'express'
|
import express from 'express'
|
||||||
import { runCodeValidation } from '../../utils'
|
import { runCodeValidation } from '../../utils'
|
||||||
import { CodeController } from '../../controllers/'
|
import { CodeController } from '../../controllers/'
|
||||||
import { authorize } from '../../middlewares'
|
|
||||||
|
|
||||||
const runRouter = express.Router()
|
const runRouter = express.Router()
|
||||||
|
|
||||||
const controller = new CodeController()
|
const controller = new CodeController()
|
||||||
|
|
||||||
runRouter.post('/execute', authorize, async (req, res) => {
|
runRouter.post('/execute', async (req, res) => {
|
||||||
const { error, value: body } = runCodeValidation(req.body)
|
const { error, value: body } = runCodeValidation(req.body)
|
||||||
if (error) return res.status(400).send(error.details[0].message)
|
if (error) return res.status(400).send(error.details[0].message)
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { deleteFile, readFile } from '@sasjs/utils'
|
|||||||
|
|
||||||
import { publishAppStream } from '../appStream'
|
import { publishAppStream } from '../appStream'
|
||||||
|
|
||||||
import { authorize } from '../../middlewares'
|
|
||||||
import { multerSingle } from '../../middlewares/multer'
|
import { multerSingle } from '../../middlewares/multer'
|
||||||
import { DriveController } from '../../controllers/'
|
import { DriveController } from '../../controllers/'
|
||||||
import {
|
import {
|
||||||
@@ -20,7 +19,7 @@ const controller = new DriveController()
|
|||||||
|
|
||||||
const driveRouter = express.Router()
|
const driveRouter = express.Router()
|
||||||
|
|
||||||
driveRouter.post('/deploy', authorize, async (req, res) => {
|
driveRouter.post('/deploy', async (req, res) => {
|
||||||
const { error, value: body } = deployValidation(req.body)
|
const { error, value: body } = deployValidation(req.body)
|
||||||
if (error) return res.status(400).send(error.details[0].message)
|
if (error) return res.status(400).send(error.details[0].message)
|
||||||
|
|
||||||
@@ -49,7 +48,6 @@ driveRouter.post('/deploy', authorize, async (req, res) => {
|
|||||||
|
|
||||||
driveRouter.post(
|
driveRouter.post(
|
||||||
'/deploy/upload',
|
'/deploy/upload',
|
||||||
authorize,
|
|
||||||
(...arg) => multerSingle('file', arg),
|
(...arg) => multerSingle('file', arg),
|
||||||
async (req, res) => {
|
async (req, res) => {
|
||||||
if (!req.file) return res.status(400).send('"file" is not present.')
|
if (!req.file) return res.status(400).send('"file" is not present.')
|
||||||
@@ -113,7 +111,7 @@ driveRouter.post(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
driveRouter.get('/file', authorize, async (req, res) => {
|
driveRouter.get('/file', async (req, res) => {
|
||||||
const { error: errQ, value: query } = fileParamValidation(req.query)
|
const { error: errQ, value: query } = fileParamValidation(req.query)
|
||||||
|
|
||||||
if (errQ) return res.status(400).send(errQ.details[0].message)
|
if (errQ) return res.status(400).send(errQ.details[0].message)
|
||||||
@@ -125,7 +123,7 @@ driveRouter.get('/file', authorize, async (req, res) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
driveRouter.get('/folder', authorize, async (req, res) => {
|
driveRouter.get('/folder', async (req, res) => {
|
||||||
const { error: errQ, value: query } = folderParamValidation(req.query)
|
const { error: errQ, value: query } = folderParamValidation(req.query)
|
||||||
|
|
||||||
if (errQ) return res.status(400).send(errQ.details[0].message)
|
if (errQ) return res.status(400).send(errQ.details[0].message)
|
||||||
@@ -138,7 +136,7 @@ driveRouter.get('/folder', authorize, async (req, res) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
driveRouter.delete('/file', authorize, async (req, res) => {
|
driveRouter.delete('/file', async (req, res) => {
|
||||||
const { error: errQ, value: query } = fileParamValidation(req.query)
|
const { error: errQ, value: query } = fileParamValidation(req.query)
|
||||||
|
|
||||||
if (errQ) return res.status(400).send(errQ.details[0].message)
|
if (errQ) return res.status(400).send(errQ.details[0].message)
|
||||||
@@ -153,7 +151,6 @@ driveRouter.delete('/file', authorize, async (req, res) => {
|
|||||||
|
|
||||||
driveRouter.post(
|
driveRouter.post(
|
||||||
'/file',
|
'/file',
|
||||||
authorize,
|
|
||||||
(...arg) => multerSingle('file', arg),
|
(...arg) => multerSingle('file', arg),
|
||||||
async (req, res) => {
|
async (req, res) => {
|
||||||
const { error: errQ, value: query } = fileParamValidation(req.query)
|
const { error: errQ, value: query } = fileParamValidation(req.query)
|
||||||
@@ -182,7 +179,6 @@ driveRouter.post(
|
|||||||
|
|
||||||
driveRouter.patch(
|
driveRouter.patch(
|
||||||
'/file',
|
'/file',
|
||||||
authorize,
|
|
||||||
(...arg) => multerSingle('file', arg),
|
(...arg) => multerSingle('file', arg),
|
||||||
async (req, res) => {
|
async (req, res) => {
|
||||||
const { error: errQ, value: query } = fileParamValidation(req.query)
|
const { error: errQ, value: query } = fileParamValidation(req.query)
|
||||||
@@ -209,7 +205,7 @@ driveRouter.patch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
driveRouter.get('/fileTree', authorize, async (req, res) => {
|
driveRouter.get('/fileTree', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const response = await controller.getFileTree()
|
const response = await controller.getFileTree()
|
||||||
res.send(response)
|
res.send(response)
|
||||||
|
|||||||
@@ -36,7 +36,12 @@ router.use('/group', desktopRestrict, groupRouter)
|
|||||||
router.use('/stp', authenticateAccessToken, stpRouter)
|
router.use('/stp', authenticateAccessToken, stpRouter)
|
||||||
router.use('/code', authenticateAccessToken, codeRouter)
|
router.use('/code', authenticateAccessToken, codeRouter)
|
||||||
router.use('/user', desktopRestrict, userRouter)
|
router.use('/user', desktopRestrict, userRouter)
|
||||||
router.use('/permission', desktopRestrict, permissionRouter)
|
router.use(
|
||||||
|
'/permission',
|
||||||
|
desktopRestrict,
|
||||||
|
authenticateAccessToken,
|
||||||
|
permissionRouter
|
||||||
|
)
|
||||||
|
|
||||||
router.use(
|
router.use(
|
||||||
'/',
|
'/',
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
import express from 'express'
|
import express from 'express'
|
||||||
import { PermissionController } from '../../controllers/'
|
import { PermissionController } from '../../controllers/'
|
||||||
import {
|
import { verifyAdmin } from '../../middlewares'
|
||||||
authenticateAccessToken,
|
|
||||||
verifyAdmin,
|
|
||||||
authorize
|
|
||||||
} from '../../middlewares'
|
|
||||||
import {
|
import {
|
||||||
registerPermissionValidation,
|
registerPermissionValidation,
|
||||||
updatePermissionValidation
|
updatePermissionValidation
|
||||||
@@ -13,65 +9,49 @@ import {
|
|||||||
const permissionRouter = express.Router()
|
const permissionRouter = express.Router()
|
||||||
const controller = new PermissionController()
|
const controller = new PermissionController()
|
||||||
|
|
||||||
permissionRouter.get(
|
permissionRouter.get('/', async (req, res) => {
|
||||||
'/',
|
try {
|
||||||
authenticateAccessToken,
|
const response = await controller.getAllPermissions()
|
||||||
authorize,
|
res.send(response)
|
||||||
async (req, res) => {
|
} catch (err: any) {
|
||||||
try {
|
const statusCode = err.code
|
||||||
const response = await controller.getAllPermissions()
|
delete err.code
|
||||||
res.send(response)
|
res.status(statusCode).send(err.message)
|
||||||
} catch (err: any) {
|
|
||||||
const statusCode = err.code
|
|
||||||
delete err.code
|
|
||||||
res.status(statusCode).send(err.message)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
|
|
||||||
permissionRouter.post(
|
permissionRouter.post('/', verifyAdmin, async (req, res) => {
|
||||||
'/',
|
const { error, value: body } = registerPermissionValidation(req.body)
|
||||||
authenticateAccessToken,
|
if (error) return res.status(400).send(error.details[0].message)
|
||||||
verifyAdmin,
|
|
||||||
async (req, res) => {
|
|
||||||
const { error, value: body } = registerPermissionValidation(req.body)
|
|
||||||
if (error) return res.status(400).send(error.details[0].message)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await controller.createPermission(body)
|
const response = await controller.createPermission(body)
|
||||||
res.send(response)
|
res.send(response)
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
const statusCode = err.code
|
const statusCode = err.code
|
||||||
delete err.code
|
delete err.code
|
||||||
res.status(statusCode).send(err.message)
|
res.status(statusCode).send(err.message)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
|
|
||||||
permissionRouter.patch(
|
permissionRouter.patch('/:permissionId', verifyAdmin, async (req: any, res) => {
|
||||||
'/:permissionId',
|
const { permissionId } = req.params
|
||||||
authenticateAccessToken,
|
|
||||||
verifyAdmin,
|
|
||||||
async (req: any, res) => {
|
|
||||||
const { permissionId } = req.params
|
|
||||||
|
|
||||||
const { error, value: body } = updatePermissionValidation(req.body)
|
const { error, value: body } = updatePermissionValidation(req.body)
|
||||||
if (error) return res.status(400).send(error.details[0].message)
|
if (error) return res.status(400).send(error.details[0].message)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await controller.updatePermission(permissionId, body)
|
const response = await controller.updatePermission(permissionId, body)
|
||||||
res.send(response)
|
res.send(response)
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
const statusCode = err.code
|
const statusCode = err.code
|
||||||
delete err.code
|
delete err.code
|
||||||
res.status(statusCode).send(err.message)
|
res.status(statusCode).send(err.message)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
|
|
||||||
permissionRouter.delete(
|
permissionRouter.delete(
|
||||||
'/:permissionId',
|
'/:permissionId',
|
||||||
authenticateAccessToken,
|
|
||||||
verifyAdmin,
|
verifyAdmin,
|
||||||
async (req: any, res) => {
|
async (req: any, res) => {
|
||||||
const { permissionId } = req.params
|
const { permissionId } = req.params
|
||||||
|
|||||||
@@ -150,6 +150,19 @@ describe('permission', () => {
|
|||||||
expect(res.body).toEqual({})
|
expect(res.body).toEqual({})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should respond with Bad Request if uri is not valid', async () => {
|
||||||
|
const res = await request(app)
|
||||||
|
.post('/SASjsApi/permission')
|
||||||
|
.auth(adminAccessToken, { type: 'bearer' })
|
||||||
|
.send({
|
||||||
|
...permission,
|
||||||
|
uri: '/some/random/api/endpoint'
|
||||||
|
})
|
||||||
|
.expect(400)
|
||||||
|
|
||||||
|
expect(res.body).toEqual({})
|
||||||
|
})
|
||||||
|
|
||||||
it('should respond with Bad Request if setting is missing', async () => {
|
it('should respond with Bad Request if setting is missing', async () => {
|
||||||
const res = await request(app)
|
const res = await request(app)
|
||||||
.post('/SASjsApi/permission')
|
.post('/SASjsApi/permission')
|
||||||
|
|||||||
@@ -2,14 +2,13 @@ import express from 'express'
|
|||||||
import { executeProgramRawValidation } from '../../utils'
|
import { executeProgramRawValidation } from '../../utils'
|
||||||
import { STPController } from '../../controllers/'
|
import { STPController } from '../../controllers/'
|
||||||
import { FileUploadController } from '../../controllers/internal'
|
import { FileUploadController } from '../../controllers/internal'
|
||||||
import { authorize } from '../../middlewares'
|
|
||||||
|
|
||||||
const stpRouter = express.Router()
|
const stpRouter = express.Router()
|
||||||
|
|
||||||
const fileUploadController = new FileUploadController()
|
const fileUploadController = new FileUploadController()
|
||||||
const controller = new STPController()
|
const controller = new STPController()
|
||||||
|
|
||||||
stpRouter.get('/execute', authorize, async (req, res) => {
|
stpRouter.get('/execute', async (req, res) => {
|
||||||
const { error, value: query } = executeProgramRawValidation(req.query)
|
const { error, value: query } = executeProgramRawValidation(req.query)
|
||||||
if (error) return res.status(400).send(error.details[0].message)
|
if (error) return res.status(400).send(error.details[0].message)
|
||||||
|
|
||||||
@@ -33,7 +32,6 @@ stpRouter.get('/execute', authorize, async (req, res) => {
|
|||||||
|
|
||||||
stpRouter.post(
|
stpRouter.post(
|
||||||
'/execute',
|
'/execute',
|
||||||
authorize,
|
|
||||||
fileUploadController.preUploadMiddleware,
|
fileUploadController.preUploadMiddleware,
|
||||||
fileUploadController.getMulterUploadObject().any(),
|
fileUploadController.getMulterUploadObject().any(),
|
||||||
async (req, res: any) => {
|
async (req, res: any) => {
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import { AppStreamConfig } from '../types'
|
|||||||
import { getAppStreamConfigPath } from './file'
|
import { getAppStreamConfigPath } from './file'
|
||||||
|
|
||||||
export const loadAppStreamConfig = async () => {
|
export const loadAppStreamConfig = async () => {
|
||||||
|
process.appStreamConfig = {}
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'test') return
|
if (process.env.NODE_ENV === 'test') return
|
||||||
|
|
||||||
const appStreamConfigPath = getAppStreamConfigPath()
|
const appStreamConfigPath = getAppStreamConfigPath()
|
||||||
@@ -21,7 +23,6 @@ export const loadAppStreamConfig = async () => {
|
|||||||
} catch (_) {
|
} catch (_) {
|
||||||
appStreamConfig = {}
|
appStreamConfig = {}
|
||||||
}
|
}
|
||||||
process.appStreamConfig = {}
|
|
||||||
|
|
||||||
for (const [streamServiceName, entry] of Object.entries(appStreamConfig)) {
|
for (const [streamServiceName, entry] of Object.entries(appStreamConfig)) {
|
||||||
const { appLoc, streamWebFolder, streamLogo } = entry
|
const { appLoc, streamWebFolder, streamLogo } = entry
|
||||||
|
|||||||
Reference in New Issue
Block a user