Run prettier

Signed-off-by: Fred Boniface <fred@fjla.uk>
This commit is contained in:
Fred Boniface 2023-08-26 00:38:26 +01:00
parent c7b1c547b0
commit 31f104f51b
74 changed files with 520386 additions and 1121 deletions

View File

@ -1,44 +1,35 @@
module.exports = {
'env': {
'browser': false,
'node': true,
'commonjs': true,
'es2021': true
env: {
browser: false,
node: true,
commonjs: true,
es2021: true,
},
'extends': 'eslint:recommended',
'overrides': [
extends: "eslint:recommended",
overrides: [
{
files: ['**/*.ts','**/*.js'],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: ['plugin:@typescript-eslint/eslint-recommended', 'plugin:@typescript-eslint/recommended']
}
files: ["**/*.ts", "**/*.js"],
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint"],
extends: [
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
],
'parserOptions': {
'ecmaVersion': 'latest'
},
'rules': {
'indent': [
'error',
2
],
'linebreak-style': [
'error',
'unix'
],
'quotes': [
'error',
'single'
],
'semi': [
'error',
'always'
],
'max-len': [
'warn',
parserOptions: {
ecmaVersion: "latest",
},
rules: {
indent: ["error", 2],
"linebreak-style": ["error", "unix"],
quotes: ["error", "single"],
semi: ["error", "always"],
"max-len": [
"warn",
{
'code': 80
}
]
}
code: 80,
},
],
},
};

File diff suppressed because one or more lines are too long

View File

@ -1 +1,11 @@
{"GetStationBoardResult":{"generatedAt":"2023-01-14T11:23:12.6558466+00:00","locationName":"Pilning","crs":"PIL","nrccMessages":{"message":"\nPoor weather affecting services in Wales due to flooding on the railway More details can be found in <a href=\"https://t.co/uBU966PUmX\">Latest Travel News</a>."},"platformAvailable":"true"}}
{
"GetStationBoardResult": {
"generatedAt": "2023-01-14T11:23:12.6558466+00:00",
"locationName": "Pilning",
"crs": "PIL",
"nrccMessages": {
"message": "\nPoor weather affecting services in Wales due to flooding on the railway More details can be found in <a href=\"https://t.co/uBU966PUmX\">Latest Travel News</a>."
},
"platformAvailable": "true"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
version: '3.1'
version: "3.1"
services:
mongo:

View File

@ -1,33 +1,52 @@
{"service":
[
{"sta":"16:07",
"eta":"On time",
"operator":"South Western Railway",
"operatorCode":"SW",
"serviceType":"ferry",
"serviceID":"37782PHBR____",
"origin":
{"location":
{"locationName":
"Ryde Pier Head","crs":"RYP"
{
"service": [
{
"sta": "16:07",
"eta": "On time",
"operator": "South Western Railway",
"operatorCode": "SW",
"serviceType": "ferry",
"serviceID": "37782PHBR____",
"origin": {
"location": { "locationName": "Ryde Pier Head", "crs": "RYP" }
},
"destination": {
"location": { "locationName": "Portsmouth Harbour", "crs": "PMH" }
},
"previousCallingPoints": {
"callingPointList": {
"callingPoint": {
"locationName": "Ryde Pier Head",
"crs": "RYP",
"st": "15:45",
"et": "On time"
}
}
}
},
"destination":
{"location":
{"locationName":"Portsmouth Harbour",
"crs":"PMH"
}
{
"std": "16:15",
"etd": "On time",
"operator": "South Western Railway",
"operatorCode": "SW",
"serviceType": "ferry",
"serviceID": "37746PHBR____",
"origin": {
"location": { "locationName": "Portsmouth Harbour", "crs": "PMH" }
},
"previousCallingPoints":
{"callingPointList":
{"callingPoint":
{"locationName":"Ryde Pier Head",
"crs":"RYP",
"st":"15:45",
"et":"On time"
"destination": {
"location": { "locationName": "Ryde Pier Head", "crs": "RYP" }
},
"subsequentCallingPoints": {
"callingPointList": {
"callingPoint": {
"locationName": "Ryde Pier Head",
"crs": "RYP",
"st": "16:37",
"et": "On time"
}
}
}
},
{"std":"16:15","etd":"On time","operator":"South Western Railway","operatorCode":"SW","serviceType":"ferry","serviceID":"37746PHBR____","origin":{"location":{"locationName":"Portsmouth Harbour","crs":"PMH"}},"destination":{"location":{"locationName":"Ryde Pier Head","crs":"RYP"}},"subsequentCallingPoints":{"callingPointList":{"callingPoint":
{"locationName":"Ryde Pier Head","crs":"RYP","st":"16:37","et":"On time"}}}}]}
}
]
}

View File

@ -17,21 +17,21 @@ API Documentation has been removed as it is now out of date. I do intent to re-
Configuration options are set through environment variables.
These configuration options are shared with other programs in the OwlBoard ecosystem.
|VAR|DEFAULT|REQUIRED|PURPOSE|
|:-:|:-----:|:------:|:-----:|
|OWL_SRV_PORT|8460|NO|Web Server Port|
|OWL_SRV_LISTEN|0.0.0.0|NO|Web Server Listen Address|
|OWL_DB_USER|owl|NO|Database Username|
|OWL_DB_PASS|twittwoo|NO|Database Password - Do not leave as default in production|
|OWL_DB_NAME|owlboard|NO|Database Name|
|OWL_DB_PORT|27017|NO|Database Server Port|
|OWL_DB_HOST|localhost|NO|Database Server Host|
|OWL_LDB_KEY||YES|National Rail LDBWS API Key|
|OWL_LDB_SVKEY||NO|National Rail LDBSVWS API Key|
|OWL_LDB_CORPUSUSER||YES|Network Rail NROD Username|
|OWL_LDB_CORPUSPASS||YES|Network Rail NROD Password|
|OWL_GIT_ISSUEBOT||NO|Gitea API Key for issue reporting|
|OWL_GIT_APIENDPOINT||NO|Gitea API Endpoint|
| VAR | DEFAULT | REQUIRED | PURPOSE |
| :-----------------: | :-------: | :------: | :-------------------------------------------------------: |
| OWL_SRV_PORT | 8460 | NO | Web Server Port |
| OWL_SRV_LISTEN | 0.0.0.0 | NO | Web Server Listen Address |
| OWL_DB_USER | owl | NO | Database Username |
| OWL_DB_PASS | twittwoo | NO | Database Password - Do not leave as default in production |
| OWL_DB_NAME | owlboard | NO | Database Name |
| OWL_DB_PORT | 27017 | NO | Database Server Port |
| OWL_DB_HOST | localhost | NO | Database Server Host |
| OWL_LDB_KEY | | YES | National Rail LDBWS API Key |
| OWL_LDB_SVKEY | | NO | National Rail LDBSVWS API Key |
| OWL_LDB_CORPUSUSER | | YES | Network Rail NROD Username |
| OWL_LDB_CORPUSPASS | | YES | Network Rail NROD Password |
| OWL_GIT_ISSUEBOT | | NO | Gitea API Key for issue reporting |
| OWL_GIT_APIENDPOINT | | NO | Gitea API Endpoint |
In the case that OWL_LDB_SVKEY is not available, staff versions of departure board, etc. will not be available.

132
app.js
View File

@ -4,41 +4,41 @@
// licensed separately, each folder contains a license file where a
// different license applies.
console.log('Initialising OwlBoard');
const mode = process.env.NODE_ENV || 'development';
console.log("Initialising OwlBoard");
const mode = process.env.NODE_ENV || "development";
// External Requires
const express = require('express');
const express = require("express");
const app = express();
// Middleware
const compression = require('compression');
const rateLimit = require('express-rate-limit');
const cors = require('cors');
const authenticate= require('./src/middlewares/auth.middlewares');
const compression = require("compression");
const rateLimit = require("express-rate-limit");
const cors = require("cors");
const authenticate = require("./src/middlewares/auth.middlewares");
// Internal Requires
const log = require('./src/utils/logs.utils');
const version = require('./src/configs/version.configs');
const listRtr = require('./src/routes/list.routes');
const ldbRtr = require('./src/routes/ldb.routes');
const ldbsRtr = require('./src/routes/ldbs.routes');
const kubeRtr = require('./src/routes/kube.routes');
const findRtr = require('./src/routes/find.routes');
const issueRtr = require('./src/routes/issue.routes');
const statRtr = require('./src/routes/stats.routes');
const regRtr = require('./src/routes/registration.routes');
const pisRtr = require('./src/routes/pis.routes');
const trainRtr = require('./src/routes/train.routes');
const pis2Rtr = require('./src/routes/pis2.routes'); // API Version 2 Routes
const ref2Rtr = require('./src/routes/ref2.routes'); // API Version 2 Routes
const live2Rtr = require('./src/routes/live2.routes'); // API Version 2 Routes
const tt2Rtr = require('./src/routes/timetable2.routes'); // API Version 2
const user2Rtr = require('./src/routes/user2.routes'); // API Version 2 Routes
const miscRtr = require('./src/routes/misc.routes'); // Non-Public API Routes
const log = require("./src/utils/logs.utils");
const version = require("./src/configs/version.configs");
const listRtr = require("./src/routes/list.routes");
const ldbRtr = require("./src/routes/ldb.routes");
const ldbsRtr = require("./src/routes/ldbs.routes");
const kubeRtr = require("./src/routes/kube.routes");
const findRtr = require("./src/routes/find.routes");
const issueRtr = require("./src/routes/issue.routes");
const statRtr = require("./src/routes/stats.routes");
const regRtr = require("./src/routes/registration.routes");
const pisRtr = require("./src/routes/pis.routes");
const trainRtr = require("./src/routes/train.routes");
const pis2Rtr = require("./src/routes/pis2.routes"); // API Version 2 Routes
const ref2Rtr = require("./src/routes/ref2.routes"); // API Version 2 Routes
const live2Rtr = require("./src/routes/live2.routes"); // API Version 2 Routes
const tt2Rtr = require("./src/routes/timetable2.routes"); // API Version 2
const user2Rtr = require("./src/routes/user2.routes"); // API Version 2 Routes
const miscRtr = require("./src/routes/misc.routes"); // Non-Public API Routes
// Set Server Configurations
const srvListen = process.env.OWL_SRV_LISTEN || '0.0.0.0';
const srvListen = process.env.OWL_SRV_LISTEN || "0.0.0.0";
const srvPort = process.env.OWL_SRV_PORT || 8460;
const limiter = rateLimit({
@ -49,65 +49,75 @@ const limiter = rateLimit({
});
// Print version number:
log.out(`app: Starting OwlBoard in ${mode} mode`, 'init');
log.out(`app: Starting OwlBoard - Backend Version: ${version.app} - ` +
`API versions: ${version.api}`, 'init');
log.out(`app: Starting OwlBoard in ${mode} mode`, "init");
log.out(
`app: Starting OwlBoard - Backend Version: ${version.app} - ` +
`API versions: ${version.api}`,
"init"
);
// Express Error Handling:
app.use((err, req, res, next) => {
const statusCode = err.statuscode || 500;
console.error(err.message, err.stack);
res.status(statusCode).json({'message': err.message});
res.status(statusCode).json({ message: err.message });
return;
});
// Global Middleware:
app.use(cors({
origin: '*'//[/\.owlboard\.info$/, 'localhost:5173', 'localhost:4173']
}));
app.use(
cors({
origin: "*", //[/\.owlboard\.info$/, 'localhost:5173', 'localhost:4173']
})
);
app.use(express.json()); //JSON Parsing for POST Requests
app.use(compression()); // Compress API Data if supported by client
app.use(limiter);
app.use(authenticate);
// 2023 Rationalisation Routes (/api/v2, /misc)
app.use('/api/v2/pis', pis2Rtr); // API Version 2
app.use('/api/v2/live', live2Rtr); // API Version 2
app.use('/api/v2/ref', ref2Rtr); // API Version 2
app.use('/api/v2/timetable', tt2Rtr); // API Version 2
app.use('/api/v2/user', user2Rtr); // API Version 2
app.use('/misc', miscRtr); // Non public-api endpoints (Stats, Issue, etc.)
app.use("/api/v2/pis", pis2Rtr); // API Version 2
app.use("/api/v2/live", live2Rtr); // API Version 2
app.use("/api/v2/ref", ref2Rtr); // API Version 2
app.use("/api/v2/timetable", tt2Rtr); // API Version 2
app.use("/api/v2/user", user2Rtr); // API Version 2
app.use("/misc", miscRtr); // Non public-api endpoints (Stats, Issue, etc.)
// Unauthenticated Routes
app.use('/api/v1/list', listRtr);
app.use('/api/v1/ldb', ldbRtr);
app.use('/api/v1/kube', kubeRtr);
app.use('/api/v1/find', findRtr);
app.use('/api/v1/issue', issueRtr);
app.use('/api/v1/stats', statRtr);
app.use('/api/v1/register', regRtr);
app.use("/api/v1/list", listRtr);
app.use("/api/v1/ldb", ldbRtr);
app.use("/api/v1/kube", kubeRtr);
app.use("/api/v1/find", findRtr);
app.use("/api/v1/issue", issueRtr);
app.use("/api/v1/stats", statRtr);
app.use("/api/v1/register", regRtr);
// Authented Routes
app.use('/api/v1/ldbs', authenticate, ldbsRtr);
app.use('/api/v1/pis', authenticate, pisRtr);
app.use('/api/v1/auth/test', authenticate, (req, res) => res.status(200).json({
status: 'ok',
message: 'Authentication successful'
})); // Returns 401 if auth failed, 200 if successful.
app.use('/api/v1/train', authenticate, trainRtr);
app.use("/api/v1/ldbs", authenticate, ldbsRtr);
app.use("/api/v1/pis", authenticate, pisRtr);
app.use("/api/v1/auth/test", authenticate, (req, res) =>
res.status(200).json({
status: "ok",
message: "Authentication successful",
})
); // Returns 401 if auth failed, 200 if successful.
app.use("/api/v1/train", authenticate, trainRtr);
// Number of proxies:
app.set('trust proxy', 4);
mode === 'development'
? app.get('/api/v1/ip', (req, res) => res.send(req.ip))
app.set("trust proxy", 4);
mode === "development"
? app.get("/api/v1/ip", (req, res) => res.send(req.ip))
: null;
// Start Express
app.listen(srvPort, srvListen, (error) =>{
if(!error) {
log.out(`app.listen: Listening on http://${srvListen}:${srvPort}`, 'init');
log.out('app.listen: State - alive', 'init');
app.listen(srvPort, srvListen, (error) => {
if (!error) {
log.out(`app.listen: Listening on http://${srvListen}:${srvPort}`, "init");
log.out("app.listen: State - alive", "init");
} else {
log.out(`app.listen: Error occurred, server can't start ${error.message}`, 'err');
log.out(
`app.listen: Error occurred, server can't start ${error.message}`,
"err"
);
}
});

View File

@ -1,5 +1,5 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
preset: "ts-jest",
testEnvironment: "node",
};

View File

@ -1,16 +1,16 @@
<html lang="en">
<head>
<title>OwlBoard - Register</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
html {
background-color:#404c55;
background-image:radial-gradient(#2b343c,#404c55);
background-color: #404c55;
background-image: radial-gradient(#2b343c, #404c55);
text-align: center;
width: 100%;
}
a {
color:azure;
color: azure;
}
table {
width: 100%;
@ -39,32 +39,45 @@
</style>
</head>
<body>
<br><br>
<br /><br />
<table>
<tr>
<td>
<img src="https://owlboard.info/images/logo/wide_logo.svg" id="title">
<img
src="https://owlboard.info/images/logo/wide_logo.svg"
id="title"
/>
</td>
</tr>
<tr>
<td>
<h1>Register for OwlBoard</h1>
<br>
<br />
<p>Use the link below to register for OwlBoard (Staff Version)</p>
<br>
<a href="https://owlboard.info/more/reg/submit?key=>>ACCESSCODE<<" id="button">Register</a>
<br><br><br>
<p>Alternatively copy and paste the link:<br>https://owlboard.info/more/reg/submit?key=>>ACCESSCODE<<</p>
<p>This registration is for one device only, you can register again using the
same email address for other devices and access OwlBoard from elsewhere.
<br />
<a
href="https://owlboard.info/more/reg/submit?key=>>ACCESSCODE<<"
id="button"
>Register</a
>
<br /><br /><br />
<p>
Alternatively copy and paste the link:<br />https://owlboard.info/more/reg/submit?key=>>ACCESSCODE<<
</p>
<p>If you did not request to sign up to OwlBoard (Staff Version), you can
safely ignore this email. Your email address has not been stored by us.
<p>
This registration is for one device only, you can register again
using the same email address for other devices and access OwlBoard
from elsewhere.
</p>
<p>
If you did not request to sign up to OwlBoard (Staff Version), you
can safely ignore this email. Your email address has not been stored
by us.
</p>
<p>The registration link will expire after 30 minutes.</p>
</td>
</tr>
</table>
<br>
<br />
</body>
</html>

View File

@ -1,37 +1,37 @@
const valid: string[] = [
'owlboard.info',
'avantiwestcoast.co.uk',
'btp.police.uk',
'c2crail.net',
'chilternrailways.co.uk',
'crosscountrytrains.co.uk',
'eastmidlandsrailway.co.uk',
'abellio.co.uk',
'tfl.gov.uk',
'mtrel.co.uk',
'eurostar.com',
'eurotunnel.com',
'ffwhr.com',
'gwr.com',
'hitachirail-eu.com',
'greateranglia.co.uk',
'heathrow.com',
'swrailway.com',
'lsltoc.co.uk',
'lner.co.uk',
'arrivarl.co.uk',
'tube.tfl.gov.uk',
'lumo.co.uk',
'merseyrail.org',
'nrcommcentre.com',
'networkrail.co.uk',
'northernrailway.co.uk',
'scotrail.co.uk',
'southeasternrailway.co.uk',
'tpeexpress.co.uk',
'tfwrail.wales',
'wmtrains.co.uk',
"owlboard.info",
"avantiwestcoast.co.uk",
"btp.police.uk",
"c2crail.net",
"chilternrailways.co.uk",
"crosscountrytrains.co.uk",
"eastmidlandsrailway.co.uk",
"abellio.co.uk",
"tfl.gov.uk",
"mtrel.co.uk",
"eurostar.com",
"eurotunnel.com",
"ffwhr.com",
"gwr.com",
"hitachirail-eu.com",
"greateranglia.co.uk",
"heathrow.com",
"swrailway.com",
"lsltoc.co.uk",
"lner.co.uk",
"arrivarl.co.uk",
"tube.tfl.gov.uk",
"lumo.co.uk",
"merseyrail.org",
"nrcommcentre.com",
"networkrail.co.uk",
"northernrailway.co.uk",
"scotrail.co.uk",
"southeasternrailway.co.uk",
"tpeexpress.co.uk",
"tfwrail.wales",
"wmtrains.co.uk",
];
module.exports = valid;
export { valid }
export { valid };

View File

@ -1,18 +1,18 @@
// statusCodes should be a map, not an object
const statusCodes = {
400: 'data not found',
700: 'no authentication attempt',
701: 'invalid credentials',
702: 'domain not whitelisted',
703: 'registration request not found, maybe expired',
800: 'location code not found',
801: 'unable to fetch location data',
900: 'invalid request format',
901: 'email not provided',
950: 'upstream server error',
951: 'unknown server error'
400: "data not found",
700: "no authentication attempt",
701: "invalid credentials",
702: "domain not whitelisted",
703: "registration request not found, maybe expired",
800: "location code not found",
801: "unable to fetch location data",
900: "invalid request format",
901: "email not provided",
950: "upstream server error",
951: "unknown server error",
};
module.exports = statusCodes;
export { statusCodes }
export { statusCodes };

View File

@ -1,12 +1,12 @@
interface versions {
api: string[],
app: string
api: string[];
app: string;
}
const version: versions = {
api: ['/api/v1/','/api/v2'],
app: '2023.8.2'
api: ["/api/v1/", "/api/v2"],
app: "2023.8.2",
};
module.exports = version;
export { version }
export { version };

View File

@ -1,51 +1,51 @@
const find = require('../services/find.services');
const find = require("../services/find.services");
async function findName(req, res, next){
async function findName(req, res, next) {
try {
var id = req.params.id;
res.json(await find.name(id));
} catch (err) {
console.error('Unknown Error', err.message);
console.error("Unknown Error", err.message);
next(err);
}
}
async function findCrs(req, res, next){
async function findCrs(req, res, next) {
try {
var id = req.params.id;
res.json(await find.crs(id));
} catch (err) {
console.error('Unknown Error', err.message);
console.error("Unknown Error", err.message);
next(err);
}
}
async function findNlc(req, res, next){
async function findNlc(req, res, next) {
try {
var id = req.params.id;
res.json(await find.nlc(id));
} catch (err) {
console.error('Unknown Error', err.message);
console.error("Unknown Error", err.message);
next(err);
}
}
async function findTiploc(req, res, next){
async function findTiploc(req, res, next) {
try {
var id = req.params.id;
res.json(await find.tiploc(id));
} catch (err) {
console.error('Unknown Error', err.message);
console.error("Unknown Error", err.message);
next(err);
}
}
async function findStanox(req, res, next){
async function findStanox(req, res, next) {
try {
var id = req.params.id;
res.json(await find.stanox(id));
} catch (err) {
console.error('Unknown Error', err.message);
console.error("Unknown Error", err.message);
next(err);
}
}
@ -54,5 +54,5 @@ module.exports = {
findCrs,
findNlc,
findTiploc,
findStanox
findStanox,
};

View File

@ -1,16 +1,16 @@
const issue = require('../services/issue.services');
const log = require('../utils/logs.utils');
const issue = require("../services/issue.services");
const log = require("../utils/logs.utils");
async function post(req, res, next){
async function post(req, res, next) {
try {
log.out(`issueControllers.post: Request Body: ${JSON.stringify(req.body)}`);
res.json(await issue.processor(req.body));
} catch (err) {
console.error('Controller Error', err.message);
console.error("Controller Error", err.message);
next(err);
}
}
module.exports = {
post
post,
};

View File

@ -1,28 +1,28 @@
const kube = require('../services/kube.services');
const kube = require("../services/kube.services");
async function getAlive(req, res, next){
async function getAlive(req, res, next) {
try {
var state = kube.getAlive();
res.status((await state).code).send((await state).state);
} catch (err) {
res.status('503').send({state: 'error'});
res.status("503").send({ state: "error" });
}
}
async function getReady(req, res, next){
async function getReady(req, res, next) {
try {
res.json(await kube.getReady(req.body));
} catch (err) {
console.error('Unknown Error', err.message);
console.error("Unknown Error", err.message);
next(err);
}
}
async function getTime(req, res, next){
async function getTime(req, res, next) {
try {
res.json(await kube.getTime(req.body));
} catch (err) {
console.error('Unknown Error', err.message);
console.error("Unknown Error", err.message);
err.status = 503;
next(err);
}
@ -31,5 +31,5 @@ async function getTime(req, res, next){
module.exports = {
getAlive,
getReady,
getTime
getTime,
};

View File

@ -1,19 +1,21 @@
const ldb = require('../services/ldb.services');
const ldb = require("../services/ldb.services");
async function get(req, res, next){ // API v1 only
async function get(req, res, next) {
// API v1 only
try {
var id = req.params.id;
res.json(await ldb.get(id));
} catch (err) {
console.error('Unknown Error', err.message);
console.error("Unknown Error", err.message);
err.status = 500;
next(err);
}
}
async function getTrain(req, res, next) { // API v2 Only
async function getTrain(req, res, next) {
// API v2 Only
if (!req.isAuthed) {
const err = new Error('Unauthorized');
const err = new Error("Unauthorized");
err.status = 401;
throw err;
}
@ -21,31 +23,34 @@ async function getTrain(req, res, next) { // API v2 Only
let id = req.params.id;
try {
switch (type.toLowerCase()) {
case 'rid':
case "rid":
res.json(await ldb.getServiceByRID(id));
break;
case 'uid':
case 'headcode':
case 'rsid':
case "uid":
case "headcode":
case "rsid":
res.json(await ldb.getServicesByOther(id));
break;
default:
res.status(400).json({status: 'error', message:'Invalid search type'});
res
.status(400)
.json({ status: "error", message: "Invalid search type" });
}
} catch (err) {
err.status = 500;
console.error('Unknown Error', err.message);
console.error("Unknown Error", err.message);
next(err);
}
}
async function getStation(req, res, next) { // API v2 Only
async function getStation(req, res, next) {
// API v2 Only
let type = req.params.type;
let id = req.params.id;
try {
if (type == 'staff') {
if (type == "staff") {
if (!req.isAuthed) {
const err = new Error('Unauthorized');
const err = new Error("Unauthorized");
err.status = 401;
throw err;
}
@ -54,7 +59,7 @@ async function getStation(req, res, next) { // API v2 Only
res.json(await ldb.get(id, false));
}
} catch (err) {
console.error('Unknown Error', err.message);
console.error("Unknown Error", err.message);
err.status = 500;
next(err);
}
@ -63,5 +68,5 @@ async function getStation(req, res, next) { // API v2 Only
module.exports = {
get,
getTrain,
getStation
getStation,
};

View File

@ -1,11 +1,11 @@
const ldb = require('../services/ldb.services');
const ldb = require("../services/ldb.services");
async function get(req, res, next){
async function get(req, res, next) {
try {
var id = req.params.id;
res.json(await ldb.get(id, true));
} catch (err) {
console.error('Unknown Error', err.message);
console.error("Unknown Error", err.message);
err.status = 500;
next(err);
}
@ -15,7 +15,7 @@ async function getReasonCodeList(req, res, next) {
try {
res.json(await ldb.getReasonCodeList());
} catch (err) {
console.error('ERROR', err.message);
console.error("ERROR", err.message);
err.status = 500;
next(err);
}
@ -26,7 +26,7 @@ async function getReasonCode(req, res, next) {
const code = req.params.code;
res.json(await ldb.getReasonCode(code));
} catch (err) {
console.error('ERROR', err.message);
console.error("ERROR", err.message);
err.status = 500;
next(err);
}
@ -37,7 +37,7 @@ async function getTrainByRID(req, res, next) {
const rid = req.params.rid;
res.json(await ldb.getServiceByRID(rid));
} catch (err) {
console.error('ERROR', err);
console.error("ERROR", err);
err.status = 500;
next(err);
}
@ -47,5 +47,5 @@ module.exports = {
get,
getReasonCodeList,
getReasonCode,
getTrainByRID
getTrainByRID,
};

View File

@ -1,20 +1,20 @@
const list = require('../services/list.services');
const list = require("../services/list.services");
async function getStations(req, res, next){
async function getStations(req, res, next) {
try {
res.json(await list.getStations(req.body));
} catch (err) {
console.error('Controller Error', err.message);
console.error("Controller Error", err.message);
err.status = 500;
next(err);
}
}
async function getCorpus(req, res, next){
async function getCorpus(req, res, next) {
try {
res.json(await list.getCorpus(req.body));
} catch (err) {
console.error('Controller Error', err.message);
console.error("Controller Error", err.message);
err.status = 500;
next(err);
}
@ -24,7 +24,7 @@ async function hits(req, res, next) {
try {
res.json(await list.hits());
} catch (err) {
console.error('Controller Error', err);
console.error("Controller Error", err);
err.status = 500;
next(err);
}
@ -33,5 +33,5 @@ async function hits(req, res, next) {
module.exports = {
getStations,
getCorpus,
hits
hits,
};

View File

@ -1,42 +1,42 @@
const pis = require('../services/pis.services');
const pis = require("../services/pis.services");
async function byOrigDest(req, res, next){
async function byOrigDest(req, res, next) {
if (!req.isAuthed) {
const err = new Error('Unauthorized');
const err = new Error("Unauthorized");
err.status = 401;
throw err;
}
try {
let start = req.params.start;
let end = req.params.end;
res.json(await pis.findPisByOrigDest(start,end));
res.json(await pis.findPisByOrigDest(start, end));
} catch (err) {
console.error('Unknown Error', err.message);
console.error("Unknown Error", err.message);
next(err);
}
}
/* Used in /api/v2 */
async function byStartEndCRS(req, res, next){
async function byStartEndCRS(req, res, next) {
if (!req.isAuthed) {
const err = new Error('Unauthorized');
const err = new Error("Unauthorized");
err.status = 401;
return next(err);
}
try {
let startCrs = req.params.startCrs;
let endCrs = req.params.endCrs;
res.json(await pis.findPisByOrigDest(startCrs,endCrs));
res.json(await pis.findPisByOrigDest(startCrs, endCrs));
} catch (err) {
console.error('Unknown Error', err.message);
console.error("Unknown Error", err.message);
return next(err);
}
}
/* Used in /api/v2 */
async function byCode(req, res, next){
async function byCode(req, res, next) {
if (!req.isAuthed) {
const err = new Error('Unauthorized');
const err = new Error("Unauthorized");
err.status = 401;
return next(err);
}
@ -44,29 +44,28 @@ async function byCode(req, res, next){
let code = req.params.code;
res.json(await pis.findPisByCode(code));
} catch (err) {
console.error('Unknown Error', err.message);
console.error("Unknown Error", err.message);
return next(err);
}
}
async function random(req, res, next){
async function random(req, res, next) {
if (!req.isAuthed) {
const err = new Error('Unauthorized');
const err = new Error("Unauthorized");
err.status = 401;
return next(err);
}
try {
res.json(await pis.findRandom());
} catch (err) {
console.error('Unknown Error', err.message);
console.error("Unknown Error", err.message);
return next(err);
}
}
module.exports = {
byOrigDest,
byStartEndCRS,
byCode,
random
random,
};

View File

@ -1,19 +1,19 @@
/* API V2 Exclusive Controller */
const ldb = require('../services/ldb.services');
const find = require('../services/find.services');
const ldb = require("../services/ldb.services");
const find = require("../services/find.services");
async function getReasonCode(req, res, next) {
try {
const code = req.params.code;
if (code === 'all') {
if (code === "all") {
res.json(await ldb.getReasonCodeList());
next;
}
res.json(await ldb.getReasonCode(code));
next;
} catch (err) {
console.error('ERROR', err.message);
console.error("ERROR", err.message);
err.status = 500;
next(err);
}
@ -24,25 +24,25 @@ async function getLocationReference(req, res, next) {
const searchType = req.params.searchType;
const id = req.params.id;
switch (searchType) {
case 'name':
case "name":
res.json(await find.name(id));
break;
case 'crs': // Same as 3alpha
case '3alpha':
case "crs": // Same as 3alpha
case "3alpha":
res.json(await find.crs(id));
break;
case 'nlc':
case "nlc":
res.json(await find.nlc(id));
break;
case 'tiploc':
case "tiploc":
res.json(await find.tiploc(id));
break;
case 'stanox':
case "stanox":
res.json(await find.stanox(id));
break;
}
} catch (err) {
console.error('ERROR', err.message);
console.error("ERROR", err.message);
err.status = 500;
next(err);
}
@ -50,5 +50,5 @@ async function getLocationReference(req, res, next) {
module.exports = {
getReasonCode,
getLocationReference
getLocationReference,
};

View File

@ -1,11 +1,11 @@
const reg = require('../services/registration.services');
const reg = require("../services/registration.services");
async function register(req, res, next) {
try {
let response = await reg.regUser(req.body);
res.status(response.status).json(response);
} catch (err) {
console.error('Controller Error', err.message);
console.error("Controller Error", err.message);
next(err);
}
}
@ -35,17 +35,18 @@ async function getUser(req, res, next) {
}
}
async function checkAuth(req,res,next) {
if (! req.isAuthed) {
res.status(401).body("Not Authorised")
async function checkAuth(req, res, next) {
if (!req.isAuthed) {
res.status(401).body("Not Authorised");
} else {
res.status(200).body("Authorised Successfully")
res.status(200).body("Authorised Successfully");
}
next();
}
next()}
module.exports = {
register,
request,
getUser,
checkAuth
checkAuth,
};

View File

@ -1,30 +1,33 @@
const stat = require('../services/stats.services');
const stat = require("../services/stats.services");
async function get(req, res, next) { // API V1
async function get(req, res, next) {
// API V1
try {
res.json(await stat.hits());
} catch (err) {
console.error('Controller Error', err);
console.error("Controller Error", err);
err.status = 500;
next(err);
}
}
async function versions(req, res, next) { // API v2
async function versions(req, res, next) {
// API v2
try {
res.json(await stat.getVersions());
} catch (err) {
console.error('Controller Error', err);
console.error("Controller Error", err);
err.status = 500;
next(err);
}
}
async function statistics(req, res, next) { // Api v2
async function statistics(req, res, next) {
// Api v2
try {
res.json(await stat.statistics());
} catch (err) {
console.error('Controller Error', err);
console.error("Controller Error", err);
err.status = 500;
next(err);
}
@ -33,5 +36,5 @@ async function statistics(req, res, next) { // Api v2
module.exports = {
get,
versions,
statistics
statistics,
};

View File

@ -1,16 +1,16 @@
const train = require('../services/trainService.services');
const train = require("../services/trainService.services");
async function getByHeadcodeToday(req, res, next){
async function getByHeadcodeToday(req, res, next) {
if (!req.isAuthed) {
const err = new Error('Unauthorized');
const err = new Error("Unauthorized");
err.status = 401;
next(err)
next(err);
}
try {
var searchHeadcode = req.params.id;
res.json(await train.findByHeadcodeToday(searchHeadcode));
} catch (err) {
console.error('Unknown Error', err.message);
console.error("Unknown Error", err.message);
err.status = 500;
next(err);
}
@ -18,7 +18,7 @@ async function getByHeadcodeToday(req, res, next){
async function get(req, res, next) {
if (!req.isAuthed) {
const err = new Error('Unauthorized');
const err = new Error("Unauthorized");
err.status = 401;
next(err);
}
@ -27,18 +27,17 @@ async function get(req, res, next) {
let id = req.params.id;
try {
switch (searchType) {
case 'headcode':
case "headcode":
res.json(await train.findByHeadcode(date, id));
break;
case 'byTrainUid':
case "byTrainUid":
res.json(await train.findByTrainUid(id, date));
break;
default:
res.status(404).json({
status:'error',
message:`Invalid search type "${searchType}"`
}
);
status: "error",
message: `Invalid search type "${searchType}"`,
});
}
} catch (err) {
console.error(err.message);
@ -49,5 +48,5 @@ async function get(req, res, next) {
module.exports = {
getByHeadcodeToday,
get
get,
};

View File

@ -1,27 +1,26 @@
const utils = require('../utils/auth.utils');
const log = require('../utils/logs.utils');
const utils = require("../utils/auth.utils");
const log = require("../utils/logs.utils");
module.exports = async function authCheck(req, res, next) {
log.out('authMiddlewares: Checking authentication', 'dbug');
log.out("authMiddlewares: Checking authentication", "dbug");
try {
var uuid = req.headers.uuid;
} catch(err) {
log.out('authMiddlewares: User !isAuthed', 'dbug');
} catch (err) {
log.out("authMiddlewares: User !isAuthed", "dbug");
req.isAuthed = false;
return next();
}
try {
var result = await utils.isAuthed(uuid) || false;
var result = (await utils.isAuthed(uuid)) || false;
if (!result) {
req.isAuthed = false;
log.out('authMiddlewares: User !isAuthed',
'warn');
log.out("authMiddlewares: User !isAuthed", "warn");
} else {
req.isAuthed = true;
log.out('authMiddlewares: User isAuthed', 'dbug');
log.out("authMiddlewares: User isAuthed", "dbug");
}
return next();
} catch(err) {
} catch (err) {
req.isAuthed = false;
return next();
}

View File

@ -1,9 +1,9 @@
const log = require('../utils/logs.utils');
const log = require("../utils/logs.utils");
module.exports = async function requireJson(req, res, next) {
if (req.headers['content-type'] !== 'application/json') {
log.out('requireJson.middlewares: Bad Request: Not in JSON format');
res.status(400).send({status: 400, message: 'Server requires JSON'});
if (req.headers["content-type"] !== "application/json") {
log.out("requireJson.middlewares: Bad Request: Not in JSON format");
res.status(400).send({ status: 400, message: "Server requires JSON" });
} else {
next();
}

View File

@ -1,9 +1,8 @@
const express = require('express');
const express = require("express");
const router = express.Router();
// Controller Imports
// Routes
module.exports = router;

View File

@ -1,4 +1,4 @@
const express = require('express');
const express = require("express");
const router = express.Router();
/* Controller Imports */
@ -7,8 +7,6 @@ const router = express.Router();
// Timetable
// Ref
// User
@ -16,17 +14,15 @@ const router = express.Router();
/* Routes */
// Live
router.get('/live/station/:id/:type');
router.get('/live/train/:searchType/:id');
router.get("/live/station/:id/:type");
router.get("/live/train/:searchType/:id");
// Timetable
router.get('/timetable/train/:date/:searchType/:id');
router.get("/timetable/train/:date/:searchType/:id");
// User
router.post('/user');
router.get('/user/:uuid');
router.delete('/user/:uuid');
router.post("/user");
router.get("/user/:uuid");
router.delete("/user/:uuid");
module.exports = router;

View File

@ -1,6 +1,6 @@
const express = require('express');
const express = require("express");
const router = express.Router();
const findController = require('../controllers/find.controllers');
const findController = require("../controllers/find.controllers");
/* GET programming languages. */
//router.get('/', programmingLanguagesController.get);
@ -14,10 +14,10 @@ const findController = require('../controllers/find.controllers');
/* DELETE programming language */
//router.delete('/:id', programmingLanguagesController.remove);
router.get('/name/:id', findController.findName);
router.get('/crs/:id', findController.findCrs);
router.get('/nlc/:id', findController.findNlc);
router.get('/tiploc/:id', findController.findTiploc);
router.get('/stanox/:id', findController.findStanox);
router.get("/name/:id", findController.findName);
router.get("/crs/:id", findController.findCrs);
router.get("/nlc/:id", findController.findNlc);
router.get("/tiploc/:id", findController.findTiploc);
router.get("/stanox/:id", findController.findStanox);
module.exports = router;

View File

@ -1,7 +1,7 @@
const express = require('express');
const express = require("express");
const router = express.Router();
const issueController = require('../controllers/issue.controllers');
const issueController = require("../controllers/issue.controllers");
router.post('/', issueController.post);
router.post("/", issueController.post);
module.exports = router;

View File

@ -1,9 +1,9 @@
const express = require('express');
const express = require("express");
const router = express.Router();
const kubeController = require('../controllers/kube.controllers');
const kubeController = require("../controllers/kube.controllers");
router.get('/alive', kubeController.getAlive);
router.get('/ready', kubeController.getReady);
router.get('/time', kubeController.getTime);
router.get("/alive", kubeController.getAlive);
router.get("/ready", kubeController.getReady);
router.get("/time", kubeController.getTime);
module.exports = router;

View File

@ -1,6 +1,6 @@
const express = require('express');
const express = require("express");
const router = express.Router();
const ldbController = require('../controllers/ldb.controllers');
const ldbController = require("../controllers/ldb.controllers");
/* GET programming languages. */
//router.get('/', programmingLanguagesController.get);
@ -14,6 +14,6 @@ const ldbController = require('../controllers/ldb.controllers');
/* DELETE programming language */
//router.delete('/:id', programmingLanguagesController.remove);
router.get('/:id', ldbController.get);
router.get("/:id", ldbController.get);
module.exports = router;

View File

@ -1,6 +1,6 @@
const express = require('express');
const express = require("express");
const router = express.Router();
const ldbsController = require('../controllers/ldbs.controllers');
const ldbsController = require("../controllers/ldbs.controllers");
/* GET programming languages. */
//router.get('/', programmingLanguagesController.get);
@ -14,9 +14,9 @@ const ldbsController = require('../controllers/ldbs.controllers');
/* DELETE programming language */
//router.delete('/:id', programmingLanguagesController.remove);
router.get('/arrdep/:id', ldbsController.get);
router.get('/reasonCode', ldbsController.getReasonCodeList);
router.get('/reasonCode/:code', ldbsController.getReasonCode);
router.get('/service/rid/:rid', ldbsController.getTrainByRID);
router.get("/arrdep/:id", ldbsController.get);
router.get("/reasonCode", ldbsController.getReasonCodeList);
router.get("/reasonCode/:code", ldbsController.getReasonCode);
router.get("/service/rid/:rid", ldbsController.getTrainByRID);
module.exports = router;

View File

@ -1,6 +1,6 @@
const express = require('express');
const express = require("express");
const router = express.Router();
const listController = require('../controllers/list.controllers');
const listController = require("../controllers/list.controllers");
/* GET programming languages. */
//router.get('/', programmingLanguagesController.get);
@ -14,7 +14,7 @@ const listController = require('../controllers/list.controllers');
/* DELETE programming language */
//router.delete('/:id', programmingLanguagesController.remove);
router.get('/stations', listController.getStations);
router.get('/corpus', listController.getCorpus);
router.get("/stations", listController.getStations);
router.get("/corpus", listController.getCorpus);
module.exports = router;

View File

@ -1,9 +1,9 @@
const express = require('express');
const express = require("express");
const router = express.Router();
const ldbCtr = require('../controllers/ldb.controllers');
const ldbCtr = require("../controllers/ldb.controllers");
// PIS
router.get('/station/:id/:type', ldbCtr.getStation);
router.get('/train/:searchType/:id', ldbCtr.getTrain);
router.get("/station/:id/:type", ldbCtr.getStation);
router.get("/train/:searchType/:id", ldbCtr.getTrain);
module.exports = router;

View File

@ -1,16 +1,15 @@
const express = require('express');
const express = require("express");
const router = express.Router();
// Controller Imports
const issueCtr = require('../controllers/issue.controllers');
const statCtr = require('../controllers/stats.controllers');
const issueCtr = require("../controllers/issue.controllers");
const statCtr = require("../controllers/stats.controllers");
// Routes
router.get('/server/stats', statCtr.statistics);
router.get('/server/versions', statCtr.versions);
router.get("/server/stats", statCtr.statistics);
router.get("/server/versions", statCtr.versions);
router.post('/issue', issueCtr.post);
router.post("/issue", issueCtr.post);
module.exports = router;

View File

@ -1,9 +1,9 @@
const express = require('express');
const express = require("express");
const router = express.Router();
const pisController = require('../controllers/pis.controllers');
const pisController = require("../controllers/pis.controllers");
router.get('/origdest/:start/:end', pisController.byOrigDest);
router.get('/code/:code', pisController.byCode);
router.get('/code/random', pisController.random);
router.get("/origdest/:start/:end", pisController.byOrigDest);
router.get("/code/:code", pisController.byCode);
router.get("/code/random", pisController.random);
module.exports = router;

View File

@ -1,9 +1,9 @@
const express = require('express');
const express = require("express");
const router = express.Router();
const pisCtr = require('../controllers/pis.controllers');
const pisCtr = require("../controllers/pis.controllers");
// PIS
router.get('/byCode/:code', pisCtr.byCode);
router.get('/byStartEnd/:startCrs/:endCrs', pisCtr.byStartEndCRS);
router.get("/byCode/:code", pisCtr.byCode);
router.get("/byStartEnd/:startCrs/:endCrs", pisCtr.byStartEndCRS);
module.exports = router;

View File

@ -1,9 +1,9 @@
const express = require('express');
const express = require("express");
const router = express.Router();
const refCtr = require('../controllers/ref.controllers');
const refCtr = require("../controllers/ref.controllers");
// Ref
router.get('/reasonCode/:code', refCtr.getReasonCode);
router.get('/locationCode/:searchType/:id', refCtr.getLocationReference);
router.get("/reasonCode/:code", refCtr.getReasonCode);
router.get("/locationCode/:searchType/:id", refCtr.getLocationReference);
module.exports = router;

View File

@ -1,8 +1,8 @@
const express = require('express');
const express = require("express");
const router = express.Router();
const regController = require('../controllers/registration.controllers');
const regController = require("../controllers/registration.controllers");
router.post('/request', regController.request);
router.post('/register', regController.register);
router.post("/request", regController.request);
router.post("/register", regController.register);
module.exports = router;

View File

@ -1,8 +1,7 @@
const express = require('express');
const express = require("express");
const router = express.Router();
const statsController = require('../controllers/stats.controllers');
const statsController = require("../controllers/stats.controllers");
router.get('/', statsController.get);
router.get("/", statsController.get);
module.exports = router;

View File

@ -1,8 +1,8 @@
const express = require('express');
const express = require("express");
const router = express.Router();
const ttCtr = require('../controllers/train.controllers');
const ttCtr = require("../controllers/train.controllers");
// PIS
router.get('/train/:date/:searchType/:id', ttCtr.get);
router.get("/train/:date/:searchType/:id", ttCtr.get);
module.exports = router;

View File

@ -1,6 +1,6 @@
const express = require('express');
const express = require("express");
const router = express.Router();
const trainController = require('../controllers/train.controllers');
const trainController = require("../controllers/train.controllers");
/* GET programming languages. */
//router.get('/', programmingLanguagesController.get);
@ -14,6 +14,6 @@ const trainController = require('../controllers/train.controllers');
/* DELETE programming language */
//router.delete('/:id', programmingLanguagesController.remove);
router.get('/headcode/today/:id', trainController.getByHeadcodeToday);
router.get("/headcode/today/:id", trainController.getByHeadcodeToday);
module.exports = router;

View File

@ -1,12 +1,12 @@
const express = require('express');
const express = require("express");
const router = express.Router();
const regCtr = require('../controllers/registration.controllers');
const regCtr = require("../controllers/registration.controllers");
// User
router.get('/:uuid', regCtr.getUser);
router.get('/checkAuth', regCtr.checkAuth);
router.get("/:uuid", regCtr.getUser);
router.get("/checkAuth", regCtr.checkAuth);
// Not Implemented router.delete('/:uuid', regCtr.deleteUser);
router.post('/request', regCtr.request);
router.post('/register', regCtr.register);
router.post("/request", regCtr.request);
router.post("/register", regCtr.register);
module.exports = router;

View File

@ -1,63 +1,72 @@
/* global process */
const log = require('../utils/logs.utils'); // Log Helper
const log = require("../utils/logs.utils"); // Log Helper
const dbUser = process.env.OWL_DB_USER || 'owl';
const dbPass = process.env.OWL_DB_PASS || 'twittwoo';
const dbName = process.env.OWL_DB_NAME || 'owlboard';
const dbUser = process.env.OWL_DB_USER || "owl";
const dbPass = process.env.OWL_DB_PASS || "twittwoo";
const dbName = process.env.OWL_DB_NAME || "owlboard";
const dbPort = process.env.OWL_DB_PORT || 27017;
const dbHost = process.env.OWL_DB_HOST || 'localhost';
const dbHost = process.env.OWL_DB_HOST || "localhost";
const uri = `mongodb://${dbUser}:${dbPass}@${dbHost}:${dbPort}`;
const { MongoClient } = require('mongodb');
const { MongoClient } = require("mongodb");
const client = new MongoClient(uri);
const db = client.db(dbName);
async function query(collection, query, returnId = false){
async function query(collection, query, returnId = false) {
await client.connect();
log.out(`dbAccess.query: Connecting to collection: '${collection}'`, 'info');
log.out(`dbAccess.query: Connecting to collection: '${collection}'`, "info");
var qcoll = db.collection(collection);
var qcursor = qcoll.find(query);
if (!returnId) {
qcursor.project({_id: 0});
qcursor.project({ _id: 0 });
}
log.out(`dbAccess.query: Running Query: ${JSON.stringify(query)}`, 'info');
log.out(`dbAccess.query: Running Query: ${JSON.stringify(query)}`, "info");
increment(collection);
return (await qcursor.toArray());
return await qcursor.toArray();
}
async function queryProject(collection, query, projection) {
await client.connect();
log.out(`dbAccess.queryProject: Connecting to col: '${collection}'`, 'info');
log.out(`dbAccess.queryProject: Connecting to col: '${collection}'`, "info");
const qcoll = db.collection(collection);
const qcursor = qcoll.find(query).project(projection);
log.out(`dbAccess.query: Running Query: ${JSON.stringify(query)}, Projection: ${JSON.stringify(projection)}`, 'dbug');
log.out(
`dbAccess.query: Running Query: ${JSON.stringify(
query
)}, Projection: ${JSON.stringify(projection)}`,
"dbug"
);
increment(collection);
return await qcursor.toArray();
}
async function queryAggregate(collection, pipeline) {
await client.connect();
log.out(`dbAccess.queryProject: Connecting to col: '${collection}'`, 'info');
log.out(`dbAccess.query: Running Aggregation: ${JSON.stringify(pipeline)}`, 'dbug');
log.out(`dbAccess.queryProject: Connecting to col: '${collection}'`, "info");
log.out(
`dbAccess.query: Running Aggregation: ${JSON.stringify(pipeline)}`,
"dbug"
);
increment(collection);
return await db.collection(collection).aggregate(pipeline).toArray();
}
async function increment(target) {
log.out(`dbAccess.increment: Incrementing counter for: ${target}`, 'info');
log.out(`dbAccess.increment: Incrementing counter for: ${target}`, "info");
await client.connect();
let col = db.collection('meta');
let col = db.collection("meta");
let update = {};
update[target] = 1;
col.updateOne({target: 'counters'}, {$inc:update});
col.updateOne({ target: "counters" }, { $inc: update });
}
async function addUser(uuid, domain) { // Needs testing
log.out('dbAccess.addUser: Adding user to database');
let doc = {uuid: uuid, domain: domain, atime: new Date};
async function addUser(uuid, domain) {
// Needs testing
log.out("dbAccess.addUser: Adding user to database");
let doc = { uuid: uuid, domain: domain, atime: new Date() };
await client.connect();
let col = db.collection('users');
let col = db.collection("users");
let res = await col.insertOne(doc);
if (res.insertedId) {
return true;
@ -65,32 +74,34 @@ async function addUser(uuid, domain) { // Needs testing
return false;
}
async function addRegReq(uuid, domain) { // Needs testing
log.out('dbAccess.addRegReq: Adding registration request');
let doc = {uuid: uuid, time: new Date, domain: domain};
async function addRegReq(uuid, domain) {
// Needs testing
log.out("dbAccess.addRegReq: Adding registration request");
let doc = { uuid: uuid, time: new Date(), domain: domain };
await client.connect();
let col = db.collection('registrations');
let col = db.collection("registrations");
let res = col.insertOne(doc);
return res;
}
async function userAtime(uuid) { // Needs testing
log.out('dbAccess.userAtime: Updating access time for user');
let q = {uuid: uuid};
let n = {$set: {uuid: uuid, atime: new Date}};
async function userAtime(uuid) {
// Needs testing
log.out("dbAccess.userAtime: Updating access time for user");
let q = { uuid: uuid };
let n = { $set: { uuid: uuid, atime: new Date() } };
await client.connect();
let col = db.collection('users');
let res = col.updateOne(q, n, {upsert: true});
let col = db.collection("users");
let res = col.updateOne(q, n, { upsert: true });
return res;
}
// Deletes one single registration request entry from the DB
async function delRegReq(uuid) {
log.out('dbAccess.delRegReq: Deleting a Registration Request');
let collection = 'registrations';
log.out("dbAccess.delRegReq: Deleting a Registration Request");
let collection = "registrations";
await client.connect();
let col = db.collection(collection);
col.deleteOne({uuid: uuid});
col.deleteOne({ uuid: uuid });
}
async function colCount(collection) {
@ -98,8 +109,10 @@ async function colCount(collection) {
await client.connect();
let col = db.collection(collection);
let count = col.countDocuments();
log.out(`dbAccess.colCount: Collection: ${collection} contains ${count}` +
' documents');
log.out(
`dbAccess.colCount: Collection: ${collection} contains ${count}` +
" documents"
);
return await count;
}
@ -112,5 +125,5 @@ module.exports = {
userAtime,
addRegReq,
delRegReq,
colCount
colCount,
};

View File

@ -1,53 +1,53 @@
// Parse and return a find request
const log = require('../utils/logs.utils'); // Log Helper
const db = require('../services/dbAccess.services');
const san = require('../utils/sanitizer.utils');
const log = require("../utils/logs.utils"); // Log Helper
const db = require("../services/dbAccess.services");
const san = require("../utils/sanitizer.utils");
// DB Query: query(collection, query)
// Define collection as all queries are for the "corpus" collection.
const col = 'corpus';
const col = "corpus";
async function name(id){
log.out(`findServices.name: Finding station name: ${id}`, 'info');
async function name(id) {
log.out(`findServices.name: Finding station name: ${id}`, "info");
var name = san.cleanApiEndpointTxt(id.toUpperCase());
let query = {NLCDESC: name};
let query = { NLCDESC: name };
//var data = await db.query(col,query)
return await db.query(col,query);
return await db.query(col, query);
}
async function crs(id){
log.out(`findServices.crs: Finding crs: ${id}`, 'info');
async function crs(id) {
log.out(`findServices.crs: Finding crs: ${id}`, "info");
var crs = san.cleanApiEndpointTxt(id.toUpperCase());
let query = {'3ALPHA': crs};
let query = { "3ALPHA": crs };
//var data = await db.query(col,query)
return await db.query(col,query);
return await db.query(col, query);
}
async function nlc(id){
log.out(`findServices.nlc: Finding nlc: ${id}`, 'info');
async function nlc(id) {
log.out(`findServices.nlc: Finding nlc: ${id}`, "info");
var nlc = san.cleanApiEndpointNum(id);
let query = {NLC: parseInt(nlc)};
log.out(`findServices.nlc: NLC Converted to int: ${query}`, 'info');
let query = { NLC: parseInt(nlc) };
log.out(`findServices.nlc: NLC Converted to int: ${query}`, "info");
//var data = await db.query(col,query)
return await db.query(col,query);
return await db.query(col, query);
}
async function tiploc(id){
log.out(`findServices.tiploc: Finding tiploc: ${id}`, 'info');
async function tiploc(id) {
log.out(`findServices.tiploc: Finding tiploc: ${id}`, "info");
var tiploc = san.cleanApiEndpointTxt(id.toUpperCase());
let query = {TIPLOC: tiploc};
let query = { TIPLOC: tiploc };
//var data = await db.query(col,query)
return await db.query(col,query);
return await db.query(col, query);
}
async function stanox(id){
log.out(`findServices.stanox: Finding stanox: ${id}`, 'info');
async function stanox(id) {
log.out(`findServices.stanox: Finding stanox: ${id}`, "info");
var stanox = san.cleanApiEndpointNum(id);
let query = {STANOX: String(stanox)};
let query = { STANOX: String(stanox) };
//var data = await db.query(col,query)
return await db.query(col,query);
return await db.query(col, query);
}
module.exports = {
@ -55,5 +55,5 @@ module.exports = {
crs,
nlc,
tiploc,
stanox
stanox,
};

View File

@ -1,22 +1,22 @@
/* eslint-disable no-useless-escape */
const axios = require('axios');
const log = require('../utils/logs.utils');
const axios = require("axios");
const log = require("../utils/logs.utils");
const issueLabels = {
bug: 120,
enhancement: 122,
question: 125,
'user-support': 152,
'web-user': 153
"user-support": 152,
"web-user": 153,
};
async function processor(data) {
log.out('issueService.processor: Issue received', 'info');
log.out("issueService.processor: Issue received", "info");
console.log(data); // TEMPORARY MEASURE
let out = {};
out.labels = [(issueLabels[data?.label] || 0), issueLabels['web-user']];
out.title = data?.subject.replace(/<[^>]+>|[\*\$]/g, '');
out.body = data?.msg.replace(/<[^>]+>|[\*\$]/g, '');
out.labels = [issueLabels[data?.label] || 0, issueLabels["web-user"]];
out.title = data?.subject.replace(/<[^>]+>|[\*\$]/g, "");
out.body = data?.msg.replace(/<[^>]+>|[\*\$]/g, "");
return await sendToGitea(out);
}
@ -25,21 +25,21 @@ async function sendToGitea(body) {
let url = process.env.OWL_GIT_APIENDPOINT;
let opts = {
headers: {
Authorization: key
}
Authorization: key,
},
};
var res = await axios.post(url, body, opts);
/* Need to read the output from the POST and pass the result upwards to the
client.*/
if (res.status == 201) {
log.out('issueService.sendToGitea: Issue sent to Gitea', 'info');
return {status: res.status,message:'issue created'};
log.out("issueService.sendToGitea: Issue sent to Gitea", "info");
return { status: res.status, message: "issue created" };
} else {
log.out(`issueService.sendToGitea: Fail to send issue: ${res.body}`, 'err');
return {status: res.status,message:'issue not created'};
log.out(`issueService.sendToGitea: Fail to send issue: ${res.body}`, "err");
return { status: res.status, message: "issue not created" };
}
}
module.exports = {
processor
processor,
};

View File

@ -1,28 +1,28 @@
const testing = require('../services/mail.services');
const log = require('../utils/logs.utils');
const testing = require("../services/mail.services");
const log = require("../utils/logs.utils");
async function getAlive(){
log.out('kubeServices.getAlive: alive hook checked', 'info');
return {code: 200, state: {state: 'alive',noise: 'twit-twoo'}};
async function getAlive() {
log.out("kubeServices.getAlive: alive hook checked", "info");
return { code: 200, state: { state: "alive", noise: "twit-twoo" } };
}
async function getReady(){
log.out('kubeServices.getReady: ready hook checked', 'info');
async function getReady() {
log.out("kubeServices.getReady: ready hook checked", "info");
testing.send({
to: 'fred@fjla.uk',
subject: 'OwlBoard Test',
txt: 'This is a test message from OwlBoard (testing)'
to: "fred@fjla.uk",
subject: "OwlBoard Test",
txt: "This is a test message from OwlBoard (testing)",
});
return 'not_implemented';
return "not_implemented";
}
async function getTime(){
async function getTime() {
var now = new Date();
return {responseGenerated: now};
return { responseGenerated: now };
}
module.exports = {
getAlive,
getReady,
getTime
getTime,
};

View File

@ -1,157 +1,162 @@
// Parse and return an LDB Request
const log = require('../utils/logs.utils'); // Log Helper
const ldb = require('ldbs-json');
const util = require('../utils/ldb.utils');
const san = require('../utils/sanitizer.utils');
const db = require('../services/dbAccess.services');
const log = require("../utils/logs.utils"); // Log Helper
const ldb = require("ldbs-json");
const util = require("../utils/ldb.utils");
const san = require("../utils/sanitizer.utils");
const db = require("../services/dbAccess.services");
import { transform as staffStationTransform } from '../utils/translators/ldb/staffStation';
import { transform as staffStationTransform } from "../utils/translators/ldb/staffStation";
const ldbKey = process.env.OWL_LDB_KEY;
const ldbsvKey = process.env.OWL_LDB_SVKEY;
async function get(id, staff=false){
async function get(id, staff = false) {
const cleanId = san.cleanApiEndpointTxt(id);
const obj = await util.checkCrs(cleanId);
try {
const crs = obj[0]['3ALPHA'];
log.out(`ldbService.get: Determined CRS for lookup to be: ${crs}`, 'info');
const crs = obj[0]["3ALPHA"];
log.out(`ldbService.get: Determined CRS for lookup to be: ${crs}`, "info");
if (staff) {
const data = arrDepBoardStaff(crs);
db.increment('ldbsvws');
db.increment("ldbsvws");
return await data;
} else {
const data = arrDepBoard(crs);
db.increment('ldbws');
db.increment("ldbws");
return await data;
}
} catch (err) {
log.out(`ldbService.get: Error, Unable to find CRS: ${err}`, 'info');
log.out(`ldbService.get: Error, Unable to find CRS: ${err}`, "info");
return {
ERROR:'NOT_FOUND',
description:'The entered station was not found.'};
ERROR: "NOT_FOUND",
description: "The entered station was not found.",
};
}
}
async function arrDepBoard(CRS){
log.out(`ldbService.arrDepBoard: Trying to fetch board for ${CRS}`, 'info');
async function arrDepBoard(CRS) {
log.out(`ldbService.arrDepBoard: Trying to fetch board for ${CRS}`, "info");
try {
const options = {
numRows: 10,
crs: CRS.toUpperCase()
crs: CRS.toUpperCase(),
};
const api = new ldb(ldbKey,false);
let d = await api.call('GetArrDepBoardWithDetails', options, false, false);
const api = new ldb(ldbKey, false);
let d = await api.call("GetArrDepBoardWithDetails", options, false, false);
return await util.cleanData(d);
} catch (err) {
log.out(`ldbService.arrDepBoard: Lookup Failed for: ${CRS}`, 'warn');
log.out(`ldbService.arrDepBoard: Lookup Failed for: ${CRS}`, "warn");
return {
GetStationBoardResult: 'not available',
Reason: `The CRS code ${CRS} is not valid`
GetStationBoardResult: "not available",
Reason: `The CRS code ${CRS} is not valid`,
};
}
}
async function arrDepBoardStaff(CRS) {
log.out(`ldbService.arrDepBoardStaff: Try to fetch board for ${CRS}`, 'dbug');
log.out(`ldbService.arrDepBoardStaff: Try to fetch board for ${CRS}`, "dbug");
try {
const options = {
numRows: 40,
crs: CRS.toUpperCase(),
getNonPassengerServices: true,
time: await getDateTimeString(new Date),
time: await getDateTimeString(new Date()),
timeWindow: 120,
services: 'PBS'
services: "PBS",
};
const api = new ldb(ldbsvKey,true);
const api = new ldb(ldbsvKey, true);
console.time(`Fetch Staff LDB for ${CRS.toUpperCase()}`);
const result = await api.call('GetArrivalDepartureBoardByCRS',options,false,false);
console.timeEnd(`Fetch Staff LDB for ${CRS.toUpperCase()}`)
const result = await api.call(
"GetArrivalDepartureBoardByCRS",
options,
false,
false
);
console.timeEnd(`Fetch Staff LDB for ${CRS.toUpperCase()}`);
try {
const _staffLdb = staffStationTransform(result)
console.log("Transformation Test Successful")
console.log(JSON.stringify(_staffLdb))
const _staffLdb = staffStationTransform(result);
console.log("Transformation Test Successful");
console.log(JSON.stringify(_staffLdb));
} catch (err) {
console.log("Transformation Test Failed: " + err)
console.log("Transformation Test Failed: " + err);
}
return result
return result;
} catch (err) {
log.out(`ldbService.arrDepBoardStaff: Lookup Failed for: ${CRS}`, 'warn');
log.out(`ldbService.arrDepBoardStaff: Lookup Failed for: ${CRS}`, "warn");
log.out(`ldbService.arrDepBoardStaff: ${err}`);
return {
GetStationBoardResult: 'not available',
Reason: `The CRS code ${CRS} is not valid`
GetStationBoardResult: "not available",
Reason: `The CRS code ${CRS} is not valid`,
};
}
}
async function getServiceByRID(rid) {
log.out(`ldbService.getServiceByRID: Finding RID: ${rid}`, 'dbug');
log.out(`ldbService.getServiceByRID: Finding RID: ${rid}`, "dbug");
try {
const options = {
rid: String(rid)
rid: String(rid),
};
const api = new ldb(ldbsvKey,true);
return await api.call('GetServiceDetailsByRID', options,false,false);
const api = new ldb(ldbsvKey, true);
return await api.call("GetServiceDetailsByRID", options, false, false);
} catch (err) {
log.out(`ldbService.queryService: ${err}`, 'EROR');
log.out(`ldbService.queryService: ${err}`, "EROR");
}
}
async function getServicesByOther(id) {
log.out(`ldbService.getServiceByOther: Finding services: ${id}`, 'dbug');
log.out(`ldbService.getServiceByOther: Finding services: ${id}`, "dbug");
try {
const options = {
serviceID: id,
sdd: getDateString(new Date)
sdd: getDateString(new Date()),
};
const api = new ldb(ldbsvKey,true);
return await api.call('QueryServices', options, false, false);
const api = new ldb(ldbsvKey, true);
return await api.call("QueryServices", options, false, false);
} catch (err) {
log.out(`ldbService.getServiceByOther: Error: ${err}`, 'EROR');
log.out(`ldbService.getServiceByOther: Error: ${err}`, "EROR");
return false;
}
}
async function getReasonCodeList() {
log.out('ldbService.getReasonCodeList: Fetching reason code list', 'eror');
log.out("ldbService.getReasonCodeList: Fetching reason code list", "eror");
try {
const dbFilter = {};
return await db.query('reasonCodes', dbFilter, false);
return await db.query("reasonCodes", dbFilter, false);
} catch (err) {
log.out(`ldbService.getReasonCodeList: ${err}`, 'eror');
log.out(`ldbService.getReasonCodeList: ${err}`, "eror");
}
}
async function getReasonCode(code) {
log.out(`ldbService.getReasonCode: Fetching reason code ${code}`, 'dbug');
log.out(`ldbService.getReasonCode: Fetching reason code ${code}`, "dbug");
try {
const dbFilter = {
code: code
code: code,
};
return await db.query('reasonCodes', dbFilter, false);
return await db.query("reasonCodes", dbFilter, false);
} catch (err) {
log.out(`ldbService.getReasonCode: ${err}`, 'eror');
log.out(`ldbService.getReasonCode: ${err}`, "eror");
}
}
async function getDateTimeString(date) {
const year = date.getFullYear(),
month = String(date.getMonth() + 1).padStart(2,'0'),
day = String(date.getDate()).padStart(2,'0'),
hour = String(date.getHours()).padStart(2,'0'),
minute = String(date.getMinutes()).padStart(2,'0'),
second = String(date.getSeconds()).padStart(2,'0');
month = String(date.getMonth() + 1).padStart(2, "0"),
day = String(date.getDate()).padStart(2, "0"),
hour = String(date.getHours()).padStart(2, "0"),
minute = String(date.getMinutes()).padStart(2, "0"),
second = String(date.getSeconds()).padStart(2, "0");
const format = `${year}-${month}-${day}T${hour}:${minute}:${second}`;
return format;
}
async function getDateString(date) {
const year = date.getFullYear(),
month = String(date.getMonth() + 1).padStart(2,'0'),
day = String(date.getDate()).padStart(2,'0');
month = String(date.getMonth() + 1).padStart(2, "0"),
day = String(date.getDate()).padStart(2, "0");
const format = `${year}-${month}-${day}`;
return format;
}
@ -161,5 +166,5 @@ module.exports = {
getServiceByRID,
getServicesByOther,
getReasonCodeList,
getReasonCode
getReasonCode,
};

View File

@ -1,19 +1,19 @@
const log = require('../utils/logs.utils'); // Log Helper
const db = require('../services/dbAccess.services');
const log = require("../utils/logs.utils"); // Log Helper
const db = require("../services/dbAccess.services");
async function getStations(){
var out = db.query('stations');
log.out('listServices.getStations: Fetching stations list', 'info');
async function getStations() {
var out = db.query("stations");
log.out("listServices.getStations: Fetching stations list", "info");
return await out;
}
async function getCorpus(){
var out = db.query('corpus');
log.out('listServices.getCorpus: Fetching CORPUS list', 'info');
async function getCorpus() {
var out = db.query("corpus");
log.out("listServices.getCorpus: Fetching CORPUS list", "info");
return await out;
}
module.exports = {
getStations,
getCorpus
getCorpus,
};

View File

@ -1,5 +1,5 @@
const log = require('../utils/logs.utils');
const mail = require('nodemailer'); //>> Probs wrong
const log = require("../utils/logs.utils");
const mail = require("nodemailer"); //>> Probs wrong
const fromAddr = process.env.OWL_EML_FROM;
const smtpUser = process.env.OWL_EML_USER;
@ -13,19 +13,19 @@ let transporter = mail.createTransport({
secure: false, // Must be false for STARTTLS on port 587
auth: {
user: smtpUser,
pass: smtpPass
}
pass: smtpPass,
},
});
/* 'message' is an object containing string values for:
*to, cc, bcc, *subject, *txt, html. * denotes required */
async function send(message) {
log.out('mailServices.send: Message send request received', 'info');
log.out("mailServices.send: Message send request received", "info");
message.from = fromAddr;
try {
var res = await transporter.sendMail(message);
} catch(err) {
log.out(`mailServices.send: Message send failed: ${err}`, 'err');
} catch (err) {
log.out(`mailServices.send: Message send failed: ${err}`, "err");
return false;
}
log.out(`mailServices.send: SMTP Response: ${res.response}`);
@ -33,5 +33,5 @@ async function send(message) {
}
module.exports = {
send
send,
};

View File

@ -1,52 +1,52 @@
// Finds PIS Codes using DB Lookups
const db = require('../services/dbAccess.services');
const log = require('../utils/logs.utils');
const clean = require('../utils/sanitizer.utils');
const db = require("../services/dbAccess.services");
const log = require("../utils/logs.utils");
const clean = require("../utils/sanitizer.utils");
const supported = [
'GW',
'UK'
];
const supported = ["GW", "UK"];
async function findPisByOrigDest(start,end) {
log.out('pisServices.findPisByOrigDest: Searching for PIS for Orig: ' +
`${start}, Dest: ${end}`, 'dbug');
async function findPisByOrigDest(start, end) {
log.out(
"pisServices.findPisByOrigDest: Searching for PIS for Orig: " +
`${start}, Dest: ${end}`,
"dbug"
);
const firstCrs = clean.cleanApiEndpointTxt(start.toLowerCase());
const lastCrs = clean.cleanApiEndpointTxt(end.toLowerCase());
const query = {
stops: {
$all: [
{ $elemMatch: { $eq: firstCrs } },
{ $elemMatch: { $eq: lastCrs } }
]
{ $elemMatch: { $eq: lastCrs } },
],
},
$expr: {
$and: [
{ $eq: [{ $arrayElemAt: [ '$stops', -1 ] }, lastCrs] },
{ $eq: [{ $arrayElemAt: [ '$stops', 0 ] }, firstCrs] }
]
}
{ $eq: [{ $arrayElemAt: ["$stops", -1] }, lastCrs] },
{ $eq: [{ $arrayElemAt: ["$stops", 0] }, firstCrs] },
],
},
};
const search = db.query('pis', query);
const search = db.query("pis", query);
return await search;
}
async function findPisByCode(code) {
log.out(`pisServices.findPisByCode: Searching for PIS code: ${code}`, 'dbug');
log.out(`pisServices.findPisByCode: Searching for PIS code: ${code}`, "dbug");
const cleanCode = clean.removeNonNumeric(code);
const query = {
'code': parseInt(cleanCode)
code: parseInt(cleanCode),
};
const search = db.query('pis', query);
const search = db.query("pis", query);
return await search;
}
async function findByTiplocArray(tiplocArray) {
const query = {
'tiplocs': tiplocArray
tiplocs: tiplocArray,
};
const res = db.query('pis', query);
const res = db.query("pis", query);
return await res;
}
@ -54,5 +54,5 @@ module.exports = {
supported,
findPisByOrigDest,
findPisByCode,
findByTiplocArray
findByTiplocArray,
};

View File

@ -1,19 +1,19 @@
import { createClient } from "redis";
import zlib from 'zlib';
import zlib from "zlib";
const client = createClient({
url: "redis:PORT"
url: "redis:PORT",
});
client.on('error', err => console.log('Redis Client Error', err));
client.on("error", (err) => console.log("Redis Client Error", err));
async function addToCache(key: string, value: Object): Promise<boolean> {
throw new Error("Unable to post to cache")
throw new Error("Unable to post to cache");
}
async function getFromCache(key: string): Promise<Object> {
throw new Error("Unable to retreive")
throw new Error("Unable to retreive");
}
/*
await client.connect();

View File

@ -1,74 +1,78 @@
const log = require('../utils/logs.utils');
const auth = require('../utils/auth.utils');
const db = require('./dbAccess.services');
const mail = require('./mail.services');
const clean = require('../utils/sanitizer.utils');
const domains = require('../configs/domains.configs');
const errors = require('../configs/errorCodes.configs');
const log = require("../utils/logs.utils");
const auth = require("../utils/auth.utils");
const db = require("./dbAccess.services");
const mail = require("./mail.services");
const clean = require("../utils/sanitizer.utils");
const domains = require("../configs/domains.configs");
const errors = require("../configs/errorCodes.configs");
async function createRegKey(body) {
log.out('registerServices.createRegKey: Incoming request', 'INFO');
log.out("registerServices.createRegKey: Incoming request", "INFO");
if (body.email) {
const domain = await clean.getDomainFromEmail(body.email);
log.out(`registerServices: Registration request from: ${domain}`, 'info');
log.out(`registerServices: Registration request from: ${domain}`, "info");
if (domains.includes(domain)) {
log.out(`registerServices.createRegKey: Key from valid: ${domain}`,'info');
log.out(
`registerServices.createRegKey: Key from valid: ${domain}`,
"info"
);
const uuid = await auth.generateKey();
db.addRegReq(uuid, domain);
const message = await auth.generateConfirmationEmail(body.email, uuid);
if (!message) {
const err = new Error('Message generation error');
log.out('registerServices.createRegKey: Error generating email', 'err');
log.out(err, 'err');
const err = new Error("Message generation error");
log.out("registerServices.createRegKey: Error generating email", "err");
log.out(err, "err");
return 500;
}
if (await mail.send(message) == true) {
return {status: 201, message: 'email sent'};
if ((await mail.send(message)) == true) {
return { status: 201, message: "email sent" };
}
return {status: 500, errorCode: 950, errorMsg: errors[950]};
return { status: 500, errorCode: 950, errorMsg: errors[950] };
}
return {status: 403, errorCode: 702, errorMsg: errors[702]};
return { status: 403, errorCode: 702, errorMsg: errors[702] };
} else {
return {status: 400, errorCode: 901, errorMsg: errors[902]};
return { status: 400, errorCode: 901, errorMsg: errors[902] };
}
}
async function regUser(req) { // Add input validation
log.out(`Read UUID: ${req.uuid}`, 'dbug');
log.out(`registrationServices.regUser: Request from: ${req.uuid}`, 'info');
async function regUser(req) {
// Add input validation
log.out(`Read UUID: ${req.uuid}`, "dbug");
log.out(`registrationServices.regUser: Request from: ${req.uuid}`, "info");
const res = await auth.checkRequest(req.uuid);
log.out(`registrationServices.regUser: ${JSON.stringify(res)}`, 'info');
log.out(`registrationServices.regUser: ${JSON.stringify(res)}`, "info");
if (res.result) {
const uuid = await auth.generateKey();
const apiKey = await db.addUser(uuid, res.domain);
if (apiKey) {
db.delRegReq(req.uuid);
return {status: 201, message: 'User added', api_key: uuid};
return { status: 201, message: "User added", api_key: uuid };
}
}
return {status: 401, errorCode: 703, errorMsg: errors[703]};
return { status: 401, errorCode: 703, errorMsg: errors[703] };
}
async function getUser(uuid) {
log.out('registrationServices: Finding user for given UUID', 'dbug');
log.out("registrationServices: Finding user for given UUID", "dbug");
try {
const filter = {
uuid: uuid
uuid: uuid,
};
const res = await db.query('users', filter, false);
const res = await db.query("users", filter, false);
if (res.length) {
return res;
} else {
return {status: 404, errorCode:400, errorMsg: errors[400]};
return { status: 404, errorCode: 400, errorMsg: errors[400] };
}
} catch (err) {
console.log(err);
return {status: 500, errorCode: 951, errorMsg: errors[951]};
return { status: 500, errorCode: 951, errorMsg: errors[951] };
}
}
module.exports = {
regUser,
createRegKey,
getUser
getUser,
};

View File

@ -1,20 +1,20 @@
const log = require('../utils/logs.utils'); // Log Helper
const db = require('../services/dbAccess.services');
const os = require('os');
const vers = require('../configs/version.configs');
const log = require("../utils/logs.utils"); // Log Helper
const db = require("../services/dbAccess.services");
const os = require("os");
const vers = require("../configs/version.configs");
async function buildJson() {
let json = {};
json.count = {};
// Async call all db queries
const counters = db.query('meta', {target: 'counters'});
const versions = db.query('meta', {target: 'versions'});
const userCount = db.colCount('users');
const regCount = db.colCount('registrations');
const pisCount = db.colCount('pis');
const corpusCount = db.colCount('corpus');
const stationsCount = db.colCount('stations');
const timetableCount = db.colCount('timetable');
const counters = db.query("meta", { target: "counters" });
const versions = db.query("meta", { target: "versions" });
const userCount = db.colCount("users");
const regCount = db.colCount("registrations");
const pisCount = db.colCount("pis");
const corpusCount = db.colCount("corpus");
const stationsCount = db.colCount("stations");
const timetableCount = db.colCount("timetable");
// Insert data
json.mode = process.env.NODE_ENV;
@ -33,41 +33,41 @@ async function buildJson() {
return json;
}
async function hits(){
log.out('statsServices.hits: Statistics Requested', 'info');
async function hits() {
log.out("statsServices.hits: Statistics Requested", "info");
const out = await buildJson();
log.out(`statsServices.hits: Sending Data: ${JSON.stringify(out)}`, 'info');
log.out(`statsServices.hits: Sending Data: ${JSON.stringify(out)}`, "info");
return out;
}
async function getVersions() {
log.out('statsServices.getVersions: Fetching versions', 'info');
const dbMan = await db.query('versions', {target: 'dbmanager'});
const mqClt = await db.query('versions', {target: 'mq-client'});
log.out("statsServices.getVersions: Fetching versions", "info");
const dbMan = await db.query("versions", { target: "dbmanager" });
const mqClt = await db.query("versions", { target: "mq-client" });
const data = {
'backend': vers.app,
'db-manager': dbMan[0]?.['version'] || '',
'mq-client': mqClt[0]?.['version'] || '',
}
return data
backend: vers.app,
"db-manager": dbMan[0]?.["version"] || "",
"mq-client": mqClt[0]?.["version"] || "",
};
return data;
}
async function statistics() {
log.out('statsServices.statistics: Fetching statistics', 'info');
log.out("statsServices.statistics: Fetching statistics", "info");
const countersPromise = db.query('meta', { target: 'counters' });
const timetablePromise = db.query('meta', { target: 'timetable' });
const pisPromise = db.query('meta', { target: 'pis' });
const corpusPromise = db.query('meta', { target: 'corpus' });
const reasonCodesPromise = db.query('meta', { target: 'reasonCodes' });
const countersPromise = db.query("meta", { target: "counters" });
const timetablePromise = db.query("meta", { target: "timetable" });
const pisPromise = db.query("meta", { target: "pis" });
const corpusPromise = db.query("meta", { target: "corpus" });
const reasonCodesPromise = db.query("meta", { target: "reasonCodes" });
const lengthUsersPromise = db.colCount('users');
const lengthRegistrationsPromise = db.colCount('registrations');
const lengthCorpusPromise = db.colCount('corpus');
const lengthStationsPromise = db.colCount('stations');
const lengthPisPromise = db.colCount('pis');
const lengthTimetablePromise = db.colCount('timetable');
const lengthReasonCodesPromise = db.colCount('reasonCodes');
const lengthUsersPromise = db.colCount("users");
const lengthRegistrationsPromise = db.colCount("registrations");
const lengthCorpusPromise = db.colCount("corpus");
const lengthStationsPromise = db.colCount("stations");
const lengthPisPromise = db.colCount("pis");
const lengthTimetablePromise = db.colCount("timetable");
const lengthReasonCodesPromise = db.colCount("reasonCodes");
const [
counters,
@ -81,7 +81,7 @@ async function statistics() {
lengthStations,
lengthPis,
lengthTimetable,
lengthReasonCodes
lengthReasonCodes,
] = await Promise.all([
countersPromise,
timetablePromise,
@ -94,27 +94,27 @@ async function statistics() {
lengthStationsPromise,
lengthPisPromise,
lengthTimetablePromise,
lengthReasonCodesPromise
lengthReasonCodesPromise,
]);
return {
hostname: os.hostname() || 'Unknown',
runtimeMode: process.env.NODE_ENV || 'Unknown',
reset: counters[0]['since'],
hostname: os.hostname() || "Unknown",
runtimeMode: process.env.NODE_ENV || "Unknown",
reset: counters[0]["since"],
updateTimes: {
timetable: timetable[0]['updated'],
pis: pis[0]['updated'],
corpus: corpus[0]['updated'],
reasonCodes: reasonCodes[0]['updated']
timetable: timetable[0]["updated"],
pis: pis[0]["updated"],
corpus: corpus[0]["updated"],
reasonCodes: reasonCodes[0]["updated"],
},
requestCounts: {
ldbws_api: counters[0]['ldbws'] || 0,
lsbsvws_api: counters[0]['ldbsvws'] || 0,
corpus_api: counters[0]['corpus_api'] || 0,
timetable_db: counters[0]['timetable'] || 0,
pis_db: counters[0]['pis'] || 0,
corpus_db: counters[0]['corpus'] || 0,
stations_db: counters[0]['stations'] || 0
ldbws_api: counters[0]["ldbws"] || 0,
lsbsvws_api: counters[0]["ldbsvws"] || 0,
corpus_api: counters[0]["corpus_api"] || 0,
timetable_db: counters[0]["timetable"] || 0,
pis_db: counters[0]["pis"] || 0,
corpus_db: counters[0]["corpus"] || 0,
stations_db: counters[0]["stations"] || 0,
},
dbLengths: {
users: lengthUsers,
@ -123,14 +123,13 @@ async function statistics() {
stations: lengthStations,
pis: lengthPis,
timetable: lengthTimetable,
reasonCodes: lengthReasonCodes
reasonCodes: lengthReasonCodes,
},
};
}
module.exports = {
hits,
statistics,
getVersions
getVersions,
};

View File

@ -1,23 +1,26 @@
const log = require('../utils/logs.utils');
const db = require('./dbAccess.services');
const clean = require('../utils/sanitizer.utils');
const pis = require('../services/pis.services');
const { filter } = require('compression');
const log = require("../utils/logs.utils");
const db = require("./dbAccess.services");
const clean = require("../utils/sanitizer.utils");
const pis = require("../services/pis.services");
const { filter } = require("compression");
async function findByHeadcodeToday(headcode) {
const sanitizedHeadcode = clean.removeNonAlphanumeric(headcode).toUpperCase();
log.out('trainServiceServices.findByHeadcode: Searching for headcode ' +
sanitizedHeadcode, 'dbug');
log.out(
"trainServiceServices.findByHeadcode: Searching for headcode " +
sanitizedHeadcode,
"dbug"
);
const now = new Date();
const dayMap = ['su', 'm', 't', 'w', 'th', 'f', 's'];
const dayMap = ["su", "m", "t", "w", "th", "f", "s"];
const shortDay = dayMap[now.getDay()]; // Fetch short day from map
const query = {
headcode: sanitizedHeadcode,
scheduleStartDate: {$lte: now},
scheduleEndDate: {$gte: now},
daysRun: {$in: [shortDay]}
scheduleStartDate: { $lte: now },
scheduleEndDate: { $gte: now },
daysRun: { $in: [shortDay] },
};
const queryData = await db.query('timetable', query);
const queryData = await db.query("timetable", query);
let trainData = await parseTrains(queryData);
let preparedData = [];
for (let trainService in trainData) {
@ -27,9 +30,9 @@ async function findByHeadcodeToday(headcode) {
//console.log(tiplocList.length); console.log(tiplocList);
if (tiplocList.length) {
const pisDetail = await pis.findByTiplocArray(tiplocList);
trainService['pis'] = pisDetail?.[0]?.['code'] ?? 'None';
} else if (trainService?.operator === 'GW') {
trainService['pis'] = '0015'; // Not in Service code
trainService["pis"] = pisDetail?.[0]?.["code"] ?? "None";
} else if (trainService?.operator === "GW") {
trainService["pis"] = "0015"; // Not in Service code
// '0015' is a string becuase 0015 is not a valid number..
}
}
@ -40,42 +43,45 @@ async function findByHeadcodeToday(headcode) {
async function findByHeadcode(date, headcode) {
const sanitizedHeadcode = clean.removeNonAlphanumeric(headcode).toUpperCase();
log.out('trainServiceServices.findByHeadcode: Searching for headcode ' +
sanitizedHeadcode, 'dbug');
log.out(
"trainServiceServices.findByHeadcode: Searching for headcode " +
sanitizedHeadcode,
"dbug"
);
let searchDate;
if (date === 'now') {
if (date === "now") {
searchDate = new Date();
} else {
searchDate = new Date(date);
}
searchDate.setHours(12,0,0); // Set to midday to avoid any timezone issues
const dayMap = ['su', 'm', 't', 'w', 'th', 'f', 's'];
searchDate.setHours(12, 0, 0); // Set to midday to avoid any timezone issues
const dayMap = ["su", "m", "t", "w", "th", "f", "s"];
const shortDay = dayMap[searchDate.getDay()]; // Fetch short day from map
const query = {
headcode: sanitizedHeadcode,
scheduleStartDate: {$lte: searchDate},
scheduleEndDate: {$gte: searchDate},
daysRun: {$in: [shortDay]}
scheduleStartDate: { $lte: searchDate },
scheduleEndDate: { $gte: searchDate },
daysRun: { $in: [shortDay] },
};
const pipeline = [
{
$match: query
$match: query,
},
{
$project: {
operator: 1,
stops: {
$concatArrays: [
[{ $first: '$stops'}],
[{ $arrayElemAt: ['$stops', -1]}]
]
[{ $first: "$stops" }],
[{ $arrayElemAt: ["$stops", -1] }],
],
},
trainUid: 1,
stpIndicator: 1
}
}
stpIndicator: 1,
},
},
];
const queryData = await db.queryAggregate('timetable', pipeline);
const queryData = await db.queryAggregate("timetable", pipeline);
console.log(JSON.stringify(queryData));
let filteredData = filterServices(queryData);
return await filteredData;
@ -83,17 +89,17 @@ async function findByHeadcode(date, headcode) {
async function findByTrainUid(uid, date = new Date()) {
let queryDate;
if (date === 'now') {
if (date === "now") {
queryDate = new Date();
} else {
queryDate = date;
}
const query = {
trainUid: uid,
scheduleStartDate: {$lte: queryDate},
scheduleEndDate: {$gte: queryDate}
scheduleStartDate: { $lte: queryDate },
scheduleEndDate: { $gte: queryDate },
};
const queryData = await db.query('timetable', query);
const queryData = await db.query("timetable", query);
if (queryData.length === 0) {
return [];
}
@ -106,8 +112,8 @@ async function findByTrainUid(uid, date = new Date()) {
if (publicStops.length) {
const pisCode = await pis.findByTiplocArray(publicStops);
services[0].pis = pisCode[0]?.code;
} else if ( services[0]?.operator === 'GW' && !publicStops.length) {
services[0].pis = '0015';
} else if (services[0]?.operator === "GW" && !publicStops.length) {
services[0].pis = "0015";
}
}
return services[0];
@ -116,7 +122,7 @@ async function findByTrainUid(uid, date = new Date()) {
module.exports = {
findByHeadcodeToday,
findByHeadcode,
findByTrainUid
findByTrainUid,
};
/* Internal Functions, not to be exported */
@ -126,8 +132,8 @@ module.exports = {
async function getPublicStops(data) {
let tiplocList = [];
for (const publicStop in data) {
if (data[publicStop]['isPublic']) {
tiplocList.push(data[publicStop]['tiploc']);
if (data[publicStop]["isPublic"]) {
tiplocList.push(data[publicStop]["tiploc"]);
}
}
return tiplocList;
@ -139,7 +145,7 @@ async function getPublicStops(data) {
async function parseTrains(data) {
let trainUids = [];
for (const i of data) {
const trainUid = i['trainUid'];
const trainUid = i["trainUid"];
if (!trainUids.includes(trainUid)) {
trainUids.push(trainUid);
}
@ -153,53 +159,55 @@ async function parseTrains(data) {
}
async function filterServices(data) {
let stpIndicators = {}, filteredServices = [];
let stpIndicators = {},
filteredServices = [];
for (const serviceDetail of data) {
const trainUid = serviceDetail['trainUid'];
const stpIndicator = serviceDetail['stpIndicator'];
const trainUid = serviceDetail["trainUid"];
const stpIndicator = serviceDetail["stpIndicator"];
if (!stpIndicators[trainUid]) {
stpIndicators[trainUid] = {
hasC: false,
hasN: false,
hasO: false,
hasP: false
hasP: false,
};
}
if (stpIndicator === 'C') {
if (stpIndicator === "C") {
stpIndicators[trainUid].hasC = true;
}
if (stpIndicator === 'N') {
if (stpIndicator === "N") {
stpIndicators[trainUid].hasN = true;
}
if (stpIndicator === 'O') {
if (stpIndicator === "O") {
stpIndicators[trainUid].hasO = true;
}
if (stpIndicator === 'P') {
if (stpIndicator === "P") {
stpIndicators[trainUid].hasP = true;
}
}
let preparedData;
for (const serviceDetail of data) {
const trainUid = serviceDetail['trainUid'];
const trainUid = serviceDetail["trainUid"];
const thisStpIndicators = stpIndicators[trainUid];
const stpIndicator = serviceDetail['stpIndicator'];
const stpIndicator = serviceDetail["stpIndicator"];
if (stpIndicator === 'C') {
if (stpIndicator === "C") {
break;
}
if (stpIndicator === 'N' &&
!thisStpIndicators.hasC) {
if (stpIndicator === "N" && !thisStpIndicators.hasC) {
filteredServices.push(serviceDetail);
} else if (stpIndicator === 'O' &&
} else if (
stpIndicator === "O" &&
!thisStpIndicators.hasC &&
!thisStpIndicators.hasN) {
!thisStpIndicators.hasN
) {
filteredServices.push(serviceDetail);
} else if (stpIndicator === 'P' &&
} else if (
stpIndicator === "P" &&
!thisStpIndicators.hasC &&
!thisStpIndicators.hasN &&
!thisStpIndicators.hasO) {
!thisStpIndicators.hasO
) {
filteredServices.push(serviceDetail);
}
}

View File

@ -1,16 +1,19 @@
const logs = require('../utils/logs.utils');
const crypt = require('crypto');
const db = require('../services/dbAccess.services');
const fs = require('fs/promises');
const logs = require("../utils/logs.utils");
const crypt = require("crypto");
const db = require("../services/dbAccess.services");
const fs = require("fs/promises");
import { minifyMail } from "./minify.utils";
// Checks users registration key against issued keys
async function isAuthed(uuid: string) { // Needs testing
const q = {uuid: uuid};
const res = await db.query('users', q);
logs.out('authUtils.checkUser: DB Query answer: ' +
JSON.stringify(res[0]), 'dbug');
async function isAuthed(uuid: string) {
// Needs testing
const q = { uuid: uuid };
const res = await db.query("users", q);
logs.out(
"authUtils.checkUser: DB Query answer: " + JSON.stringify(res[0]),
"dbug"
);
const authorized = res && res[0] && res[0].domain;
if (authorized) db.userAtime(uuid);
return authorized;
@ -18,37 +21,43 @@ async function isAuthed(uuid: string) { // Needs testing
// Checks whether a registration request key is valid
async function checkRequest(key: string) {
const collection = 'registrations';
const query = {uuid: key};
const collection = "registrations";
const query = { uuid: key };
const res = await db.query(collection, query);
logs.out('authUtils.checkRequest: DB Query result: ' +
JSON.stringify(res), 'dbug');
const result = res.length > 0 && res[0].time
logs.out(
"authUtils.checkRequest: DB Query result: " + JSON.stringify(res),
"dbug"
);
const result =
res.length > 0 && res[0].time
? { result: true, domain: res[0].domain }
: { result: false };
return result;
}
// Creates an API key for a user
async function generateKey() { // Needs testing & moving to 'register.utils'
async function generateKey() {
// Needs testing & moving to 'register.utils'
return crypt.randomUUID();
}
async function generateConfirmationEmail(eml: string, uuid: string) {
try {
const htmlTpl = await fs.readFile('mail-templates/register.html', 'utf-8');
const htmlTpl = await fs.readFile("mail-templates/register.html", "utf-8");
const htmlStr = htmlTpl.replace(/>>ACCESSCODE<</g, uuid);
const htmlMin = await minifyMail(htmlStr);
const txtTpl = fs.readFile('mail-templates/register.txt', 'utf-8');
const txtTpl = fs.readFile("mail-templates/register.txt", "utf-8");
return {
to: eml,
subject: 'OwlBoard Registration',
subject: "OwlBoard Registration",
text: (await txtTpl).replace(/>>ACCESSCODE<</g, uuid),
html: htmlMin
html: htmlMin,
};
} catch(err) {
logs.out('mailServices.generateConfirmationEmail: Error reading template, ' +
err, 'err');
} catch (err) {
logs.out(
"mailServices.generateConfirmationEmail: Error reading template, " + err,
"err"
);
return false;
}
}
@ -57,12 +66,7 @@ module.exports = {
isAuthed,
generateKey,
generateConfirmationEmail,
checkRequest
checkRequest,
};
export {
isAuthed,
generateKey,
generateConfirmationEmail,
checkRequest
}
export { isAuthed, generateKey, generateConfirmationEmail, checkRequest };

View File

@ -1,32 +1,30 @@
const log = require('./logs.utils'); // Log Helper
const db = require('../services/dbAccess.services'); // DB Access
const log = require("./logs.utils"); // Log Helper
const db = require("../services/dbAccess.services"); // DB Access
//const san = require('../utils/sanitizer.utils'); // Sanitiser
import * as san from '../utils/sanitizer.utils'
import * as san from "../utils/sanitizer.utils";
async function checkCrs(input = ""){
async function checkCrs(input = "") {
var INPUT = input.toUpperCase();
var query = {
'$or':[
{'3ALPHA':INPUT},
{'TIPLOC':INPUT},
{'STANOX':INPUT}
]
$or: [{ "3ALPHA": INPUT }, { TIPLOC: INPUT }, { STANOX: INPUT }],
};
var result = await db.query('stations', query);
log.out('ldbUtils.checkCrs: Query results: ' +
JSON.stringify(result), 'dbug');
var result = await db.query("stations", query);
log.out(
"ldbUtils.checkCrs: Query results: " + JSON.stringify(result),
"dbug"
);
return result;
}
// Needs to be moved to the frontend `ensureArray() func`
async function cleanMessages(input){
log.out('ldbUtils.cleanMessages: Deprecated function has been called', 'err');
async function cleanMessages(input) {
log.out("ldbUtils.cleanMessages: Deprecated function has been called", "err");
var out = [];
if (typeof input.message == 'string') {
if (typeof input.message == "string") {
out.push(san.cleanNrcc(input.message));
} else if (typeof input.message == 'object') {
for(var i = 0; i < input.message.length; i++) {
} else if (typeof input.message == "object") {
for (var i = 0; i < input.message.length; i++) {
out.push(san.cleanNrcc(input.message[i]));
}
}
@ -34,13 +32,13 @@ async function cleanMessages(input){
}
// Accepts an object but not an Array and returns it wrapped in an array.
async function cleanServices(input){
log.out('ldbUtils.cleanServices: Deprecated function has been called', 'err');
async function cleanServices(input) {
log.out("ldbUtils.cleanServices: Deprecated function has been called", "err");
var out = [];
if (!Array.isArray(input)) {
log.out(`ldbUtils.cleanServices: Transforming input: ${input}`, 'dbug');
log.out(`ldbUtils.cleanServices: Transforming input: ${input}`, "dbug");
out.push(input);
log.out(`ldbUtils.cleanServices: Returning output: ${out}`, 'dbug');
log.out(`ldbUtils.cleanServices: Returning output: ${out}`, "dbug");
return out;
} else {
return input;
@ -50,19 +48,31 @@ async function cleanServices(input){
async function cleanData(input) {
try {
if (input?.GetStationBoardResult?.trainServices) {
log.out('ldbUtils.cleanData: Changing train service data to array','dbug');
input.GetStationBoardResult.trainServices.service = await ensureArray(input.GetStationBoardResult.trainServices.service);
log.out(
"ldbUtils.cleanData: Changing train service data to array",
"dbug"
);
input.GetStationBoardResult.trainServices.service = await ensureArray(
input.GetStationBoardResult.trainServices.service
);
}
if (input?.GetStationBoardResult?.busServices) {
log.out('ldbUtils.cleanData: Changing bus service data to array','dbug');
input.GetStationBoardResult.busServices.service = await ensureArray(input.GetStationBoardResult.busServices.service);
log.out("ldbUtils.cleanData: Changing bus service data to array", "dbug");
input.GetStationBoardResult.busServices.service = await ensureArray(
input.GetStationBoardResult.busServices.service
);
}
if (input?.GetStationBoardResult?.ferryServices) {
log.out('ldbUtils.cleanData: Changing ferry service data to array','dbug');
input.GetStationBoardResult.ferryServices.service = await ensureArray(input.GetStationBoardResult.ferryServices.service);
log.out(
"ldbUtils.cleanData: Changing ferry service data to array",
"dbug"
);
input.GetStationBoardResult.ferryServices.service = await ensureArray(
input.GetStationBoardResult.ferryServices.service
);
}
} catch (err) {
log.out(`ldbUtils.cleanData: Error: ${err}`, 'eror');
log.out(`ldbUtils.cleanData: Error: ${err}`, "eror");
}
return input;
}
@ -78,5 +88,5 @@ module.exports = {
checkCrs,
cleanMessages,
cleanServices,
cleanData
cleanData,
};

View File

@ -1,10 +1,12 @@
const environment: string = process.env.NODE_ENV || "Unknown";
const hideInProduction: string[] = ['info', 'dbug'];
const hideInProduction: string[] = ["info", "dbug"];
async function out(msg: string, level = 'othr') {
if (environment === 'production' &&
hideInProduction.includes(level.toLowerCase())) {
async function out(msg: string, level = "othr") {
if (
environment === "production" &&
hideInProduction.includes(level.toLowerCase())
) {
return;
} else {
const time = new Date().toISOString();
@ -13,7 +15,7 @@ async function out(msg: string, level = 'othr') {
}
module.exports = {
out
out,
};
export { out }
export { out };

View File

@ -1,13 +1,13 @@
const htmlShrink = require('html-minifier').minify;
const juice = require('juice');
const htmlShrink = require("html-minifier").minify;
const juice = require("juice");
async function minifyMail(input: string): Promise<string> {
const inlined: string = juice(input);
return htmlShrink(inlined, {
removeComments: true,
collapseWhitespace: true
collapseWhitespace: true,
});
};
}
module.exports = {minifyMail}
export {minifyMail}
module.exports = { minifyMail };
export { minifyMail };

View File

@ -1,6 +1,6 @@
export function removeNewlineAndPTag(input: string): string {
const regex = /[\n\r]|<\/?p[^>]*>/g;
return input.replace(regex, function(match) {
return input.replace(regex, function (match) {
if (match === "\n" || match === "\r") {
return "";
} else {

View File

@ -1,27 +1,29 @@
//const log = require('../utils/log.utils');
function removeNonAlphanumeric(inputString: string) {
return inputString.replace(/[^a-zA-Z0-9]/g, '');
return inputString.replace(/[^a-zA-Z0-9]/g, "");
}
function removeNonAlpha(inputString: string) {
return inputString.replace(/[^a-zA-Z]/g, '');
return inputString.replace(/[^a-zA-Z]/g, "");
}
function removeNonNumeric(inputString: string) {
return inputString.replace(/[^0-9]/g, '');
return inputString.replace(/[^0-9]/g, "");
}
const cleanApiEndpointTxt = removeNonAlpha;
const cleanApiEndpointNum = removeNonAlphanumeric;
function cleanNrcc(input: string) { // Remove newlines and then <p> tags from input
const cleanInput = input.replace(/[\n\r]/g, '').replace(/<\/?p[^>]*>/g, '');
function cleanNrcc(input: string) {
// Remove newlines and then <p> tags from input
const cleanInput = input.replace(/[\n\r]/g, "").replace(/<\/?p[^>]*>/g, "");
return cleanInput;
}
function getDomainFromEmail(mail: string) { // Needs testing
let split = mail.split('@');
function getDomainFromEmail(mail: string) {
// Needs testing
let split = mail.split("@");
return split[1];
}
@ -43,4 +45,4 @@ export {
removeNonNumeric,
cleanNrcc,
getDomainFromEmail,
}
};

View File

@ -1,5 +1,5 @@
function unixLocal(unix: number) {
var jsTime = unix*1000;
var jsTime = unix * 1000;
var dt = new Date(jsTime);
return dt.toLocaleString();
}

View File

@ -1,14 +1,18 @@
import type { StaffLdb, NrccMessage, TrainServices,
ServiceLocation } from '@owlboard/ts-types';
import type {
StaffLdb,
NrccMessage,
TrainServices,
ServiceLocation,
} from "@owlboard/ts-types";
import { tz } from 'moment-timezone';
import { removeNewlineAndPTag } from '../../newSanitizer';
import { tz } from "moment-timezone";
import { removeNewlineAndPTag } from "../../newSanitizer";
/// I do not yet have a type defined for any of the input object
export function transform(input: any): StaffLdb | null {
console.time("StaffLdb Transformation")
const data = input.GetBoardResult
let output: StaffLdb
console.time("StaffLdb Transformation");
const data = input.GetBoardResult;
let output: StaffLdb;
try {
output = {
generatedAt: transformDateTime(data?.generatedAt) || new Date(),
@ -17,57 +21,57 @@ export function transform(input: any): StaffLdb | null {
nrccMessages: transformNrcc(data?.nrccMessages) || undefined,
trainServices: transformTrainServices(data?.trainServices) || undefined,
busServices: transformTrainServices(data?.busServices) || undefined,
ferryServices: transformTrainServices(data?.ferryServices) || undefined
}
console.timeEnd("StaffLdb Transformation")
return output
ferryServices: transformTrainServices(data?.ferryServices) || undefined,
};
console.timeEnd("StaffLdb Transformation");
return output;
} catch (err) {
console.log("utils/translators/ldb/staffLdb.transform: Caught Error")
console.log('Unable to parse data, assuming no data: ' + err)
console.log("utils/translators/ldb/staffLdb.transform: Caught Error");
console.log("Unable to parse data, assuming no data: " + err);
}
console.timeEnd("StaffLdb Transformation")
return null
console.timeEnd("StaffLdb Transformation");
return null;
}
function transformDateTime(input: string): Date {
return new Date(input)
return new Date(input);
}
function transformNrcc(input: any): NrccMessage[] | undefined {
let output: NrccMessage[] = []
let messages = input
let output: NrccMessage[] = [];
let messages = input;
if (!Array.isArray(input?.message)) {
messages = [input?.message]
messages = [input?.message];
}
if (messages.length) {
for (const item of messages) {
let message: NrccMessage = {
severity: item?.severity,
xhtmlMessage: removeNewlineAndPTag(item?.xhtmlMessage)
xhtmlMessage: removeNewlineAndPTag(item?.xhtmlMessage),
};
output.push(message);
}
output.push(message)
return output;
}
return output
}
return undefined
return undefined;
}
function transformTrainServices(input: any): TrainServices[] {
let services: any = input?.service
let output: TrainServices[] = []
let services: any = input?.service;
let output: TrainServices[] = [];
if (services === undefined) {
return output
return output;
}
if (!Array.isArray(input.service)) {
services = [input.service]
services = [input.service];
}
for (const service of services) {
const trainService: TrainServices = {
rid: service?.rid,
uid: service?.uid,
trainid: service?.trainid,
operatorCode: service?.operatorCode || 'UK',
platform: service?.platform || '-',
operatorCode: service?.operatorCode || "UK",
platform: service?.platform || "-",
platformIsHidden: service?.platformIsHidden,
serviceIsSupressed: service?.serviceIsSupressed,
origin: transformLocation(service?.origin),
@ -84,48 +88,50 @@ function transformTrainServices(input: any): TrainServices[] {
std: transformUnspecifiedDateTime(service?.std),
etd: transformUnspecifiedDateTime(service?.etd),
atd: transformUnspecifiedDateTime(service?.atd),
};
Object.keys(trainService).forEach(
(key) => trainService[key] === undefined && delete trainService[key]
);
output.push(trainService);
}
Object.keys(trainService).forEach(key => trainService[key] === undefined && delete trainService[key]);
output.push(trainService)
}
return output
return output;
}
function transformLocation(input: any): ServiceLocation[] {
let output: ServiceLocation[] = []
let locations: any[] = input.location
let output: ServiceLocation[] = [];
let locations: any[] = input.location;
if (!Array.isArray(input.location)) {
locations = [input.location]
locations = [input.location];
}
for (const item of locations) {
const location: ServiceLocation = {
tiploc: item?.tiploc
}
tiploc: item?.tiploc,
};
if (item?.via) {
location.via = item.via
location.via = item.via;
}
output.push(location)
output.push(location);
}
return output
return output;
}
export function calculateLength(input: any): number | undefined {
let length: number;
if (input?.length) {
length = input.length
return Number(length)
length = input.length;
return Number(length);
}
if (input?.formation?.coaches?.coach) {
length = input.formation.coaches.coach.length
return Number(length)
length = input.formation.coaches.coach.length;
return Number(length);
}
return undefined
return undefined;
}
function transformUnspecifiedDateTime(input: string): Date | undefined {
if (!input) {
return undefined
return undefined;
}
const date = tz(input, "Europe/London");
return date.toDate()
return date.toDate();
}

View File

@ -1,9 +1,9 @@
import { removeNewlineAndPTag } from "../../src/utils/newSanitizer";
describe('newSanitizer', () => {
test('Should remove /\n and <p>/</p> elements', () => {
describe("newSanitizer", () => {
test("Should remove /\n and <p>/</p> elements", () => {
const input = "\n<p>This is a string</p>";
const expectedOutput = "This is a string"
const expectedOutput = "This is a string";
expect(removeNewlineAndPTag(input)).toEqual(expectedOutput);
});
});

View File

@ -1,31 +1,31 @@
import { getDomainFromEmail } from "../../src/utils/sanitizer.utils";
import { removeNonNumeric } from "../../src/utils/sanitizer.utils";
describe('Sanitize Email', () => {
describe("Sanitize Email", () => {
const inputs = [
"this+is+an-_email@example.com",
'"unusual email"@example.com',
"(brackets)addr@example.com",
"I%Have{Special}%Characters@example.com",
"Basic.address@example.com",
`"very.(),:;<>[]\".VERY.\"very\ \"very\".unusual"@example.com`
]
const expectedOutput = "example.com"
`"very.(),:;<>[]\".VERY.\"very\ \"very\".unusual"@example.com`,
];
const expectedOutput = "example.com";
for (const addr of inputs) {
test(`Should return only domain: ${addr}`, () => {
expect(getDomainFromEmail(addr)).toEqual(expectedOutput);
})
});
}
});
describe('Remove non-numeric', () => {
const inputs = ['abc123','<%43)($£@:}jfkd4']
const expectedOutputs = ['123','434']
describe("Remove non-numeric", () => {
const inputs = ["abc123", "<%43)($£@:}jfkd4"];
const expectedOutputs = ["123", "434"];
for (const key in inputs) {
const input = inputs[key];
const desired = expectedOutputs[key];
test(`Should return only numbers: ${key}`, () => {
expect(removeNonNumeric(input)).toEqual(desired);
})
});
}
})
});

View File

@ -1,45 +1,43 @@
import {
transform,
calculateLength
} from "../../../../src/utils/translators/ldb/staffStation";
calculateLength,
} from "../../../../src/utils/translators/ldb/staffStation";
import { inputs } from "./stationInputs";
import { outputs } from "./stationOutputs";
import { noLength as serviceNoLength } from "./trainServiceInputs";
import { trainServices } from "./trainServiceInputs";
describe('transform', () => {
test('Should return null for empty input', () => {
describe("transform", () => {
test("Should return null for empty input", () => {
const input = {};
expect(transform(input)).toBeNull();
});
for (const testNo in inputs) {
test(`Should correctly transform data ${testNo}`, () => {
const input = inputs[testNo]
const expectedOutput = outputs[testNo]
const input = inputs[testNo];
const expectedOutput = outputs[testNo];
expect(transform(input)).toEqual(expectedOutput);
});
}
});
// Write test for calculateLength(input: TrainServices): number | undefined
describe('calculateLength', () => {
test('Should return ubdefined for no length', () => {
describe("calculateLength", () => {
test("Should return ubdefined for no length", () => {
const input = serviceNoLength;
expect(calculateLength(input)).toBeUndefined();
});
for (const testNo in trainServices) {
test(`Should correctly calculate ${testNo}`, () => {
const input = trainServices[testNo]
const expectedOutput = 4
const input = trainServices[testNo];
const expectedOutput = 4;
expect(calculateLength(input)).toEqual(expectedOutput);
});
}
});

View File

@ -1,19 +1,19 @@
export const inputs: any[] = [
{
GetBoardResult: {
generatedAt: '2023-08-01T20:37:05.559123+01:00',
locationName: 'Railway Station',
crs: 'RLY',
stationManager: 'Network Rail',
stationManagerCode: 'RT',
generatedAt: "2023-08-01T20:37:05.559123+01:00",
locationName: "Railway Station",
crs: "RLY",
stationManager: "Network Rail",
stationManagerCode: "RT",
nrccMessages: {
message: {
severity: "minor",
xhtmlMessage: '\n<p>Minor Alert</p>',
type: "station"
}
xhtmlMessage: "\n<p>Minor Alert</p>",
type: "station",
},
isTruncated: 'true',
},
isTruncated: "true",
trainServices: {
service: [
{
@ -36,21 +36,21 @@ export const inputs: any[] = [
location: {
locationName: "Plymouth",
crs: "PLY",
tiploc: "PLYMTH"
}
tiploc: "PLYMTH",
},
},
destination: {
location: {
locationName: "Birmingham New Street",
crs: "BHM",
tiploc: "BHAMNWS"
}
tiploc: "BHAMNWS",
},
},
category: "XX",
activities: "T",
}
]
}
}
},
]
],
},
},
},
];

View File

@ -1,5 +1,9 @@
import type { StaffLdb, NrccMessage, TrainServices,
ServiceLocation } from '@owlboard/ts-types';
import type {
StaffLdb,
NrccMessage,
TrainServices,
ServiceLocation,
} from "@owlboard/ts-types";
export const outputs: StaffLdb[] = [
{
@ -9,8 +13,8 @@ export const outputs: StaffLdb[] = [
nrccMessages: [
{
severity: "minor",
xhtmlMessage: "Minor Alert"
}
xhtmlMessage: "Minor Alert",
},
],
trainServices: [
{
@ -28,17 +32,17 @@ export const outputs: StaffLdb[] = [
length: 10,
origin: [
{
tiploc: "PLYMTH"
}
tiploc: "PLYMTH",
},
],
destination: [
{
tiploc: "BHAMNWS"
}
]
}
tiploc: "BHAMNWS",
},
],
},
],
busServices: [],
ferryServices: []
ferryServices: [],
},
]
];

View File

@ -1,41 +1,149 @@
import type { TrainServices } from "@owlboard/ts-types";
export const noLength: any = {
"rid": "202308058004480",
"uid": "P04480",
"trainid": "1A39",
"sdd": "2023-08-05",
"operator": "Great Western Railway",
"operatorCode": "GW",
"sta": "2023-08-05T21:51:00",
"eta": "2023-08-05T23:04:18",
"arrivalType": "Forecast",
"std": "2023-08-05T22:00:00",
"etd": "2023-08-05T23:05:18",
"departureType": "Forecast",
"departureSource": "Darwin",
"platform": "7",
"origin": {
"location": {
"locationName": "Penzance",
"crs": "PNZ",
"tiploc": "PENZNCE"
}
rid: "202308058004480",
uid: "P04480",
trainid: "1A39",
sdd: "2023-08-05",
operator: "Great Western Railway",
operatorCode: "GW",
sta: "2023-08-05T21:51:00",
eta: "2023-08-05T23:04:18",
arrivalType: "Forecast",
std: "2023-08-05T22:00:00",
etd: "2023-08-05T23:05:18",
departureType: "Forecast",
departureSource: "Darwin",
platform: "7",
origin: {
location: {
locationName: "Penzance",
crs: "PNZ",
tiploc: "PENZNCE",
},
"destination": {
"location": {
"locationName": "London Paddington",
"crs": "PAD",
"tiploc": "PADTON"
}
},
"delayReason": "887",
"category": "XX",
"activities": "T"
}
destination: {
location: {
locationName: "London Paddington",
crs: "PAD",
tiploc: "PADTON",
},
},
delayReason: "887",
category: "XX",
activities: "T",
};
export const trainServices: any[] = [
{"rid":"202308058005927","uid":"P05927","trainid":"2T53","sdd":"2023-08-05","operator":"Great Western Railway","operatorCode":"GW","sta":"2023-08-05T19:52:00","eta":"2023-08-05T19:52:00","arrivalType":"Forecast","std":"2023-08-05T19:56:00","etd":"2023-08-05T19:56:00","departureType":"Forecast","departureSource":"Darwin","platform":"2","formation":{"coaches":{"coach":[{"coachClass":"Standard"},{"coachClass":"Standard"},{"coachClass":"Standard"},{"coachClass":"Standard"}]}},"origin":{"location":{"locationName":"Worcester Foregate Street","crs":"WOF","tiploc":"WORCSFS"}},"destination":{"location":{"locationName":"Bristol Temple Meads","crs":"BRI","tiploc":"BRSTLTM","via":"via Gloucester"}},"category":"OO","activities":"T"},
{"rid":"202308057126314","uid":"G26314","trainid":"2V88","sdd":"2023-08-05","operator":"West Midlands Trains","operatorCode":"LM","sta":"2023-08-05T18:28:00","eta":"2023-08-05T18:28:00","arrivalType":"Forecast","std":"2023-08-05T18:33:00","etd":"2023-08-05T18:33:00","departureType":"Forecast","departureSource":"Darwin","platform":"2","formation":{"coaches":{"coach":[{"coachClass":"Standard"},{"coachClass":"Standard","toilet":"Accessible"},{"coachClass":"Standard"},{"coachClass":"Standard","toilet":"Accessible"}]}},"origin":{"location":{"locationName":"Dorridge","crs":"DDG","tiploc":"DORIDGE"}},"destination":{"location":{"locationName":"Worcester Foregate Street","crs":"WOF","tiploc":"WORCSFS"}},"category":"OO","activities":"T RM","length":"4"},
{"rid":"202308057126318","uid":"G26318","trainid":"2V96","sdd":"2023-08-05","operator":"West Midlands Trains","operatorCode":"LM","sta":"2023-08-05T19:28:00","eta":"2023-08-05T19:28:00","arrivalType":"Forecast","std":"2023-08-05T19:33:00","etd":"2023-08-05T19:33:00","departureType":"Forecast","departureSource":"Darwin","platform":"2","origin":{"location":{"locationName":"Dorridge","crs":"DDG","tiploc":"DORIDGE"}},"destination":{"location":{"locationName":"Worcester Foregate Street","crs":"WOF","tiploc":"WORCSFS"}},"category":"OO","activities":"T RM","length":"4"}
]
{
rid: "202308058005927",
uid: "P05927",
trainid: "2T53",
sdd: "2023-08-05",
operator: "Great Western Railway",
operatorCode: "GW",
sta: "2023-08-05T19:52:00",
eta: "2023-08-05T19:52:00",
arrivalType: "Forecast",
std: "2023-08-05T19:56:00",
etd: "2023-08-05T19:56:00",
departureType: "Forecast",
departureSource: "Darwin",
platform: "2",
formation: {
coaches: {
coach: [
{ coachClass: "Standard" },
{ coachClass: "Standard" },
{ coachClass: "Standard" },
{ coachClass: "Standard" },
],
},
},
origin: {
location: {
locationName: "Worcester Foregate Street",
crs: "WOF",
tiploc: "WORCSFS",
},
},
destination: {
location: {
locationName: "Bristol Temple Meads",
crs: "BRI",
tiploc: "BRSTLTM",
via: "via Gloucester",
},
},
category: "OO",
activities: "T",
},
{
rid: "202308057126314",
uid: "G26314",
trainid: "2V88",
sdd: "2023-08-05",
operator: "West Midlands Trains",
operatorCode: "LM",
sta: "2023-08-05T18:28:00",
eta: "2023-08-05T18:28:00",
arrivalType: "Forecast",
std: "2023-08-05T18:33:00",
etd: "2023-08-05T18:33:00",
departureType: "Forecast",
departureSource: "Darwin",
platform: "2",
formation: {
coaches: {
coach: [
{ coachClass: "Standard" },
{ coachClass: "Standard", toilet: "Accessible" },
{ coachClass: "Standard" },
{ coachClass: "Standard", toilet: "Accessible" },
],
},
},
origin: {
location: { locationName: "Dorridge", crs: "DDG", tiploc: "DORIDGE" },
},
destination: {
location: {
locationName: "Worcester Foregate Street",
crs: "WOF",
tiploc: "WORCSFS",
},
},
category: "OO",
activities: "T RM",
length: "4",
},
{
rid: "202308057126318",
uid: "G26318",
trainid: "2V96",
sdd: "2023-08-05",
operator: "West Midlands Trains",
operatorCode: "LM",
sta: "2023-08-05T19:28:00",
eta: "2023-08-05T19:28:00",
arrivalType: "Forecast",
std: "2023-08-05T19:33:00",
etd: "2023-08-05T19:33:00",
departureType: "Forecast",
departureSource: "Darwin",
platform: "2",
origin: {
location: { locationName: "Dorridge", crs: "DDG", tiploc: "DORIDGE" },
},
destination: {
location: {
locationName: "Worcester Foregate Street",
crs: "WOF",
tiploc: "WORCSFS",
},
},
category: "OO",
activities: "T RM",
length: "4",
},
];

View File

@ -11,7 +11,7 @@
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
@ -25,9 +25,9 @@
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "commonjs", /* Specify what module code is generated. */
"module": "commonjs" /* Specify what module code is generated. */,
// "rootDir": "./", /* Specify the root folder within your source files. */
"moduleResolution": "node16", /* Specify how TypeScript looks up a file from a given module specifier. */
"moduleResolution": "node16" /* Specify how TypeScript looks up a file from a given module specifier. */,
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
@ -44,8 +44,8 @@
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
"allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
"checkJs": false, /* Enable error reporting in type-checked JavaScript files. */
"allowJs": true /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */,
"checkJs": false /* Enable error reporting in type-checked JavaScript files. */,
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
@ -55,7 +55,7 @@
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
"outDir": "./dist", /* Specify an output folder for all emitted files. */
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
@ -77,12 +77,12 @@
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
"strict": true /* Enable all strict type-checking options. */,
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
@ -106,10 +106,5 @@
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"include": [
"src",
"test",
"./*",
"./config"
]
"include": ["src", "test", "./*", "./config"]
}