feat(cryptography): unified-canvas UX + PGP private-key resource toggle [STUD-80718]#588
Open
alexandru-petre wants to merge 12 commits into
Open
feat(cryptography): unified-canvas UX + PGP private-key resource toggle [STUD-80718]#588alexandru-petre wants to merge 12 commits into
alexandru-petre wants to merge 12 commits into
Conversation
Implements the three gaps recorded in the STUD=80718 unified-UX review for UiPath.Cryptography.Activities: - S1: move the third-party-interop knobs (Format, KeyFormat, Iv, KdfIterations, AesKeySize) out of the primary Input section into a new secondary "Advanced" section, applied to both the unified-canvas ViewModels and the runtime [LocalizedCategory] attributes so the two layers stay consistent. - P1: add a path<->resource toggle (PrivateKeyFile IResource) for the PGP private key in Encrypt/Decrypt Text & File, mirroring PublicKeyFile and the PgpSign activities. The encrypt path resolves the resource only when SignData is enabled, so a bound-but-unused key never fails a non-signing encrypt. - S2: order the Output property after Options in the Text activities. Adds the Category_Advanced_Name and PrivateKeyFile resx/Designer entries, plus reflection existence tests and non-signing regression tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wn28po9dSpgQjnBU2Jh4yJ
Completes the STUD=80718 S2 fix for the remaining two activities the review flagged: KeyedHashText and KeyedHashFile assigned Result (Output) a lower OrderIndex than ContinueOnError (Options), so Output could render before Options. Assign Result last, matching the Encrypt/Decrypt activities. Design-time ordering only; no runtime behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wn28po9dSpgQjnBU2Jh4yJ
KeyedHashText/KeyedHashFile were the only activities marking their output (Result) IsPrincipal = true, which surfaced it in the collapsed canvas card among the inputs instead of the Output section. Align with every other Cryptography output (Encrypt/Decrypt Text & File) by setting IsPrincipal = false, so the output renders in the Output section after Options. Design-time only; no runtime behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wn28po9dSpgQjnBU2Jh4yJ
The encoding config was scattered across sections in the unified canvas: Text (plaintext) encoding under Input, Key encoding under Options, and the interop knobs under Advanced. Introduce a dedicated "Encoding" category for the two encoding dropdowns (keeping Advanced for the interop knobs), applied across all six activities with encoding options: Encrypt/Decrypt Text & File and Hash Text & File. Key encoding moves to Encoding on all six; Text encoding (Text activities only) moves from Input to Encoding. Applied to both the unified-canvas ViewModel Category and the runtime [LocalizedCategory] attributes, which also resolves a pre-existing layer mismatch (runtime typed key-encoding was Input while the ViewModel used Options). Adds the Category_Encoding_Name resx/Designer entry. Design-time grouping only; no runtime behavior change. Resulting Text sections: Input, Encoding, Advanced, Options, Output. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wn28po9dSpgQjnBU2Jh4yJ
EncryptFile/DecryptFile were the only file-writing activities that marked Overwrite IsPrincipal = true (surfacing it in the collapsed canvas card) and whose runtime [LocalizedCategory] was Input. Align them with PgpSignFile / PgpClearSignFile / PgpGenerateKeys: IsPrincipal = false so it renders in the Options section, and runtime category Input -> Options to match the ViewModel and the other activities. Design-time/metadata only; no runtime behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wn28po9dSpgQjnBU2Jh4yJ
The (Key, IV) reuse warning is only surfaced at design time when an explicit IV is entered. Add a short form of it to the IV property description (Encrypt Text and Encrypt File) so the risk is visible up front, before a value is filled in. English resx only; no behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wn28po9dSpgQjnBU2Jh4yJ
Tooltips render as plain text (no markdown), so emphasize the warning with a warning glyph, uppercase "WARNING", and a blank line separating it from the descriptive text. Applies to Encrypt Text and Encrypt File IV descriptions. English resx only; no behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wn28po9dSpgQjnBU2Jh4yJ
Emphasize the IV nonce-reuse warning with just an uppercase "WARNING" on its own line (blank-line separated), removing the warning glyph. Encrypt Text / Encrypt File. English resx only; no behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wn28po9dSpgQjnBU2Jh4yJ
The warning after the colon is a complete sentence, so capitalize its first word per Microsoft style. Encrypt Text / Encrypt File. English resx only; no behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wn28po9dSpgQjnBU2Jh4yJ
…and IV caution Keep the activity reference docs complete and current with the branch's changes: - Encrypt/Decrypt Text & File: note that PublicKeyFilePath and PrivateKeyFilePath each have a hidden IResource alternative (PublicKeyFile / PrivateKeyFile) selectable via a designer menu action — matching how the package documents the same pairing for InputFilePath and the PgpSign activities. (PrivateKeyFile is new on these activities; PublicKeyFile was a pre-existing doc gap.) - Encrypt Text/File: add the (Key, IV) nonce-reuse caution to the IV description, mirroring the property tooltip. Docs only; no code change. Category/section moves (Advanced, Encoding, Overwrite->Options, output ordering) need no doc changes — the docs group by argument kind, not designer category. coded-api.md and the other docs are unaffected by this branch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wn28po9dSpgQjnBU2Jh4yJ
…ltips Codex validation flagged that the PublicKeyFile / PrivateKeyFile descriptions said the resource "takes precedence over the file-path variant", but the runtime uses the file path first and only falls back to the resource when the path is empty (and the path/resource toggle also prefers the path side). The two are mutually exclusive in the designer anyway, so the precedence detail is dropped from all 8 descriptions (PublicKeyFile + PrivateKeyFile across Encrypt/Decrypt Text & File). English resx only; no behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wn28po9dSpgQjnBU2Jh4yJ
Collapse the duplicated PGP key path↔resource resolution blocks (public + private key, across Encrypt/Decrypt Text & File) into a single PgpFileResolver.ResolveLocalPath helper. This removes the copy-pasted blocks SonarCloud flagged as new-code duplication, and concentrates the precedence logic (path-first, resource fallback, non-throwing) in one unit-tested place. The thin sync-over-async adapter that calls ToLocalResource() is isolated behind a [ExcludeFromCodeCoverage] private method — it can't be exercised without the platform resource stack — while ResolveLocalPath's precedence branches are covered directly by new PgpFileResolverTests. Runtime behavior is unchanged (path still wins; resource used only when the path is empty; encrypt still resolves the private key only when SignData). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wn28po9dSpgQjnBU2Jh4yJ
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Context
UiPath.Cryptography.Activitiesis the Cryptography activity package (Encrypt/Decrypt Text & File, Hash Text & File, and the PGP activities). Each activity has a runtime class (CodeActivity) and a design-timeDesignPropertiesViewModelthat drives the unified canvas — the property panel and card shown in Studio. Property placement there is controlled by each property's ViewModelCategory/IsPrincipal/OrderIndex, kept in sync with the runtime[LocalizedCategory]attributes.This PR implements the follow-up fixes from the STUD-80718 unified-canvas adoption review, plus polish items surfaced while doing so.
Problem Statement
The review found the Encrypt/Decrypt/Hash activities didn't fully follow the unified-canvas guideline: interop and encoding knobs were scattered across the primary Input section and Options; outputs weren't consistently ordered last;
Overwritesat outside Options on the file activities; and the PGP private key could only be given as a file path — unlike its sibling public key and the PgpSign activities, it had no path↔resource toggle. The IV nonce-reuse risk was also only surfaced after a value was entered. These affect automation authors configuring these activities in Studio.Behavior Before This PR
Opening Encrypt Text in Studio: Text encoding sat under Input, Key encoding under Options, and the third-party knobs (Format, KeyFormat, IV, KDF iterations, AES key size) under Input alongside the primary fields; the Result output could render before the Options tail. On Encrypt/Decrypt File, Overwrite surfaced on the collapsed card rather than in Options. For PGP, the private key (
PrivateKeyFilePath) was a plain string only — it could not be picked from project resources / a Storage Bucket. The IV field's nonce-reuse warning only appeared as a design-time validation once an explicit IV was set.Behavior After This PR
Encrypt/Decrypt Text sections read Input → Advanced → Encoding → Options → Output: both encodings live in a dedicated Encoding section, the interop knobs in Advanced, and the output is ordered last. Overwrite renders in Options on Encrypt/Decrypt File (consistent with the PGP file activities). The PGP private key now offers a path↔resource toggle (
PrivateKeyFile,IResource) via a designer menu action, mirroringPublicKeyFileand PgpSign; at runtime the file path is used first, falling back to the resource only when the path is empty. The IV property description now carries a shortWARNING:about never reusing a (Key, IV) pair, in addition to the existing design-time validation.Considered Use Cases
These all concern the new PGP private-key path↔resource toggle — the only change here with runtime impact (everything else is design-time placement) — so its correctness and backward-compatibility edges were the focus:
PrivateKeyFileresource — must not resolve it (resolution is gated onSignData); covered by new regression tests.PairedInputTogglebehavior as the existing key/passphrase toggles).PrivateKeyFileis a new optional[Browsable(false)]InArgument<IResource>with[DefaultValue(null)]; existing XAML that binds onlyPrivateKeyFilePathis unaffected.Implementation
Category/placement changes are applied to both the ViewModel
Categoryand the runtime[LocalizedCategory]attributes (the package keeps the classic grid and unified canvas consistent); this also resolved a pre-existing key-encoding layer mismatch (runtimeInputvs ViewModelOptions). The new private-key resource resolution mirrors the existingPublicKeyFileinlineToLocalResource().ResolveAsync().GetAwaiter().GetResult()pattern (these are synchronousCodeActivityclasses) and is deliberately non-throwing so an unused key can't fail a non-signing encrypt.ActivitiesMetadata.jsonneeds no change — itsPropertiesarrays are empty and the ViewModel drives everything. Activity reference docs underPackaging/docs/activities/were updated for the new key resource pairing and the IV caution.Caveats / Potential Issues
How to Test
dotnet build Activities/Activities.Cryptography.sln— clean.dotnet test Activities/Activities.Cryptography.sln— green (404 package + 123 API tests), including new reflection existence tests forPrivateKeyFileand two regression tests asserting a boundPrivateKeyFileresource is never resolved whenSignData = false.Independently cross-validated with Codex (2 rounds, final verdict Green — no outstanding findings).
🤖 Generated with Claude Code
https://claude.ai/code/session_01Wn28po9dSpgQjnBU2Jh4yJ