fix: Postgres auth + worker startup

This commit is contained in:
2026-06-16 19:38:32 +02:00
parent 1a5d998cc8
commit 3136d55742
6 changed files with 31 additions and 24 deletions
+4 -4
View File
@@ -8,20 +8,20 @@ services:
POSTGRES_USER: ${POSTGRES_USER:-postgres} POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB:-postgres} POSTGRES_DB: ${POSTGRES_DB:-postgres}
POSTGRES_HOST_AUTH_METHOD: trust
volumes: volumes:
- ./data/db:/var/lib/postgresql/data - ./data/db:/var/lib/postgresql/data
- ./supabase/postgresql.conf:/etc/postgresql.conf:ro - ./supabase/pg_hba.conf:/etc/postgresql/pg_hba.conf:ro
- ./supabase/migrations/00-run-init.sh:/docker-entrypoint-initdb.d/00-run-init.sh:ro - ./supabase/migrations/00-run-init.sh:/docker-entrypoint-initdb.d/00-run-init.sh:ro
- ./supabase/migrations/01-init.sql:/docker-entrypoint-initdb.d/01-init.sql:ro - ./supabase/migrations/01-init.sql:/docker-entrypoint-initdb.d/01-init.sql:ro
- ./supabase/migrations/post-boot.sql:/docker-entrypoint-initdb.d/post-boot.sql:ro - ./supabase/migrations/post-boot.sql:/docker-entrypoint-initdb.d/post-boot.sql:ro
command: > command: >
postgres postgres
-c config_file=/etc/postgresql.conf -c hba_file=/etc/postgresql/pg_hba.conf
-c wal_level=logical -c wal_level=logical
-c max_wal_senders=0 -c max_wal_senders=0
-c max_replication_slots=0 -c max_replication_slots=0
-c idle_in_transaction_session_timeout=1min -c idle_in_transaction_session_timeout=1min
-c jsonb_output_as_text=true
ports: ports:
- "55632:5432" - "55632:5432"
healthcheck: healthcheck:
@@ -34,7 +34,7 @@ services:
image: postgrest/postgrest:v12.2.0 image: postgrest/postgrest:v12.2.0
restart: unless-stopped restart: unless-stopped
environment: environment:
PGRST_DB_URI: postgres://authenticator:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-postgres} PGRST_DB_URI: postgres://authenticator@db:5432/${POSTGRES_DB:-postgres}
PGRST_DB_SCHEMAS: public PGRST_DB_SCHEMAS: public
PGRST_DB_ANON_ROLE: authenticator PGRST_DB_ANON_ROLE: authenticator
PGRST_JWT_SECRET: ${JWT_SECRET:-your-super-secret-jwt-key-change-in-production} PGRST_JWT_SECRET: ${JWT_SECRET:-your-super-secret-jwt-key-change-in-production}
+1 -1
View File
@@ -7,7 +7,7 @@ psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<'E
DO $$ DO $$
BEGIN BEGIN
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'authenticator') THEN IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'authenticator') THEN
CREATE ROLE authenticator NOLOGIN; CREATE ROLE authenticator LOGIN;
END IF; END IF;
END END
$$; $$;
+6
View File
@@ -0,0 +1,6 @@
# TYPE DATABASE USER ADDRESS METHOD
local all all trust
host all all 127.0.0.1/32 trust
host all all ::1/128 trust
host all all 0.0.0.0/0 trust
host all all ::/0 trust
+2 -2
View File
@@ -16,5 +16,5 @@ maintenance_work_mem = 64MB
# Timeouts # Timeouts
idle_in_transaction_session_timeout = 60000 idle_in_transaction_session_timeout = 60000
# JSONB output as text for PostgREST compatibility # Logging
jsonb_output_as_text = true log_statement = 'ddl'
+17 -16
View File
@@ -1,16 +1,17 @@
import logging import logging
import uuid import uuid
from typing import Any
import asyncpg import asyncpg
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.ext import CommandHandler, ExtBot, ContextTypes from telegram.ext import Application, CommandHandler, ContextTypes
from db import get_pool from db import get_pool
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
async def _require_user(update: Update) -> asyncpg.Row | None: # type: ignore[name-defined] async def _require_user(update: Update) -> dict[str, Any] | None:
"""Look up user by telegram_id. Auto-register on first /start.""" """Look up user by telegram_id. Auto-register on first /start."""
telegram_id = update.effective_user.id telegram_id = update.effective_user.id
pool = await get_pool() pool = await get_pool()
@@ -24,7 +25,7 @@ async def _require_user(update: Update) -> asyncpg.Row | None: # type: ignore[n
return row return row
async def _require_admin(update: Update) -> asyncpg.Row | None: # type: ignore[name-defined] async def _require_admin(update: Update) -> dict[str, Any] | None:
"""Require the sender to be a whitelisted admin.""" """Require the sender to be a whitelisted admin."""
telegram_id = update.effective_user.id telegram_id = update.effective_user.id
pool = await get_pool() pool = await get_pool()
@@ -38,7 +39,7 @@ async def _require_admin(update: Update) -> asyncpg.Row | None: # type: ignore[
return row return row
async def _auto_register(update: Update) -> asyncpg.Row | None: # type: ignore[name-defined] async def _auto_register(update: Update) -> dict[str, Any] | None:
"""Create user row on first contact if not present. Returns nothing if un-whitelisted.""" """Create user row on first contact if not present. Returns nothing if un-whitelisted."""
telegram_id = update.effective_user.id telegram_id = update.effective_user.id
username = update.effective_user.username or None username = update.effective_user.username or None
@@ -71,20 +72,20 @@ async def _auto_register(update: Update) -> asyncpg.Row | None: # type: ignore[
first_name, first_name,
) )
logger.info("Auto-registered user %s (%s)", telegram_id, first_name) logger.info("Auto-registered user %s (%s)", telegram_id, first_name)
return asyncpg.Record(("id", user_uuid), ("is_active", True)) # type: ignore[call-arg] return {"id": user_uuid, "is_active": True}
def register_handlers(bot: ExtBot) -> None: def register_handlers(app: Application) -> None:
bot.add_handler(CommandHandler("start", start_handler)) app.add_handler(CommandHandler("start", start_handler))
bot.add_handler(CommandHandler("add", add_handler)) app.add_handler(CommandHandler("add", add_handler))
bot.add_handler(CommandHandler("list", list_handler)) app.add_handler(CommandHandler("list", list_handler))
bot.add_handler(CommandHandler("pause", pause_handler)) app.add_handler(CommandHandler("pause", pause_handler))
bot.add_handler(CommandHandler("resume", resume_handler)) app.add_handler(CommandHandler("resume", resume_handler))
bot.add_handler(CommandHandler("delete", delete_handler)) app.add_handler(CommandHandler("delete", delete_handler))
bot.add_handler(CommandHandler("stats", stats_handler)) app.add_handler(CommandHandler("stats", stats_handler))
bot.add_handler(CommandHandler("adduser", adduser_handler)) app.add_handler(CommandHandler("adduser", adduser_handler))
bot.add_handler(CommandHandler("removeuser", removeuser_handler)) app.add_handler(CommandHandler("removeuser", removeuser_handler))
bot.add_handler(CommandHandler("users", users_handler)) app.add_handler(CommandHandler("users", users_handler))
# -- /start --------------------------------------------------------------- # -- /start ---------------------------------------------------------------
+1 -1
View File
@@ -160,7 +160,7 @@ async def main() -> None:
from bot import register_handlers # noqa: E402 from bot import register_handlers # noqa: E402
register_handlers(app.bot) register_handlers(app)
scheduler = asyncio.ensure_future(scheduler_task(pool, app.bot)) scheduler = asyncio.ensure_future(scheduler_task(pool, app.bot))