mirror of
https://github.com/we-promise/sure.git
synced 2026-09-09 08:34:26 +00:00
* fix(wise): refuse an SCA private key when encryption is unavailable WiseItem wraps its `encrypts` declarations in `if encryption_ready?`, which is false on any install that has not explicitly configured Active Record encryption. On those installs the declaration never runs, so assigning sca_private_key writes the PEM into the column verbatim. That is a tolerable degraded mode for a display name. It is not one for the key that signs Wise balance-statement requests, and nothing in the flow told the user it had happened: the panel reported a keypair as generated either way. generate_sca_keypair! now raises SCAEncryptionUnavailable instead of writing, and a validation refuses the attribute on every other write path. The exception is raised rather than returned so no caller can read "not stored" as "stored". WiseItemsController#generate_sca_keypair already rescues broadly, so the user sees the same panel error as any other keypair failure rather than a 500. The three existing tests that generate a keypair now stub encryption_ready? to true. The test environment configures no encryption keys, so without the stub they would be exercising the refused path rather than the one they describe. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(wise): validate the SCA key only when it is being written Review found a real regression in the first commit, and CI found a scanner hit. The validation ran on every save. An install that generated a key before this change still has that plaintext value in the column, so the record became permanently unsaveable: renaming the connection failed, and the destroy path failed worse. WiseItemsController#destroy calls unlink_all! and only then destroy_later, whose update!(scheduled_for_deletion: true) would now raise, so the accounts were already unlinked while the provider stayed active. Refusing a NEW key is the point; refusing to let go of an old one is not. The validation now returns unless sca_private_key is actually changing, and the explicit guard in generate_sca_keypair! is unchanged. The regression test fails without the guard, on the reload-and-save assertion. pipelock flagged the literal "BEGIN RSA PRIVATE KEY" header in the test as a critical Private Key Header finding in the diff, which is exactly what a secret scanner should do. The value only ever needed to be non-blank, and the file already uses a plain placeholder two tests above, so it now uses one too. Also adds the encrypted-attributes assertion the other Encryptable models carry, in their shape: it skips when encryption is unconfigured, because the suite deliberately runs that way (see EncryptionVerificationTest's own comment) and turning ENV-based encryption on globally would change encryption_ready? for every Encryptable model, well outside this change. 49 Wise tests green, 1 skipped by that convention. Rubocop clean, Brakeman 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>