/**
* @module routes/api/roomdata
* @author jesse reichler <mouser@donationcoder.com>
* @copyright 4/16/20
* @description
* ##### Overview
* This file handles all requests related to the programmatic API interface for accessing the system.
* These routes are all intended to be called programmatically by other code, and so should all return json replies.
*/
"use strict";
// modules
const express = require("express");
// requirement service locator
const jrequire = require("../../helpers/jrequire");
// controllers
const arserver = jrequire("arserver");
// helpers
const JrContext = require("../../helpers/jrcontext");
const jrhExpress = require("../../helpers/jrh_express");
const jrhMisc = require("../../helpers/jrh_misc");
const jrdebug = require("../../helpers/jrdebug");
// models
const RoomModel = jrequire("models/room");
const AppModel = jrequire("models/app");
// constants
const appdef = jrequire("appdef");
//---------------------------------------------------------------------------
/**
* Add the API routes
*
* @param {string} urlPath - the base path of these relative paths
* @returns router object
*/
function setupRouter(urlPath) {
// create express router
const router = express.Router();
// setup routes
router.all("/lookup", routerLookup);
router.all("/add", routerAdd);
// return router
return router;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
async function routerLookup(req, res, next) {
const jrContext = JrContext.makeNew(req, res, next);
// new
const user = await arserver.lookupLoggedInUser(jrContext);
if (!user) {
jrContext.pushError("Failed to authenticate user for request; missing access token?");
}
if (jrContext.isError()) {
jrhExpress.sendJsonErrorAuthToken(jrContext);
return;
}
// the api roomdata list function is for retrieving a list of (matching) roomdata items
// for a specific appid, and roomid, with optional filters (on data)
const query = jrhExpress.parseReqGetJsonField(jrContext, "query");
if (jrContext.isError()) {
jrhExpress.sendJsonResult(jrContext, 400);
return;
}
// now we expect to find appid, and room shortcode; error if missing
const appShortcode = jrhMisc.getNonNullValueFromObject(jrContext, query, "appShortcode", "application shortcode hosting the room");
const roomShortcode = jrhMisc.getNonNullValueFromObject(jrContext, query, "roomShortcode", "room shortcode");
if (jrContext.isError()) {
jrhExpress.sendJsonResult(jrContext, 400);
return;
}
// look up app id
const app = await AppModel.mFindOneByShortcode(appShortcode);
if (!app) {
jrContext.pushError("Specified application shortcode [" + appShortcode + "] could not be found.");
jrhExpress.sendJsonResult(jrContext, 400);
return;
}
// look up the room
const room = await RoomModel.mFindOneByAppIdAndRoomShortcode(app.id, roomShortcode);
if (!room) {
jrContext.pushError("Could not find specified room with shortcode [" + roomShortcode + "] in specified app [" + appShortcode + "].");
jrhExpress.sendJsonResult(jrContext, 400);
return;
}
// now let's ask if user is actually ALLOWED to look at this room room
const permission = appdef.DefAclActionView;
const permissionObjType = RoomModel.getAclName();
const permissionObjId = room.getIdAsM();
const hasPermission = await user.aclHasPermission(jrContext, permission, permissionObjType, permissionObjId);
if (!hasPermission) {
jrhExpress.sendJsonErorrAcl(jrContext, permission, permissionObjType, permissionObjId);
return;
}
// success
const returnData = {
room,
// oringinalQuery: query,
};
jrhExpress.sendJsonDataSuccess(jrContext, "room", returnData);
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
async function routerAdd(req, res, next) {
const jrContext = JrContext.makeNew(req, res, next);
// new
const user = await arserver.lookupLoggedInUser(jrContext);
if (!user) {
jrContext.pushError("Failed to authenticate user for request; missing access token?");
}
if (jrContext.isError()) {
jrhExpress.sendJsonErrorAuthToken(jrContext);
return;
}
// get query
const query = jrhExpress.parseReqGetJsonField(jrContext, "query");
if (jrContext.isError()) {
jrhExpress.sendJsonResult(jrContext, 400);
return;
}
// allow lookup by app shortcode instead of id
if (!query.appId && query.appShortcode) {
const queryApp = await AppModel.mFindOneByShortcode(query.appShortcode);
query.appId = !queryApp ? null : queryApp.getIdAsString();
}
// now let's ask if user is actually ALLOWED to add a room to this app
const appId = query.appId;
const permission = appdef.DefAclActionAddData;
const permissionObjType = AppModel.getAclName();
const permissionObjId = appId;
const hasPermission = await user.aclHasPermission(jrContext, permission, permissionObjType, permissionObjId);
if (!hasPermission) {
jrhExpress.sendJsonErorrAcl(jrContext, permission, permissionObjType, permissionObjId);
return;
}
// create the item
const room = RoomModel.createModel();
// force some values
room.creator = user.getIdAsM();
// validate and save the fields passed
const saveFields = RoomModel.getSaveFields("add");
const preValidatedFields = [];
// form fields that we dont complain about finding even though they arent for the form object
const ignoreFields = [];
const roomdoc = await RoomModel.validateSave(jrContext, {}, true, user, query, saveFields, preValidatedFields, ignoreFields, room, RoomModel.getShouldBeOwned());
if (jrContext.isError()) {
jrhExpress.sendJsonResult(jrContext, 400);
return;
}
// success
const returnData = {
room: roomdoc,
};
// provide it
jrhExpress.sendJsonDataSuccess(jrContext, "room", returnData);
}
//---------------------------------------------------------------------------
module.exports = {
setupRouter,
};