UNPKG

8.1 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var tslib_1 = require("tslib");
4var shortid = require("shortid");
5var lodash_1 = require("lodash");
6var defaultOptions = {
7 userCollectionName: 'users',
8 sessionCollectionName: 'sessions',
9 timestamps: {
10 createdAt: 'createdAt',
11 updatedAt: 'updatedAt',
12 },
13 idProvider: function () { return shortid.generate(); },
14 dateProvider: function (date) { return (date ? date.getTime() : Date.now()); },
15};
16var RedisSessions = /** @class */ (function () {
17 function RedisSessions(db, options) {
18 this.options = lodash_1.merge(tslib_1.__assign({}, defaultOptions), options);
19 if (!db) {
20 throw new Error('A database connection is required');
21 }
22 this.db = db;
23 }
24 RedisSessions.prototype.createSession = function (userId, token, connection, extraData) {
25 if (connection === void 0) { connection = {}; }
26 return tslib_1.__awaiter(this, void 0, void 0, function () {
27 var sessionId, pipeline;
28 var _a;
29 return tslib_1.__generator(this, function (_b) {
30 switch (_b.label) {
31 case 0:
32 sessionId = this.options.idProvider();
33 pipeline = this.db.pipeline();
34 pipeline.hmset(this.options.sessionCollectionName + ":" + sessionId, (_a = {
35 userId: userId,
36 token: token,
37 userAgent: connection.userAgent,
38 ip: connection.ip,
39 valid: true
40 },
41 _a[this.options.timestamps.createdAt] = this.options.dateProvider(),
42 _a[this.options.timestamps.updatedAt] = this.options.dateProvider(),
43 _a));
44 // Push the sessionId inside the userId
45 pipeline.sadd(this.options.sessionCollectionName + ":" + this.options.userCollectionName + ":" + userId, sessionId);
46 // Link the session token to the sessionId
47 pipeline.set(this.options.sessionCollectionName + ":token:" + token, sessionId);
48 return [4 /*yield*/, pipeline.exec()];
49 case 1:
50 _b.sent();
51 return [2 /*return*/, sessionId];
52 }
53 });
54 });
55 };
56 RedisSessions.prototype.updateSession = function (sessionId, connection) {
57 return tslib_1.__awaiter(this, void 0, void 0, function () {
58 var _a;
59 return tslib_1.__generator(this, function (_b) {
60 switch (_b.label) {
61 case 0: return [4 /*yield*/, this.db.exists(this.options.sessionCollectionName + ":" + sessionId)];
62 case 1:
63 if (!_b.sent()) return [3 /*break*/, 3];
64 return [4 /*yield*/, this.db.hmset(this.options.sessionCollectionName + ":" + sessionId, (_a = {
65 userAgent: connection.userAgent,
66 ip: connection.ip
67 },
68 _a[this.options.timestamps.updatedAt] = this.options.dateProvider(),
69 _a))];
70 case 2:
71 _b.sent();
72 _b.label = 3;
73 case 3: return [2 /*return*/];
74 }
75 });
76 });
77 };
78 RedisSessions.prototype.invalidateSession = function (sessionId) {
79 return tslib_1.__awaiter(this, void 0, void 0, function () {
80 var _a;
81 return tslib_1.__generator(this, function (_b) {
82 switch (_b.label) {
83 case 0: return [4 /*yield*/, this.db.exists(this.options.sessionCollectionName + ":" + sessionId)];
84 case 1:
85 if (!_b.sent()) return [3 /*break*/, 3];
86 return [4 /*yield*/, this.db.hmset(this.options.sessionCollectionName + ":" + sessionId, (_a = {
87 valid: false
88 },
89 _a[this.options.timestamps.updatedAt] = this.options.dateProvider(),
90 _a))];
91 case 2:
92 _b.sent();
93 _b.label = 3;
94 case 3: return [2 /*return*/];
95 }
96 });
97 });
98 };
99 RedisSessions.prototype.invalidateAllSessions = function (userId) {
100 return tslib_1.__awaiter(this, void 0, void 0, function () {
101 var sessionIds;
102 var _this = this;
103 return tslib_1.__generator(this, function (_a) {
104 switch (_a.label) {
105 case 0: return [4 /*yield*/, this.db.exists(this.options.sessionCollectionName + ":" + this.options.userCollectionName + ":" + userId)];
106 case 1:
107 if (!_a.sent()) return [3 /*break*/, 4];
108 return [4 /*yield*/, this.db.smembers(this.options.sessionCollectionName + ":" + this.options.userCollectionName + ":" + userId)];
109 case 2:
110 sessionIds = _a.sent();
111 return [4 /*yield*/, sessionIds.map(function (sessionId) { return _this.invalidateSession(sessionId); })];
112 case 3:
113 _a.sent();
114 _a.label = 4;
115 case 4: return [2 /*return*/];
116 }
117 });
118 });
119 };
120 RedisSessions.prototype.findSessionByToken = function (token) {
121 return tslib_1.__awaiter(this, void 0, void 0, function () {
122 var sessionId;
123 return tslib_1.__generator(this, function (_a) {
124 switch (_a.label) {
125 case 0: return [4 /*yield*/, this.db.exists(this.options.sessionCollectionName + ":token:" + token)];
126 case 1:
127 if (!_a.sent()) return [3 /*break*/, 3];
128 return [4 /*yield*/, this.db.get(this.options.sessionCollectionName + ":token:" + token)];
129 case 2:
130 sessionId = _a.sent();
131 if (sessionId) {
132 return [2 /*return*/, this.findSessionById(sessionId)];
133 }
134 _a.label = 3;
135 case 3: return [2 /*return*/, null];
136 }
137 });
138 });
139 };
140 RedisSessions.prototype.findSessionById = function (sessionId) {
141 return tslib_1.__awaiter(this, void 0, void 0, function () {
142 var session;
143 return tslib_1.__generator(this, function (_a) {
144 switch (_a.label) {
145 case 0: return [4 /*yield*/, this.db.exists(this.options.sessionCollectionName + ":" + sessionId)];
146 case 1:
147 if (!_a.sent()) return [3 /*break*/, 3];
148 return [4 /*yield*/, this.db.hgetall(this.options.sessionCollectionName + ":" + sessionId)];
149 case 2:
150 session = _a.sent();
151 return [2 /*return*/, this.formatSession(sessionId, session)];
152 case 3: return [2 /*return*/, null];
153 }
154 });
155 });
156 };
157 /**
158 * We need to format the session to have an object the server can understand.
159 */
160 RedisSessions.prototype.formatSession = function (sessionId, session) {
161 // Redis doesn't store boolean values, so we need turn this string into a boolean
162 session.valid = session.valid === 'true';
163 return tslib_1.__assign({ id: sessionId }, session);
164 };
165 return RedisSessions;
166}());
167exports.RedisSessions = RedisSessions;
168//# sourceMappingURL=redis.js.map
\No newline at end of file