login ok
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import mysql from 'mysql2/promise'
|
||||
|
||||
export class MySQLClient {
|
||||
constructor(db, kal = 0) {
|
||||
this.db = db
|
||||
this.lastInsertedId = -1
|
||||
this.kalIntervalId = null
|
||||
if(kal > 0){
|
||||
this.kalIntervalId = setInterval(() => {
|
||||
this.db.query('SELECT 1')
|
||||
}, 1000 * kal);
|
||||
}
|
||||
}
|
||||
|
||||
async close(){
|
||||
if(this.db) await this.db.end()
|
||||
if(this.kalIntervalId) clearInterval(this.kalIntervalId)
|
||||
this.db = null
|
||||
}
|
||||
|
||||
escape(x) { return(mysql.escape(x)) }
|
||||
|
||||
async execute(query, values = []){
|
||||
if(!this.db) return([])
|
||||
if(query.search(RegExp('(^|;) *(INSERT|REPLACE) +INTO','i'))>-1) this.lastInsertedId = -1
|
||||
const [result] = await this.db.execute(query, values)
|
||||
|
||||
if('insertId' in result) {
|
||||
this.lastInsertedId = result.insertId
|
||||
}
|
||||
return(result)
|
||||
}
|
||||
|
||||
/* Makes a multi-line VALUES insert, with values for an array of objects { columns:value }
|
||||
*/
|
||||
async InsertObjectsStatement(table, rows){
|
||||
this.lastInsertedId = -1
|
||||
if((!this.db) || (rows.length==0)) return([])
|
||||
const keys = Object.keys(rows[0]).map((key) => `\`${key}\``).join(', ')
|
||||
let valuesArr = []
|
||||
for(let row of rows){
|
||||
valuesArr.push(Object.values(row))
|
||||
}
|
||||
const query = `INSERT INTO ${table} (${keys}) VALUES ?`
|
||||
const [result] = await this.db.query(query, [valuesArr]) //Note the wierd array in array of arrays, also, query, not execute
|
||||
if('insertId' in result) {
|
||||
this.lastInsertedId = result.insertId
|
||||
}
|
||||
return(result)
|
||||
}
|
||||
|
||||
/* Makes a multi-line VALUES insert, with values for an array of objects { columns:value }
|
||||
*/
|
||||
async ReplaceObjectsStatement(table, rows){
|
||||
this.lastInsertedId = -1
|
||||
if((!this.db) || (rows.length==0)) return([])
|
||||
const keys = Object.keys(rows[0]).map((key) => `\`${key}\``).join(', ')
|
||||
let valuesArr = []
|
||||
for(let row of rows){
|
||||
valuesArr.push(Object.values(row))
|
||||
}
|
||||
const query = `REPLACE INTO ${table} (${keys}) VALUES ?`
|
||||
const [result] = await this.db.query(query, [valuesArr]) //Note the wierd array in array of arrays, also, query, not execute
|
||||
if('insertId' in result) {
|
||||
this.lastInsertedId = result.insertId
|
||||
}
|
||||
return(result)
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
const argon2 = require('argon2')
|
||||
import argon2 from 'argon2'
|
||||
|
||||
// --- Hash a password (e.g. at signup) ---
|
||||
export async function hashPassword(plainPassword) {
|
||||
|
||||
+90
-31
@@ -1,20 +1,20 @@
|
||||
import { Utils } from './helpers/utils.js'
|
||||
import { verifyPassword } from './helpers/pwd.js'
|
||||
import { MySQLClient } from './helpers/mysqlClient.js'
|
||||
export class P42ApiEndpoints{
|
||||
constructor(app, db) {
|
||||
this.db = db
|
||||
this.db = new MySQLClient(db, 60)
|
||||
this.app = app
|
||||
this.userinfos = null
|
||||
this.utils = new Utils()
|
||||
this.registerPaths()
|
||||
setInterval(() => {
|
||||
this.db.query('SELECT 1');
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
registerPaths(){
|
||||
this.app.get('/hw', this.hw.bind(this))
|
||||
this.app.get('/checkauth', this.checkauth.bind(this))
|
||||
this.app.post('/login', this.login.bind(this))
|
||||
this.app.get('/logout', this.logout.bind(this))
|
||||
|
||||
}
|
||||
|
||||
@@ -47,17 +47,6 @@ export class P42ApiEndpoints{
|
||||
this.ok(req, res, {})
|
||||
}
|
||||
|
||||
getSession(req, res) {
|
||||
if((!req.session.userinfo) || (!req.session.userinfo.isAuthenticated)) {
|
||||
this.userinfos = null
|
||||
return(false)
|
||||
} else {
|
||||
req.session.touch()
|
||||
this.userinfos = req.session.userinfo
|
||||
return(true)
|
||||
}
|
||||
}
|
||||
|
||||
hasRole(roles) {
|
||||
if(!this.userinfos.userRoles) return(false)
|
||||
if(typeof(roles) == 'string') return(this.userinfos.userRoles.includes(roles))
|
||||
@@ -74,51 +63,121 @@ export class P42ApiEndpoints{
|
||||
this.ok(req, res, {hello:'world'})
|
||||
}
|
||||
|
||||
async checkauth(req, res)
|
||||
if(req.session.userInfos && req.session.userInfos.authenticated && req.session.userInfos.username) {
|
||||
async checkauth(req, res) {
|
||||
if(req.session.userInfos && req.session.authenticated && req.session.userInfos.username) {
|
||||
this.ok(req, res, {
|
||||
authenticated: true,
|
||||
userInfos: this.userInfos,
|
||||
trials: 3,
|
||||
locked: false,
|
||||
})
|
||||
} else {
|
||||
let trials = 3
|
||||
let locked = false
|
||||
if(req.session.userInfos && req.session.userInfos.username) {
|
||||
const results = await this.db.execute('SELECT usr_trials, usr_locked FROM users WHERE usr_name = ?', [req.session.userInfos.username])
|
||||
if(results.length==1){
|
||||
trials = results[0].usr_trials
|
||||
locked = results[0].usr_locked
|
||||
}
|
||||
}
|
||||
this.ok(req, res, {
|
||||
authenticated: false,
|
||||
userInfos: null,
|
||||
trials: trials,
|
||||
locked: locked,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async setUserLock(username, locked, trials){
|
||||
await this.db.execute('UPDATE users SET usr_locked=?, usr_trials=? WHERE usr_name = ?', [locked, trials, username])
|
||||
}
|
||||
|
||||
async login(req, res) {
|
||||
let [isValid, payload, errors] = this.utils.validateMapObject(req.body, {
|
||||
username: ((val, obj) => (typeof(val)=='string') && (val.length>3) ),
|
||||
passwd: ((val, obj) => (typeof(val)=='string') && (val.length>7) ),
|
||||
username: ((val, obj) => (typeof(val)=='string') && (val.length>0) && (/^\w+$/.test(val))),
|
||||
passwd: ((val, obj) => (typeof(val)=='string') && (val.length>0) ),
|
||||
},{
|
||||
'username': 'username',
|
||||
'passwd': 'passwd',
|
||||
})
|
||||
|
||||
if((!isValid)){
|
||||
this.err(req, res, `Invalid request', 'Invalid login payload:: ${errors}`, 401)
|
||||
this.err(req, res, `Invalid request`, `Invalid login payload:: ${errors}`, 401)
|
||||
return
|
||||
}
|
||||
|
||||
if((payload.username=='toto') && (payload.passwd=='azertyuiop')){
|
||||
req.session.userInfos = {
|
||||
authenticated: true,
|
||||
username: payload.username,
|
||||
roles: ['admin']
|
||||
}
|
||||
this.ok(req, res, {
|
||||
authenticated: true,
|
||||
userInfos: req.session.userInfos,
|
||||
})
|
||||
} else {
|
||||
const results = await this.db.execute('SELECT * FROM users WHERE usr_name = ?', [payload.username])
|
||||
let pwdCheck = false
|
||||
let userLocked = false
|
||||
let trials = 3
|
||||
if(results.length==1){
|
||||
userLocked = results[0].usr_locked
|
||||
trials = results[0].usr_trials
|
||||
if(userLocked) {
|
||||
this.ok(req, res, {
|
||||
authenticated: false,
|
||||
userInfos: null,
|
||||
trials: 0,
|
||||
locked: true,
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
pwdCheck = await verifyPassword(payload.passwd, results[0].usr_pwd)
|
||||
if(pwdCheck){
|
||||
req.session.userInfos = {
|
||||
username: payload.username,
|
||||
roles: ['admin'],
|
||||
}
|
||||
req.session.authenticated = true
|
||||
|
||||
await this.setUserLock(payload.username, false, 3)
|
||||
this.ok(req, res, {
|
||||
authenticated: true,
|
||||
userInfos: req.session.userInfos,
|
||||
trials: 3,
|
||||
locked: false,
|
||||
})
|
||||
} else {
|
||||
let newtrials = (trials>0) ? trials-1 : 0
|
||||
if(newtrials == 0){
|
||||
await this.setUserLock(payload.username, true, 0)
|
||||
this.ok(req, res, {
|
||||
authenticated: false,
|
||||
userInfos: null,
|
||||
trials: 0,
|
||||
locked: true,
|
||||
})
|
||||
return
|
||||
} else {
|
||||
await this.setUserLock(payload.username, false, newtrials)
|
||||
}
|
||||
|
||||
req.session.authenticated = false
|
||||
req.session.userInfos = null
|
||||
this.ok(req, res, {
|
||||
authenticated: false,
|
||||
userInfos: null,
|
||||
trials: newtrials,
|
||||
locked: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async logout(req, res) {
|
||||
if(req.session.userInfos && req.session.authenticated) {
|
||||
req.session.authenticated = false
|
||||
this.ok(req, res, {
|
||||
authenticated: false,
|
||||
userInfos: null,
|
||||
trials: 3,
|
||||
locked: false,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user