Commit 693671a
update to 2.3.3 (#712)
* upating package.json to 2.3.3 for clean release
Signed-off-by: Will <will@dower.dev>
* fix: remove release workflow specs after workflow deletion
The release_infrastructure_spec tested the deleted release.yml
workflow file, causing CI to fail on the release-triggered run.
Remove the release workflow describe block; keep changelog, version
consistency, Docker trigger, and API version specs.
Signed-off-by: Will Dower <will@dower.dev>
* Fix/OIDC provider conflict (#711)
* fix: resolve OIDC provider conflict and add auto-link
OmniAuth returns auth.provider as symbol (:oidc) but DB
stores string ("oidc"). Comparison always triggered
ProviderConflictError. rescue_from ordering hid the
actionable message behind generic "unexpected error."
- Provider+uid-first lookup in User.from_omniauth
- .to_s coercion for type-safe comparison
- Fix rescue_from ordering (StandardError first)
- Add VULCAN_AUTO_LINK_USER global setting
- email_verified check for auto-link security
- just_auto_linked? flag (no duplicate lookup)
- Genericize oauth_error flash message
- Replace gitlab_omniauth-ldap with omniauth-ldap
- Remove nkf gem, lazy-load LDAP
- 75 backend auth specs
Authored by: Aaron Lippold<lippold@gmail.com>
* feat: session auth tracking, profile UX, unlink
- session[:auth_method] tracks HOW user signed in
- Profile shows "Signed in via X" + "Linked to Y"
- POST /users/unlink_identity with password check
- Unlink button with confirmation modal
- 15 backend + 29 frontend tests
Authored by: Aaron Lippold<lippold@gmail.com>
* fix: pre-existing bugs + infrastructure hardening
Bug fixes found during auth code review:
- vulcan_audit.rb: bitwise & vs && crash on nil rule
- users_controller: Slack fires on every update
(now gated on saved_change_to_admin?)
- History.vue: suppress raw field changes when
audit has a comment (link/unlink UX)
- registrations: polymorphic audit + user_type
Infrastructure:
- Ruby 3.4.8 -> 3.4.9
- parallel_sync.rake: recursion guard
- docker-compose.dev.yml: trust auth for VPN
Authored by: Aaron Lippold<lippold@gmail.com>
* docs: add what's-left tracking and beads export
- WHATS-LEFT.md: pending bug fixes, future features
- beads-export.jsonl: full task board for handoff
Authored by: Aaron Lippold<lippold@gmail.com>
* chore: fix Gemfile extra blank line (rubocop)
Authored by: Aaron Lippold<lippold@gmail.com>
* test: add TDD tests for Slack notification gate and polymorphic audit filter
71q.1: Verify Slack notification only fires on admin flag changes,
not on name/email updates. Tests promotion, demotion, and no-op cases.
71q.2: Verify registrations#edit filters audits by user_type: 'User',
excluding rogue audits with matching user_id but different user_type.
Signed-off-by: Will Dower <will@dower.dev>
* fix: restore prev_unconfirmed_email for reconfirmation flash (71q.3)
The update action read resource.unconfirmed_email but discarded the
value (no assignment). After email change, users got generic "Profile
updated" instead of "confirmation link sent to new address".
Fix: capture prev_unconfirmed_email, compare after update, show
appropriate flash message per Devise stock behavior.
TDD: red (email-change test failed with generic flash) → green.
Signed-off-by: Will Dower <will@dower.dev>
* fix: use update_columns for reset token to bypass validations (71q.4)
generate_reset_url used update! which runs full validations. If a
user has pre-existing validation failures (e.g., name exceeds a
tightened limit), the admin's reset link generation fails with
RecordInvalid — blocking an unrelated recovery flow.
Fix: use update_columns (matches Devise's save(validate: false)
pattern). Token writes carry no business logic.
TDD: red (user with 500-char name → validation error) → green.
Signed-off-by: Will Dower <will@dower.dev>
* fix: stop leaking exception.message in users_controller rescues (71q.5)
Both send_password_reset and set_password rescue blocks echoed
e.message directly to the client, leaking SMTP hostnames, DB
connection strings, or other internal details.
Fix: log full exception with backtrace server-side via
Rails.logger.error, return generic message to client.
TDD:
- send_password_reset: red (response contained 'smtp.internal.corp')
→ green (generic message returned)
- set_password: source inspection test verifies rescue block does
not interpolate e.message (Rails test mode re-raises before
controller rescue runs, preventing request-level testing)
Signed-off-by: Will Dower <will@dower.dev>
* fix: remove dead authProvider computed and add visibility guard (71q.6, 71q.7)
71q.6: Add source-inspection test ensuring no bare 'public' keyword
exists between private and protected sections in registrations
controller (issue was already fixed, test prevents regression).
71q.7: Remove dead authProvider computed property from UserProfile.vue.
Nothing in the template or script references it — the refactored
linkedProvider + currentSessionMethod properties cover all use cases.
TDD: red (authProvider still in computed options) → green (removed).
Signed-off-by: Will Dower <will@dower.dev>
* fix: P3/P4 hardening — backtraces, email_verified, null guard, constants, docs
71q.8: Log OmniAuth exception backtraces in all environments (was
dev-only). Use error level with first 10 frames.
71q.9: Cast email_verified OIDC claim via ActiveModel::Type::Boolean
to catch providers sending "false" (string) instead of false.
71q.10: Use falsy check in UsersTable typeColumn to handle both
null and undefined provider gracefully.
71q.11: Normalize PROJECT_MEMBER_ADMINS to array for consistency
with VIEWERS/AUTHORS/REVIEWERS. Add ROLE_ADMIN scalar constant
for attribute assignment. Update call sites.
71q.12: Document valid_password? hidden bcrypt→PBKDF2 rehash
side-effect at the unlink call site.
Signed-off-by: Will Dower <will@dower.dev>
* fix: use fake ID in vulcan_audit destroy action test
Test referenced undefined `rule` variable. Use a fake ID like the
adjacent nil-rule test — the destroy action guard skips before any
DB lookup so the ID value doesn't matter.
Signed-off-by: Will Dower <will@dower.dev>
* fix: address Copilot review — v-for key, remove dev artifacts
- Fix History.vue v-for key: changes.id is undefined, use
changes.field with index fallback for stable Vue diffing
- Remove WHATS-LEFT.md and beads-export.jsonl (branch-specific
tracking docs, not for the repo)
Signed-off-by: Will Dower <will@dower.dev>
* fix: properly exercise RecordNotUnique retry path in race condition test
Test claimed to verify retry-on-RecordNotUnique but never stubbed
save! to raise. Now stubs save! to raise once, pre-creates the user
with matching provider+uid so retry lookup succeeds, and asserts
save! was called exactly once before the retry found the existing user.
Signed-off-by: Will Dower <will@dower.dev>
---------
Signed-off-by: Will Dower <will@dower.dev>
Co-authored-by: Aaron Lippold <lippold@gmail.com>
* fix: exclude xml/binary blobs from with_severity_counts (prod crash) (#713)
* fix: exclude xml/binary blobs from with_severity_counts
The with_severity_counts scope used select("table.*") which loaded
ALL columns including multi-MB xml blobs on Stig and SRG models.
On index pages this blew Heroku dyno memory (R14/R15) and caused
30s timeouts (H12), crashing the app.
Fix: auto-detect columns of type xml/binary and exclude them from
the SELECT in with_severity_counts. This is a DRY fix at the
concern level — all models (Stig, SRG, Component) benefit without
per-controller workarounds. Models without heavy columns are
unaffected (all columns loaded as before).
The xml column is still loaded via Stig.find(id) for export/download
endpoints that need it.
Authored by: Aaron Lippold<lippold@gmail.com>
* fix: address Copilot review — use abstract column type, update docs, dynamic test assertions
- Use c.type (ActiveRecord abstract) instead of c.sql_type (adapter-
specific) for heavy column detection. Catches Postgres bytea, MySQL
blob, etc.
- Update concern header docs to reflect auto-generated scope (was
stale "define your own" instruction)
- Spec column assertions now dynamically check all non-blob columns
instead of hardcoded subset
Signed-off-by: Will Dower <will@dower.dev>
---------
Signed-off-by: Will Dower <will@dower.dev>
Co-authored-by: Will Dower <will@dower.dev>
* bumping versionfile
Signed-off-by: Will Dower <will@dower.dev>
* fix: fixes to development composefile
- Bind Puma to 0.0.0.0 in dev compose (was 127.0.0.1, unreachable
from Docker network)
- Clear stale server.pid on startup (volume mount persists it)
- Run yarn build:watch in background instead of foreman (avoids
missing bundle exec and bind address issues)
- Align Dockerfile Ruby version to 3.4.9
Signed-off-by: Will Dower <will@dower.dev>
---------
Signed-off-by: Will <will@dower.dev>
Signed-off-by: Will Dower <will@dower.dev>
Co-authored-by: Aaron Lippold <lippold@gmail.com>1 parent 5ec0994 commit 693671a
4 files changed
Lines changed: 6 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
| 20 | + | |
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
66 | | - | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
67 | 69 | | |
68 | 70 | | |
69 | 71 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
32 | | - | |
| 32 | + | |
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
| |||
0 commit comments