Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

connect-session-knex

Package Overview
Dependencies
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

connect-session-knex - npm Package Compare versions

Comparing version 1.6.0 to 1.7.0

index.d.ts

673

index.js

@@ -1,15 +0,58 @@

"use strict";
var Bluebird = require("bluebird");
var resolve = Bluebird.resolve;
var util = require("util");
/* eslint-disable func-names */
var oneDay = 86400000;
const Bluebird = require('bluebird');
const knexFactory = require('knex');
module.exports = function(connect) {
/**
* Connect's Store.
const { resolve } = Bluebird;
const util = require('util');
const oneDay = 86400000;
/*
* Returns true if the specified knex instance is using sqlite3.
* @return {bool}
* @api private
*/
var Store = connect.session ? connect.session.Store : connect.Store;
function isSqlite3(knex) {
return knex.client.dialect === 'sqlite3';
}
/*
/*
* Returns true if the specified knex instance is using mysql.
* @return {bool}
* @api private
*/
function isMySQL(knex) {
return ['mysql', 'mariasql', 'mariadb'].indexOf(knex.client.dialect) > -1;
}
/*
* Returns true if the specified knex instance is using mssql.
* @return {bool}
* @api private
*/
function isMSSQL(knex) {
return ['mssql'].indexOf(knex.client.dialect) > -1;
}
/*
* Returns true if the specified knex instance is using postgresql.
* @return {bool}
* @api private
*/
function isPostgres(knex) {
return ['postgresql'].indexOf(knex.client.dialect) > -1;
}
/*
* Returns true if the specified knex instance is using oracle.
* @return {bool}
* @api private
*/
function isOracle(knex) {
return ['oracle', 'oracledb'].indexOf(knex.client.dialect) > -1;
}
/*
* Return datastore appropriate string of the current time

@@ -19,21 +62,21 @@ * @api private

*/
function dateAsISO(knex, aDate) {
var date;
if (aDate != null) {
date = new Date(aDate);
} else {
date = new Date();
}
if (isOracle(knex)) {
return date;
}
return isMySQL(knex) || isMSSQL(knex)
? date
.toISOString()
.slice(0, 19)
.replace("T", " ")
: date.toISOString();
function dateAsISO(knex, aDate) {
let date;
if (aDate != null) {
date = new Date(aDate);
} else {
date = new Date();
}
if (isOracle(knex)) {
return date;
}
return isMySQL(knex) || isMSSQL(knex)
? date
.toISOString()
.slice(0, 19)
.replace('T', ' ')
: date.toISOString();
}
/*
/*
* Return dialect-aware type name for timestamp

@@ -43,11 +86,12 @@ * @return {String} type name for timestamp

*/
function timestampTypeName(knex) {
return isMySQL(knex) || isMSSQL(knex)
? "DATETIME"
: isPostgres(knex)
? "timestamp with time zone"
: "timestamp";
}
function timestampTypeName(knex) {
// eslint-disable-next-line no-nested-ternary
return isMySQL(knex) || isMSSQL(knex)
? 'DATETIME'
: isPostgres(knex)
? 'timestamp with time zone'
: 'timestamp';
}
/*
/*
* Return condition for filtering by expiration

@@ -57,59 +101,14 @@ * @return {String} expired sql condition string

*/
function expiredCondition(knex) {
var condition = "CAST(? as " + timestampTypeName(knex) + ") <= expired";
if (isSqlite3(knex)) {
// sqlite3 date condition is a special case.
condition = "datetime(?) <= datetime(expired)";
} else if (isOracle(knex)) {
condition = "CAST(? as " + timestampTypeName(knex) + ') <= "expired"';
}
return condition;
function expiredCondition(knex) {
let condition = `CAST(? as ${timestampTypeName(knex)}) <= expired`;
if (isSqlite3(knex)) {
// sqlite3 date condition is a special case.
condition = 'datetime(?) <= datetime(expired)';
} else if (isOracle(knex)) {
condition = `CAST(? as ${timestampTypeName(knex)}) <= "expired"`;
}
return condition;
}
/*
* Returns true if the specified knex instance is using sqlite3.
* @return {bool}
* @api private
*/
function isSqlite3(knex) {
return knex.client.dialect === "sqlite3";
}
/*
* Returns true if the specified knex instance is using mysql.
* @return {bool}
* @api private
*/
function isMySQL(knex) {
return ["mysql", "mariasql", "mariadb"].indexOf(knex.client.dialect) > -1;
}
/*
* Returns true if the specified knex instance is using mssql.
* @return {bool}
* @api private
*/
function isMSSQL(knex) {
return ["mssql"].indexOf(knex.client.dialect) > -1;
}
/*
* Returns true if the specified knex instance is using postgresql.
* @return {bool}
* @api private
*/
function isPostgres(knex) {
return ["postgresql"].indexOf(knex.client.dialect) > -1;
}
/*
* Returns true if the specified knex instance is using oracle.
* @return {bool}
* @api private
*/
function isOracle(knex) {
return ["oracle", "oracledb"].indexOf(knex.client.dialect) > -1;
}
/*
/*
* Returns PostgreSQL fast upsert query.

@@ -119,47 +118,47 @@ * @return {string}

*/
function getPostgresFastQuery(tablename, sidfieldname) {
return (
"with new_values (" +
sidfieldname +
", expired, sess) as (" +
" values (?, ?::timestamp with time zone, ?::json)" +
"), " +
"upsert as " +
"( " +
" update " +
tablename +
" cs set " +
" " +
sidfieldname +
" = nv." +
sidfieldname +
", " +
" expired = nv.expired, " +
" sess = nv.sess " +
" from new_values nv " +
" where cs." +
sidfieldname +
" = nv." +
sidfieldname +
" " +
" returning cs.* " +
")" +
"insert into " +
tablename +
" (" +
sidfieldname +
", expired, sess) " +
"select " +
sidfieldname +
", expired, sess " +
"from new_values " +
"where not exists (select 1 from upsert up where up." +
sidfieldname +
" = new_values." +
sidfieldname +
")"
);
}
function getPostgresFastQuery(tablename, sidfieldname) {
return (
`with new_values (${
sidfieldname
}, expired, sess) as (`
+ ' values (?, ?::timestamp with time zone, ?::json)'
+ '), '
+ 'upsert as '
+ '( '
+ ` update ${
tablename
} cs set `
+ ` ${
sidfieldname
} = nv.${
sidfieldname
}, `
+ ' expired = nv.expired, '
+ ' sess = nv.sess '
+ ' from new_values nv '
+ ` where cs.${
sidfieldname
} = nv.${
sidfieldname
} `
+ ' returning cs.* '
+ ')'
+ `insert into ${
tablename
} (${
sidfieldname
}, expired, sess) `
+ `select ${
sidfieldname
}, expired, sess `
+ 'from new_values '
+ `where not exists (select 1 from upsert up where up.${
sidfieldname
} = new_values.${
sidfieldname
})`
);
}
/*
/*
* Returns SQLite fast upsert query.

@@ -169,13 +168,13 @@ * @return {string}

*/
function getSqliteFastQuery(tablename, sidfieldname) {
return (
"insert or replace into " +
tablename +
" (" +
sidfieldname +
", expired, sess) values (?, ?, ?);"
);
}
function getSqliteFastQuery(tablename, sidfieldname) {
return (
`insert or replace into ${
tablename
} (${
sidfieldname
}, expired, sess) values (?, ?, ?);`
);
}
/*
/*
* Returns MySQL fast upsert query.

@@ -185,13 +184,13 @@ * @return {string}

*/
function getMysqlFastQuery(tablename, sidfieldname) {
return (
"insert into " +
tablename +
" (" +
sidfieldname +
", expired, sess) values (?, ?, ?) on duplicate key update expired=values(expired), sess=values(sess);"
);
}
function getMysqlFastQuery(tablename, sidfieldname) {
return (
`insert into ${
tablename
} (${
sidfieldname
}, expired, sess) values (?, ?, ?) on duplicate key update expired=values(expired), sess=values(sess);`
);
}
/*
/*
* Returns MSSQL fast upsert query.

@@ -201,28 +200,28 @@ * @return {string}

*/
function getMssqlFastQuery(tablename, sidfieldname) {
return (
"merge " +
tablename +
" as T " +
"using (values (?, ?, ?)) as S (" +
sidfieldname +
", expired, sess) " +
"on (T." +
sidfieldname +
" = S." +
sidfieldname +
") " +
"when matched then " +
"update set expired = S.expired, sess = S.sess " +
"when not matched by target then " +
"insert (" +
sidfieldname +
", expired, sess) values (S." +
sidfieldname +
", S.expired, S.sess) " +
"output inserted.*;"
);
}
function getMssqlFastQuery(tablename, sidfieldname) {
return (
`merge ${
tablename
} as T `
+ `using (values (?, ?, ?)) as S (${
sidfieldname
}, expired, sess) `
+ `on (T.${
sidfieldname
} = S.${
sidfieldname
}) `
+ 'when matched then '
+ 'update set expired = S.expired, sess = S.sess '
+ 'when not matched by target then '
+ `insert (${
sidfieldname
}, expired, sess) values (S.${
sidfieldname
}, S.expired, S.sess) `
+ 'output inserted.*;'
);
}
/*
/*
* Remove expired sessions from database.

@@ -233,29 +232,34 @@ * @param {Object} store

*/
function dbCleanup(store, interval) {
return store.ready
.then(function() {
var condition =
"expired < CAST(? as " + timestampTypeName(store.knex) + ")";
if (isSqlite3(store.knex)) {
// sqlite3 date condition is a special case.
condition = "datetime(expired) < datetime(?)";
} else if (isOracle(store.knex)) {
condition =
'"expired" < CAST(? as ' + timestampTypeName(store.knex) + ")";
}
return store
.knex(store.tablename)
.del()
.whereRaw(condition, dateAsISO(store.knex));
})
.finally(function() {
KnexStore.nextDbCleanup = setTimeout(
dbCleanup,
interval,
store,
interval
).unref();
});
}
function dbCleanup(store, interval, KnexStore) {
return store.ready
.then(() => {
let condition = `expired < CAST(? as ${timestampTypeName(store.knex)})`;
if (isSqlite3(store.knex)) {
// sqlite3 date condition is a special case.
condition = 'datetime(expired) < datetime(?)';
} else if (isOracle(store.knex)) {
condition = `"expired" < CAST(? as ${timestampTypeName(store.knex)})`;
}
return store
.knex(store.tablename)
.del()
.whereRaw(condition, dateAsISO(store.knex));
})
.finally(() => {
// eslint-disable-next-line no-param-reassign
KnexStore.nextDbCleanup = setTimeout(
dbCleanup,
interval,
store,
interval,
).unref();
});
}
module.exports = function (connect) {
/**
* Connect's Store.
*/
const Store = connect.session ? connect.session.Store : connect.Store;
/*

@@ -267,6 +271,5 @@ * Initialize KnexStore with the given options.

*/
function KnexStore(options) {
var self = this;
function KnexStore(options = {}) {
const self = this;
options = options || {};
Store.call(self, options);

@@ -276,18 +279,18 @@

// Time to run clear expired function.
// eslint-disable-next-line no-param-reassign
options.clearInterval = 60000;
}
self.createtable = options.hasOwnProperty("createtable")
self.createtable = Object.prototype.hasOwnProperty.call(options, 'creatable')
? options.createtable
: true;
self.tablename = options.tablename || "sessions";
self.sidfieldname = options.sidfieldname || "sid";
self.knex =
options.knex ||
require("knex")({
client: "sqlite3",
self.tablename = options.tablename || 'sessions';
self.sidfieldname = options.sidfieldname || 'sid';
self.knex = options.knex
|| knexFactory({
client: 'sqlite3',
// debug: true,
connection: {
filename: "connect-session-knex.sqlite"
}
filename: 'connect-session-knex.sqlite',
},
});

@@ -297,14 +300,14 @@

.hasTable(self.tablename)
.then(function(exists) {
.then((exists) => {
if (!exists && self.createtable) {
return self.knex.schema.createTable(self.tablename, function(table) {
return self.knex.schema.createTable(self.tablename, (table) => {
table.string(self.sidfieldname).primary();
if (isMSSQL(self.knex)) {
table.text("sess").notNullable();
table.text('sess').notNullable();
} else {
table.json("sess").notNullable();
table.json('sess').notNullable();
}
if (isMySQL(self.knex) || isMSSQL(self.knex)) {
table
.dateTime("expired")
.dateTime('expired')
.notNullable()

@@ -314,3 +317,3 @@ .index();

table
.timestamp("expired")
.timestamp('expired')
.notNullable()

@@ -323,5 +326,5 @@ .index();

})
.then(function(exists) {
.then((exists) => {
if (exists) {
dbCleanup(self, options.clearInterval);
dbCleanup(self, options.clearInterval, KnexStore);
}

@@ -342,16 +345,16 @@ return null;

*/
KnexStore.prototype.get = function(sid, fn) {
var self = this;
return self.ready.then(function() {
var condition = expiredCondition(self.knex);
KnexStore.prototype.get = function (sid, fn) {
const self = this;
return self.ready.then(() => {
const condition = expiredCondition(self.knex);
return resolve(self.knex
.select("sess")
.select('sess')
.from(self.tablename)
.where(self.sidfieldname, "=", sid)
.where(self.sidfieldname, '=', sid)
.andWhereRaw(condition, dateAsISO(self.knex))
.then(function(response) {
var ret;
.then((response) => {
let ret;
if (response[0]) {
ret = response[0].sess;
if (typeof ret === "string") {
if (typeof ret === 'string') {
ret = JSON.parse(ret);

@@ -374,90 +377,74 @@ }

*/
KnexStore.prototype.set = function(sid, sess, fn) {
var self = this;
var maxAge = sess.cookie.maxAge;
var now = new Date().getTime();
var expired = maxAge ? now + maxAge : now + oneDay;
sess = JSON.stringify(sess);
KnexStore.prototype.set = function (sid, sessObject, fn) {
const self = this;
const { maxAge } = sessObject.cookie;
const now = new Date().getTime();
const expired = maxAge ? now + maxAge : now + oneDay;
const sess = JSON.stringify(sessObject);
var dbDate = dateAsISO(self.knex, expired);
const dbDate = dateAsISO(self.knex, expired);
if (isSqlite3(self.knex)) {
// sqlite optimized query
return self.ready.then(function() {
return resolve(self.knex
.raw(getSqliteFastQuery(self.tablename, self.sidfieldname), [
sid,
dbDate,
sess
])
.then(function(result) {
return [1];
}))
.asCallback(fn);
});
} else if (
isPostgres(self.knex) &&
parseFloat(self.knex.client.version) >= 9.2
return self.ready.then(() => resolve(self.knex
.raw(getSqliteFastQuery(self.tablename, self.sidfieldname), [
sid,
dbDate,
sess,
])
.then(() => [1]))
.asCallback(fn));
} if (
isPostgres(self.knex)
&& parseFloat(self.knex.client.version) >= 9.2
) {
// postgresql optimized query
return self.ready.then(function() {
return resolve(self.knex
.raw(getPostgresFastQuery(self.tablename, self.sidfieldname), [
sid,
dbDate,
sess
]))
.asCallback(fn);
});
} else if (isMySQL(self.knex)) {
return self.ready.then(() => resolve(self.knex
.raw(getPostgresFastQuery(self.tablename, self.sidfieldname), [
sid,
dbDate,
sess,
]))
.asCallback(fn));
} if (isMySQL(self.knex)) {
// mysql/mariaDB optimized query
return self.ready.then(function() {
return resolve(self.knex
.raw(getMysqlFastQuery(self.tablename, self.sidfieldname), [
sid,
dbDate,
sess
]))
.asCallback(fn);
});
} else if (isMSSQL(self.knex)) {
return self.ready.then(() => resolve(self.knex
.raw(getMysqlFastQuery(self.tablename, self.sidfieldname), [
sid,
dbDate,
sess,
]))
.asCallback(fn));
} if (isMSSQL(self.knex)) {
// mssql optimized query
return self.ready.then(function() {
return resolve(self.knex
.raw(getMssqlFastQuery(self.tablename, self.sidfieldname), [
sid,
dbDate,
sess
]))
.asCallback(fn);
});
} else {
return self.ready.then(function() {
return resolve(self.knex
.transaction(function(trx) {
return trx
.select("*")
.forUpdate()
.from(self.tablename)
.where(self.sidfieldname, "=", sid)
.then(function(foundKeys) {
if (foundKeys.length === 0) {
return trx.from(self.tablename).insert({
[self.sidfieldname]: sid,
expired: dbDate,
sess: sess
});
} else {
return trx(self.tablename)
.where(self.sidfieldname, "=", sid)
.update({
expired: dbDate,
sess: sess
});
}
});
}))
.asCallback(fn);
});
return self.ready.then(() => resolve(self.knex
.raw(getMssqlFastQuery(self.tablename, self.sidfieldname), [
sid,
dbDate,
sess,
]))
.asCallback(fn));
}
return self.ready.then(() => resolve(self.knex
.transaction((trx) => trx
.select('*')
.forUpdate()
.from(self.tablename)
.where(self.sidfieldname, '=', sid)
.then((foundKeys) => {
if (foundKeys.length === 0) {
return trx.from(self.tablename).insert({
[self.sidfieldname]: sid,
expired: dbDate,
sess,
});
}
return trx(self.tablename)
.where(self.sidfieldname, '=', sid)
.update({
expired: dbDate,
sess,
});
})))
.asCallback(fn));
};

@@ -473,11 +460,11 @@

*/
KnexStore.prototype.touch = function(sid, sess, fn) {
KnexStore.prototype.touch = function (sid, sess, fn) {
if (sess && sess.cookie && sess.cookie.expires) {
var condition = expiredCondition(this.knex);
const condition = expiredCondition(this.knex);
return resolve(this.knex(this.tablename)
.where(this.sidfieldname, "=", sid)
.where(this.sidfieldname, '=', sid)
.andWhereRaw(condition, dateAsISO(this.knex))
.update({
expired: dateAsISO(this.knex, sess.cookie.expires)
expired: dateAsISO(this.knex, sess.cookie.expires),
}))

@@ -488,2 +475,3 @@ .asCallback(fn);

fn();
return null;
};

@@ -497,11 +485,9 @@

*/
KnexStore.prototype.destroy = function(sid, fn) {
var self = this;
return self.ready.then(function() {
return resolve(self.knex
.del()
.from(self.tablename)
.where(self.sidfieldname, "=", sid))
.asCallback(fn);
});
KnexStore.prototype.destroy = function (sid, fn) {
const self = this;
return self.ready.then(() => resolve(self.knex
.del()
.from(self.tablename)
.where(self.sidfieldname, '=', sid))
.asCallback(fn));
};

@@ -515,13 +501,10 @@

*/
KnexStore.prototype.length = function(fn) {
var self = this;
return self.ready.then(function() {
return resolve(self.knex
.count(self.sidfieldname + " as count")
.from(self.tablename)
.then(function(response) {
return response[0].count | 0;
}))
.asCallback(fn);
});
KnexStore.prototype.length = function (fn) {
const self = this;
return self.ready.then(() => resolve(self.knex
.count(`${self.sidfieldname} as count`)
.from(self.tablename)
// eslint-disable-next-line no-bitwise
.then((response) => response[0].count | 0))
.asCallback(fn));
};

@@ -535,14 +518,12 @@

*/
KnexStore.prototype.clear = function(fn) {
var self = this;
return self.ready.then(function() {
return resolve(self.knex
.del()
.from(self.tablename))
.asCallback(fn);
});
KnexStore.prototype.clear = function (fn) {
const self = this;
return self.ready.then(() => resolve(self.knex
.del()
.from(self.tablename))
.asCallback(fn));
};
/* stop the dbCleanupTimeout */
KnexStore.prototype.stopDbCleanup = function() {
KnexStore.prototype.stopDbCleanup = function () {
if (KnexStore.nextDbCleanup) {

@@ -549,0 +530,0 @@ clearTimeout(KnexStore.nextDbCleanup);

{
"name": "connect-session-knex",
"description": "A knex.js session store for Express and Connect",
"version": "1.6.0",
"version": "1.7.0",
"main": "index.js",

@@ -10,3 +10,4 @@ "engines": {

"files": [
"index.js"
"index.js",
"index.d.ts"
],

@@ -26,8 +27,11 @@ "repository": {

"dependencies": {
"bluebird": "^3.7.2"
"bluebird": "^3.7.2",
"knex": "^0.21.1"
},
"devDependencies": {
"eslint": "^7.0.0",
"eslint-config-airbnb-base": "^14.1.0",
"eslint-plugin-import": "^2.20.2",
"express": "^4.17.1",
"express-session": "^1.17.0",
"knex": "^0.20.11",
"express-session": "^1.17.1",
"mysql": "^2.18.1",

@@ -34,0 +38,0 @@ "pg": "^7.18.2",

@@ -78,1 +78,63 @@ # Connect Session Knex

[io-url]: https://iojs.org
## Testing
Install Postgresql
Instructions for Ubuntu after intalling the db:
```bash
sudo -u postgres psql
```
```sql
CREATE DATABASE travis_ci_test OWNER postgres;
```
```sql
GRANT all privileges ON DATABASE travis_ci_test TO postgres;
```
```sql
ALTER USER postgres WITH PASSWORD 'postgres';
```
```sql
\q
```
Install Mysql
Instructions for Ubuntu after installing the db:
```bash
sudo mysql -u root
```
```sql
create user 'travis' identified by 'travis';
```
```sql
ALTER USER 'travis'@'localhost' IDENTIFIED BY 'travis';
```
```sql
create database travis_ci_test;
```
```sql
grant all on travis_ci_test.* to 'travis';
```
```sql
\q
```
```bash
sudo service mysql restart
```
Make sure both the MySQL and Postgres services are running
```bash
npm run test
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc