Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
86beb6b
Added comments for todo list
Oct 7, 2019
424828c
Began implementing database builders
Oct 8, 2019
515537f
Fixed some typos
Oct 8, 2019
f562e2c
no idea why this is happening. Very frustrating
Oct 8, 2019
16f9b84
Began adding api-keys for security
Oct 8, 2019
2b98925
Removed logging
Oct 8, 2019
7d86c41
Added UUID
Oct 8, 2019
02f8571
Added temporary routing for creating an API key
Oct 8, 2019
bbb5c9e
moved api-key to folder
Oct 8, 2019
54f05b5
create a tools folder
Oct 8, 2019
659cefc
File updates
Oct 8, 2019
ca9969e
Removed routes from base route folder
Oct 9, 2019
6a41ff7
Re-added routes in organised folders
Oct 9, 2019
46c1c05
Changed database folder layout
Oct 9, 2019
c393e0e
Added Helmet for automated default security headers
Oct 9, 2019
4f7bda2
Updated gitignore in preperation for config changes
Oct 9, 2019
d02ae81
Beginning config changes
Oct 9, 2019
c81d6fa
Removed dotenv in preperation for config.json
Oct 9, 2019
c9ef82a
Swapped over to config.json
Oct 9, 2019
3dd9811
Renamed the API folder to specify more as to what it is
Oct 9, 2019
3bd416c
Removed old api route folder
Oct 9, 2019
146061a
Added a route controller
Oct 9, 2019
d6c65b1
Removed all .env files
Oct 9, 2019
1e3525b
Added default route objects for all routes in preperation for route c…
Oct 9, 2019
b376f51
Pushing all changes with eslint applied
Oct 9, 2019
4e5027b
Implemented API key authorisation middleware
Oct 10, 2019
ef23f08
Changed how the create API works. May have gotten this confused with …
Oct 10, 2019
ac9d973
linting
Oct 10, 2019
9a4ca29
Added templated config file
Oct 10, 2019
6f712fc
Re-written generation SQL
Oct 10, 2019
fabdddb
Swapped createKey to a promise that is not Async (will force to wait …
Oct 10, 2019
2bd2981
Added ability to get all keys or just one defined
Oct 12, 2019
c10e1e4
Added other API SQL functions in preperation
Oct 12, 2019
859e0d7
Fixed module export in index.js for db
Oct 12, 2019
8f4962c
Basic bitch changes
Oct 12, 2019
621410e
Added caching code for GET calls only!!!
Oct 13, 2019
ae2b02a
Fixed createKey export
Oct 13, 2019
9fad904
Fixed Get query for API-Keys
Oct 13, 2019
ed220c2
Added catch statement for API middleware
Oct 13, 2019
1b04172
Added memory-cache for caching
Oct 13, 2019
7001c5c
Added default API-Key routing
Oct 13, 2019
3c94cf0
Pushing all changes with eslint applied
Oct 13, 2019
0953b13
Implemented Kristian's suggestion of removing URL Hyphens
Oct 13, 2019
78b360f
Added default caching duration to template config
Oct 13, 2019
d146c1b
Fixed some bugs
Oct 13, 2019
91f434c
Added deleteKey function
Oct 13, 2019
e4b83e8
Added updateKey function for API-Keys
Oct 13, 2019
66e090c
Added body-parser
Oct 13, 2019
df58b13
Minor layout changes
Oct 13, 2019
51302e4
added preperatory files for user system
Oct 13, 2019
8d44f6a
General changes
Oct 13, 2019
8bbcbb3
Added delete and patch routes to API-Keys
Oct 13, 2019
17799cd
Pushing all changes with eslint applied
Oct 13, 2019
38a03a0
Pushing all changes with eslint applied
Oct 13, 2019
6c8b6f9
Added caching to getting of API Keys
Oct 13, 2019
dac7ff2
Small changes
Oct 13, 2019
7c32052
Allowed the RequireApi middleware to update last_request_at value for…
Oct 14, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions .env.template

This file was deleted.

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,6 @@ typings/

# next.js build output
.next

# Config files
config.json
Empty file removed Routes/playlist.js
Empty file.
Empty file removed Routes/video.js
Empty file.
12 changes: 12 additions & 0 deletions config/config.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"DATABASE": {
"USERNAME": "",
"DATABASE": "",
"PASSWORD": "",
"HOST": "",
"PORT": 3306
},
"CACHING": {
"DURATION": 15
}
}
22 changes: 22 additions & 0 deletions database/Tools/SQL/table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";

CREATE DATABASE IF NOT EXISTS `la1tv` DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci;
USE `la1tv`;

CREATE TABLE IF NOT EXISTS `api_keys` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`api_key` varchar(32) COLLATE utf8_swedish_ci NOT NULL,
`enabled` tinyint(1) NOT NULL,
`view_vod_uri` tinyint(1) NOT NULL,
`view_stream_uri` tinyint(1) NOT NULL,
`use_webhook` tinyint(1) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`last_request_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`ID`),
UNIQUE KEY `api_key` (`api_key`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci;
COMMIT;
21 changes: 21 additions & 0 deletions database/api-key/create.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const mysql = require('../connect')
const uuid = require('uuid/v4');

// > Creates a new key based on parameters passed
// > Returns the key that was created
const createKey = ({ enabled = 1, view_vod_uri = 0, view_stream_uri = 0, use_webhook = 0 }) => {
return new Promise((resolve, reject) => {
const id = uuid().toString().replace(/-/g, '')
mysql.promise().execute('INSERT INTO `api_keys` (`ID`, `api_key`, `enabled`, `view_vod_uri`, `view_stream_uri`, `use_webhook`) VALUES (NULL, ?, ?, ?, ?, ?)', [id, enabled, view_vod_uri, view_stream_uri, use_webhook])
.then(([fields, rows]) => {
resolve(id)
})
.catch((err) => {
reject(err)
})
})
}

module.exports = {
createKey
}
18 changes: 18 additions & 0 deletions database/api-key/delete.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const mysql = require('../connect')

// > Deletes an API Key
const deleteKey = (api) => {
return new Promise((resolve, reject) => {
mysql.promise().execute('DELETE FROM `api_keys` WHERE api_key = ?;', [api])
.then(([fields, rows]) => {
resolve("success")
})
.catch(err => {
reject(err)
})
})
}

module.exports = {
deleteKey
}
38 changes: 38 additions & 0 deletions database/api-key/get.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const mysql = require('../connect')

// > Returns a specified key
const getSpecifiedKey = (api) => {
return new Promise((resolve, reject) => {
mysql.promise().execute('SELECT * FROM `api_keys` WHERE `api_key` = ?', [api])
.then(([rows, fields]) => {
resolve(JSON.stringify(rows[0]))
})
.catch(err => {
reject(err)
})
})
}

// > Returns all API keys
const getAllKeys = ({ start = -1, quantity = 10 }) => {
var tempSQL = ""

if (start !== -1) {
tempSQL = " WHERE ID >= " + start + " LIMIT " + quantity
}

return new Promise((resolve, reject) => {
mysql.promise().execute('SELECT * FROM `api_keys`' + tempSQL + ';')
.then(([rows, fields]) => {
resolve(rows)
})
.catch(err => {
reject(err)
})
})
}

module.exports = {
getSpecifiedKey,
getAllKeys
}
17 changes: 17 additions & 0 deletions database/api-key/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const { getAllKeys, getSpecifiedKey } = require('./get')
const { createKey } = require('./create')
const { updateKey } = require('./update')
const { deleteKey } = require('./delete')

/*
> This file allows us to import all or just what we need from the SQL Queries for api-keys
> May add authorisation to this route but I may not
*/

module.exports = {
getAllKeys,
getSpecifiedKey,
createKey,
updateKey,
deleteKey
}
40 changes: 40 additions & 0 deletions database/api-key/update.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const mysql = require('../connect')

const updateKey = (api, { enabled, view_vod_uri, view_stream_uri, use_webhook }) => {
return new Promise((resolve, reject) => {
let enabledSQL = enabled ? ('`enabled` = ' + enabled) : ('')
let view_vod_uri_SQL = view_vod_uri ? ('`view_vod_uri` = ' + view_vod_uri) : ('')
let view_stream_uri_SQL = view_stream_uri ? ('`view_stream_uri` = ' + view_stream_uri) : ('')
let use_webhook_SQL = use_webhook ? ('`use_webhook` = ' + use_webhook) : ('')

mysql.promise().execute('UPDATE api_keys SET ' + enabledSQL +
' ' + view_vod_uri_SQL +
' ' + view_stream_uri_SQL +
' ' + use_webhook_SQL +
' WHERE `api_key` = ?;', [api]).then(([fields, rows]) => {
resolve("success")
})
.catch(err => {
reject(err)
})
})
}

// > Updates the timestamp for the API key
// > Is mainly used in the middleware RequireApi.js
const updateTimeStamp = (api) => {
return new Promise((resolve, reject) => {
mysql.promise().execute('UPDATE api_keys SET last_request_at = CURRENT_TIMESTAMP WHERE `api_key` = ?;', [api])
.then(([fields, rows]) => {
resolve("success")
})
.catch(err => {
reject(err)
})
})
}

module.exports = {
updateKey,
updateTimeStamp
}
14 changes: 14 additions & 0 deletions database/builder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const mysql = require("./connect")

// > TODO: Generate database based off of SQL in table.

function generateDatabase() {
// mysql.query(
// "CREATE SCHEMA IF NOT EXISTS ${process.env.DATABASE};" +
// "CREATE TABLE `la1tv`.`APIKEys` ( `ID` INT NOT NULL AUTO_INCREMENT , `Key` VARCHAR(32) NOT NULL , PRIMARY KEY (`ID`), UNIQUE (`Key`)) ENGINE = InnoDB;"
// )

console.log("In development")
}

module.exports = generateDatabase
14 changes: 10 additions & 4 deletions database/connect.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
const mysql = require('mysql2');
const { DATABASE } = require('../config/config.json')

// > TODO: Test the connection
// > TODO: Create database creation scripts
// > TODO: Create seeders

// Create the connection pool. The pool-specific settings are the defaults
const pool = mysql.createPool({
host: process.env.DATABASE_HOST,
user: process.env.DATABASE_USERNAME,
database: process.env.DATABASE_PASSWORD,
host: DATABASE.HOST | '127.0.0.1',
user: DATABASE.USERNAME,
password: DATABASE.PASSWORD,
database: DATABASE.DATABASE,
port: DATABASE.PORT | 3306,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
Expand Down
28 changes: 24 additions & 4 deletions middleware/RequireApi.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
const mysql = require('../database/connect')
const { getSpecifiedKey } = require('../database/api-key/get')
const { updateTimeStamp } = require('../database/api-key/update')

// > TODO: Implement checking from database for valid API keys
// > TODO: Add header to incoming request that filters for adding and / or removing
// > TODO: Send a more suitable response

const requireAPI = (req, res, next) => {
if (!req.get("x-api-key")) {
console.log("No X-API-KEY sent");
res.send("Invalid or No API Key provided");
res.status(401).send("Invalid or No API Key provided");

return;
}

next();
getSpecifiedKey(req.get("x-api-key")).then((result) => {
if (JSON.parse(result).enabled === 1) {
updateTimeStamp(req.get("x-api-key")).then(data => {
next()
}).catch(err => {
console.log(err)
res.status(401).send("Unable to update timestamp of API key provided")
return
})
} else {
res.status(401).send("Invalid or No API Key provided")
return
}
})
.catch(err => {
res.status(500).send("Error retrieving API-Key information from database")
})
}

module.exports = requireAPI
28 changes: 28 additions & 0 deletions middleware/cache.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const mcache = require('memory-cache')
const { CACHING } = require('../config/config.json')

const cache = (duration = CACHING.DURATION) => {
return (req, res, next) => {
if (req.type !== 'GET') {
next()
return
}

let key = '__express__' + req.originalUrl || req.url
let cachedObject = mcache.get(key)

if (cachedObject) {
res.status(200).send(cachedObject)
return
} else {
res.sendResponse = res.send
res.send = (body) => {
mcache.put(key, body, duration * 1000);
res.sendResponse(body)
}
next()
}
}
}

module.exports = cache
Loading