Auth system

This commit is contained in:
MrFry 2020-04-03 08:54:48 +02:00
parent 52778532dc
commit 9435cc6533
14 changed files with 637 additions and 23 deletions

View file

@ -0,0 +1,69 @@
{
"subj": "2019/20/2 - Elektronika - AMEEL0IBNE/L1",
"version": "2.0.0.4",
"id": "1585155641104",
"quiz": [
{
"Q": "A multiméterek váltakozó jellemzők mérése esetén mindig csúcsértéket jeleznek ki.\n",
"A": "Hamis",
"data": {
"type": "simple"
}
},
{
"Q": "A multiméterek váltakozó jellemzők mérése esetén mindig effektív értéket jeleznek ki.\n",
"A": "Igaz",
"data": {
"type": "simple"
}
},
{
"Q": "Az analóg multiméter kijelzője lágyvasas műszer.\n",
"A": "Hamis",
"data": {
"type": "simple"
}
},
{
"Q": "Az analóg multiméter kijelzője Deprez műszer.\n",
"A": "Igaz",
"data": {
"type": "simple"
}
},
{
"Q": "Az állandó mágnesű Deprez műszer egyenirányítóval kiegészítve (egyenirányítós állandó mágnesű műszer) kizárólag egyenáram (illetve egyenfeszültség) mérésére alkalmas.",
"A": "Hamis",
"data": {
"type": "image",
"images": [
"6emZyTu7t7Y2PjPyatVf0h9RWybD15"
]
}
},
{
"Q": "Az állandó mágnesű Deprez alapműszer alkalmas mind egyen, mind váltakozó áram (illetve feszültség) mérésére is.",
"A": "Hamis",
"data": {
"type": "image",
"images": [
"jLtbYDdNNoQAAAAASUVORK5CYIIA"
]
}
},
{
"Q": "A korszerűbb digitális multiméterek általában Tru RMS konvertereket (egyenirányítókat) tartalmaznak, így egyszerű középértéket mérnek és effektív értéket is jeleznek ki.\n",
"A": "Hamis",
"data": {
"type": "simple"
}
},
{
"Q": "A korszerűbb digitális multiméterek általában Tru RMS konvertereket (egyenirányítókat) tartalmaznak, így abszolút középértéket mérnek és effektív értéket is jeleznek ki.\n",
"A": "Hamis",
"data": {
"type": "simple"
}
}
]
}

View file

@ -0,0 +1,49 @@
{
"subj": "2019/20/2 - Elektronika - NIEEL0HBNE/EL0_LA_07-H:13:30-15:10",
"version": "2.0.0.4",
"id": "1585554409104",
"quiz": [
{
"Q": "Az egyenirányító kapcsolásokban a kimeneti hullámosság hogyan csökkenthető, az alábbi lehetőségek közül?",
"A": "a. A pufferkondenzátor értékének növelésével.",
"data": {
"type": "simple"
}
},
{
"Q": "ELAB paneles mérés során hogyan lehet a dióda nyitó irányú előfeszítését záró irányú előfeszítésre változtatni?",
"A": "a. A tápegység csatlakozóit meg kell cserélni, így negatív feszültség kerül a kapcsolásra.",
"data": {
"type": "simple"
}
},
{
"Q": "Feszültségmérő műszert hogyan kapcsolunk egy mérőkörre?",
"A": "c. Csak párhuzamosan kapcsolhatjuk egy vagy több elemmel.",
"data": {
"type": "simple"
}
},
{
"Q": "Milyen szerepet tölt be az egyenirányító kapcsolásokban a kapacitás?",
"A": "A helyes válasz: Amikor a bemeneti feszültség ÉRTÉKE KISEBB mint a kimeneti feszültség, a dióda lezár az egyenirányító kapcsolásban. Ezalatt az idő alatt az egyenirányító kimenetén folyó áramot a kondenzátorban tárolt energia biztosítja. .",
"data": {
"type": "simple"
}
},
{
"Q": "Mit jelent a dióda záróirányú feléledési ideje?",
"A": "a. Egy dióda nyitóirányú előfeszítésből, ha hirtelen záróirányú előfeszítésbe kerül, a záróirányú előfeszítésbe kapcsoláskor egy rövid ideig (nanosec. nagyságrend) folyik rajta egy záróirányú áram, majd ez az áram 0 értékűre csökken.",
"data": {
"type": "simple"
}
},
{
"Q": "Egy TTL inverter esetén a logikai igaz értékhez 2V-5V, illetve 2,7V-5V feszültségtartomány van megadva. Mit jelent ez? ",
"A": "c. Logikai igaz értéknek 2V-5V között a bemeneti, 2,7V-5V között a kimeneti feszültségtartományt értjük.",
"data": {
"type": "simple"
}
}
]
}

View file

@ -0,0 +1,35 @@
{
"subj": "2019/20/2 - Újrakonfigurálható digitális áramkörök",
"version": "2.0.0.4",
"id": "1575851111714",
"quiz": [
{
"Q": "A tömbök optimalizálására alkalmazható kényszerfeltételek:\n\n\n",
"A": "A helyes válaszok: ARRAY_MAP, ARRAY_PARTITION, ARRAY_RESHAPE",
"data": {
"type": "simple"
}
},
{
"Q": "Az alábbi felsorolásból válassza ki a modul szintű protokollokat:\n\n\n",
"A": "A helyes válaszok: al_ctrl_hs, ap_ctrl_none, ap_ctrl_chain",
"data": {
"type": "simple"
}
},
{
"Q": "Ciklusok optimalizálásaira alkalmazható kényszerfeltételek:\n",
"A": "A helyes válaszok: UNROLL, LOOP_FLATTEN, LOOP_MERGE,\nPIPELINE",
"data": {
"type": "simple"
}
},
{
"Q": "Egy tömb típusú függvényargumentumhoz automatikusan a következő típusú protokoll rendelődik:",
"A": "c. ap_bram",
"data": {
"type": "simple"
}
}
]
}

View file

@ -0,0 +1,50 @@
{
"subj": "2019/20/2 - Digitális technika II.",
"version": "2.0.0.4",
"id": "1585143211102",
"quiz": [
{
"Q": "Melyik tároló működési tábláját látja? Válassza ki a helyes megoldást!",
"A": "A helyes válasz: RS.",
"data": {
"type": "image",
"images": [
"NeQ5NhVhEjEEovqtIc xqQiTiCEQ1W"
]
}
},
{
"Q": "Melyik flip-flop állapotgráfja az alábbi?\n\n",
"A": "A helyes válasz: JKnegált.",
"data": {
"type": "image",
"images": [
"0C4Xu0TgekRTx2ECAiXL0RgesTzAyE"
]
}
},
{
"Q": "Készítsen T flip-flopból JK flip-flopot! Válassza ki a kapcsolási rajzot!\n\n\n\n",
"A": "",
"data": {
"type": "image",
"images": [
"ZYJDqZQKATWDvRgGAuIBRACAmYBQAi",
"e1a9eWlpZigW9b8K1I1dik QiC1BI0",
"EAO6UFkQPWwAAAABJRU5ErkJggg==",
"wdy3q M gpKygAAAABJRU5ErkJggg=",
"t5yLDOdM4AAAAASUVORK5CYII=",
"1 0IdIQbygbYUDbAhrIBNpQNsKFsgA",
"8FEOmCBoLJ8AAAAASUVORK5CYII="
]
}
},
{
"Q": "A flip-flopok aszinkron vezérlő bemenetei erősebbek a szinkron vezérlő bemeneteknél.\n",
"A": "Igaz",
"data": {
"type": "simple"
}
}
]
}

View file

@ -0,0 +1,147 @@
{
"subj": "2019/20/2 - IT Networks - BMXIHE6BNE/NMEI_IHE6BNE_01GY",
"version": "2.0.0.4",
"id": "1572281342041",
"quiz": [
{
"Q": "How many layers in OSI model?\n\n\nThere are...\n",
"A": "A helyes válasz: 7 layers.",
"data": {
"type": "simple"
}
},
{
"Q": "What does FTP stand for?\n",
"A": "A helyes válasz: File Transfer Protocol.",
"data": {
"type": "simple"
}
},
{
"Q": "What is an Ip address?\n\n\nIt is ...\n",
"A": "A helyes válasz: All of above.",
"data": {
"type": "simple"
}
},
{
"Q": "Which are types of a network by Geography distance?\n",
"A": "A helyes válasz: LAN, MAN, WAN, Internet.",
"data": {
"type": "simple"
}
},
{
"Q": "What is a repeater function?\n",
"A": "A helyes válasz: Amplifier, Expand the network, and operating in Physical layer.",
"data": {
"type": "simple"
}
},
{
"Q": "What is the unit of Network layer?\n",
"A": "A helyes válasz: Packets.",
"data": {
"type": "simple"
}
},
{
"Q": "What is the right order of a network size by geography distance?\n",
"A": "A helyes válasz: LAN → 1, Internet → 4, WAN → 3, MAN → 2.",
"data": {
"type": "simple"
}
},
{
"Q": "What is the right order of OSI model?\n",
"A": "A helyes válasz: Data link → Layer 2, Presentation → Layer 6, Transportation → Layer 4, Network → Layer 3, Physical → Layer 1, Session → Layer 5, Application → Layer 7.",
"data": {
"type": "simple"
}
},
{
"Q": "What does the Ipv4 address include?\n\n\nIpv4 address includes...\n",
"A": "A helyes válasz: Network ID and Host ID.",
"data": {
"type": "simple"
}
},
{
"Q": "What does DHCP stand for?\n",
"A": "A helyes válasz: Dynamic Host Configuration Protocol.",
"data": {
"type": "simple"
}
},
{
"Q": "What is the order of Standard A?\n",
"A": "A helyes válasz: White Orange → 1, Orange → 2, White green → 3, White blue → 5, Green → 6, White Brown → 7, Brown → 8, Blue → 4.",
"data": {
"type": "simple"
}
},
{
"Q": "What is the maximum speed of STP cable?\n",
"A": "A helyes válasz: 155 Mbps.",
"data": {
"type": "simple"
}
},
{
"Q": "How many kinds of media transmission?\n",
"A": "A helyes válasz: 2.",
"data": {
"type": "simple"
}
},
{
"Q": "What is the maximum length of thin coaxial cable?\n",
"A": "A helyes válasz: 185 m.",
"data": {
"type": "simple"
}
},
{
"Q": "What is the maximum length of thick coaxial cable?\n",
"A": "A helyes válasz: 500 m.",
"data": {
"type": "simple"
}
},
{
"Q": "What is the maximum length of UTP cable?\n",
"A": "A helyes válasz: 100 m.",
"data": {
"type": "simple"
}
},
{
"Q": "Which is the right answer to these sentences about Switch?\n",
"A": "A helyes válasz: Combination between Bridge and Hub.",
"data": {
"type": "simple"
}
},
{
"Q": "What is modem function?\n",
"A": "A helyes válasz: Convert digital signal to analog signal and vice versa.",
"data": {
"type": "simple"
}
},
{
"Q": "List the order of designing a network?\n",
"A": "A helyes válasz: Network testing → Step 5, Requirement analysis → Step 2, Gathering requirements from clients → Step 1, Design solutions → Step 3, System maintenance → Step 6, Network settings → Step 4.",
"data": {
"type": "simple"
}
},
{
"Q": "When will we use straight-through cable?\n",
"A": "A helyes válasz: Hub - Switch.",
"data": {
"type": "simple"
}
}
]
}

View file

@ -29,6 +29,8 @@ const app = express()
const logger = require('../../utils/logger.js') 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 auth = require('../../modules/api/auth.middleware.js')
const recivedFiles = 'public/recivedfiles' const recivedFiles = 'public/recivedfiles'
const uloadFiles = 'public/f' const uloadFiles = 'public/f'
@ -39,12 +41,31 @@ const versionFile = 'public/version'
const passwordFile = 'data/dataEditorPasswords.json' 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 dbStructPath = './modules/api/apiDBStruct.json'
let authDB
function CreateDB () {
const dbStruct = utils.ReadJSON(dbStructPath)
// TODO: check if path exists, create it if not
authDB = dbtools.GetDB(usersDBPath)
Object.keys(dbStruct).forEach((tableName) => {
const tableData = dbStruct[tableName]
dbtools.CreateTable(authDB, tableName, tableData.tableStruct)
})
}
CreateDB()
app.set('view engine', 'ejs') app.set('view engine', 'ejs')
app.set('views', [ app.set('views', [
'./modules/api/views', './modules/api/views',
'./sharedViews' './sharedViews'
]) ])
app.use(auth({
debugLog: true,
authDB: authDB
}))
app.use(express.static('public')) app.use(express.static('public'))
app.use(busboy({ app.use(busboy({
limits: { limits: {

View file

@ -0,0 +1,35 @@
{
"users": {
"tableStruct": {
"userID": {
"type": "number",
"primary": true,
"notNull": true
},
"pw": {
"type": "text"
},
"lastIP": {
"type": "text"
},
"notes": {
"type": "text"
},
"loginCount": {
"type": "number"
}
}
},
"acesses": {
"tableStruct": {
"userID": {
"type": "number",
"primary": true,
"notNull": true
},
"ip": {
"type": "text"
}
}
}
}

View file

@ -0,0 +1,16 @@
const logger = require('../../utils/logger.js')
const dbtools = require('../../utils/dbtools.js')
module.exports = function (options) {
const { debugLog, authDB } = options
return function (req, res, next) {
if (debugLog) {
logger.Log('AUTH: ' + req.url)
}
res.end('NO ACCESS')
// next()
}
}

@ -1 +1 @@
Subproject commit 35263fccad68f2b8a564532658a5489c92674675 Subproject commit 86b01f443a306695a9a17f29785ba20b7f08f810

View file

@ -2,15 +2,18 @@
"name": "node-ejs", "name": "node-ejs",
"main": "server.js", "main": "server.js",
"dependencies": { "dependencies": {
"better-sqlite3": "^6.0.1",
"connect-busboy": "0.0.2", "connect-busboy": "0.0.2",
"cookie-parser": "^1.4.5", "cookie-parser": "^1.4.5",
"cors": "^2.8.5", "cors": "^2.8.5",
"ejs": "^1.0.0", "ejs": "^1.0.0",
"express": "^4.6.1", "express": "^4.6.1",
"express-ejs-layouts": "^1.1.0", "express-ejs-layouts": "^1.1.0",
"sqlite3": "^4.1.1",
"vhost": "^3.0.2" "vhost": "^3.0.2"
}, },
"scripts": { "scripts": {
"start": "node ./server.js" "start": "node ./server.js",
"dev": "node ./server.js"
} }
} }

View file

@ -38,16 +38,7 @@ const loggableKeywords = [
] ]
let modules = JSON.parse(utils.ReadFile(modulesFile)) let modules = JSON.parse(utils.ReadFile(modulesFile))
let logLevel = parseInt(GetParams()[0]) logger.Load()
if (isNaN(logLevel)) {
logLevel = 0
}
logger.Log('Loglevel is: ' + logLevel)
logger.Load(logLevel) // TODO: debug level in enviromet variable / param
function GetParams () {
return process.argv.splice(2)
}
try { try {
if (utils.FileExists(extraModulesFile)) { if (utils.FileExists(extraModulesFile)) {
@ -169,6 +160,7 @@ function setLogTimer () {
setLogTimer() setLogTimer()
logger.Log('Node version: ' + process.version) logger.Log('Node version: ' + process.version)
logger.Log('Current working directory: ' + process.cwd())
logger.Log('Listening on port: ' + port) logger.Log('Listening on port: ' + port)
const httpServer = http.createServer(app) const httpServer = http.createServer(app)

189
utils/dbtools.js Normal file
View file

@ -0,0 +1,189 @@
// https://www.sqlitetutorial.net/sqlite-nodejs/
// https://github.com/JoshuaWise/better-sqlite3/blob/HEAD/docs/api.md
module.exports = {
GetDB,
AddColumn,
TableInfo,
UpdateRecord,
Delete,
CreateTable,
SelectAll,
Select,
Insert,
CloseDB
}
const Sqlite = require('better-sqlite3')
const logger = require('../utils/logger.js')
const debugLog = process.env.NS_SQL_DEBUG_LOG
// { asd: 'asd', basd: 4 } => asd = 'asd', basd = 4
function GetSqlQuerry (conditions) {
return Object.keys(conditions).reduce((acc, key) => {
const item = conditions[key]
if (typeof item === 'string') {
acc.push(`${key} = '${conditions[key]}'`)
} else {
acc.push(`${key} = ${conditions[key]}`)
}
return acc
}, []).join(', ')
}
// -------------------------------------------------------------------------
function GetDB (path) {
return new Sqlite(path)
}
function DebugLog (msg) {
if (debugLog) {
logger.DebugLog(msg, 'sql', 0)
}
}
function AddColumn (db, table, col) {
try {
const colName = Object.keys(col)[0]
const colType = col.type
const s = `ALTER TABLE ${table} ADD COLUMN ${colName} ${colType}`
DebugLog(s)
const stmt = db.prepare(s)
return stmt.run()
} catch (e) {
console.error(e)
}
}
function TableInfo (db, table) {
try {
} catch (e) {
console.error(e)
}
const s = `PRAGMA table_info(${table})`
DebugLog(s)
const stmt = db.prepare(s)
const infoRes = stmt.all()
const s2 = `SELECT COUNT(*) FROM ${table}`
DebugLog(s2)
const stmt2 = db.prepare(s2)
const countRes = stmt2.get()
return {
columns: infoRes,
dataCount: countRes[Object.keys(countRes)[0]]
}
}
function UpdateRecord (db, table, newData, conditions) {
try {
const s = `UPDATE ${table} SET ${GetSqlQuerry(newData)} WHERE ${GetSqlQuerry(conditions)}`
DebugLog(s)
const stmt = db.prepare(s)
return stmt.run()
} catch (e) {
console.error(e)
}
}
function Delete (db, table, conditions) {
try {
const s = `DELETE FROM ${table} WHERE ${GetSqlQuerry(conditions)}`
DebugLog(s)
const stmt = db.prepare(s)
return stmt.run()
} catch (e) {
console.error(e)
}
}
function CreateTable (db, name, columns) {
try {
const cols = Object.keys(columns).reduce((acc, key) => {
const item = columns[key]
const isPrimary = item.primary ? ' PRIMARY KEY' : ''
const isNotNull = item.notNull ? ' NOT NULL' : ''
acc.push(`${key} ${item.type}${isPrimary}${isNotNull}`)
return acc
}, []).join(', ')
const s = `CREATE TABLE IF NOT EXISTS ${name}(${cols})`
DebugLog(s)
const stmt = db.prepare(s)
return stmt.run()
} catch (e) {
console.error(e)
}
}
function SelectAll (db, from) {
try {
const s = `SELECT * from ${from}`
DebugLog(s)
const stmt = db.prepare(s)
return stmt.all()
} catch (e) {
console.error(e)
}
}
function Select (db, from, conditions) {
try {
const s = `SELECT * from ${from} WHERE ${GetSqlQuerry(conditions)}`
DebugLog(s)
const stmt = db.prepare(s)
return stmt.all()
} catch (e) {
console.error(e)
}
}
function Insert (db, table, data) {
try {
const cols = Object.keys(data).reduce((acc, key) => {
acc.push(`${key}`)
return acc
}, []).join(', ')
const values = Object.keys(data).reduce((acc, key) => {
const item = data[key]
if (typeof item === 'string') {
acc.push(`'${item}'`)
} else {
acc.push(`${item}`)
}
return acc
}, []).join(', ')
const s = `INSERT INTO ${table} (${cols}) VALUES (${values})`
DebugLog(s)
const stmt = db.prepare(s)
return stmt.run()
} catch (e) {
console.error(e)
}
}
function CloseDB (db) {
db.close((err) => {
if (err) {
return console.error(err.message)
}
DebugLog('Close the database connection.')
})
}

View file

@ -43,13 +43,6 @@ const statFile = 'stats/stats'
const vStatFile = 'stats/vstats' const vStatFile = 'stats/vstats'
const nologFile = './nolog' const nologFile = './nolog'
const writeInterval = 10
let data = {}
let vData = {}
let writes = 0
let debugLevel = 0
const colors = [ const colors = [
'green', 'green',
'red', 'red',
@ -59,6 +52,14 @@ const colors = [
'cyan' 'cyan'
] ]
const writeInterval = 10
const debugLevel = parseInt(process.env.NS_LOGLEVEL) || 0
Log('Loglevel is: ' + debugLevel)
let data = {}
let vData = {}
let writes = 0
let noLogips = [] let noLogips = []
function GetDateString () { function GetDateString () {
@ -158,10 +159,7 @@ function setNoLogReadInterval () {
parseNoLogFile(utils.ReadFile(nologFile)) parseNoLogFile(utils.ReadFile(nologFile))
} }
function Load (debugLvl) { function Load () {
if (debugLvl) {
debugLevel = debugLvl
}
Log('Loading logger...') Log('Loading logger...')
try { try {
var prevData = utils.ReadFile(statFile) var prevData = utils.ReadFile(statFile)

View file

@ -1,5 +1,6 @@
module.exports = { module.exports = {
ReadFile: ReadFile, ReadFile: ReadFile,
ReadJSON: ReadJSON,
WriteFile: WriteFile, WriteFile: WriteFile,
writeFileAsync: WriteFileAsync, writeFileAsync: WriteFileAsync,
AppendToFile: AppendToFile, AppendToFile: AppendToFile,
@ -27,6 +28,15 @@ function ReadDir (path) {
return fs.readdirSync(path) return fs.readdirSync(path)
} }
function ReadJSON (name) {
try {
return JSON.parse(ReadFile(name))
} catch (e) {
console.log(e)
throw new Error('Coulndt parse JSON in "ReadJSON", file: ' + name)
}
}
function ReadFile (name) { function ReadFile (name) {
if (!FileExists(name)) { throw new Error('No such file: ' + name) } if (!FileExists(name)) { throw new Error('No such file: ' + name) }
return fs.readFileSync(name, 'utf8') return fs.readFileSync(name, 'utf8')