From 8d686b54d449fb528511209618ccf565ee56514e Mon Sep 17 00:00:00 2001 From: STEINNI Date: Sat, 13 Jun 2026 14:21:20 +0000 Subject: [PATCH] cleand config file & more --- api/index.js | 3 + api/sims.js | 134 +++++++++++++++++++++++++++++++++++++++++++++ api/users.js | 2 +- p42ApiEndpoints.js | 10 ++-- p42api.js | 9 ++- p42api.json | 4 ++ startApi.sh | 31 +++++++++-- 7 files changed, 179 insertions(+), 14 deletions(-) create mode 100644 api/sims.js create mode 100644 p42api.json diff --git a/api/index.js b/api/index.js index d36a0d4..663a4d6 100644 --- a/api/index.js +++ b/api/index.js @@ -1,17 +1,20 @@ import { methods as userMethods, mappings as userMappings } from './users.js' import { methods as agentMethods, mappings as agentMappings } from './agents.js' import { methods as keyframesMethods, mappings as keyframesMappings } from './keyframes.js' +import { methods as simsMethods, mappings as simsMappings } from './sims.js' export const apiMappings = [ ...userMappings, ...agentMappings, ...keyframesMappings, + ...simsMappings, ] export const apiMethods = { ...userMethods, ...agentMethods, ...keyframesMethods, + ...simsMethods, } diff --git a/api/sims.js b/api/sims.js new file mode 100644 index 0000000..679c8d6 --- /dev/null +++ b/api/sims.js @@ -0,0 +1,134 @@ +import { authGuard } from '../authGuard.js' +import { UUID } from 'uuidv7' + +export const mappings = [ + { method: 'post', url:'/sims', handler: 'listSims', middlewares: [authGuard]}, + { method: 'get', url:'/sims/:simid', handler: 'getSim', middlewares: [authGuard]}, + { method: 'put', url:'/sims', handler: 'createSim', middlewares: [authGuard]}, + { method: 'put', url:'/sims/:simid/start', handler: 'startSim', middlewares: [authGuard]}, + { method: 'put', url:'/sims/:simid/pause', handler: 'pauseSim', middlewares: [authGuard]}, +] + +export const methods = { + + async listSims(req, res) { + const userUuid = req.session.userInfos.identity.uuid + const results = await this.db.execute(` + SELECT s.sim_id, s.sim_name, BIN_TO_UUID(s.sim_root_kf_uuid) AS sim_root_kf_uuid + FROM p42SIM.simulations s + INNER JOIN simowners o ON o.own_sim_id = s.sim_id + INNER JOIN users u ON o.own_usr_id = u.usr_id + WHERE u.usr_uuid = ? + ORDER BY s.sim_name`, [userUuid]) + this.ok(req, res, results) + }, + + async getSim(req, res) { + const simId = req.params.simid + if(!/^[1-9]\d*$/.test(simId)) { + this.err(req, res, `Cannot find this simulation !`, `Invalid simulation ID !`, 400) + return + } + + const userUuid = req.session.userInfos.identity.uuid + const results = await this.db.execute(` + SELECT s.sim_id, s.sim_name, BIN_TO_UUID(s.sim_root_kf_uuid) AS sim_root_kf_uuid + FROM p42SIM.simulations s + INNER JOIN simowners o ON o.own_sim_id = s.sim_id + INNER JOIN users u ON o.own_usr_id = u.usr_id + WHERE s.sim_id = ? AND u.usr_uuid = ?`, [simId, userUuid]) + + if(results.length != 1) { + this.err(req, res, `Cannot find this simulation !`, `Simulation ${simId} not found !`, 404) + return + } + this.ok(req, res, results[0]) + }, + + async createSim(req, res) { + const[isOk, payload, errors] = this.utils.validateMapObject(req.body, + { + 'simName': ((val, obj) => ((typeof(val) == 'string') && (new RegExp(/^[\w\s]{5,200}$/).test(val)))), + 'kfId': ((val, obj) => (this.utils.isValidUUIDV7(val))), + }, + { + 'simName': 'simName', + 'kfId': 'kfId', + }) + if(!isOk) { + this.err(req, res, `Cannot create this simulation !`, `Validations errors for creating simulation : ${errors.join(', ')}`, 400) + return + } + + const kfResults = await this.db.execute(` + SELECT ekf_uuid + FROM p42SIM.edited_keyframes + WHERE ekf_uuid = UUID_TO_BIN(?)`, [payload.kfId]) + if(kfResults.length != 1) { + this.err(req, res, `Cannot create this simulation !`, `Keyframe ${payload.kfId} not found !`, 404) + return + } + + const userUuid = req.session.userInfos.identity.uuid + + const result = await this.db.execute(` + INSERT INTO p42SIM.simulations + (sim_name, sim_root_kf_uuid) + VALUES (?, ?)`, + [payload.simName, UUID.parse(payload.kfId).bytes]) + + await this.db.execute(` + INSERT INTO simowners (own_usr_id, own_sim_id) + SELECT usr_id, ? + FROM users + WHERE usr_uuid = ?`, [result.insertId, userUuid]) + + this.ok(req, res, { simId: result.insertId }) + }, + + async startSim(req, res) { + const simId = req.params.simid + if(!/^[1-9]\d*$/.test(simId)) { + this.err(req, res, `Cannot start this simulation !`, `Invalid simulation ID !`, 400) + return + } + + const userUuid = req.session.userInfos.identity.uuid + const results = await this.db.execute(` + SELECT s.sim_id + FROM p42SIM.simulations s + INNER JOIN simowners o ON o.own_sim_id = s.sim_id + INNER JOIN users u ON o.own_usr_id = u.usr_id + WHERE s.sim_id = ? AND u.usr_uuid = ?`, [simId, userUuid]) + if(results.length != 1) { + this.err(req, res, `Cannot start this simulation !`, `Simulation ${simId} not found !`, 404) + return + } + + // TODO: delegate to GodDaemons runtime + this.ok(req, res, { simId: Number(simId) }) + }, + + async pauseSim(req, res) { + const simId = req.params.simid + if(!/^[1-9]\d*$/.test(simId)) { + this.err(req, res, `Cannot pause this simulation !`, `Invalid simulation ID !`, 400) + return + } + + const userUuid = req.session.userInfos.identity.uuid + const results = await this.db.execute(` + SELECT s.sim_id + FROM p42SIM.simulations s + INNER JOIN simowners o ON o.own_sim_id = s.sim_id + INNER JOIN users u ON o.own_usr_id = u.usr_id + WHERE s.sim_id = ? AND u.usr_uuid = ?`, [simId, userUuid]) + if(results.length != 1) { + this.err(req, res, `Cannot pause this simulation !`, `Simulation ${simId} not found !`, 404) + return + } + + // TODO: delegate to GodDaemons runtime + this.ok(req, res, { simId: Number(simId) }) + }, +} diff --git a/api/users.js b/api/users.js index d50b44e..6c327d2 100644 --- a/api/users.js +++ b/api/users.js @@ -22,7 +22,7 @@ export const methods = { let trials = 3 let locked = false if(req.session.userInfos && req.session.userInfos.identity && req.session.userInfos.identity.username) { - const results = await this.db.execute('SELECT usr_trials, usr_locked FROM users WHERE usr_name = ?', [req.session.userInfos.username]) + const results = await this.db.execute('SELECT usr_trials, usr_locked FROM users WHERE usr_name = ?', [req.session.userInfos.identity.username]) if(results.length==1){ trials = results[0].usr_trials locked = results[0].usr_locked diff --git a/p42ApiEndpoints.js b/p42ApiEndpoints.js index c3d446c..6e157c5 100644 --- a/p42ApiEndpoints.js +++ b/p42ApiEndpoints.js @@ -6,7 +6,6 @@ export class P42ApiEndpoints{ constructor(app, db) { this.db = new MySQLClient(db, 60) this.app = app - this.userinfos = null this.utils = new Utils() Object.assign(this, apiMethods) this.registerPaths() @@ -47,12 +46,13 @@ export class P42ApiEndpoints{ this.ok(req, res, {}) } - hasRole(roles) { - if(!this.userinfos.userRoles) return(false) - if(typeof(roles) == 'string') return(this.userinfos.userRoles.includes(roles)) + hasRole(req, roles) { + const userRoles = req.session?.userInfos?.roles + if(!userRoles) return(false) + if(typeof(roles) == 'string') return(userRoles.includes(roles)) else if(Array.isArray(roles)) { for(let role of roles) { - if(this.userinfos.userRoles.includes(role)) return(true) + if(userRoles.includes(role)) return(true) } } return(false) diff --git a/p42api.js b/p42api.js index 1d22db4..a4e81a1 100755 --- a/p42api.js +++ b/p42api.js @@ -21,14 +21,19 @@ const mysqlCreds = { // host: '127.0.0.1', // port: 3306, socketPath: '/var/run/mysqld/mysqld.sock', - user: 'p42', - password: 'C3h=V9!r>Mvc>skxPf9?W2P3duJTk', + user: process.env.user, + password: process.env.mysql_pass, database: 'p42GUI', waitForConnections: true, connectionLimit: 10, queueLimit: 0 } +if(!mysqlCreds.user || !mysqlCreds.password) { + console.error('Missing MySQL credentials: set user and mysql_pass in environment') + process.exit(1) +} + const db = await mysql.createConnection(mysqlCreds) const sessionStore = new MySQLStore({ diff --git a/p42api.json b/p42api.json new file mode 100644 index 0000000..6589342 --- /dev/null +++ b/p42api.json @@ -0,0 +1,4 @@ +{ + "listenHost": "127.0.0.1", + "listenPort": "8123" +} diff --git a/startApi.sh b/startApi.sh index 6284241..a94cf3e 100755 --- a/startApi.sh +++ b/startApi.sh @@ -1,13 +1,32 @@ #!/bin/sh -cd /opt/p42api/ +. /etc/p42/secrets.env + +daemon=p42api +logfile=p42api.log + + +pid=$(pgrep -f "$daemon") -pid=`ps -ef | grep p42api |grep -v grep | awk '{print $2}'` if [ -z "$pid" ] then - node p42api.js > p42api.log 2>&1 & + node "${daemon}.js" > "$logfile" 2>&1 & + pid=$! + + sleep 1 + + if kill -0 "$pid" 2>/dev/null + then + echo "" + echo "$daemon is now running with PID=$pid" + echo "" + else + echo "" + echo "Failed to start $daemon. Check p42api.log" + echo "" + fi else - echo '' - echo 'Already running PID='"$pid"' (use stopApi.sh to stop it)' - echo '' + echo "" + echo "$daemon is already running with PID=$pid" + echo "" fi