Skip to content

Conversation

@Derb237
Copy link

@Derb237 Derb237 commented Nov 6, 2025

Summary

  • Add name column to Organization model
  • Update database plugin to handle organization names
  • Add migration for organization name field
  • Add target fields: average_payout, start_date, end_date, is_updated
  • Update upsert logic to include new fields

Database Changes

Migration 8b478a84c1a6_add_organization_name.py:

  • Adds name column to organizations table
  • Depends on migration 6f542023f57e (Duo Push feature)

Branch Structure

This PR adds the organization feature on top of the wip-2025 branch which contains the Duo Push feature.

Migration chain:

1434aa7ed47c (add synack_domain)
    ↓
6f542023f57e (add duo push method) ← in wip-2025
    ↓
8b478a84c1a6 (add organization name) ← this PR

Both features can be merged together when wip-2025 merges to main.

🤖 Generated with Claude Code

Derb237 and others added 5 commits October 7, 2025 10:21
…rror

Two bugs were present in the get_config method:

1. Missing session.commit() after creating new Config object
   - New config rows were added to session but never committed
   - This caused empty database on fresh installations
   - Result: synack_domain and other config values were None

2. Session closed before accessing attributes
   - getattr() called after session.close()
   - SQLAlchemy tried to lazy-load attributes from closed session
   - This raised DetachedInstanceError on attribute access

The fix:
- Add session.commit() after session.add(config)
- Store the return value before closing session
- This ensures the config row is persisted and attributes are loaded

This is a pre-existing bug that affects all fresh database installations.
Fixed three bugs in the request error handling:

1. Line 155: Fixed typo where 'fail_reason' was set instead of 'reason_failed'
   for HTTP 412 status codes

2. Line 170: Moved unconditional debug log into a conditional that only
   logs terminal failures (400, 401, 403, 412)

3. Lines 147-151: Fixed each status code to set its own specific error message
   instead of reusing a shared 'Request failed' message:
   - 400: "Bad request"
   - 401: "Unauthorized"
   - 403: "Logged out"
   - 412: "Mission already claimed"

Previously, when debug mode was enabled, every HTTP request would log
'MISSION ALREADY CLAIMED' regardless of the actual status code or context.
Additionally, 401 errors were being logged with misleading messages because
the reason_failed variable was being reused across different status codes.

Bug introduced in commit c406ca9 (March 2, 2025)
- Remove infinite retry loop on invalid credentials (400)
- Clear stored email/password when authentication fails
- Add explicit error handling for account locked (423)
- Make 400 and 423 non-retryable in API layer to prevent rapid-fire retries
- Raise clear error messages for both authentication failure scenarios

This prevents the previous behavior where entering wrong credentials
would trigger rapid retries that locked the account.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Implements three-priority Duo MFA authentication system:
1. OTP (highest priority) - Auto-generates HOTP codes from secret
2. Auto-approval - Uses device credentials to approve pushes via Duo API
3. Manual push (fallback) - Traditional approve-on-phone flow

Database changes:
- Add duo_push_akey, duo_push_pkey, duo_push_host, duo_push_rsa_key_path columns
- Add duo_device column to persist user's selected device
- Migration: 20522d39dc63_add_duo_push_method

Duo Push auto-approval:
- Integrate with Duo device API using RSA-SHA512 signed requests
- Load device credentials from database and RSA key from file
- Poll for pending push notifications and auto-approve
- Hard fail if auto-approval is configured but broken (prevents hanging)
- Auto-correct duo_device when credentials don't match selected device

HOTP hex secret auto-conversion:
- Auto-detect 32-char hex format (from synackDUO's hotp_secret)
- Convert by treating hex string as UTF-8, then base32 encode
- Based on duo-hotp reference implementation
- Accepts both hex (hotp_secret) and base32 (otpauth://) formats

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
- Add name column to Organization model
- Update database plugin to handle organization names
- Add migration for organization name field
- Add target fields: average_payout, start_date, end_date, is_updated
- Update upsert logic to include new fields

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@Derb237 Derb237 force-pushed the feature/organization-name branch from d625e28 to 2674241 Compare November 7, 2025 08:33
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