Skip to content
Merged
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
21 changes: 0 additions & 21 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ services:
ports:
- "3000:3000"
environment:
- REDIS_URI=redis://redis:6379
- BASE_URL=http://localhost:3000
- NODE_ENV=development
- APOS_MONGODB_URI=mongodb://mongodb:27017/apostrophe
Expand All @@ -61,7 +60,6 @@ services:
depends_on:
- mongodb
- localstack
- redis
restart: unless-stopped
healthcheck:
test:
Expand Down Expand Up @@ -118,25 +116,6 @@ services:
networks:
- proxynet

# Redis for caching (optional, but recommended for production)
redis:
image: redis:7-alpine
container_name: apostrophe-redis
ports:
- "6379:6379"
volumes:
- redis_data:/data
command: redis-server --appendonly yes
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
networks:
- proxynet

volumes:
mongodb_data:
redis_data:
localstack_data:
33 changes: 23 additions & 10 deletions website/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,29 @@ const apostrophe = require('apostrophe');
require('dotenv').config({ path: '../.env' });
const { getEnv } = require('./utils/env');

/**
* Creates the Apostrophe CMS configuration object.
* Configures session (with optional Redis store), base URL, CORS, and all
* modules (express, template, widgets, pieces, etc.).
*
* @returns {object} Apostrophe configuration with shortName, baseUrl, and modules.
*/
function createAposConfig() {
const redisUri = process.env.REDIS_URI;

const sessionConfig = {
secret: getEnv('SESSION_SECRET'),
};

if (redisUri) {
sessionConfig.store = {
connect: require('connect-redis'),
options: {
url: redisUri,
},
};
}
Comment on lines +13 to +26
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check the current state of the code files mentioned
head -30 website/app.js

Repository: speedandfunction/website

Length of output: 882


🏁 Script executed:

# Check the test file to see what it expects
sed -n '60,75p' website/app.test.js

Repository: speedandfunction/website

Length of output: 485


🏁 Script executed:

# Find package.json to check `@apostrophecms/express` version
find . -name "package.json" -type f | head -5

Repository: speedandfunction/website

Length of output: 117


🏁 Script executed:

# Search for `@apostrophecms/express` in dependencies
rg "@apostrophecms/express" --type json

Repository: speedandfunction/website

Length of output: 50


🏁 Script executed:

cat website/package.json | grep -A 5 "@apostrophecms"

Repository: speedandfunction/website

Length of output: 732


🏁 Script executed:

# Search for any documentation or comments about session behavior in the codebase
rg "session" -t js -i | head -20

Repository: speedandfunction/website

Length of output: 1211


🏁 Script executed:

# Look for the full test context to understand expectations
sed -n '50,80p' website/app.test.js

Repository: speedandfunction/website

Length of output: 926


🏁 Script executed:

# Search for any configuration or setup that might define session defaults
rg "MemoryStore|sessionConfig" -t js -B 2 -A 2

Repository: speedandfunction/website

Length of output: 639


🏁 Script executed:

# Check if there's an express module configuration
cat website/modules/@apostrophecms/express/index.js

Repository: speedandfunction/website

Length of output: 280


🏁 Script executed:

# Look for any documentation files or comments about session handling
find . -type f \( -name "*.md" -o -name "*.txt" \) | xargs rg -l "session" 2>/dev/null | head -5

Repository: speedandfunction/website

Length of output: 50


🏁 Script executed:

# Check if there are any other session-related configurations
rg "store.*:" website/app.js -B 3 -A 3

Repository: speedandfunction/website

Length of output: 50


🏁 Script executed:

# Search for any comments or documentation about the default session behavior
rg "MongoDB|MemoryStore|session.*default" -i

Repository: speedandfunction/website

Length of output: 5942


🏁 Script executed:

# Check if there's any initialization code that sets up session handling
rg "express.*session|connect.*session" -i -t js

Repository: speedandfunction/website

Length of output: 338


🏁 Script executed:

# Look at the full createAposConfig function to see where sessionConfig is used
sed -n '13,100p' website/app.js | cat -n

Repository: speedandfunction/website

Length of output: 2930


🏁 Script executed:

# Search for any references to how `@apostrophecms/express` handles session
rg "@apostrophecms/express" -A 5 -B 5 website/app.js

Repository: speedandfunction/website

Length of output: 348


🌐 Web query:

@apostrophecms/express session store default MongoDB

💡 Result:

@apostrophecms/express uses a MongoDB-backed session store by default—you don’t need to install/configure an additional store just to persist sessions (it stores them in MongoDB, reducing reliance on the in-memory default of express-session). It also notes this uses a “3.x mongo store” and its default session options are tuned accordingly (e.g., saveUninitialized: false, resave: false). Sessions are stored in the aposSessions MongoDB collection. [1]

If you want something else (e.g., Redis), you can configure session.store and provide the store package name + options (and install that package), e.g. connect-redis. [1]

Source

  1. ApostropheCMS docs: @apostrophecms/express module reference (session defaults + MongoDB session store). [1]

🌐 Web query:

apostrophecms session configuration store undefined default behavior

💡 Result:

If you leave @apostrophecms/express session store unset/undefined, Apostrophe’s default behavior is to store sessions in MongoDB (so you don’t need Redis or another external session store just to get sessions working). [1], [2]

In Apostrophe 3, the session option object is passed through to express-session, with Apostrophe applying defaults like saveUninitialized: false, resave: false, rolling: true, etc.; you only need to provide session.store if you want to override the default MongoDB-backed store (e.g., Redis). [1]

Sources:
[1] Apostrophe 3 docs — @apostrophecms/express module (session option and default MongoDB sessions)
[2] Apostrophe 2 docs — “Storing sessions in Redis and other session stores” (default MongoDB sessions)


🏁 Script executed:

# Check if there's any documentation in the node_modules or comments
rg "session.*store.*MongoDB|default.*session" -i -B 2 -A 2

Repository: speedandfunction/website

Length of output: 50


🏁 Script executed:

# Let's verify the exact test expectation and name one more time
sed -n '64,72p' website/app.test.js

Repository: speedandfunction/website

Length of output: 326


🏁 Script executed:

# Check if there are any comments in the codebase about the session store behavior
rg "session.*store" -B 3 -A 3 website/app.js | head -30

Repository: speedandfunction/website

Length of output: 477


🏁 Script executed:

# Check if there's an explicit MemoryStore or any other session store setup
rg "MemoryStore|connect-mongo|session.*default" -t js

Repository: speedandfunction/website

Length of output: 50


🏁 Script executed:

# Look at the apostrophe version to confirm it's version 4.x (modern)
grep '"apostrophe"' website/package.json

Repository: speedandfunction/website

Length of output: 96


The test name and code comment are misleading—the fallback is MongoDB-backed, not in-memory.

When session.store is omitted, @apostrophecms/express does not implement an in-memory store. According to Apostrophe's official documentation, it defaults to a MongoDB-backed session store. The test at lines 64–72 is titled "uses in-memory session store when REDIS_URI is not set" but will actually use MongoDB by default, making the test name and assertion misleading. Either configure an explicit in-memory session store (e.g., connect-memorystore) if that is the intended fallback, or update the test name and PR description to reflect the actual MongoDB default behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/app.js` around lines 13 - 26, The test and comment are wrong because
when REDIS_URI is absent Apostrophe defaults to a MongoDB-backed session store;
fix by either making the app explicitly use an in-memory store or by updating
the test to expect MongoDB. To explicitly use an in-memory fallback, in the
sessionConfig block check when redisUri is falsy and set sessionConfig.store to
an in-memory implementation (e.g., require('connect-memorystore')(session) or
another memory store) with appropriate options; alternatively update the test
name and assertions to reflect that omitting sessionConfig.store results in the
default MongoDB-backed store. Reference the symbols redisUri, sessionConfig, and
sessionConfig.store (and the connect-redis usage) when making the change.


return {
shortName: 'apostrophe-site',
baseUrl: process.env.BASE_URL || 'https://speedandfunction.com',
Expand All @@ -13,16 +35,7 @@ function createAposConfig() {
'@apostrophecms/security-headers': {},
'@apostrophecms/express': {
options: {
session: {
// If using Redis (recommended for production)
secret: getEnv('SESSION_SECRET'),
store: {
connect: require('connect-redis'),
options: {
url: getEnv('REDIS_URI'),
},
},
},
session: sessionConfig,
csrf: {
cookie: {
key: '_csrf',
Expand Down
13 changes: 13 additions & 0 deletions website/app.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/**
* Tests for website/app.js: createAposConfig and module exports.
*/
const { createAposConfig } = require('./app');
const mockConnectRedis = jest.fn();
jest.mock('connect-redis', () => mockConnectRedis);
Expand Down Expand Up @@ -58,6 +61,16 @@ describe('createAposConfig', () => {
});
});

test('uses in-memory session store when REDIS_URI is not set', () => {
delete process.env.REDIS_URI;

const config = createAposConfig();

expect(
config.modules['@apostrophecms/express'].options.session.store,
).toBeUndefined();
});

// Define module categories for verification - moved outside the test
const moduleCategories = [
{
Expand Down
Loading