feat: make demo user configurable via environment variables

- Move demo user credentials from hardcoded values to environment variables
- Add DEMO_USER_EMAIL, DEMO_USER_PASSWORD_HASH, DEMO_USER_NAME, DEMO_USERNAME env vars
- Add password hashing utility script for generating secure password hashes
- Update docker-compose.yml to properly load .env files and add restart policies
- Update .env.example with demo user configuration documentation

BREAKING CHANGE: Demo user is now configured via environment variables instead of hardcoded values
This commit is contained in:
Rohit Amarnath 2025-09-21 20:06:59 -04:00
parent a7ad44d840
commit 09a1a8b80d
6 changed files with 77 additions and 11 deletions

View file

@ -10,6 +10,7 @@
"start": "node dist/src/server.js",
"start_queue_processor": "node dist/src/queue-processor.js",
"start_export_processor": "node dist/src/export-processor.js",
"hash-password": "node --import tsx scripts/hash-password.ts",
"lint": "eslint src --ext ts,js,tsx,jsx",
"lint:fix": "eslint src --fix --ext ts,js,tsx,jsx",
"test:typecheck": "tsc --noEmit",
@ -175,7 +176,8 @@
"sinon": "^14.0.0",
"sinon-chai": "^3.7.0",
"ts-node-dev": "^1.1.8",
"typescript": "5.7.3"
"typescript": "5.7.3",
"tsx": "^4.0.0"
},
"volta": {

View file

@ -0,0 +1,23 @@
#!/usr/bin/env node
const bcrypt = require('bcryptjs')
async function main() {
const password = process.argv[2]
if (!password) {
console.error('Usage: yarn hash-password <password>')
process.exit(1)
}
try {
const hash = await bcrypt.hash(password, 10)
console.log(`Password: ${password}`)
console.log(`Hash: ${hash}`)
} catch (error) {
console.error('Error generating hash:', error)
process.exit(1)
}
}
main()

View file

@ -0,0 +1,23 @@
#!/usr/bin/env ts-node
import { hashPassword } from '../src/utils/auth'
async function main() {
const password = process.argv[2]
if (!password) {
console.error('Usage: yarn hash-password <password>')
process.exit(1)
}
try {
const hash = await hashPassword(password)
console.log(`Password: ${password}`)
console.log(`Hash: ${hash}`)
} catch (error) {
console.error('Error generating hash:', error)
process.exit(1)
}
}
main()

11
packages/db/setup.sh Executable file → Normal file
View file

@ -17,10 +17,13 @@ PG_USER=$POSTGRES_USER PG_PASSWORD=$PGPASSWORD yarn workspace @omnivore/db migra
psql --host $PG_HOST --username $POSTGRES_USER --dbname $PG_DB --command "GRANT omnivore_user TO app_user;" || true
echo "granted omnivore_user to app_user"
# create demo user with email: demo@omnivore.app, password: demo_password
# create demo user with configurable credentials
if [ -z "${NO_DEMO_USER}" ]; then
USER_ID=$(uuidgen)
PASSWORD='$2a$10$41G6b1BDUdxNjH1QFPJYDOM29EE0C9nTdjD1FoseuQ8vZU1NWtrh6'
psql --host $PG_HOST --username $POSTGRES_USER --dbname $PG_DB --command "INSERT INTO omnivore.user (id, source, email, source_user_id, name, password) VALUES ('$USER_ID', 'EMAIL', 'demo@omnivore.app', 'demo@omnivore.app', 'Demo User', '$PASSWORD'); INSERT INTO omnivore.user_profile (user_id, username) VALUES ('$USER_ID', 'demo_user');"
echo "created demo user with email: demo@omnivore.app, password: demo_password"
DEMO_EMAIL=${DEMO_USER_EMAIL:-"demo@omnivore.app"}
DEMO_PASSWORD_HASH=${DEMO_USER_PASSWORD_HASH:-'$2a$10$41G6b1BDUdxNjH1QFPJYDOM29EE0C9nTdjD1FoseuQ8vZU1NWtrh6'}
DEMO_NAME=${DEMO_USER_NAME:-"Demo User"}
DEMO_USERNAME=${DEMO_USERNAME:-"demo_user"}
psql --host $PG_HOST --username $POSTGRES_USER --dbname $PG_DB --command "INSERT INTO omnivore.user (id, source, email, source_user_id, name, password) VALUES ('$USER_ID', 'EMAIL', '$DEMO_EMAIL', '$DEMO_EMAIL', '$DEMO_NAME', '$DEMO_PASSWORD_HASH') ON CONFLICT(email) DO NOTHING; INSERT INTO omnivore.user_profile (user_id, username) VALUES ('$USER_ID', '$DEMO_USERNAME') ON CONFLICT(user_id) DO NOTHING;"
echo "created demo user with email: $DEMO_EMAIL"
fi

View file

@ -14,6 +14,13 @@ PG_USER=app_user
PG_PORT=5432
PG_POOL_MAX=20
# Demo User (optional - set NO_DEMO_USER=true to disable)
# To generate a password hash: cd packages/api && yarn hash-password "your_password"
DEMO_USER_EMAIL=demo@omnivore.app
DEMO_USER_PASSWORD_HASH=xxxxx
DEMO_USER_NAME="Demo User"
DEMO_USERNAME=demo_user
# API
API_ENV=local

View file

@ -17,6 +17,7 @@ services:
- pgdata:/var/lib/postgresql/data
env_file:
- .env
restart: always
migrate:
image: "ghcr.io/omnivore-app/sh-migrate:latest"
@ -27,7 +28,7 @@ services:
depends_on:
postgres:
condition: service_healthy
api:
image: "ghcr.io/omnivore-app/sh-backend:latest"
container_name: "omnivore-api"
@ -43,6 +44,7 @@ services:
depends_on:
migrate:
condition: service_completed_successfully
restart: always
queue-processor:
image: "ghcr.io/omnivore-app/sh-queue-processor:latest"
@ -52,6 +54,7 @@ services:
depends_on:
api:
condition: service_started
restart: always
web:
image: "ghcr.io/omnivore-app/sh-web:latest"
@ -59,10 +62,11 @@ services:
ports:
- "3000:8080"
env_file:
.env
- .env
depends_on:
api:
condition: service_healthy
restart: always
image-proxy:
image: "ghcr.io/omnivore-app/sh-image-proxy:latest"
@ -71,6 +75,7 @@ services:
- "7070:8080"
env_file:
- .env
restart: always
content-fetch:
image: "ghcr.io/omnivore-app/sh-content-fetch:latest"
@ -86,6 +91,7 @@ services:
condition: service_healthy
api:
condition: service_healthy
restart: always
redis:
image: "redis:7.2.4"
@ -98,6 +104,7 @@ services:
test: [ "CMD", "redis-cli", "--raw", "incr", "ping" ]
volumes:
- redis_data:/data
restart: always
minio:
image: minio/minio
@ -109,13 +116,12 @@ services:
test: [ "CMD", "mc", "ready", "local" ]
interval: 5s
timeout: 1s
environment:
- "MINIO_ACCESS_KEY=minio"
- "MINIO_SECRET_KEY=miniominio"
- "AWS_S3_ENDPOINT_URL=http://minio:1010"
env_file:
- .env
command: server /data
volumes:
- minio_data:/data
restart: always
createbuckets:
image: minio/mc
@ -145,6 +151,8 @@ services:
depends_on:
redis:
condition: service_healthy
restart: always
volumes:
pgdata:
redis_data: