arcane-middleware-session
Version:
Session manager for arcane
162 lines (133 loc) • 5.01 kB
text/coffeescript
#!package export Session
#!import crypto
#!import util
#!import path
#!import tools.wait
#!import harmony-proxy
#!import pool-redis
#!import MiddlewareHandler from arcane-middleware
#!import ORM from arcane-middleware-orm
class Session extends MiddlewareHandler
cache: {}
# @redis: poolRedis
# @poolRedis: @redis 'host': 'localhost', 'password': '', 'maxConnections': 10
@redisClient: null
@ORMMap: require('arcane-middleware-orm/lib/map').Map
@ORMConnection: require('arcane-middleware-orm/lib/connection').Connection
middleware: (@config, @globals) ->
# unless Session.redisClient
# Session.redisClient = wait.for (func) ->
# Session.poolRedis.getClient (client, done) ->
# func null, client
sessionConnection = new Session.ORMConnection
adapter: 'sqlite'
root: __dirname
file: "#{@globals.root}/session.sqlite3"
model = new Session.ORMMap "#{__dirname}/OrmSession.coffee"
model.setConnection(sessionConnection)
session_default_handler = ($req, $res) ->
try
ses = model.objects.get(session_id: $req.sessionID)
catch err
ses = null
{
data: JSON.parse(ses?.value ? '{}')
save: (data) ->
[updated_data, iscreated] = model.objects.update_or_create(value: data, defaults: { session_id: $req.sessionID })
}
self = @
(req, res, app) ->
port_num = req.get('host')?.split ':'
throw 404 unless port_num?
cookies = {
options:
maxAge: 14 * 24 * 3600000
# domain: req.hostname
path: '/'
}
cookies.options.port = port_num[1] if port_num[1]?
req.sessionID = self.get req, 'NTARCE'
unless req.sessionID?
shasum = crypto.createHash('sha1', 'd8aae46eba9976b0cbb399444e710f4b')
shasum.update self.guid()
req.sessionID = shasum.digest('hex')
res.cookie 'NTARCE', req.sessionID, cookies.options
# req.events.on 'session-pull', ->
# console.log 'session setted', req.url
req.session = wait.for (callback) ->
app.use self.config.settings.middleware?.session ? session_default_handler, (err, result) ->
console.log err.stack ? err if err
tmp_data = util._extend {}, (result?.data ? {})
if result?.data? and result?.save?
d = new harmonyProxy tmp_data, #Proxy.create {
get: (target, name) ->
if req.session_live?
try
tmp_data = app.use self.config.settings.middleware?.session ? session_default_handler
tmp_data = util._extend {}, (tmp_data?.data ? {})
catch
console.log _error.stack ? _error
if name is 'toJSON'
return ->
JSON.stringify tmp_data
else if name is 'valueOf'
return ->
tmp_data
else
tmp_data?[name] ? null
set: (target, name, value) ->
tmp_data[name] = value
if req.session_live
result.save JSON.stringify(tmp_data)
if typeof result?.save is 'function'
req.events.on 'request-complete', ->
result.save d.toJSON()
callback null, d
# req.events.emit 'session-pull'
get: ($req, name) ->
if header_cookies = $req.get('cookie')
match = header_cookies.match @getPattern name
return match?[1] ? null
null
getPattern: (name) ->
return @cache[name] if @cache[name]?
@cache[name] = new RegExp "(?:^|;) *#{name.replace /[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"}=([^;]*)"
guid: ->
s4 = ->
Math.floor((1 + Math.random()) * 0x10000).toString(16).substring 1
s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4()
default_session: ($req, $config, $connector) ->
connection_type = if $config?.connection? then config$config.connection else 'redis'
if $connector and connection_type is 'memory'
is_new = true
if $connector.session.$?
wait.for $connector.session.$
wait.forMethod $connector.session, 'table', 'session', {
'session_id': String
'value': String
'expiration': Number
}
result = wait.forMethod $connector.session, 'query', "SELECT * FROM `tbl_session` WHERE `session_id` LIKE ?", [$req.sessionID]
if result.length is 0
tmp_session = {}
else if result.length isnt 0
is_new = false
tmp_session = JSON.parse result[0].value
$req.events.on 'request-complete', ->
if is_new
wait.forMethod $connector.session, 'query', "INSERT INTO `tbl_session` (`session_id`, `value`) VALUES (?, ?)", [$req.sessionID, JSON.stringify tmp_session]
else
wait.forMethod $connector.session, 'query', "UPDATE `tbl_session` SET `value`=? WHERE `session_id` LIKE ?", [JSON.stringify(tmp_session), $req.sessionID]
else
value = wait.forMethod session.redisClient, 'get', $req.sessionID
if not value?
tmp_session = {}
else
tmp_session = JSON.parse value
$req.events.on 'request-complete', ->
wait.forMethod session.redisClient, 'set', $req.sessionID, JSON.stringify(tmp_session)
return new harmonyProxy {},
get: (target, name) ->
tmp_session[name]
set: (target, name, value) ->
tmp_session[name] = value