Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions ghost/core/core/server/web/shared/middleware/api/spam-prevention.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const handleStoreError = (err) => {
// Defaults to 50 attempts per hour and locks the endpoint for an hour
const globalBlock = () => {
const ExpressBrute = require('express-brute');
const BruteKnex = require('brute-knex');
const BruteKnex = require('@tryghost/brute-knex');
const db = require('../../../../data/db');

store = store || new BruteKnex({
Expand Down Expand Up @@ -121,7 +121,7 @@ const globalBlock = () => {

const globalReset = () => {
const ExpressBrute = require('express-brute');
const BruteKnex = require('brute-knex');
const BruteKnex = require('@tryghost/brute-knex');
const db = require('../../../../data/db');

store = store || new BruteKnex({
Expand Down Expand Up @@ -150,7 +150,7 @@ const globalReset = () => {

const webmentionsBlock = () => {
const ExpressBrute = require('express-brute');
const BruteKnex = require('brute-knex');
const BruteKnex = require('@tryghost/brute-knex');
const db = require('../../../../data/db');

store = store || new BruteKnex({
Expand All @@ -176,7 +176,7 @@ const webmentionsBlock = () => {

const emailPreviewBlock = () => {
const ExpressBrute = require('express-brute');
const BruteKnex = require('brute-knex');
const BruteKnex = require('@tryghost/brute-knex');
const db = require('../../../../data/db');

store = store || new BruteKnex({
Expand All @@ -202,7 +202,7 @@ const emailPreviewBlock = () => {

const membersAuth = () => {
const ExpressBrute = require('express-brute');
const BruteKnex = require('brute-knex');
const BruteKnex = require('@tryghost/brute-knex');
const db = require('../../../../data/db');

store = store || new BruteKnex({
Expand Down Expand Up @@ -235,7 +235,7 @@ const membersAuth = () => {
*/
const membersAuthEnumeration = () => {
const ExpressBrute = require('express-brute');
const BruteKnex = require('brute-knex');
const BruteKnex = require('@tryghost/brute-knex');
const db = require('../../../../data/db');

store = store || new BruteKnex({
Expand Down Expand Up @@ -265,7 +265,7 @@ const membersAuthEnumeration = () => {

const checkoutSessionGlobal = () => {
const ExpressBrute = require('express-brute');
const BruteKnex = require('brute-knex');
const BruteKnex = require('@tryghost/brute-knex');
const db = require('../../../../data/db');

store = store || new BruteKnex({
Expand Down Expand Up @@ -295,7 +295,7 @@ const checkoutSessionGlobal = () => {

const checkoutSessionEmail = () => {
const ExpressBrute = require('express-brute');
const BruteKnex = require('brute-knex');
const BruteKnex = require('@tryghost/brute-knex');
const db = require('../../../../data/db');

store = store || new BruteKnex({
Expand Down Expand Up @@ -325,7 +325,7 @@ const checkoutSessionEmail = () => {

const otcVerificationEnumeration = () => {
const ExpressBrute = require('express-brute');
const BruteKnex = require('brute-knex');
const BruteKnex = require('@tryghost/brute-knex');
const db = require('../../../../data/db');

store = store || new BruteKnex({
Expand Down Expand Up @@ -356,7 +356,7 @@ const otcVerificationEnumeration = () => {

const otcVerification = () => {
const ExpressBrute = require('express-brute');
const BruteKnex = require('brute-knex');
const BruteKnex = require('@tryghost/brute-knex');
const db = require('../../../../data/db');

store = store || new BruteKnex({
Expand Down Expand Up @@ -391,7 +391,7 @@ const otcVerification = () => {
// Default value of 5 attempts per user+IP pair
const userLogin = () => {
const ExpressBrute = require('express-brute');
const BruteKnex = require('brute-knex');
const BruteKnex = require('@tryghost/brute-knex');
const db = require('../../../../data/db');

store = store || new BruteKnex({
Expand Down Expand Up @@ -422,7 +422,7 @@ const userLogin = () => {
// The endpoint is then locked for an hour
const userReset = function userReset() {
const ExpressBrute = require('express-brute');
const BruteKnex = require('brute-knex');
const BruteKnex = require('@tryghost/brute-knex');
const db = require('../../../../data/db');

store = store || new BruteKnex({
Expand Down Expand Up @@ -451,7 +451,7 @@ const userReset = function userReset() {

const userVerification = function userVerification() {
const ExpressBrute = require('express-brute');
const BruteKnex = require('brute-knex');
const BruteKnex = require('@tryghost/brute-knex');
const db = require('../../../../data/db');

store = store || new BruteKnex({
Expand All @@ -477,7 +477,7 @@ const userVerification = function userVerification() {

const sendVerificationCode = function sendVerificationCode() {
const ExpressBrute = require('express-brute');
const BruteKnex = require('brute-knex');
const BruteKnex = require('@tryghost/brute-knex');
const db = require('../../../../data/db');

store = store || new BruteKnex({
Expand Down Expand Up @@ -505,7 +505,7 @@ const sendVerificationCode = function sendVerificationCode() {
// The endpoint is then locked for an hour
const privateBlog = () => {
const ExpressBrute = require('express-brute');
const BruteKnex = require('brute-knex');
const BruteKnex = require('@tryghost/brute-knex');
const db = require('../../../../data/db');

store = store || new BruteKnex({
Expand Down
2 changes: 1 addition & 1 deletion ghost/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"@tryghost/admin-api-schema": "4.7.5",
"@tryghost/api-framework": "catalog:",
"@tryghost/bookshelf-plugins": "2.2.4",
"@tryghost/brute-knex": "catalog:",
"@tryghost/color-utils": "catalog:",
"@tryghost/config-url-helpers": "1.0.26",
"@tryghost/custom-fonts": "catalog:",
Expand Down Expand Up @@ -140,7 +141,6 @@
"body-parser": "1.20.5",
"bookshelf": "1.2.0",
"bookshelf-relations": "2.8.0",
"brute-knex": "4.0.1",
"bson-objectid": "catalog:",
"cache-manager": "4.1.0",
"cache-manager-ioredis": "2.1.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const assert = require('node:assert/strict');
const BruteKnex = require('@tryghost/brute-knex');

const db = require('../../../../../../core/server/data/db');
const dbUtils = require('../../../../../utils/db-utils');

describe('BruteKnex store', function () {
const key = 'brute-knex-store-test';

beforeAll(async function () {
await dbUtils.reset();
});

beforeEach(async function () {
await dbUtils.truncate('brute');
});

afterEach(async function () {
await dbUtils.truncate('brute');
});

it('stores, increments and resets rate limit entries through Ghost\'s brute table', async function () {
const store = new BruteKnex({
tablename: 'brute',
createTable: false,
knex: db.knex
});

await store.ready;

const firstRequest = new Date('2026-01-01T00:00:00.000Z');
const lastRequest = new Date('2026-01-01T00:01:00.000Z');

await store.set(key, {
firstRequest,
lastRequest,
count: 3
}, 60);

const row = await db.knex('brute').where({key}).first();
assert.equal(row.key, key);
assert.equal(Number(row.count), 3);

const storedValue = await store.get(key);
assert.equal(storedValue.count, 3);
assert.equal(storedValue.firstRequest.getTime(), firstRequest.getTime());
assert.equal(storedValue.lastRequest.getTime(), lastRequest.getTime());

await store.increment(key, 60);

const incrementedValue = await store.get(key);
assert.equal(incrementedValue.count, 4);

await new Promise((resolve, reject) => {
store.reset(key, (err) => {
if (err) {
reject(err);
return;
}

resolve();
});
});

assert.equal(await store.get(key), null);
assert.equal(await db.knex('brute').where({key}).first(), undefined);
});
});
Loading
Loading