Skip to content

chore(auth): drop password-auth enum values via text-column conversion (preserves hash chains) - #1064

Merged
2witstudios merged 1 commit into
masterfrom
pu/password-auth-removal
Apr 22, 2026
Merged

2witstudios merged 1 commit into
masterfrom
pu/password-auth-removal

Conversation

@2witstudios

@2witstudios 2witstudios commented Apr 21, 2026 •

Copy link
Copy Markdown
Owner

Summary

Extracts the code-only portion of commit a3013a93 (originally on pu/docs-audit, PR #1063) onto its own branch and adds the Postgres migration required to actually deploy the enum drops. pu/docs-audit keeps its 6 marketing-docs files; on merge of this PR to master, pu/docs-audit rebases cleanly.

Migration approach — why text columns, not DELETE + rename-and-swap

Both tables are tamper-evident hash chains. activity_logs.operation is part of computeLogHash (packages/lib/src/monitoring/activity-logger.ts) and security_audit_log.event_type is part of computeSecurityEventHash (packages/lib/src/audit/security-audit.ts). Both chain verifiers (hash-chain-verifier.ts, security-audit-chain-verifier.ts) require each row's previousHash to match the immediately prior row's stored hash.

  • DELETE on orphan rows → next surviving row's previousHash points to a removed predecessor → verifier reports a chain break on every deleted segment, on unmodified data.
  • UPDATE event_type to another value → stored eventHash no longer matches recomputed hash → verifier reports hash mismatches on every rewritten row.

Converting the column to text preserves every stored value verbatim, so the chains stay valid and the /api/cron/verify-audit-chain job keeps passing without any verifier changes. Writer-side type safety is preserved via ActivityOperation (already a string-literal union) and SecurityEventType (now a hand-written union in packages/db/src/schema/security-audit.ts replacing the enumValues-derived type).

Tradeoff: the DB no longer enforces enum membership at INSERT time. TS is the source of truth — ActivityOperation / SecurityEventType types constrain all in-repo writers.

What changed

Schema (2 files) — drop the pgEnum declarations, change the consuming columns to text:

  • packages/db/src/schema/monitoring.ts — drop activityOperationEnum; activity_logs.operation and activity_logs.rollbackSourceOperation become text.
  • packages/db/src/schema/security-audit.ts — drop securityEventTypeEnum; security_audit_log.event_type becomes text. SecurityEventType now a hand-written string-literal union.

DB package exports — packages/db/src/index.ts drops both enum re-exports. SecurityEventType export preserved.

Schema test — packages/db/src/schema/__tests__/schema-definitions.test.ts drops the two enum-existence assertions.

Code (9 files, from a3013a93) — remove dead hooks:

  • SecurityAuditService.logPasswordChanged()
  • RATE_LIMIT_CONFIGS.PASSWORD_RESET, DISTRIBUTED_RATE_LIMITS.PASSWORD_RESET
  • ActivityOperation type union entry
  • Admin UI + rollback-service filter arrays
  • Associated tests

Test-label cleanup (2 files, not in a3013a93) — two pre-existing session tests passed 'password_change' / 'password_changed' as a free-form reason string to revokeAllUserSessions(); switched to 'admin_action' (a neighboring test already uses that value) so grepping for password refs comes back clean. Cosmetic only; reason is a free-form text column, not an enum.

Migration (new file) — packages/db/drizzle/0105_drop_password_auth_enums.sql:

ALTER TABLE "activity_logs"
  ALTER COLUMN "operation" TYPE text USING "operation"::text;
ALTER TABLE "activity_logs"
  ALTER COLUMN "rollbackSourceOperation" TYPE text USING "rollbackSourceOperation"::text;
DROP TYPE "activity_operation";

ALTER TABLE "security_audit_log"
  ALTER COLUMN "event_type" TYPE text USING "event_type"::text;
DROP TYPE "security_event_type";

No DELETEs, no UPDATEs on hashed rows. drizzle-kit generate detects the column-type changes and produces a compatible snapshot (meta/0105_snapshot.json); the hand-written SQL adds explicit USING casts and the DROP TYPE statements that Drizzle doesn't emit.

Verification checklist (reviewer can run locally)

git fetch origin && git checkout pu/password-auth-removal
pnpm install

# Migration is clean; no follow-up diff:
pnpm db:generate
# Expect: "No schema changes, nothing to migrate".

# Snapshot no longer references the dropped values or enum types:
grep -E "password_change|auth\.password|activity_operation|security_event_type" packages/db/drizzle/meta/0105_snapshot.json
# Expect: no matches.

# No lingering password refs in TS code:
grep -rE "password_change|auth\.password" packages/ apps/ --include='*.ts' --include='*.tsx'
# Expect: no matches.

pnpm lint
pnpm typecheck

# Hash-chain verifier tests still pass:
cd packages/lib && npx vitest run \
  src/audit/__tests__/security-audit.test.ts \
  src/audit/__tests__/security-audit-chain-verifier.test.ts \
  src/monitoring/__tests__/hash-chain-verifier.test.ts \
  src/monitoring/__tests__/activity-logger.test.ts

Then a dry-run of 0105_drop_password_auth_enums.sql against staging before production apply. The migration is non-destructive — no rows are deleted or modified — so rollback if needed is a matter of re-creating the enums and casting columns back (new migration), not restoring data.

Rollback note

Re-creating the dropped enum types and casting the columns back requires a follow-up migration; but since no data was deleted or rewritten, existing values cast back cleanly (as long as no new non-enum values were inserted in the meantime).

Summary by CodeRabbit

Release Notes

  • Chores
    • Updated internal database schema architecture for operation and event type handling, replacing database-level constraints with application-level validation for improved system flexibility and maintainability.

@coderabbitai

coderabbitai Bot commented Apr 21, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5227a3c8-7975-4548-b1b0-c8d827f96fa2

📥 Commits

Reviewing files that changed from the base of the PR and between 1d2ac17 and c72ef7a.

📒 Files selected for processing (12)
  • packages/db/drizzle/0105_drop_password_auth_enums.sql
  • packages/db/drizzle/meta/0105_snapshot.json
  • packages/db/drizzle/meta/_journal.json
  • packages/db/src/index.ts
  • packages/db/src/schema/__tests__/schema-definitions.test.ts
  • packages/db/src/schema/monitoring.ts
  • packages/db/src/schema/security-audit.ts
  • packages/lib/src/audit/__tests__/audit-test-helpers.ts
  • packages/lib/src/audit/__tests__/security-audit-chain-verifier.test.ts
  • packages/lib/src/auth/__tests__/session-abuse-vectors.test.ts
  • packages/lib/src/auth/__tests__/session-service-unit.test.ts
  • packages/lib/src/monitoring/__tests__/hash-chain-verifier.test.ts
💤 Files with no reviewable changes (2)
  • packages/db/src/schema/tests/schema-definitions.test.ts
  • packages/db/src/index.ts
✅ Files skipped from review due to trivial changes (2)
  • packages/lib/src/auth/tests/session-abuse-vectors.test.ts
  • packages/db/drizzle/0105_drop_password_auth_enums.sql
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/lib/src/auth/tests/session-service-unit.test.ts
  • packages/db/drizzle/meta/_journal.json
  • packages/db/src/schema/security-audit.ts

📝 Walkthrough

Walkthrough

This PR removes two PostgreSQL enum types (activity_operation and security_event_type) from the database schema by converting their corresponding columns to plain text type. The changes include a new SQL migration, schema definition updates, enum export removals, and test updates to verify legacy value compatibility.

Changes

Cohort / File(s) Summary
Database Migration
packages/db/drizzle/0105_drop_password_auth_enums.sql, packages/db/drizzle/meta/_journal.json
New migration that converts activity_logs.operation and activity_logs.rollbackSourceOperation to text, drops activity_operation enum, converts security_audit_log.event_type to text, and drops security_event_type enum. Journal updated with migration record.
Schema Definition Updates
packages/db/src/schema/monitoring.ts, packages/db/src/schema/security-audit.ts
Removed activityOperationEnum and securityEventTypeEnum PostgreSQL enums. Converted columns to text type. Replaced securityEventTypeEnum with a TypeScript SecurityEventType union type for type safety.
Module Exports
packages/db/src/index.ts
Removed activityOperationEnum and securityEventTypeEnum from public exports.
Schema Test Updates
packages/db/src/schema/__tests__/schema-definitions.test.ts
Removed test assertions validating the presence of enum definitions and their enum values.
Auth Test Updates
packages/lib/src/auth/__tests__/session-abuse-vectors.test.ts, packages/lib/src/auth/__tests__/session-service-unit.test.ts
Changed revokeAllUserSessions reason argument from 'password_changed'/'password_change' to 'admin_action' in test calls and expectations.
Audit Test Infrastructure
packages/lib/src/audit/__tests__/audit-test-helpers.ts, packages/lib/src/audit/__tests__/security-audit-chain-verifier.test.ts
Added createValidSecurityChainWithEventTypes helper to support testing with explicit event types. Added test cases verifying chain validity with legacy event type strings.
Monitoring Test Infrastructure
packages/lib/src/monitoring/__tests__/hash-chain-verifier.test.ts
Added createValidHashChainWithOperations helper and new test cases verifying hash chain integrity with legacy operation values.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

Poem

🐰 Enums away, we hop to text so free,
Type safety stays through TypeScript's decree,
Legacy strings now dance without a cage,
Schema evolved to a simpler page! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: removing password-auth enum types by converting columns to text while preserving hash chains. It is specific, concise, and directly related to the primary objective of the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pu/password-auth-removal

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1d2ac1791b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/db/drizzle/0105_drop_password_auth_enums.sql Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/lib/src/auth/__tests__/session-abuse-vectors.test.ts (1)

389-413: LGTM — reason-label swap aligned with sibling test.

Cosmetic change; reason is free-form. Minor nit while you're in the file: the section header at line 169 still reads TOKEN VERSION MISMATCH (PASSWORD CHANGE, FORCED LOGOUT) and the inline comment at line 188 references "password change, etc." — since the product is passwordless-only now, you may want to retire those references (e.g., FORCED LOGOUT / TOKEN ROTATION) to keep the file consistent with the PR's intent.

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

In `@packages/lib/src/auth/__tests__/session-abuse-vectors.test.ts` around lines
389 - 413, Update the obsolete header and inline comment text to remove
password-specific wording: replace the section header string "TOKEN VERSION
MISMATCH (PASSWORD CHANGE, FORCED LOGOUT)" with a neutral label such as "TOKEN
VERSION MISMATCH (FORCED LOGOUT / TOKEN ROTATION)" and update the nearby inline
comment that currently references "password change, etc." to reference "forced
logout or token rotation" (locate these exact strings in the tests to change the
text).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/lib/src/auth/__tests__/session-abuse-vectors.test.ts`:
- Around line 389-413: Update the obsolete header and inline comment text to
remove password-specific wording: replace the section header string "TOKEN
VERSION MISMATCH (PASSWORD CHANGE, FORCED LOGOUT)" with a neutral label such as
"TOKEN VERSION MISMATCH (FORCED LOGOUT / TOKEN ROTATION)" and update the nearby
inline comment that currently references "password change, etc." to reference
"forced logout or token rotation" (locate these exact strings in the tests to
change the text).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 64ee6dca-8e5e-4c5b-90bd-1b581eb1364e

📥 Commits

Reviewing files that changed from the base of the PR and between b422a3b and 1d2ac17.

📒 Files selected for processing (16)
  • apps/web/src/app/admin/audit-logs/page.tsx
  • apps/web/src/services/api/rollback-service.ts
  • packages/db/drizzle/0105_drop_password_auth_enums.sql
  • packages/db/drizzle/meta/0105_snapshot.json
  • packages/db/drizzle/meta/_journal.json
  • packages/db/src/schema/monitoring.ts
  • packages/db/src/schema/security-audit.ts
  • packages/lib/src/audit/security-audit.ts
  • packages/lib/src/auth/__tests__/rate-limit-utils.test.ts
  • packages/lib/src/auth/__tests__/session-abuse-vectors.test.ts
  • packages/lib/src/auth/__tests__/session-service-unit.test.ts
  • packages/lib/src/auth/rate-limit-utils.ts
  • packages/lib/src/monitoring/activity-logger.ts
  • packages/lib/src/permissions/__tests__/rollback-permissions.test.ts
  • packages/lib/src/security/__tests__/distributed-rate-limit.test.ts
  • packages/lib/src/security/distributed-rate-limit.ts
💤 Files with no reviewable changes (10)
  • packages/lib/src/auth/tests/rate-limit-utils.test.ts
  • packages/lib/src/permissions/tests/rollback-permissions.test.ts
  • packages/lib/src/audit/security-audit.ts
  • packages/db/src/schema/monitoring.ts
  • packages/db/src/schema/security-audit.ts
  • packages/lib/src/auth/rate-limit-utils.ts
  • packages/lib/src/security/tests/distributed-rate-limit.test.ts
  • packages/lib/src/monitoring/activity-logger.ts
  • apps/web/src/app/admin/audit-logs/page.tsx
  • packages/lib/src/security/distributed-rate-limit.ts

@2witstudios
2witstudios force-pushed the pu/password-auth-removal branch from 1d2ac17 to 6750da7 Compare April 21, 2026 23:21
@2witstudios 2witstudios changed the title chore(auth): remove password-auth enum values + Postgres migration chore(auth): drop password-auth enum values via text-column conversion (preserves hash chains) Apr 21, 2026
… + drop legacy password values

Password authentication was removed from PageSpace (passwordless-only:
passkey + magic link). Vestigial enum values on activity_operation and
security_event_type had no live consumers but blocked a clean schema.

Schema + code changes replicated from commit a3013a9 (originally on
pu/docs-audit, extracted here so the migration ships atomically with
the schema edit):

- activity_operation: drop 'password_change'
- security_event_type: drop auth.password.{changed,reset.requested,reset.completed}
- Remove SecurityAuditService.logPasswordChanged()
- Remove RATE_LIMIT_CONFIGS.PASSWORD_RESET and DISTRIBUTED_RATE_LIMITS.PASSWORD_RESET
- Drop 'password_change' from ActivityOperation type union and UI filter arrays

Also updates two pre-existing session-test fixtures that passed
'password_change' / 'password_changed' as a free-form 'reason' string to
revokeAllUserSessions() — switched to 'admin_action' (a neighboring test
already uses that value) so grepping for password refs comes back clean.

Migration 0105_drop_password_auth_enums.sql converts the three consuming
columns to text and drops the enum types:

  activity_logs.operation                (was activity_operation, now text)
  activity_logs.rollbackSourceOperation  (was activity_operation, now text)
  security_audit_log.event_type          (was security_event_type, now text)

Why text columns instead of DELETE + rename-and-swap: both tables are
tamper-evident hash chains. computeLogHash (activity-logger.ts) and
computeSecurityEventHash (security-audit.ts) include the column value
in the hashed payload, and the chain verifiers (hash-chain-verifier.ts,
security-audit-chain-verifier.ts) require each row's previousHash to
match the immediately prior row's stored hash. Either DELETE-ing or
UPDATE-ing affected rows would make the verifiers report chain breaks
on unmodified data. Converting the column to text preserves every stored
value verbatim so the chains remain valid without verifier changes.

Writer-side type safety is preserved: ActivityOperation (already a
string-literal union) and SecurityEventType (now a hand-written union
replacing the Drizzle enumValues-derived type) continue to constrain
callers at the TS layer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@2witstudios
2witstudios force-pushed the pu/password-auth-removal branch from 6750da7 to c72ef7a Compare April 22, 2026 00:42
@2witstudios
2witstudios merged commit 17b5ab4 into master Apr 22, 2026
10 checks passed
@2witstudios
2witstudios deleted the pu/password-auth-removal branch April 22, 2026 12:31
@coderabbitai coderabbitai Bot mentioned this pull request Apr 22, 2026
5 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant