This is the code that runs https://bandolier.learnjsthehardway.com/ for you to review. It uses the https://git.learnjsthehardway.com/learn-javascript-the-hard-way/bandolier-template to create the documentation for the project.
https://bandolier.learnjsthehardway.com/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
4.2 KiB
143 lines
4.2 KiB
import { knex, validation } from '../../lib/ormish.js';
|
|
import logging from "../../lib/logging.js";
|
|
import { developer_admin, API } from '../../lib/api.js';
|
|
|
|
const log = logging.create("api/admin/table.js");
|
|
|
|
export const get = async (req, res) => {
|
|
const api = new API(req, res);
|
|
const { name, search, row_id, currentPage } = req.query;
|
|
|
|
try {
|
|
const page = parseInt(currentPage || "0", 10);
|
|
|
|
if(!api.admin_authenticated) {
|
|
return api.error(401, "Admin rights required.");
|
|
} else if(name && search) {
|
|
// get the list of columns to search
|
|
const col_info = await knex(name).columnInfo();
|
|
const query = knex(name);
|
|
let columns = Object.getOwnPropertyNames(col_info);
|
|
|
|
for(let col of columns) {
|
|
// SECURITY: string interpolation but not sure how to do this without it
|
|
query.orWhere(col, "like", `%${search}%`);
|
|
}
|
|
|
|
// loop through and construct a mega where clause
|
|
let result = await query.paginate({perPage: 20, currentPage: page});
|
|
|
|
return api.reply(200, result);
|
|
} else if(name && !row_id) {
|
|
|
|
// TODO: restrict the tables that can be queried?
|
|
let result = await knex(name).paginate({perPage: 20, currentPage: page});
|
|
|
|
return api.reply(200, result);
|
|
} else if(name && row_id) {
|
|
let result = await knex(name).where({id: row_id}).first();
|
|
return api.reply(200, result);
|
|
} else {
|
|
return api.error(500, "name query parameter required, or name and row_id.");
|
|
}
|
|
} catch(error) {
|
|
log.error(error);
|
|
return api.error(500, "Internal server error.");
|
|
}
|
|
}
|
|
|
|
get.authenticated = !developer_admin;
|
|
|
|
export const del = async (req, res) => {
|
|
const api = new API(req, res);
|
|
const { name, row_id } = req.query;
|
|
|
|
try {
|
|
if(!api.admin_authenticated) {
|
|
return api.error(401, "Admin rights required.");
|
|
} else if(name && row_id) {
|
|
let res = await knex(name).where({id: row_id}).delete();
|
|
return api.reply(200, {message: "OK", result: res});
|
|
} else {
|
|
return api.error(500, "name and row_id required for delete");
|
|
}
|
|
} catch(error) {
|
|
log.error(error);
|
|
return api.error(500, "Internal server error.");
|
|
}
|
|
}
|
|
|
|
del.authenticated = !developer_admin;
|
|
|
|
export const post = async (req, res) => {
|
|
const api = new API(req, res);
|
|
const { name, row_id } = req.query;
|
|
|
|
try {
|
|
if(!api.admin_authenticated) {
|
|
return api.error(401, "Admin rights required.");
|
|
} else if(name && row_id) {
|
|
// normally the validation rules come from the
|
|
// model class once and placed at the top of the
|
|
// module, but here we get it dynamically based
|
|
// on the name.
|
|
const rules = validation(name, {}, true);
|
|
const data = api.validate(rules);
|
|
|
|
// remove the id since they can't set it
|
|
delete data["id"];
|
|
|
|
if(!data._valid) {
|
|
return api.validation_error(res, data);
|
|
} else {
|
|
// remove id so it's not updated too
|
|
api.clean_form(data, rules, ["id"]);
|
|
let res = await knex(name).
|
|
where({id: row_id}).update(data);
|
|
|
|
return api.reply(200, {message: "OK", result: res});
|
|
}
|
|
} else {
|
|
return api.error(500, "name and row_id required for delete");
|
|
}
|
|
} catch(error) {
|
|
log.error(error);
|
|
return api.error(500, error.message || "Internal server error.");
|
|
}
|
|
}
|
|
|
|
post.authenticated = !developer_admin;
|
|
|
|
export const put = async (req, res) => {
|
|
const api = new API(req, res);
|
|
const { name } = req.query;
|
|
|
|
try {
|
|
if(!api.admin_authenticated) {
|
|
return api.error(401, "Admin rights required.");
|
|
} else if(name) {
|
|
const rules = validation(name, {}, true);
|
|
// don't validate id or accept it
|
|
const data = api.validate(rules);
|
|
|
|
// remove the id since they can't set it
|
|
delete data["id"];
|
|
|
|
if(!data._valid) {
|
|
return api.validation_error(res, data);
|
|
} else {
|
|
api.clean_form(data, rules, ["id"]);
|
|
let res = await knex(name).insert(data);
|
|
|
|
return api.reply(200, {message: "OK", id: res[0]});
|
|
}
|
|
} else {
|
|
return api.error(500, "name required for delete");
|
|
}
|
|
} catch(error) {
|
|
log.error(error);
|
|
return api.error(500, "Internal server error.");
|
|
}
|
|
}
|
|
|
|
put.authenticated = !developer_admin;
|
|
|