123
This commit is contained in:
48
node_modules/connect-redis/dist/cjs/index.d.ts
generated
vendored
Normal file
48
node_modules/connect-redis/dist/cjs/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
import { SessionData, Store } from "express-session";
|
||||
interface NormalizedRedisClient {
|
||||
get(key: string): Promise<string | null>;
|
||||
set(key: string, value: string, ttl?: number): Promise<string | null>;
|
||||
expire(key: string, ttl: number): Promise<number | boolean>;
|
||||
scanIterator(match: string, count: number): AsyncIterable<string>;
|
||||
del(key: string[]): Promise<number>;
|
||||
mget(key: string[]): Promise<(string | null)[]>;
|
||||
}
|
||||
interface Serializer {
|
||||
parse(s: string): SessionData | Promise<SessionData>;
|
||||
stringify(s: SessionData): string;
|
||||
}
|
||||
interface RedisStoreOptions {
|
||||
client: any;
|
||||
prefix?: string;
|
||||
scanCount?: number;
|
||||
serializer?: Serializer;
|
||||
ttl?: number | {
|
||||
(sess: SessionData): number;
|
||||
};
|
||||
disableTTL?: boolean;
|
||||
disableTouch?: boolean;
|
||||
}
|
||||
declare class RedisStore extends Store {
|
||||
client: NormalizedRedisClient;
|
||||
prefix: string;
|
||||
scanCount: number;
|
||||
serializer: Serializer;
|
||||
ttl: number | {
|
||||
(sess: SessionData): number;
|
||||
};
|
||||
disableTTL: boolean;
|
||||
disableTouch: boolean;
|
||||
constructor(opts: RedisStoreOptions);
|
||||
private normalizeClient;
|
||||
get(sid: string, cb?: (_err?: unknown, _data?: any) => void): Promise<void>;
|
||||
set(sid: string, sess: SessionData, cb?: (_err?: unknown, _data?: any) => void): Promise<void>;
|
||||
touch(sid: string, sess: SessionData, cb?: (_err?: unknown, _data?: any) => void): Promise<void>;
|
||||
destroy(sid: string, cb?: (_err?: unknown, _data?: any) => void): Promise<void>;
|
||||
clear(cb?: (_err?: unknown, _data?: any) => void): Promise<void>;
|
||||
length(cb?: (_err?: unknown, _data?: any) => void): Promise<void>;
|
||||
ids(cb?: (_err?: unknown, _data?: any) => void): Promise<void>;
|
||||
all(cb?: (_err?: unknown, _data?: any) => void): Promise<void>;
|
||||
private _getTTL;
|
||||
private _getAllKeys;
|
||||
}
|
||||
export default RedisStore;
|
||||
179
node_modules/connect-redis/dist/cjs/index.js
generated
vendored
Normal file
179
node_modules/connect-redis/dist/cjs/index.js
generated
vendored
Normal file
@ -0,0 +1,179 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const express_session_1 = require("express-session");
|
||||
const noop = (_err, _data) => { };
|
||||
class RedisStore extends express_session_1.Store {
|
||||
constructor(opts) {
|
||||
super();
|
||||
this.prefix = opts.prefix == null ? "sess:" : opts.prefix;
|
||||
this.scanCount = opts.scanCount || 100;
|
||||
this.serializer = opts.serializer || JSON;
|
||||
this.ttl = opts.ttl || 86400; // One day in seconds.
|
||||
this.disableTTL = opts.disableTTL || false;
|
||||
this.disableTouch = opts.disableTouch || false;
|
||||
this.client = this.normalizeClient(opts.client);
|
||||
}
|
||||
// Create a redis and ioredis compatible client
|
||||
normalizeClient(client) {
|
||||
let isRedis = "scanIterator" in client;
|
||||
return {
|
||||
get: (key) => client.get(key),
|
||||
set: (key, val, ttl) => {
|
||||
if (ttl) {
|
||||
return isRedis
|
||||
? client.set(key, val, { EX: ttl })
|
||||
: client.set(key, val, "EX", ttl);
|
||||
}
|
||||
return client.set(key, val);
|
||||
},
|
||||
del: (key) => client.del(key),
|
||||
expire: (key, ttl) => client.expire(key, ttl),
|
||||
mget: (keys) => (isRedis ? client.mGet(keys) : client.mget(keys)),
|
||||
scanIterator: (match, count) => {
|
||||
if (isRedis)
|
||||
return client.scanIterator({ MATCH: match, COUNT: count });
|
||||
// ioredis impl.
|
||||
return (async function* () {
|
||||
let [c, xs] = await client.scan("0", "MATCH", match, "COUNT", count);
|
||||
for (let key of xs)
|
||||
yield key;
|
||||
while (c !== "0") {
|
||||
;
|
||||
[c, xs] = await client.scan(c, "MATCH", match, "COUNT", count);
|
||||
for (let key of xs)
|
||||
yield key;
|
||||
}
|
||||
})();
|
||||
},
|
||||
};
|
||||
}
|
||||
async get(sid, cb = noop) {
|
||||
let key = this.prefix + sid;
|
||||
try {
|
||||
let data = await this.client.get(key);
|
||||
if (!data)
|
||||
return cb();
|
||||
return cb(null, await this.serializer.parse(data));
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
async set(sid, sess, cb = noop) {
|
||||
let key = this.prefix + sid;
|
||||
let ttl = this._getTTL(sess);
|
||||
try {
|
||||
let val = this.serializer.stringify(sess);
|
||||
if (ttl > 0) {
|
||||
if (this.disableTTL)
|
||||
await this.client.set(key, val);
|
||||
else
|
||||
await this.client.set(key, val, ttl);
|
||||
return cb();
|
||||
}
|
||||
else {
|
||||
return this.destroy(sid, cb);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
async touch(sid, sess, cb = noop) {
|
||||
let key = this.prefix + sid;
|
||||
if (this.disableTouch || this.disableTTL)
|
||||
return cb();
|
||||
try {
|
||||
await this.client.expire(key, this._getTTL(sess));
|
||||
return cb();
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
async destroy(sid, cb = noop) {
|
||||
let key = this.prefix + sid;
|
||||
try {
|
||||
await this.client.del([key]);
|
||||
return cb();
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
async clear(cb = noop) {
|
||||
try {
|
||||
let keys = await this._getAllKeys();
|
||||
if (!keys.length)
|
||||
return cb();
|
||||
await this.client.del(keys);
|
||||
return cb();
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
async length(cb = noop) {
|
||||
try {
|
||||
let keys = await this._getAllKeys();
|
||||
return cb(null, keys.length);
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
async ids(cb = noop) {
|
||||
let len = this.prefix.length;
|
||||
try {
|
||||
let keys = await this._getAllKeys();
|
||||
return cb(null, keys.map((k) => k.substring(len)));
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
async all(cb = noop) {
|
||||
let len = this.prefix.length;
|
||||
try {
|
||||
let keys = await this._getAllKeys();
|
||||
if (keys.length === 0)
|
||||
return cb(null, []);
|
||||
let data = await this.client.mget(keys);
|
||||
let results = data.reduce((acc, raw, idx) => {
|
||||
if (!raw)
|
||||
return acc;
|
||||
let sess = this.serializer.parse(raw);
|
||||
sess.id = keys[idx].substring(len);
|
||||
acc.push(sess);
|
||||
return acc;
|
||||
}, []);
|
||||
return cb(null, results);
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
_getTTL(sess) {
|
||||
if (typeof this.ttl === "function") {
|
||||
return this.ttl(sess);
|
||||
}
|
||||
let ttl;
|
||||
if (sess && sess.cookie && sess.cookie.expires) {
|
||||
let ms = Number(new Date(sess.cookie.expires)) - Date.now();
|
||||
ttl = Math.ceil(ms / 1000);
|
||||
}
|
||||
else {
|
||||
ttl = this.ttl;
|
||||
}
|
||||
return ttl;
|
||||
}
|
||||
async _getAllKeys() {
|
||||
let pattern = this.prefix + "*";
|
||||
let keys = [];
|
||||
for await (let key of this.client.scanIterator(pattern, this.scanCount)) {
|
||||
keys.push(key);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
exports.default = RedisStore;
|
||||
1
node_modules/connect-redis/dist/cjs/index_test.d.ts
generated
vendored
Normal file
1
node_modules/connect-redis/dist/cjs/index_test.d.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export {};
|
||||
124
node_modules/connect-redis/dist/cjs/index_test.js
generated
vendored
Normal file
124
node_modules/connect-redis/dist/cjs/index_test.js
generated
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const blue_tape_1 = __importDefault(require("blue-tape"));
|
||||
const express_session_1 = require("express-session");
|
||||
const ioredis_1 = require("ioredis");
|
||||
const node_util_1 = require("node:util");
|
||||
const redis_1 = require("redis");
|
||||
const _1 = __importDefault(require("./"));
|
||||
const redisSrv = __importStar(require("./testdata/server"));
|
||||
(0, blue_tape_1.default)("setup", async () => {
|
||||
await redisSrv.connect();
|
||||
});
|
||||
(0, blue_tape_1.default)("defaults", async (t) => {
|
||||
let client = (0, redis_1.createClient)({ url: `redis://localhost:${redisSrv.port}` });
|
||||
await client.connect();
|
||||
let store = new _1.default({ client });
|
||||
t.ok(store.client, "stores client");
|
||||
t.equal(store.prefix, "sess:", "defaults to sess:");
|
||||
t.equal(store.ttl, 86400, "defaults to one day");
|
||||
t.equal(store.scanCount, 100, "defaults SCAN count to 100");
|
||||
t.equal(store.serializer, JSON, "defaults to JSON serialization");
|
||||
t.equal(store.disableTouch, false, "defaults to having `touch` enabled");
|
||||
t.equal(store.disableTTL, false, "defaults to having `ttl` enabled");
|
||||
await client.disconnect();
|
||||
});
|
||||
(0, blue_tape_1.default)("redis", async (t) => {
|
||||
let client = (0, redis_1.createClient)({ url: `redis://localhost:${redisSrv.port}` });
|
||||
await client.connect();
|
||||
let store = new _1.default({ client });
|
||||
await lifecycleTest(store, client, t);
|
||||
await client.disconnect();
|
||||
});
|
||||
(0, blue_tape_1.default)("ioredis", async (t) => {
|
||||
let client = new ioredis_1.Redis(`redis://localhost:${redisSrv.port}`);
|
||||
let store = new _1.default({ client });
|
||||
await lifecycleTest(store, client, t);
|
||||
client.disconnect();
|
||||
});
|
||||
(0, blue_tape_1.default)("teardown", redisSrv.disconnect);
|
||||
async function lifecycleTest(store, client, t) {
|
||||
const P = (f) => (0, node_util_1.promisify)(f).bind(store);
|
||||
let res = await P(store.clear)();
|
||||
let sess = { foo: "bar" };
|
||||
await P(store.set)("123", sess);
|
||||
res = await P(store.get)("123");
|
||||
t.same(res, sess, "store.get");
|
||||
let ttl = await client.ttl("sess:123");
|
||||
t.ok(ttl >= 86399, "check one day ttl");
|
||||
ttl = 60;
|
||||
let expires = new Date(Date.now() + ttl * 1000).toISOString();
|
||||
await P(store.set)("456", { cookie: { expires } });
|
||||
ttl = await client.ttl("sess:456");
|
||||
t.ok(ttl <= 60, "check expires ttl");
|
||||
ttl = 90;
|
||||
let expires2 = new Date(Date.now() + ttl * 1000).toISOString();
|
||||
await P(store.touch)("456", { cookie: { expires: expires2 } });
|
||||
ttl = await client.ttl("sess:456");
|
||||
t.ok(ttl > 60, "check expires ttl touch");
|
||||
res = await P(store.length)();
|
||||
t.equal(res, 2, "stored two keys length");
|
||||
res = await P(store.ids)();
|
||||
res.sort();
|
||||
t.same(res, ["123", "456"], "stored two keys ids");
|
||||
res = await P(store.all)();
|
||||
res.sort((a, b) => (a.id > b.id ? 1 : -1));
|
||||
t.same(res, [
|
||||
{ id: "123", foo: "bar" },
|
||||
{ id: "456", cookie: { expires } },
|
||||
], "stored two keys data");
|
||||
await P(store.destroy)("456");
|
||||
res = await P(store.length)();
|
||||
t.equal(res, 1, "one key remains");
|
||||
res = await P(store.clear)();
|
||||
res = await P(store.length)();
|
||||
t.equal(res, 0, "no keys remain");
|
||||
let count = 1000;
|
||||
await load(store, count);
|
||||
res = await P(store.length)();
|
||||
t.equal(res, count, "bulk count");
|
||||
await P(store.clear)();
|
||||
res = await P(store.length)();
|
||||
t.equal(res, 0, "bulk clear");
|
||||
expires = new Date(Date.now() + ttl * 1000).toISOString(); // expires in the future
|
||||
res = await P(store.set)("789", { cookie: { expires } });
|
||||
res = await P(store.length)();
|
||||
t.equal(res, 1, "one key exists (session 789)");
|
||||
expires = new Date(Date.now() - ttl * 1000).toISOString(); // expires in the past
|
||||
await P(store.set)("789", { cookie: { expires } });
|
||||
res = await P(store.length)();
|
||||
t.equal(res, 0, "no key remains and that includes session 789");
|
||||
}
|
||||
async function load(store, count) {
|
||||
let cookie = new express_session_1.Cookie();
|
||||
for (let sid = 0; sid < count; sid++) {
|
||||
cookie.expires = new Date(Date.now() + 1000);
|
||||
await store.set("s" + sid, { cookie });
|
||||
}
|
||||
}
|
||||
48
node_modules/connect-redis/dist/esm/index.d.ts
generated
vendored
Normal file
48
node_modules/connect-redis/dist/esm/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
import { SessionData, Store } from "express-session";
|
||||
interface NormalizedRedisClient {
|
||||
get(key: string): Promise<string | null>;
|
||||
set(key: string, value: string, ttl?: number): Promise<string | null>;
|
||||
expire(key: string, ttl: number): Promise<number | boolean>;
|
||||
scanIterator(match: string, count: number): AsyncIterable<string>;
|
||||
del(key: string[]): Promise<number>;
|
||||
mget(key: string[]): Promise<(string | null)[]>;
|
||||
}
|
||||
interface Serializer {
|
||||
parse(s: string): SessionData | Promise<SessionData>;
|
||||
stringify(s: SessionData): string;
|
||||
}
|
||||
interface RedisStoreOptions {
|
||||
client: any;
|
||||
prefix?: string;
|
||||
scanCount?: number;
|
||||
serializer?: Serializer;
|
||||
ttl?: number | {
|
||||
(sess: SessionData): number;
|
||||
};
|
||||
disableTTL?: boolean;
|
||||
disableTouch?: boolean;
|
||||
}
|
||||
declare class RedisStore extends Store {
|
||||
client: NormalizedRedisClient;
|
||||
prefix: string;
|
||||
scanCount: number;
|
||||
serializer: Serializer;
|
||||
ttl: number | {
|
||||
(sess: SessionData): number;
|
||||
};
|
||||
disableTTL: boolean;
|
||||
disableTouch: boolean;
|
||||
constructor(opts: RedisStoreOptions);
|
||||
private normalizeClient;
|
||||
get(sid: string, cb?: (_err?: unknown, _data?: any) => void): Promise<void>;
|
||||
set(sid: string, sess: SessionData, cb?: (_err?: unknown, _data?: any) => void): Promise<void>;
|
||||
touch(sid: string, sess: SessionData, cb?: (_err?: unknown, _data?: any) => void): Promise<void>;
|
||||
destroy(sid: string, cb?: (_err?: unknown, _data?: any) => void): Promise<void>;
|
||||
clear(cb?: (_err?: unknown, _data?: any) => void): Promise<void>;
|
||||
length(cb?: (_err?: unknown, _data?: any) => void): Promise<void>;
|
||||
ids(cb?: (_err?: unknown, _data?: any) => void): Promise<void>;
|
||||
all(cb?: (_err?: unknown, _data?: any) => void): Promise<void>;
|
||||
private _getTTL;
|
||||
private _getAllKeys;
|
||||
}
|
||||
export default RedisStore;
|
||||
177
node_modules/connect-redis/dist/esm/index.js
generated
vendored
Normal file
177
node_modules/connect-redis/dist/esm/index.js
generated
vendored
Normal file
@ -0,0 +1,177 @@
|
||||
import { Store } from "express-session";
|
||||
const noop = (_err, _data) => { };
|
||||
class RedisStore extends Store {
|
||||
constructor(opts) {
|
||||
super();
|
||||
this.prefix = opts.prefix == null ? "sess:" : opts.prefix;
|
||||
this.scanCount = opts.scanCount || 100;
|
||||
this.serializer = opts.serializer || JSON;
|
||||
this.ttl = opts.ttl || 86400; // One day in seconds.
|
||||
this.disableTTL = opts.disableTTL || false;
|
||||
this.disableTouch = opts.disableTouch || false;
|
||||
this.client = this.normalizeClient(opts.client);
|
||||
}
|
||||
// Create a redis and ioredis compatible client
|
||||
normalizeClient(client) {
|
||||
let isRedis = "scanIterator" in client;
|
||||
return {
|
||||
get: (key) => client.get(key),
|
||||
set: (key, val, ttl) => {
|
||||
if (ttl) {
|
||||
return isRedis
|
||||
? client.set(key, val, { EX: ttl })
|
||||
: client.set(key, val, "EX", ttl);
|
||||
}
|
||||
return client.set(key, val);
|
||||
},
|
||||
del: (key) => client.del(key),
|
||||
expire: (key, ttl) => client.expire(key, ttl),
|
||||
mget: (keys) => (isRedis ? client.mGet(keys) : client.mget(keys)),
|
||||
scanIterator: (match, count) => {
|
||||
if (isRedis)
|
||||
return client.scanIterator({ MATCH: match, COUNT: count });
|
||||
// ioredis impl.
|
||||
return (async function* () {
|
||||
let [c, xs] = await client.scan("0", "MATCH", match, "COUNT", count);
|
||||
for (let key of xs)
|
||||
yield key;
|
||||
while (c !== "0") {
|
||||
;
|
||||
[c, xs] = await client.scan(c, "MATCH", match, "COUNT", count);
|
||||
for (let key of xs)
|
||||
yield key;
|
||||
}
|
||||
})();
|
||||
},
|
||||
};
|
||||
}
|
||||
async get(sid, cb = noop) {
|
||||
let key = this.prefix + sid;
|
||||
try {
|
||||
let data = await this.client.get(key);
|
||||
if (!data)
|
||||
return cb();
|
||||
return cb(null, await this.serializer.parse(data));
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
async set(sid, sess, cb = noop) {
|
||||
let key = this.prefix + sid;
|
||||
let ttl = this._getTTL(sess);
|
||||
try {
|
||||
let val = this.serializer.stringify(sess);
|
||||
if (ttl > 0) {
|
||||
if (this.disableTTL)
|
||||
await this.client.set(key, val);
|
||||
else
|
||||
await this.client.set(key, val, ttl);
|
||||
return cb();
|
||||
}
|
||||
else {
|
||||
return this.destroy(sid, cb);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
async touch(sid, sess, cb = noop) {
|
||||
let key = this.prefix + sid;
|
||||
if (this.disableTouch || this.disableTTL)
|
||||
return cb();
|
||||
try {
|
||||
await this.client.expire(key, this._getTTL(sess));
|
||||
return cb();
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
async destroy(sid, cb = noop) {
|
||||
let key = this.prefix + sid;
|
||||
try {
|
||||
await this.client.del([key]);
|
||||
return cb();
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
async clear(cb = noop) {
|
||||
try {
|
||||
let keys = await this._getAllKeys();
|
||||
if (!keys.length)
|
||||
return cb();
|
||||
await this.client.del(keys);
|
||||
return cb();
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
async length(cb = noop) {
|
||||
try {
|
||||
let keys = await this._getAllKeys();
|
||||
return cb(null, keys.length);
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
async ids(cb = noop) {
|
||||
let len = this.prefix.length;
|
||||
try {
|
||||
let keys = await this._getAllKeys();
|
||||
return cb(null, keys.map((k) => k.substring(len)));
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
async all(cb = noop) {
|
||||
let len = this.prefix.length;
|
||||
try {
|
||||
let keys = await this._getAllKeys();
|
||||
if (keys.length === 0)
|
||||
return cb(null, []);
|
||||
let data = await this.client.mget(keys);
|
||||
let results = data.reduce((acc, raw, idx) => {
|
||||
if (!raw)
|
||||
return acc;
|
||||
let sess = this.serializer.parse(raw);
|
||||
sess.id = keys[idx].substring(len);
|
||||
acc.push(sess);
|
||||
return acc;
|
||||
}, []);
|
||||
return cb(null, results);
|
||||
}
|
||||
catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}
|
||||
_getTTL(sess) {
|
||||
if (typeof this.ttl === "function") {
|
||||
return this.ttl(sess);
|
||||
}
|
||||
let ttl;
|
||||
if (sess && sess.cookie && sess.cookie.expires) {
|
||||
let ms = Number(new Date(sess.cookie.expires)) - Date.now();
|
||||
ttl = Math.ceil(ms / 1000);
|
||||
}
|
||||
else {
|
||||
ttl = this.ttl;
|
||||
}
|
||||
return ttl;
|
||||
}
|
||||
async _getAllKeys() {
|
||||
let pattern = this.prefix + "*";
|
||||
let keys = [];
|
||||
for await (let key of this.client.scanIterator(pattern, this.scanCount)) {
|
||||
keys.push(key);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
export default RedisStore;
|
||||
1
node_modules/connect-redis/dist/esm/index_test.d.ts
generated
vendored
Normal file
1
node_modules/connect-redis/dist/esm/index_test.d.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export {};
|
||||
96
node_modules/connect-redis/dist/esm/index_test.js
generated
vendored
Normal file
96
node_modules/connect-redis/dist/esm/index_test.js
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
import test from "blue-tape";
|
||||
import { Cookie } from "express-session";
|
||||
import { Redis } from "ioredis";
|
||||
import { promisify } from "node:util";
|
||||
import { createClient } from "redis";
|
||||
import RedisStore from "./";
|
||||
import * as redisSrv from "./testdata/server";
|
||||
test("setup", async () => {
|
||||
await redisSrv.connect();
|
||||
});
|
||||
test("defaults", async (t) => {
|
||||
let client = createClient({ url: `redis://localhost:${redisSrv.port}` });
|
||||
await client.connect();
|
||||
let store = new RedisStore({ client });
|
||||
t.ok(store.client, "stores client");
|
||||
t.equal(store.prefix, "sess:", "defaults to sess:");
|
||||
t.equal(store.ttl, 86400, "defaults to one day");
|
||||
t.equal(store.scanCount, 100, "defaults SCAN count to 100");
|
||||
t.equal(store.serializer, JSON, "defaults to JSON serialization");
|
||||
t.equal(store.disableTouch, false, "defaults to having `touch` enabled");
|
||||
t.equal(store.disableTTL, false, "defaults to having `ttl` enabled");
|
||||
await client.disconnect();
|
||||
});
|
||||
test("redis", async (t) => {
|
||||
let client = createClient({ url: `redis://localhost:${redisSrv.port}` });
|
||||
await client.connect();
|
||||
let store = new RedisStore({ client });
|
||||
await lifecycleTest(store, client, t);
|
||||
await client.disconnect();
|
||||
});
|
||||
test("ioredis", async (t) => {
|
||||
let client = new Redis(`redis://localhost:${redisSrv.port}`);
|
||||
let store = new RedisStore({ client });
|
||||
await lifecycleTest(store, client, t);
|
||||
client.disconnect();
|
||||
});
|
||||
test("teardown", redisSrv.disconnect);
|
||||
async function lifecycleTest(store, client, t) {
|
||||
const P = (f) => promisify(f).bind(store);
|
||||
let res = await P(store.clear)();
|
||||
let sess = { foo: "bar" };
|
||||
await P(store.set)("123", sess);
|
||||
res = await P(store.get)("123");
|
||||
t.same(res, sess, "store.get");
|
||||
let ttl = await client.ttl("sess:123");
|
||||
t.ok(ttl >= 86399, "check one day ttl");
|
||||
ttl = 60;
|
||||
let expires = new Date(Date.now() + ttl * 1000).toISOString();
|
||||
await P(store.set)("456", { cookie: { expires } });
|
||||
ttl = await client.ttl("sess:456");
|
||||
t.ok(ttl <= 60, "check expires ttl");
|
||||
ttl = 90;
|
||||
let expires2 = new Date(Date.now() + ttl * 1000).toISOString();
|
||||
await P(store.touch)("456", { cookie: { expires: expires2 } });
|
||||
ttl = await client.ttl("sess:456");
|
||||
t.ok(ttl > 60, "check expires ttl touch");
|
||||
res = await P(store.length)();
|
||||
t.equal(res, 2, "stored two keys length");
|
||||
res = await P(store.ids)();
|
||||
res.sort();
|
||||
t.same(res, ["123", "456"], "stored two keys ids");
|
||||
res = await P(store.all)();
|
||||
res.sort((a, b) => (a.id > b.id ? 1 : -1));
|
||||
t.same(res, [
|
||||
{ id: "123", foo: "bar" },
|
||||
{ id: "456", cookie: { expires } },
|
||||
], "stored two keys data");
|
||||
await P(store.destroy)("456");
|
||||
res = await P(store.length)();
|
||||
t.equal(res, 1, "one key remains");
|
||||
res = await P(store.clear)();
|
||||
res = await P(store.length)();
|
||||
t.equal(res, 0, "no keys remain");
|
||||
let count = 1000;
|
||||
await load(store, count);
|
||||
res = await P(store.length)();
|
||||
t.equal(res, count, "bulk count");
|
||||
await P(store.clear)();
|
||||
res = await P(store.length)();
|
||||
t.equal(res, 0, "bulk clear");
|
||||
expires = new Date(Date.now() + ttl * 1000).toISOString(); // expires in the future
|
||||
res = await P(store.set)("789", { cookie: { expires } });
|
||||
res = await P(store.length)();
|
||||
t.equal(res, 1, "one key exists (session 789)");
|
||||
expires = new Date(Date.now() - ttl * 1000).toISOString(); // expires in the past
|
||||
await P(store.set)("789", { cookie: { expires } });
|
||||
res = await P(store.length)();
|
||||
t.equal(res, 0, "no key remains and that includes session 789");
|
||||
}
|
||||
async function load(store, count) {
|
||||
let cookie = new Cookie();
|
||||
for (let sid = 0; sid < count; sid++) {
|
||||
cookie.expires = new Date(Date.now() + 1000);
|
||||
await store.set("s" + sid, { cookie });
|
||||
}
|
||||
}
|
||||
1
node_modules/connect-redis/dist/esm/package.json
generated
vendored
Normal file
1
node_modules/connect-redis/dist/esm/package.json
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"type":"module"}
|
||||
Reference in New Issue
Block a user