Authetication, logger middleware, db create tool

This commit is contained in:
MrFry 2020-04-07 09:26:45 +02:00
parent 5f0b17a0db
commit ebd27f93c1
11 changed files with 164 additions and 94 deletions

View file

@ -1,5 +1,5 @@
const logger = require('../../utils/logger.js') const logger = require('../utils/logger.js')
const dbtools = require('../../utils/dbtools.js') const dbtools = require('../utils/dbtools.js')
const exceptions = [ const exceptions = [
'favicon', 'favicon',
@ -47,8 +47,15 @@ module.exports = function (options) {
return return
} }
req.session = {
user: user,
sessionID: sessionID
}
logger.DebugLog(`ID #${user.id}: ${req.url}`, 'auth', 1) logger.DebugLog(`ID #${user.id}: ${req.url}`, 'auth', 1)
// TODO: add stat to acesses table
dbtools.Update(authDB, 'sessions', { dbtools.Update(authDB, 'sessions', {
lastAccess: new Date().toString() lastAccess: new Date().toString()
}, { }, {
@ -69,6 +76,7 @@ module.exports = function (options) {
function GetUserBySessionID (db, sessionID, req) { function GetUserBySessionID (db, sessionID, req) {
logger.DebugLog(`Getting user from db`, 'auth', 2) logger.DebugLog(`Getting user from db`, 'auth', 2)
// TODO: check same ip?
const session = dbtools.Select(db, 'sessions', { const session = dbtools.Select(db, 'sessions', {
id: sessionID id: sessionID
})[0] })[0]

View file

@ -0,0 +1,32 @@
const logger = require('../utils/logger.js')
// TODO: use this middleware in all modules
module.exports = function (options) {
const loggableKeywords = options ? options.loggableKeywords : undefined
return function (req, res, next) {
res.on('finish', function () {
if (req.url.includes('_next/static')) {
return
}
const ip = req.headers['cf-connecting-ip'] || req.connection.remoteAddress
const hostname = req.hostname.replace('www.', '').split('.')[0]
// TODO: merge req.url and req.hostname checking
// TODO: regexp includes checking
let toLog = loggableKeywords && loggableKeywords.some((x) => {
return req.url.includes(x)
})
if (hostname.includes('dataeditor')) {
toLog = true
}
logger.LogReq(req, true, res.statusCode)
if (toLog) { logger.LogReq(req) }
if (res.statusCode !== 404) { logger.LogStat(req.url, ip) }
})
next()
}
}

View file

@ -33,7 +33,8 @@ const logger = require('../../utils/logger.js')
const utils = require('../../utils/utils.js') const utils = require('../../utils/utils.js')
const actions = require('../../utils/actions.js') const actions = require('../../utils/actions.js')
const dbtools = require('../../utils/dbtools.js') const dbtools = require('../../utils/dbtools.js')
const auth = require('../../modules/api/auth.middleware.js') const auth = require('../../middlewares/auth.middleware.js')
const reqlogger = require('../../middlewares/reqlogger.middleware.js')
const recivedFiles = 'public/recivedfiles' const recivedFiles = 'public/recivedfiles'
const uloadFiles = 'public/f' const uloadFiles = 'public/f'
@ -45,34 +46,11 @@ const passwordFile = 'data/dataEditorPasswords.json'
const dataEditsLog = 'stats/dataEdits' const dataEditsLog = 'stats/dataEdits'
const dailyDataCountFile = 'stats/dailyDataCount' const dailyDataCountFile = 'stats/dailyDataCount'
const usersDBPath = 'data/dbs/users.db' const usersDBPath = 'data/dbs/users.db'
const dbStructPath = './modules/api/apiDBStruct.json'
let authDB if (!utils.FileExists(usersDBPath)) {
function CreateDB () { throw new Error('No user DB exists yet! please run utils/dbSetup.js first!')
const dbStruct = utils.ReadJSON(dbStructPath)
// TODO: check if path exists, create it if not
authDB = dbtools.GetDB(usersDBPath)
// TODO: foreign key
Object.keys(dbStruct).forEach((tableName) => {
const tableData = dbStruct[tableName]
dbtools.CreateTable(authDB, tableName, tableData.tableStruct)
})
// TODO: fill with data
dbtools.Insert(authDB, 'users', {
pw: 2,
id: 2,
notes: 'hemnlo'
})
dbtools.Insert(authDB, 'users', {
pw: 1,
id: 1,
notes: 'hemnlo'
})
// console.log(dbtools.TableInfo(authDB, 'users'))
} }
CreateDB() const authDB = dbtools.GetDB(usersDBPath)
const cookieSecret = uuidv4() const cookieSecret = uuidv4()
app.use(cookieParser(cookieSecret)) app.use(cookieParser(cookieSecret))
@ -92,6 +70,9 @@ app.use(auth({
authDB: authDB, authDB: authDB,
jsonResponse: true jsonResponse: true
})) }))
app.use(reqlogger([
'stable.user.js' // TODO
]))
app.use(express.static('public')) app.use(express.static('public'))
app.use(busboy({ app.use(busboy({
limits: { limits: {
@ -130,9 +111,7 @@ Load()
// ------------------------------------------------------------- // -------------------------------------------------------------
app.post('/login', (req, res) => { app.post('/login', (req, res) => {
// TODO: user.logincount update in db
logger.LogReq(req) logger.LogReq(req)
const isScript = req.body.script
const pw = req.body.pw const pw = req.body.pw
const ip = req.headers['cf-connecting-ip'] || req.connection.remoteAddress const ip = req.headers['cf-connecting-ip'] || req.connection.remoteAddress
const user = dbtools.Select(authDB, 'users', { const user = dbtools.Select(authDB, 'users', {
@ -174,15 +153,10 @@ app.post('/login', (req, res) => {
// TODO: cookie age // TODO: cookie age
res.cookie('sessionID', sessionID) res.cookie('sessionID', sessionID)
if (isScript) { res.json({
res.json({ result: 'success',
result: 'success', sessionID: sessionID
sessionID: sessionID })
})
} else {
// FIXME: redirect to original url
res.redirect('/')
}
logger.Log(`Successfull login with user ID: #${user.id}`, logger.GetColor('cyan')) logger.Log(`Successfull login with user ID: #${user.id}`, logger.GetColor('cyan'))
} else { } else {
@ -202,8 +176,9 @@ app.post('/logout', (req, res) => {
id: sessionID id: sessionID
}) })
// TODO: remove old sessions every once in a while // TODO: remove old sessions every once in a while
// FIXME: redirect to original url res.clearCookie('sessionID').json({
res.clearCookie('sessionID').redirect('/') result: 'success'
})
}) })
// -------------------------------------------------------------- // --------------------------------------------------------------

View file

@ -1,13 +1,15 @@
{ {
"users": { "users": {
"tableStruct": { "tableStruct": {
"id": {
"type": "integer",
"primary": true,
"autoIncrement": true
},
"pw": { "pw": {
"type": "text", "type": "text",
"primary": true, "notNull": true,
"notNull": true "unique": true
},
"id": {
"type": "number"
}, },
"lastIP": { "lastIP": {
"type": "text" "type": "text"
@ -27,6 +29,15 @@
} }
}, },
"sessions": { "sessions": {
"foreignKey": {
"keysFrom": [
"userID"
],
"table": "users",
"keysTo": [
"id"
]
},
"tableStruct": { "tableStruct": {
"id": { "id": {
"type": "text", "type": "text",

View file

@ -71,6 +71,7 @@ AddHtmlRoutes(utils.ReadDir('modules/dataEditor/public'))
// -------------------------------------------------------------- // --------------------------------------------------------------
app.get('/', function (req, res) { app.get('/', function (req, res) {
// TODO: log this, regexp $/^
res.end('hai') res.end('hai')
logger.LogReq(req) logger.LogReq(req)
}) })

@ -1 +1 @@
Subproject commit 72ea24c07133d02a983152b4416ff98eb5dc4369 Subproject commit 9f576a41f6a8b1de82f2a0cf901046a76ff9a1ed

View file

@ -23,6 +23,7 @@ const bodyParser = require('body-parser')
const busboy = require('connect-busboy') const busboy = require('connect-busboy')
const app = express() const app = express()
const reqlogger = require('../../middlewares/reqlogger.middleware.js')
const utils = require('../../utils/utils.js') const utils = require('../../utils/utils.js')
const logger = require('../../utils/logger.js') const logger = require('../../utils/logger.js')
@ -33,19 +34,6 @@ try {
logger.Log('Couldnt read donate URL file!', logger.GetColor('red')) logger.Log('Couldnt read donate URL file!', logger.GetColor('red'))
} }
app.set('view engine', 'ejs')
app.set('views', [
'./modules/qmining/views',
'./sharedViews'
])
app.use(express.static('modules/qmining/public'))
app.use(express.static('public'))
app.use(busboy({
limits: {
fileSize: 10000 * 1024 * 1024
}
}))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ app.use(bodyParser.urlencoded({
limit: '5mb', limit: '5mb',
extended: true extended: true
@ -53,6 +41,19 @@ app.use(bodyParser.urlencoded({
app.use(bodyParser.json({ app.use(bodyParser.json({
limit: '5mb' limit: '5mb'
})) }))
app.set('view engine', 'ejs')
app.set('views', [
'./modules/qmining/views',
'./sharedViews'
])
app.use(reqlogger())
app.use(express.static('modules/qmining/public'))
app.use(express.static('public'))
app.use(busboy({
limits: {
fileSize: 10000 * 1024 * 1024
}
}))
// -------------------------------------------------------------- // --------------------------------------------------------------
// REDIRECTS // REDIRECTS

View file

@ -34,9 +34,6 @@ const cors = require('cors')
const extraModulesFile = './extraModules.json' const extraModulesFile = './extraModules.json'
const modulesFile = './modules.json' const modulesFile = './modules.json'
const loggableKeywords = [
'user.js'
]
let modules = JSON.parse(utils.ReadFile(modulesFile)) let modules = JSON.parse(utils.ReadFile(modulesFile))
logger.Load() logger.Load()
@ -57,29 +54,6 @@ try {
const app = express() const app = express()
app.use(cors()) app.use(cors())
app.use(function (req, res, next) {
res.on('finish', function () {
if (req.url.includes('_next/static')) {
return
}
let ip = req.headers['cf-connecting-ip'] || req.connection.remoteAddress
logger.LogReq(req, true, res.statusCode)
let toLog = loggableKeywords.some((x) => {
return req.url.includes(x)
})
const hostname = req.hostname.replace('www.', '').split('.')[0]
if (hostname.includes('dataeditor')) {
toLog = true
}
if (toLog) { logger.LogReq(req) }
if (res.statusCode !== 404) { logger.LogStat(req.url, ip) }
})
next()
})
Object.keys(modules).forEach(function (k, i) { Object.keys(modules).forEach(function (k, i) {
let x = modules[k] let x = modules[k]
try { try {

39
utils/dbSetup.js Normal file
View file

@ -0,0 +1,39 @@
const utils = require('../utils/utils.js')
const dbtools = require('../utils/dbtools.js')
const dbStructPath = '../modules/api/apiDBStruct.json'
const usersDBPath = '../data/dbs/users.db'
let authDB
console.clear()
function CreateDB () {
const dbStruct = utils.ReadJSON(dbStructPath)
authDB = dbtools.GetDB(usersDBPath)
Object.keys(dbStruct).forEach((tableName) => {
const tableData = dbStruct[tableName]
dbtools.CreateTable(authDB, tableName, tableData.tableStruct, tableData.foreignKey)
})
try {
// TODO: fill with data
dbtools.Insert(authDB, 'users', {
pw: 2,
notes: 'hemnlo'
})
dbtools.Insert(authDB, 'users', {
pw: 1,
notes: 'hemnlo'
})
} catch (e) {
console.error(e)
}
// Object.keys(dbStruct).forEach((key) => {
// console.log(key)
// console.log(dbtools.TableInfo(authDB, key))
// })
}
CreateDB()

View file

@ -109,19 +109,41 @@ function Delete (db, table, conditions) {
} }
} }
function CreateTable (db, name, columns) { function CreateTable (db, name, columns, foreignKeys) {
// CREATE TABLE users(pw text PRIMARY KEY NOT NULL, id number, lastIP text, notes text, loginCount
// number, lastLogin text, lastAccess text
//
// FOREIGN KEY(songartist, songalbum) REFERENCES album(albumartist, albumname) )
try { try {
const cols = Object.keys(columns).reduce((acc, key) => { const cols = Object.keys(columns).reduce((acc, key) => {
const item = columns[key] const item = columns[key]
const isPrimary = item.primary ? ' PRIMARY KEY' : '' // FIXME: array, and push stuff, then join()
const isNotNull = item.notNull ? ' NOT NULL' : '' const flags = []
const toCheck = {
primary: 'PRIMARY KEY',
notNull: 'NOT NULL',
unique: 'UNIQUE',
autoIncrement: 'AUTOINCREMENT'
}
Object.keys(toCheck).forEach((key) => {
if (item[key]) {
flags.push(toCheck[key])
}
})
acc.push(`${key} ${item.type}${isPrimary}${isNotNull}`) acc.push(`${key} ${item.type} ${flags.join(' ')}`)
return acc return acc
}, []).join(', ') }, []).join(', ')
// IF NOT EXISTS // TODO let fKeys = ''
const s = `CREATE TABLE ${name}(${cols})` if (foreignKeys) {
const { keysFrom, table, keysTo } = foreignKeys
fKeys = `, FOREIGN KEY(${keysFrom.join(', ')}) REFERENCES ${table}(${keysTo.join(', ')})`
}
// IF NOT EXISTS
const s = `CREATE TABLE ${name}(${cols}${fKeys})`
DebugLog(s) DebugLog(s)
const stmt = db.prepare(s) const stmt = db.prepare(s)

View file

@ -125,7 +125,14 @@ function LogReq (req, toFile, sc) {
hostname = 'NOHOST' hostname = 'NOHOST'
Log('req.hostname is undefined! req.hostname: ' + req.hostname, GetColor('redbg')) Log('req.hostname is undefined! req.hostname: ' + req.hostname, GetColor('redbg'))
} }
logEntry += dl + hostname + dl + req.headers['user-agent'] + dl + req.method + dl logEntry += dl +
hostname + dl +
req.headers['user-agent'] + dl +
req.method + dl
if (req.session && req.session.user) {
logEntry += C('cyan') + req.session.user.id + C() + dl
}
logEntry += GetRandomColor(req.url.split('?')[0]) + req.url logEntry += GetRandomColor(req.url.split('?')[0]) + req.url