mirror of
https://gitlab.com/wgp/dougal/software.git
synced 2025-12-06 11:07:08 +00:00
This will be used by the new event dialogue in the frontend to get shotpoint information when creating or editing events.
289 lines
7.2 KiB
JavaScript
289 lines
7.2 KiB
JavaScript
|
|
const http = require('http');
|
|
const express = require('express');
|
|
const cookieParser = require('cookie-parser')
|
|
|
|
const maybeSendAlert = require("../lib/alerts");
|
|
const mw = require('./middleware');
|
|
|
|
const app = express();
|
|
const verbose = process.env.NODE_ENV != 'test';
|
|
|
|
app.map = function(a, route){
|
|
route = route || '';
|
|
for (var key in a) {
|
|
switch (typeof a[key]) {
|
|
// { '/path': { ... }}
|
|
case 'object':
|
|
if (!Array.isArray(a[key])) {
|
|
app.map(a[key], route + key);
|
|
break;
|
|
} // else drop through
|
|
// get: function(){ ... }
|
|
case 'function':
|
|
if (verbose) console.log('%s %s', key, route);
|
|
app[key](route, a[key]);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
app.use(express.json({type: "application/json", strict: false, limit: '10mb'}));
|
|
app.use(express.urlencoded({ type: "application/x-www-form-urlencoded", extended: true }));
|
|
app.use(express.text({type: "text/*", limit: '10mb'}));
|
|
app.use((req, res, next) => {
|
|
res.set("Access-Control-Allow-Origin", "*");
|
|
res.set("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, PATCH, DELETE");
|
|
res.set("Access-Control-Allow-Headers", "Content-Type");
|
|
next();
|
|
});
|
|
|
|
app.use(cookieParser());
|
|
app.use(mw.auth.jwt);
|
|
// app.use(mw.auth.access({path: {allow:["^/login", "^/user$"]}}));
|
|
|
|
// Adds arbitrary information to the request object
|
|
const meta = (key, value) => {
|
|
return (req, res, next) => {
|
|
if (!req.meta) {
|
|
req.meta = {};
|
|
}
|
|
|
|
if (key) {
|
|
req.meta[key] = value;
|
|
}
|
|
|
|
next();
|
|
}
|
|
};
|
|
|
|
// Short for adding meta to all methods
|
|
const allMeta = (key, value) => {
|
|
return { all: [ meta(key, value) ] };
|
|
};
|
|
|
|
// These routes do not require authentication
|
|
app.map({
|
|
'*': { all: [ meta() ] }, // Create the req.meta object
|
|
'/login': {
|
|
post: [ mw.user.login ]
|
|
},
|
|
'/logout': {
|
|
get: [ mw.user.logout ],
|
|
post: [ mw.user.logout ]
|
|
},
|
|
'/': {
|
|
get: [ mw.openapi.get ]
|
|
}
|
|
});
|
|
|
|
app.use(mw.auth.authentify);
|
|
|
|
// We must be authenticated before we can access these
|
|
app.map({
|
|
'/project': {
|
|
get: [ mw.project.list ], // Get list of projects
|
|
},
|
|
'/project/:project': {
|
|
get: [ mw.project.get ], // Get project data
|
|
},
|
|
'/project/:project/summary': {
|
|
get: [ mw.project.get ],
|
|
},
|
|
'/project/:project/gis': {
|
|
get: [ mw.gis.project.bbox ]
|
|
},
|
|
'/project/:project/gis/preplot': {
|
|
get: [ mw.gis.project.preplot ]
|
|
},
|
|
'/project/:project/gis/preplot/:featuretype(line|point)': {
|
|
get: [ mw.gis.project.preplot ]
|
|
},
|
|
'/project/:project/gis/raw/:featuretype(line|point)': {
|
|
get: [ mw.gis.project.raw ]
|
|
},
|
|
'/project/:project/gis/final/:featuretype(line|point)': {
|
|
get: [ mw.gis.project.final ]
|
|
},
|
|
'/project/:project/line/': {
|
|
get: [ mw.line.list ],
|
|
},
|
|
'/project/:project/line/:line': {
|
|
// get: [ mw.line.get ],
|
|
patch: [ mw.auth.access.write, mw.line.patch ],
|
|
},
|
|
|
|
'/project/:project/sequence/': {
|
|
get: [ mw.sequence.list ],
|
|
},
|
|
'/project/:project/sequence/:sequence': {
|
|
get: [ mw.sequence.get ],
|
|
patch: [ mw.auth.access.write, mw.sequence.patch ],
|
|
'/:point': {
|
|
get: [ mw.sequence.point.get ]
|
|
}
|
|
},
|
|
|
|
'/project/:project/plan/': {
|
|
get: [ mw.plan.list ],
|
|
put: [ mw.auth.access.write, mw.plan.put ],
|
|
post: [ mw.auth.access.write, mw.plan.post ]
|
|
},
|
|
'/project/:project/plan/:sequence': {
|
|
// get: [ mw.plan.get ],
|
|
patch: [ mw.auth.access.write, mw.plan.patch ],
|
|
delete: [ mw.auth.access.write, mw.plan.delete ]
|
|
},
|
|
//
|
|
'/project/:project/event/': {
|
|
get: [ mw.event.cache.get, mw.event.list, mw.event.cache.save ],
|
|
post: [ mw.auth.access.write, mw.event.post ],
|
|
put: [ mw.auth.access.write, mw.event.put ],
|
|
delete: [ mw.auth.access.write, mw.event.delete ],
|
|
'-/:sequence/': { // NOTE: We need to avoid conflict with the next endpoint ☹
|
|
get: [ mw.event.get ],
|
|
},
|
|
':type/': {
|
|
':id/': {
|
|
// get: [ mw.event.get ],
|
|
put: [ mw.auth.access.write, mw.event.put ],
|
|
delete: [mw.auth.access.write, mw.event.delete ]
|
|
}
|
|
},
|
|
},
|
|
'/project/:project/label/': {
|
|
get: [ mw.label.list ],
|
|
// post: [ mw.label.post ],
|
|
},
|
|
'/project/:project/configuration/:path(*)?': {
|
|
get: [ mw.configuration.get ],
|
|
// post: [ mw.auth.access.admin, mw.label.post ],
|
|
},
|
|
'/project/:project/info/:path(*)': {
|
|
get: [ mw.info.get ],
|
|
post: [ mw.auth.access.write, mw.info.post ],
|
|
put: [ mw.auth.access.write, mw.info.put ],
|
|
delete: [ mw.auth.access.write, mw.info.delete ]
|
|
},
|
|
'/project/:project/meta/': {
|
|
put: [ mw.auth.access.write, mw.meta.put ],
|
|
},
|
|
'/project/:project/meta/:path(*)': {
|
|
// Path examples:
|
|
// GET:
|
|
// `/raw/sequences/qc/missing_shots`,
|
|
// `/final/points/qc/sync_warn/results
|
|
get: [ mw.meta.get ],
|
|
// // PUT:
|
|
// // `/raw/qc/missing_shots` ← { sequence: …, value: … }
|
|
// put: [ mw.meta.put ]
|
|
},
|
|
//
|
|
// '/project/:id/permissions/:mode(read|write)?': {
|
|
// get: [ mw.permissions.get ],
|
|
// put: [ mw.permissions.put ],
|
|
// // post: [ mw.permissions.post ],
|
|
// // delete: [ mw.permissions.delete ]
|
|
// },
|
|
'/navdata/': {
|
|
get: [ mw.navdata.get ],
|
|
'gis/:featuretype(line|point)': {
|
|
get: [ mw.gis.navdata.get ]
|
|
}
|
|
},
|
|
'/info/': {
|
|
':path(*)': {
|
|
get: [ mw.info.get ],
|
|
put: [ mw.auth.access.write, mw.info.put ],
|
|
post: [ mw.auth.access.write, mw.info.post ],
|
|
delete: [ mw.auth.access.write, mw.info.delete ]
|
|
}
|
|
},
|
|
'/queue/outgoing/': {
|
|
'asaqc': {
|
|
get: [ mw.queue.asaqc.get ],
|
|
post: [ mw.auth.access.write, mw.queue.asaqc.post ],
|
|
'/project/:project': {
|
|
get: [ mw.queue.asaqc.get ],
|
|
'/sequence/:sequence': {
|
|
get: [ mw.queue.asaqc.get ],
|
|
}
|
|
},
|
|
'/:id': {
|
|
delete: [ mw.auth.access.write, mw.queue.asaqc.delete ]
|
|
}
|
|
}
|
|
},
|
|
'/rss/': {
|
|
get: [ mw.rss.get ]
|
|
}
|
|
//
|
|
// '/user': {
|
|
// get: [ mw.user.get ],
|
|
// post: [ mw.user.put ]
|
|
// },
|
|
// '/user/:user': {
|
|
// get: [ mw.user.get ],
|
|
// put: [ mw.user.put ],
|
|
// // delete: [ mw.user.delete ]
|
|
// },
|
|
//
|
|
});
|
|
|
|
// Generic error handler. Stops stack dumps
|
|
// being sent to clients.
|
|
app.use(function (err, req, res, next) {
|
|
const title = `HTTP backend error at ${req.method} ${req.originalUrl}`;
|
|
const description = err.message;
|
|
const message = err.message;
|
|
const alert = {title, message, description, error: err};
|
|
|
|
console.log("Error:", err);
|
|
|
|
res.set("Content-Type", "application/json");
|
|
if (err instanceof Error && err.name != "UnauthorizedError") {
|
|
console.error(err.stack);
|
|
res.set("Content-Type", "text/plain");
|
|
res.status(500).send('General internal error');
|
|
maybeSendAlert(alert);
|
|
} else if (typeof err === 'string') {
|
|
res.status(500).send({message: err});
|
|
maybeSendAlert(alert);
|
|
} else {
|
|
res.status(err.status || 500).send({message: err.message || (err.inner && err.inner.message) || "Internal error"});
|
|
if (!res.status) {
|
|
maybeSendAlert(alert);
|
|
}
|
|
}
|
|
});
|
|
|
|
app.disable('x-powered-by');
|
|
app.enable('trust proxy');
|
|
console.log('trust proxy is ' + (app.get('trust proxy')? 'on' : 'off'));
|
|
|
|
const addr = "127.0.0.1";
|
|
|
|
if (!module.parent) {
|
|
var port = process.env.HTTP_PORT || 3000;
|
|
var server = http.createServer(app).listen(port, addr);
|
|
|
|
console.log('API started on port ' + port);
|
|
} else {
|
|
app.start = function (port = 3000, path) {
|
|
|
|
var root = app;
|
|
if (path) {
|
|
root = express();
|
|
['x-powered-by', 'trust proxy'].forEach(k => root.set(k, app.get(k)));
|
|
root.use(path, app);
|
|
}
|
|
|
|
const server = http.createServer(root).listen(port, addr);
|
|
if (server) {
|
|
console.log(`API started on port ${port}, prefix: ${path || "/"}`);
|
|
}
|
|
return server;
|
|
}
|
|
module.exports = app;
|
|
}
|