-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
87 lines (87 loc) · 4.33 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
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
const sequelize_1 = require("sequelize");
class Session extends sequelize_1.Model {
get expiry() { return this.expiryTo.getTime() - this.createAt.getTime(); }
set expiry(value) { this.expiryTo = new Date(this.createAt.getTime() + value); }
gc() {
return __awaiter(this, void 0, void 0, function* () { return yield Session.destroy({ where: { expiryTo: { [sequelize_1.Op.lt]: new Date() } } }); });
}
}
(function (Session) {
function proxyData(session, target) {
return new Proxy(target, {
set: (target, key, value) => {
session.changed('data', true);
return Reflect.set(target, key, value);
},
get: (target, key) => {
return typeof target[key] !== 'object' ? target[key] : proxyData(session, target[key]);
}
});
}
function middware(sequelize, initOptions) {
const { tableName = undefined, gcOpts = { type: 'auto', probMolecular: 1, probDenominator: 100 }, sync = { enable: false, force: false }, sessKey = 'koa2:sess', logger = true, defaultExpiry = 24 * 60 * 60 * 1000 } = initOptions || {};
Session.init({
id: { type: sequelize_1.DataTypes.CHAR(36), primaryKey: true, defaultValue: sequelize_1.DataTypes.UUIDV4 },
data: {
type: sequelize_1.DataTypes.JSON,
defaultValue: {},
get() { return proxyData(this, this.getDataValue('data')); },
set(value) { this.setDataValue('data', value); }
},
expiryTo: { type: sequelize_1.DataTypes.DATE, defaultValue: () => new Date(Date.now() + defaultExpiry) },
createAt: { type: sequelize_1.DataTypes.DATE, defaultValue: sequelize_1.DataTypes.NOW }
}, {
sequelize,
tableName,
timestamps: false,
underscored: true,
paranoid: false,
});
if (sync && sync.enable)
Session.sync({ force: sync.force }).catch(e => console.log(e));
return (ctx, next) => __awaiter(this, void 0, void 0, function* () {
const id = ctx.cookies.get(sessKey);
if (id) {
const session = yield Session.findOne({ where: { id } });
ctx.session = session && session.expiryTo.getTime() > Date.now() ? session : new Session();
}
else {
ctx.session = new Session();
}
yield next();
if (ctx.session.changed()) {
if (ctx.session.isNewRecord || ctx.session.changed('expiryTo')) {
if (ctx.session.changed('expiryTo')) {
ctx.cookies.set(sessKey, ctx.session.id, { path: '/', overwrite: true, expires: ctx.session.expiryTo });
}
else {
ctx.cookies.set(sessKey, ctx.session.id, { path: '/', overwrite: true });
}
}
yield ctx.session.save();
}
if (gcOpts.type == 'auto' && Math.random() * Math.abs(gcOpts.probDenominator) <= Math.abs(gcOpts.probMolecular)) {
if (logger == true)
console.log(`[${Date()}]: Auto collect ${yield ctx.session.gc()} session garbage.`);
if (typeof logger == 'function')
logger(yield ctx.session.gc());
}
});
}
Session.middware = middware;
})(Session || (Session = {}));
exports.default = Session;
__export(require("sequelize"));