-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
97 lines (75 loc) · 1.82 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
const fs = require("fs"),
path = require("path"),
jBD = require("jbd"),
{randomBytes} = require("crypto");
class Store {
constructor () {
this.session = {};
this.timer = {};
}
destroy (sid) {
delete this.session[sid];
delete this.timer[sid];
}
getID (length) {
return randomBytes(length).toString("hex");
}
get (sid) {
if (!this.session[sid]) return null;
return JSON.parse(this.session[sid]);
}
set (session, {sid = this.getID(24), maxAge} = {}) {
if (this.session[sid] && this.timer[sid]) {
if (this.timer[sid]) clearTimeout(this.timer[sid]);
}
if (maxAge) {
this.timer[sid] = setTimeout(() => this.destroy(sid), maxAge);
}
try {
this.session[sid] = JSON.stringify(session);
}
catch (e) {
console.error(`set session error: ${e}`)
}
return sid;
}
}
async function middleware (ctx, next) {
let {key, store} = opts,
id = ctx.cookies.get(key, opts);
if (!id) ctx.session = {};
else {
ctx.session = await store.get(id, ctx);
if (!jBD.isObject(ctx.session)) ctx.session = {};
}
let state = false,
vold = JSON.stringify(ctx.session),
vnew;
ctx.session.refresh = () => { state = true; };
await next();
vnew = JSON.stringify(ctx.session);
if (!state && vold === vnew) return;
if (vnew === "{}") ctx.session = null;
if (id && !ctx.session) {
await store.destroy(id, ctx);
ctx.cookies.set(key, null);
}
else {
let sid = await store.set(ctx.session, Object.assign({}, opts, {sid: id}), ctx);
ctx.cookies.set(key, sid, opts);
}
}
function Session (opt) {
opts = opt || {};
for (let key in defaults) {
if (opts[key] === undefined) opts[key] = defaults[key];
}
return middleware;
}
let defaults = {
key: "koa:session",
store: new Store()
},
opts;
Session.Store = Store;
module.exports = exports = Session;