diff --git a/api/agents.js b/api/agents.js index 32971dc..b4555c2 100644 --- a/api/agents.js +++ b/api/agents.js @@ -1,8 +1,9 @@ import { authGuard } from '../authGuard.js' export const mappings = [ - { method: 'get', url:'/agent-types', handler: 'getAgentTypes', middlewares: [authGuard]}, + { method: 'get', url:'/agent-types/:family', handler: 'getAgentTypes', middlewares: [authGuard]}, { method: 'get', url:'/agent-sprites/:group', handler: 'getAgentSprites', middlewares: [authGuard]}, + { method: 'get', url:'/agent/:id', handler: 'getAgentProps', middlewares: [authGuard]}, ] export const methods = { @@ -24,9 +25,9 @@ export const methods = { }) }, - async getAgentSprites(req, res) { + async getAgentSprites(req, res) { //TODO implement group & family filtering const results = await this.db.execute(` - SELECT * + SELECT atp_id, atp_name, asp_3d FROM p42SIM.agent_types LEFT JOIN p42GUI.agents_sprites on asp_atp_id = atp_id WHERE asp_group = ?`, [req.params.group]) @@ -35,7 +36,31 @@ export const methods = { fullObj[row.atp_name] = row.asp_3d } this.ok(req, res, { - agentSprites: fullObj + agentSprites: results + }) + }, + + async getAgentProps(req, res) { + let results + if(req.params.id){ + results = await this.db.execute(` + SELECT * + FROM p42SIM.agent_types + WHERE atp_id = ? + `, [req.params.id]) + + } else { + this.err(req, res, `Invalid request`, `Missing Agent ID`, 401) + return + } + + if(results.length==0){ + this.err(req, res, `Agent not found !`, `Unknown Agent ID (${req.params.id})`, 401) + return + } + + this.ok(req, res, { + agentProperties : results[0] }) }, } \ No newline at end of file diff --git a/api/keyframes.js b/api/keyframes.js new file mode 100644 index 0000000..edd8124 --- /dev/null +++ b/api/keyframes.js @@ -0,0 +1,72 @@ +import { authGuard } from '../authGuard.js' +import { uuidv7 } from "uuidv7" + + +export const mappings = [ + { method: 'put', url:'/keyframes/:kfid', handler: 'saveKeyframe', middlewares: [authGuard]}, + { method: 'put', url:'/keyframes', handler: 'createKeyframe', middlewares: [authGuard]}, +] + +export const methods = { + async createKeyframe(req, res) { + const[isOk, payload, errors] = this.utils.validateMapObject(req.body, + { + 'kfName': ((val, obj) => ( (typeof(val)=='string') && (new RegExp(/^\w{5,50}$/).test(val))) ), + 'prevKFId': ((val, obj) => ( (typeof(val)=='undefined') || (this.utils.isValidUUIDV7(val)) ) ), + }, + { + 'kfName': 'kfName', + 'prevKFId': 'prevKFId', + }) + if(!isOk){ + this.err(req, res,`Cannot create this keyframe ! `, `Validations errors for creating KF : ${errors.join(', ')}`, 400) + return + } + + const kfid = uuidv7() + await this.db.execute(` + INSERT INTO edited_keyframes + (ekf_uuid, ekf_name, ekf_prev_uuid) + VALUES (?, ?, ?)`, + [kfid, payload.kfName, prevKFId || null]) + + this.ok(req, res, { kfid: kfid }) + }, + + async saveKeyframe(req, res) { + const kfid = req.params.kfid + if(!this.utils.isValidUUIDV7(kfid)) { + this.err(req, res,`Cannot create Keyframe ! `, `Invalid Keyframe ID !`, 400) + return + } + + const[isOk, payload, errors] = this.utils.validateMapArray(req.body, + { + 'aid': ((val, obj) => (this.utils.isValidUUIDV7(val)) ), + 'storeValues': ((val, obj) => (typeof(val)==='object') ), + 'gpsValues': ((val, obj) => (typeof(val)==='object') ), + }, + { 'aid': 'aid', + 'storeValues': 'storeValues', + 'gpsValues': 'gpsValues', + } + ) + if(!isOk){ + this.err(req, res,`Cannot save this keyframe ! `, `Validations errors for saving KF : ${errors.join(', ')}`, 400) + return + } + + await this.db.execute(`DELETE FROM edited_kf_store WHERE ekfs_ekf_uuid = ?`, [kfid]) + for(const entry of payload){ + await this.db.execute(` + INSERT INTO edited_kf_store + (ekfs_ekf_uuid, ekfs_agent_id, ekfs_store_value, ekfs_gps_values) + VALUES (?, ?, ?, ?)`, + [kfid, entry.aid, entry.storeValues, entry.gpsValues]) + } + + this.ok(req, res, { kfid: kfid }) + }, + + +} \ No newline at end of file diff --git a/helpers/utils.js b/helpers/utils.js index ccf1006..3f9a37f 100644 --- a/helpers/utils.js +++ b/helpers/utils.js @@ -12,11 +12,16 @@ export class Utils { return(mailRFC5322Regex.test(val)) } - isValidUUID(val) { + isValidUUIDV4(val) { const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i return(uuidRegex.test(val)) } + isValidUUIDV7(val) { + const reUUIDv7 = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i + return(uuidRegex.test(val)) + } + isIterable(obj) { if (obj == null) { return false; diff --git a/p42api.js b/p42api.js index 4e3304a..3dbce16 100755 --- a/p42api.js +++ b/p42api.js @@ -43,6 +43,7 @@ const db = await mysql.createConnection(mysqlCreds) const sessionStore = new MySQLStore({ createDatabaseTable: false, clearExpired: true, + expiration: 1000 * 60 * 60, schema: { tableName: 'sessions', columnNames: { @@ -60,8 +61,9 @@ app.use(session({ store: sessionStore, resave: false, saveUninitialized: false, + rolling: true, //Autorefresh cookie: { - maxAge: 1000 * 60 * 60 * 4, + maxAge: 1000 * 60 * 60, secure: true, //See trust proxy above sameSite: 'lax', }, diff --git a/package.json b/package.json index 55121c7..2fd9574 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "express-session": "^1.18.2", "mysql": "^2.18.1", "mysql2": "^3.14.3", - "swagger-ui-express": "^5.0.1" + "swagger-ui-express": "^5.0.1", + "uuidv7": "^1.0.2" } }