basic session management, not really working

This commit is contained in:
Jörn-Michael Miehe 2019-02-14 17:47:47 +01:00
parent 678a30e94d
commit d30f92aa46
7 changed files with 129 additions and 79 deletions

View file

@ -1,4 +1,4 @@
# libraries
# node libraries
bcrypt = (require 'bcrypt')
sqlite3 = (require 'sqlite3').verbose()
logger = (require 'logging').default 'db'
@ -28,10 +28,11 @@ FFTCGDB = (filename, truncate) ->
user integer PRIMARY KEY,
login text NOT NULL COLLATE NOCASE,
pwdhash text NOT NULL,
settings text,
UNIQUE(login)
);
''', (err) ->
FFTCGLOG.error err.message if err
logger.error err.message if err
that.db.run 'DROP TABLE IF EXISTS decks;', (err) ->
logger.error err.message if err
@ -46,7 +47,7 @@ FFTCGDB = (filename, truncate) ->
''', (err) ->
logger.error err.message if err
logger.info 'recreated DB'
logger.info 'recreated sqlite3 db'
return
@ -74,7 +75,7 @@ FFTCGDB::register = (login, password) ->
# hash password
bcrypt.hash password, saltRounds, (err, hash) ->
if err
logger.info "reg: hash fail for name '#{login}'"
logger.warn "reg: hash fail for name '#{login}'"
reject 'hash'
# try creating row in users table
@ -117,7 +118,7 @@ FFTCGDB::login = (login, password) ->
else
bcrypt.compare password, row.pwdhash, (err, res) ->
if err
logger.info "login: hash fail for name '#{login}'"
logger.warn "login: hash fail for name '#{login}'"
reject 'hash'
if res == true

View file

@ -22,6 +22,7 @@
"fastify-static": "^1.1.0",
"fastify-ws": "^1.0.0",
"logging": "^3.2.0",
"redis": "^2.8.0",
"sqlite3": "^4.0.4"
}
}

View file

@ -1,13 +1,15 @@
# node libraries
express = (require 'express')
path = (require 'path')
# my libraries
FFTCGDB = (require './db')
logger = (require 'logging').default 'router'
FFTCGSESSION = (require './session')
logger = (require 'logging').default 'routes'
# open fftcg db
fftcgdb = new FFTCGDB path.resolve(__dirname, 'fftcg.db')
# open fftcg.db (persistent data)
fftcgdb = new FFTCGDB path.resolve(__dirname, 'fftcg.db'), true
# open session storage (volatile data)
session = new FFTCGSESSION
module.exports = [
# test
@ -15,6 +17,7 @@ module.exports = [
method: 'POST'
handler: (request, reply) ->
logger.info 'Cookies', request.cookies
logger.info 'Body', request.body
logger.info 'Query', request.query
logger.info 'Params', request.params
@ -26,16 +29,16 @@ module.exports = [
url: '/user/register'
method: 'POST'
handler: (request, reply) ->
fftcgdb.register req.body.login, req.body.password
fftcgdb.register request.body.login, request.body.password
.then (user) ->
# registration successful, return JSON status
# registration successful
reply.send
status: 'ok'
user: user.user
login: user.login
.catch (err) ->
# registration failed, return JSON status
# registration failed
reply.send
status: 'fail'
text: err
@ -44,20 +47,28 @@ module.exports = [
url: '/user/login'
method: 'POST'
handler: (request, reply) ->
fftcgdb.login req.body.login, req.body.password
session_id = request.cookies.session
logger.info session_id
session.action session_id
.then (user) ->
# login successful, save stuff in cookie
logger.info user
.catch (err) ->
logger.error err
fftcgdb.login request.body.login, request.body.password
.then (user) ->
# login successful
reply.setCookie 'user', JSON.stringify user
# return JSON status
res.json
reply.send
status: 'ok'
user: user.user
login: user.login
.catch (err) ->
# login failed, return JSON status
res.json
# login failed
reply.send
status: 'fail'
text: err
,

View file

@ -1,40 +0,0 @@
# node libraries
bodyParser = (require 'body-parser')
express = (require 'express')
sharedSession = (require 'express-socket.io-session')
helmet = (require 'helmet')
http = (require 'http')
path = (require 'path')
logger = (require 'logging').default 'FFTCG'
# my libraries
FFTCGSOCKET = (require './socket')
FFTCGSESSION = (require './session')
FFTCGROUTER = (require './router')
# express framework
app = express()
app.use helmet()
app.use bodyParser.urlencoded
extended: true
# sessions
sessionMiddleware = FFTCGSESSION(app)
app.use sessionMiddleware
# routes
app.use FFTCGROUTER
# socket.io
web = http.Server app
socket = new FFTCGSOCKET web, sharedSession sessionMiddleware
# Create server
web.listen 3001, ->
logger.info 'Listening on port 3001 ...'
# Handle termination
process.on 'SIGINT', ->
socket.close()
logger.info 'shutting down after SIGINT'
process.exit()

View file

@ -1,22 +1,66 @@
# node libraries
expressSession = (require 'express-session')
RedisStore = (require 'connect-redis')(expressSession)
redis = (require 'redis')
crypto = (require 'crypto')
logger = (require 'logging').default 'session'
module.exports = (app) ->
session =
secret: 'keyboard cat'
store: new RedisStore
host: 'redis'
port: 6379
cookie:
httpOnly: true
sameSite: 'strict'
proxy: true
resave: true
saveUninitialized: true
# expiry times in seconds
TIMES =
minute: 60
hour: 60 * 60
day: 60 * 60 * 24
week: 60 * 60 * 24 * 7
month: 60 * 60 * 24 * 7 * 4
if app.get 'env' == 'production'
app.set 'trust proxy', 1
session.cookie.secure = true
EXPIRY =
# games expire 1 week after last action
game: 1 * TIMES.week
# logins expire 1 month after last action
login: 1 * TIMES.month
expressSession session
FFTCGSESSION = () ->
@db = redis.createClient 6379, 'redis'
@db.on 'error', (err) ->
logger.error err.message
return
FFTCGSESSION::login = (login) ->
that = @
new Promise (resolve, reject) ->
hmac = crypto.createHmac 'sha256', Math.random().toString()
hmac.update login
digest = hmac.digest 'hex'
that.db.setex digest, EXPIRY.login, login, (err) ->
if err
reject err
else
resolve digest
FFTCGSESSION::action = (digest) ->
that = @
new Promise (resolve, reject) ->
that.db.get digest (err, res) ->
logger.info 'err', err, 'res', res
if err
reject err
else if res == 0
resolve null
else
that.db.expire digest, EXPIRY.login, (err, res) ->
if err
reject err
else
resolve res
module.exports = FFTCGSESSION

View file

@ -17,12 +17,21 @@
ws.send('Ping') // Send the message 'Ping' to the server
}
console.log(JSON.stringify(document.cookie))
axios.post('/test',{
x: 123
axios.post('/user/register',{
login: 'jmm',
password: '123'
})
.then( (response) => {
console.log(response)
console.log('register', response)
})
axios.post('/user/login',{
login: 'jmm',
password: '123'
})
.then( (response) => {
console.log('login', response)
console.log('cookie', document.cookie)
})
</script>
</body>

View file

@ -586,6 +586,11 @@ dot-prop@^4.1.0:
dependencies:
is-obj "^1.0.0"
double-ended-queue@^2.1.0-0:
version "2.1.0-0"
resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c"
integrity sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=
duplexer3@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
@ -1996,6 +2001,25 @@ readdirp@^2.2.1:
micromatch "^3.1.10"
readable-stream "^2.0.2"
redis-commands@^1.2.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.4.0.tgz#52f9cf99153efcce56a8f86af986bd04e988602f"
integrity sha512-cu8EF+MtkwI4DLIT0x9P8qNTLFhQD4jLfxLR0cCNkeGzs87FN6879JOJwNQR/1zD7aSYNbU0hgsV9zGY71Itvw==
redis-parser@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-2.6.0.tgz#52ed09dacac108f1a631c07e9b69941e7a19504b"
integrity sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=
redis@^2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/redis/-/redis-2.8.0.tgz#202288e3f58c49f6079d97af7a10e1303ae14b02"
integrity sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==
dependencies:
double-ended-queue "^2.1.0-0"
redis-commands "^1.2.0"
redis-parser "^2.6.0"
regex-not@^1.0.0, regex-not@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c"