@@ -3,7 +3,7 @@ const Form = require("@saltcorn/data/models/form");
33const File = require ( "@saltcorn/data/models/file" ) ;
44const Plugin = require ( "@saltcorn/data/models/plugin" ) ;
55const db = require ( "@saltcorn/data/db" ) ;
6- const { getState } = require ( "@saltcorn/data/db/state" ) ;
6+ const { getState, features } = require ( "@saltcorn/data/db/state" ) ;
77const { spawn } = require ( "child_process" ) ;
88const fs = require ( "fs" ) . promises ;
99const path = require ( "path" ) ;
@@ -250,12 +250,30 @@ const configuration_workflow = () =>
250250 ] ,
251251 } ) ;
252252
253+ // Only admins may trigger a rebuild of the main bundle. Uses the centralized
254+ // authorize_api hook when the running core supports it (features.authorize_access_hooks),
255+ // falling back to a plain role check on older cores.
256+ const isRunBuildAuthorized = async ( req ) => {
257+ if ( features ?. authorize_access_hooks ) {
258+ return await getState ( ) . authorizeApi ( req . user , {
259+ name : "react/run_build" ,
260+ action : "post" ,
261+ req,
262+ } ) ;
263+ }
264+ return ! ! ( req . user && req . user . role_id <= 1 ) ;
265+ } ;
266+
253267const routes = ( { app_code_source, app_code_path, sc_folder, build_mode } ) => {
254268 return [
255269 {
256270 url : "/react/run_build" ,
257271 method : "post" ,
258272 callback : async ( req , res ) => {
273+ if ( ! ( await isRunBuildAuthorized ( req ) ) ) {
274+ res . status ( 401 ) . json ( { error : "Not authorized" } ) ;
275+ return ;
276+ }
259277 getState ( ) . log ( 5 , "Building your React code" ) ;
260278 getState ( ) . log (
261279 6 ,
@@ -297,6 +315,15 @@ module.exports = {
297315 plugin_name : "react" ,
298316 configuration_workflow,
299317 routes,
318+ authorize_api : ( cfg ) => async ( request , user ) => {
319+ if ( request . name !== "react/run_build" ) return { decision : "deny" } ;
320+ return user && user . role_id <= 1
321+ ? { decision : "allow" }
322+ : {
323+ decision : "deny" ,
324+ reason : "Only admins may rebuild the React bundle" ,
325+ } ;
326+ } ,
300327 viewtemplates : ( cfg ) => [ require ( "./react_view" ) ] ,
301328 headers : ( cfg ) => {
302329 const tenant = db . getTenantSchema ( ) || "public" ;
0 commit comments