123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- const AbstractClientStore = require('express-brute/lib/AbstractClientStore')
- const KnexStore = module.exports = function (options) {
- options = options || Object.create(null)
- AbstractClientStore.apply(this, arguments)
- this.options = Object.assign(Object.create(null), KnexStore.defaults, options)
- if (this.options.knex) {
- this.knex = this.options.knex
- } else {
- this.knex = require('knex')(KnexStore.defaultsKnex)
- }
- if (options.createTable === false) {
- this.ready = Promise.resolve()
- } else {
- this.ready = this.knex.schema.hasTable(this.options.tablename)
- .then((exists) => {
- if (exists) {
- return
- }
- return this.knex.schema.createTable(this.options.tablename, (table) => {
- table.string('key')
- table.bigInteger('firstRequest').nullable()
- table.bigInteger('lastRequest').nullable()
- table.bigInteger('lifetime').nullable()
- table.integer('count')
- })
- })
- }
- }
- KnexStore.prototype = Object.create(AbstractClientStore.prototype)
- KnexStore.prototype.set = async function (key, value, lifetime, callback) {
- try {
- lifetime = lifetime || 0
- await this.ready
- const resp = await this.knex.transaction((trx) => {
- return trx
- .select('*')
- .forUpdate()
- .from(this.options.tablename)
- .where('key', '=', key)
- .then((foundKeys) => {
- if (foundKeys.length === 0) {
- return trx.from(this.options.tablename)
- .insert({
- key: key,
- lifetime: new Date(Date.now() + lifetime * 1000).getTime(),
- lastRequest: new Date(value.lastRequest).getTime(),
- firstRequest: new Date(value.firstRequest).getTime(),
- count: value.count
- })
- } else {
- return trx(this.options.tablename)
- .where('key', '=', key)
- .update({
- lifetime: new Date(Date.now() + lifetime * 1000).getTime(),
- count: value.count,
- lastRequest: new Date(value.lastRequest).getTime()
- })
- }
- })
- })
- callback(null, resp)
- } catch (err) {
- callback(err, null)
- }
- }
- KnexStore.prototype.get = async function (key, callback) {
- try {
- await this.ready
- await this.clearExpired()
- const resp = await this.knex.select('*')
- .from(this.options.tablename)
- .where('key', '=', key)
- let o = null
- if (resp[0]) {
- o = {}
- o.lastRequest = new Date(resp[0].lastRequest)
- o.firstRequest = new Date(resp[0].firstRequest)
- o.count = resp[0].count
- }
- callback(null, o)
- } catch (err) {
- callback(err, null)
- }
- }
- KnexStore.prototype.reset = async function (key, callback) {
- try {
- await this.ready
- const resp = await this.knex(this.options.tablename)
- .where('key', '=', key)
- .del()
- callback(null, resp)
- } catch (err) {
- callback(err, null)
- }
- }
- KnexStore.prototype.increment = async function (key, lifetime, callback) {
- try {
- const result = await this.get(key)
- let resp = null
- if (result) {
- resp = await this.knex(this.options.tablename)
- .increment('count', 1)
- .where('key', '=', key)
- } else {
- resp = await this.knex(this.options.tablename)
- .insert({
- key: key,
- firstRequest: new Date().getTime(),
- lastRequest: new Date().getTime(),
- lifetime: new Date(Date.now() + lifetime * 1000).getTime(),
- count: 1
- })
- }
- callback(null, resp)
- } catch (err) {
- callback(err, null)
- }
- }
- KnexStore.prototype.clearExpired = async function (callback) {
- await this.ready
- return this.knex(this.options.tablename)
- .del()
- .where('lifetime', '<', new Date().getTime())
- }
- KnexStore.defaults = {
- tablename: 'brute',
- createTable: true
- }
- KnexStore.defaultsKnex = {
- client: 'sqlite3',
- // debug: true,
- connection: {
- filename: './brute-knex.sqlite'
- }
- }
|