187 lines
5.0 KiB
JavaScript
187 lines
5.0 KiB
JavaScript
const express = require('express');
|
|
const passport = require('passport');
|
|
const db = require('../db/models');
|
|
const Project_ui_control_settingsService = require('../services/project_ui_control_settings');
|
|
const Project_ui_control_settingsDBApi = require('../db/api/project_ui_control_settings');
|
|
const { wrapAsync, commonErrorHandler, isUuidV4 } = require('../helpers');
|
|
const { checkCrudPermissions } = require('../middlewares/check-permissions');
|
|
const RuntimePresentationAccessService = require('../services/runtime-presentation-access');
|
|
|
|
const router = express.Router();
|
|
const jwtAuth = passport.authenticate('jwt', { session: false });
|
|
|
|
const allowAuthenticatedRead = (req, _res, next) => {
|
|
if (['GET', 'OPTIONS'].includes(req.method)) {
|
|
req.isRuntimePublicRequest = true;
|
|
}
|
|
return next();
|
|
};
|
|
|
|
const getRuntimeProjectSlug = async (req) => {
|
|
if (req.runtimeContext?.headerProjectSlug) {
|
|
return req.runtimeContext.headerProjectSlug;
|
|
}
|
|
|
|
if (!isUuidV4(req.params.projectId)) {
|
|
return null;
|
|
}
|
|
|
|
const project = await db.projects.findByPk(req.params.projectId, {
|
|
attributes: ['slug'],
|
|
});
|
|
return project?.slug || null;
|
|
};
|
|
|
|
const requireProductionOrAuth = async (req, res, next) => {
|
|
const { environment } = req.params;
|
|
const isProduction = environment === 'production';
|
|
const isReadOnly = ['GET', 'OPTIONS'].includes(req.method);
|
|
|
|
let runtimeProjectSlug = null;
|
|
let isPrivateProductionPresentation = false;
|
|
|
|
try {
|
|
runtimeProjectSlug = await getRuntimeProjectSlug(req);
|
|
isPrivateProductionPresentation =
|
|
await RuntimePresentationAccessService.isPrivateProductionPresentation(
|
|
runtimeProjectSlug,
|
|
);
|
|
} catch (error) {
|
|
return next(error);
|
|
}
|
|
|
|
if (isProduction && isReadOnly && !isPrivateProductionPresentation) {
|
|
return next();
|
|
}
|
|
|
|
if (isProduction && isReadOnly && isPrivateProductionPresentation) {
|
|
return passport.authenticate(
|
|
'jwt',
|
|
{ session: false },
|
|
async (error, user) => {
|
|
if (error) return next(error);
|
|
if (!user) {
|
|
return res.status(401).send({ message: 'Authentication required' });
|
|
}
|
|
|
|
req.currentUser = user;
|
|
const canAccess =
|
|
await RuntimePresentationAccessService.canUserAccessPrivateProductionPresentation(
|
|
user,
|
|
runtimeProjectSlug,
|
|
);
|
|
|
|
if (!canAccess) {
|
|
return res
|
|
.status(403)
|
|
.send({ message: 'Presentation access denied' });
|
|
}
|
|
|
|
req.isRuntimePublicRequest = true;
|
|
return next();
|
|
},
|
|
)(req, res, next);
|
|
}
|
|
|
|
return jwtAuth(req, res, next);
|
|
};
|
|
|
|
router.use(allowAuthenticatedRead);
|
|
router.use(checkCrudPermissions('project_ui_control_settings'));
|
|
|
|
router.get(
|
|
'/project/:projectId/env/:environment',
|
|
requireProductionOrAuth,
|
|
wrapAsync(async (req, res) => {
|
|
const { projectId, environment } = req.params;
|
|
|
|
if (!isUuidV4(projectId)) {
|
|
return res.status(400).send({ message: 'Invalid project ID' });
|
|
}
|
|
|
|
if (!['dev', 'stage', 'production'].includes(environment)) {
|
|
return res.status(400).send({ message: 'Invalid environment' });
|
|
}
|
|
|
|
const settings =
|
|
await Project_ui_control_settingsService.findByProjectAndEnvironment(
|
|
projectId,
|
|
environment,
|
|
req.currentUser,
|
|
);
|
|
|
|
res.status(200).send(settings);
|
|
}),
|
|
);
|
|
|
|
router.put(
|
|
'/project/:projectId/env/:environment',
|
|
jwtAuth,
|
|
wrapAsync(async (req, res) => {
|
|
const { projectId, environment } = req.params;
|
|
|
|
if (!isUuidV4(projectId)) {
|
|
return res.status(400).send({ message: 'Invalid project ID' });
|
|
}
|
|
|
|
if (!['dev', 'stage', 'production'].includes(environment)) {
|
|
return res.status(400).send({ message: 'Invalid environment' });
|
|
}
|
|
|
|
const settings = await Project_ui_control_settingsService.upsertForProject(
|
|
projectId,
|
|
environment,
|
|
req.body.data || {},
|
|
req.currentUser,
|
|
);
|
|
|
|
res.status(200).send(settings);
|
|
}),
|
|
);
|
|
|
|
router.delete(
|
|
'/project/:projectId/env/:environment',
|
|
jwtAuth,
|
|
wrapAsync(async (req, res) => {
|
|
const { projectId, environment } = req.params;
|
|
|
|
if (!isUuidV4(projectId)) {
|
|
return res.status(400).send({ message: 'Invalid project ID' });
|
|
}
|
|
|
|
if (!['dev', 'stage', 'production'].includes(environment)) {
|
|
return res.status(400).send({ message: 'Invalid environment' });
|
|
}
|
|
|
|
const settings =
|
|
await Project_ui_control_settingsService.findByProjectAndEnvironment(
|
|
projectId,
|
|
environment,
|
|
req.currentUser,
|
|
);
|
|
|
|
if (settings) {
|
|
await Project_ui_control_settingsService.remove({
|
|
id: settings.id,
|
|
currentUser: req.currentUser,
|
|
runtimeContext: req.runtimeContext,
|
|
});
|
|
}
|
|
|
|
res.status(200).send({ success: true });
|
|
}),
|
|
);
|
|
|
|
router.get(
|
|
'/',
|
|
jwtAuth,
|
|
wrapAsync(async (req, res) => {
|
|
const payload = await Project_ui_control_settingsDBApi.findAll(req.query);
|
|
res.status(200).send(payload);
|
|
}),
|
|
);
|
|
|
|
router.use('/', commonErrorHandler);
|
|
|
|
module.exports = router;
|