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
118 changes: 118 additions & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
name: API Performance Benchmark

on:
pull_request:
branches: [main, develop]
schedule:
- cron: '0 6 * * 1' # Weekly on Monday at 6am UTC
workflow_dispatch:
inputs:
iterations:
description: 'Number of iterations per endpoint'
required: false
default: '50'

jobs:
benchmark:
runs-on: ubuntu-latest

services:
postgres:
image: postgres:15
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:7
ports:
- 6379:6379

steps:
- uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Generate Prisma Client
run: npx prisma generate
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test

- name: Sync database schema
run: npx prisma db push --skip-generate --accept-data-loss
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test

- name: Build application
run: npm run build

- name: Start application
run: |
npm run start:dist &
for i in $(seq 1 30); do
if curl -s http://localhost:3000/api > /dev/null 2>&1; then
echo "Server is up"
break
fi
echo "Waiting for server... ($i)"
sleep 2
done
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test
REDIS_URL: redis://localhost:6379
JWT_SECRET: bench-secret
JWT_REFRESH_SECRET: bench-refresh-secret
NODE_ENV: production

- name: Run benchmarks
run: npx ts-node scripts/benchmark.ts
env:
BENCHMARK_BASE_URL: http://localhost:3000/api
BENCHMARK_ITERATIONS: ${{ github.event.inputs.iterations || '100' }}

- name: Upload benchmark results
uses: actions/upload-artifact@v4
if: always()
with:
name: benchmark-results
path: benchmark-results.json

- name: Comment on PR with results
if: github.event_name == 'pull_request' && always()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
try {
const report = JSON.parse(fs.readFileSync('benchmark-results.json', 'utf8'));
const lines = ['## API Benchmark Results\n'];
lines.push(`| Endpoint | p50 (ms) | p95 (ms) | p99 (ms) | Budget (ms) | Status |`);
lines.push(`|----------|----------|----------|----------|-------------|--------|`);
for (const r of report.results) {
const status = r.passed ? 'PASS' : 'FAIL';
lines.push(`| ${r.endpoint} | ${r.latencyMs.p50} | ${r.latencyMs.p95} | ${r.latencyMs.p99} | ${r.budgetMs} | ${status} |`);
}
lines.push(`\n**Summary:** ${report.summary.passed}/${report.summary.total} passed`);
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: lines.join('\n'),
});
} catch (e) {
console.log('Could not post benchmark results:', e.message);
}
45 changes: 0 additions & 45 deletions docs/MFA_ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,3 @@
<<<<<<< ours
# Multi-Factor Authentication (MFA) Roadmap

## Purpose
This document outlines the planned MFA implementation for PropChain. MFA is opt-in and will be introduced without breaking current authentication flows.

## Goals
- Add second-factor verification for sensitive actions and login.
- Support TOTP-based authenticators and backup codes.
- Keep MFA optional for users.
- Provide a developer-friendly path for future enrollment, verification, and recovery.

## Current placeholder endpoints
The backend exposes the following auth-related endpoints today:

- `POST /auth/2fa/setup` — initialize enrollment, generate a TOTP secret, QR code URL, and backup codes.
- `POST /auth/2fa/verify` — verify the TOTP code and enable two-factor authentication for the user.
- `POST /auth/2fa/disable` — disable two-factor authentication after password confirmation.

These endpoints are currently implemented in the `AuthService` as enrollment and verification flow placeholders.

## Implementation plan

### Phase 1: Secure enrollment and verification
1. Generate a TOTP secret and hashed backup codes.
2. Store the secret and backup codes in the user record.
3. Present the user with a QR code URL and a code list.
4. Verify the first TOTP code before enabling MFA.

### Phase 2: Login flow support
1. Require a second factor during login only for users with MFA enabled.
2. Accept either a valid TOTP code or an unused backup code.
3. Consume backup codes on use and maintain a fresh in-memory/hard storage list.

### Phase 3: Recovery and revocation
1. Add endpoints to regenerate backup codes.
2. Add endpoint to disable MFA after re-authentication.
3. Audit MFA changes in user activity logs.

## Notes
- The API contract is simple and opt-in.
- Existing auth workflows continue to work for users who do not enable MFA.
- Future expansion can include push notifications, SMS OTP, or hardware keys.
=======
# MFA / 2FA Roadmap

## Current State
Expand Down Expand Up @@ -89,4 +45,3 @@ Two-factor authentication is fully implemented using TOTP (Time-based One-Time P
- [ ] Hardware key (WebAuthn/FIDO2) support
- [ ] Admin-enforced 2FA for agent/admin roles
- [ ] Trusted device management
>>>>>>> theirs
Loading
Loading