1. [SQL] Fix username uniqueness constraint - Changed from global unique to composite unique(tenant_id, username) - Multi-tenant apps need same usernames across tenants (e.g., each tenant can have 'admin') 2. [Go] Fix inconsistent error handling in scanSession - Now returns pgx.ErrNoRows when session not found (like scanUser) - Allows proper 404 vs 500 error distinction in handlers 3. [Go] Add missing VerifyPassword function - Implements bcrypt.CompareHashAndPassword for password verification - Enables login flow with proper error handling for missing users - Paired with existing GenerateFromPassword for secure password hashing Security checks: - SQL injection: All queries parameterized (no string interpolation) - bcrypt: Cost factor 12 (production-recommended) - Session tokens: PostgreSQL gen_random_uuid() (cryptographically secure) - Password hashes: Protected with json:"-" tag (never exposed in responses) - Error handling: Comprehensive, no silent failures Build & Vet: All checks pass (go build ./..., go vet ./...) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
22 lines
951 B
SQL
22 lines
951 B
SQL
-- 002_auth.sql
|
|
-- Auth-Schema: Users und Sessions fuer Tenant-Login
|
|
|
|
create table if not exists users (
|
|
id text primary key default gen_random_uuid()::text,
|
|
tenant_id text not null references tenants(id) on delete cascade,
|
|
username text not null,
|
|
password_hash text not null,
|
|
role text not null default 'tenant',
|
|
created_at timestamptz not null default now(),
|
|
unique(tenant_id, username)
|
|
);
|
|
|
|
create table if not exists sessions (
|
|
id text primary key default gen_random_uuid()::text,
|
|
user_id text not null references users(id) on delete cascade,
|
|
created_at timestamptz not null default now(),
|
|
expires_at timestamptz not null default (now() + interval '8 hours')
|
|
);
|
|
|
|
create index if not exists idx_sessions_user_id on sessions(user_id);
|
|
create index if not exists idx_sessions_expires_at on sessions(expires_at);
|