mirror of
https://gitlab.com/MrFry/mrfrys-node-server
synced 2025-04-01 20:24:18 +02:00
Authetication, logger middleware, db create tool
This commit is contained in:
parent
5f0b17a0db
commit
ebd27f93c1
11 changed files with 164 additions and 94 deletions
|
@ -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]
|
32
middlewares/reqlogger.middleware.js
Normal file
32
middlewares/reqlogger.middleware.js
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
|
@ -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'
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
26
server.js
26
server.js
|
@ -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
39
utils/dbSetup.js
Normal 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()
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue