Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve UX and functionality of the secret share page #3327

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

beaukuhn
Copy link

@beaukuhn beaukuhn commented Mar 28, 2025

Description 📣

Improves the UX and functionality of the secret share page:

  • Added a confirm password field that transitions in when there is text in the password field and disappears otherwise
  • Added border highlighting for better UX
  • Added a hide secret button that hides the text in a similar fashion to the view secret page to prevent shoulder surfing
  • Made it so you can’t copy and paste the text when its hidden via right click + copy + paste, cmd+c, cmd+v, ctrl+c, ctrl+v
  • Fixed an issue in the secret view page where the FontAwesome eye icon was closed when it should be open and vice versa (canonical)
  • Removed magic numbers by setting them to constants for additional context
Google.Chrome.-.28.March.2025.mp4

Type ✨

  • Bug fix
  • New feature
  • Improvement
  • Breaking change
  • Documentation

Tests 🛠️

# Here's some code block to paste some code snippets

Summary by CodeRabbit

  • New Features
    • Enhanced the secret sharing form with improved validation, feedback on password confirmation, and a refined reset behavior.
    • Updated the secret visibility toggle so the eye icon clearly indicates when the secret is visible or hidden.

Copy link

coderabbitai bot commented Mar 28, 2025

Walkthrough

The pull request introduces enhancements to the secret-sharing functionality in two components. The ShareSecretForm component now includes new state variables (isSecretVisible, passwordConfirmation, and secretModified) to manage secret visibility, track password confirmation, and indicate if the secret has been modified. The logic for handling secret input has been improved with new functions for managing state changes. Additionally, form submission logic has been updated to reset fields and validate password confirmation. In the SecretContainer component, the icon toggle logic has been reversed to ensure that the displayed icon accurately reflects the visibility state of the secret.

Suggested reviewers

  • DanielHougaard
  • scott-ray-wilson
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx (2)

85-94: Consider modifying the secretModified logic

The current implementation sets secretModified to true when the secret field has a value, but doesn't account for when a user intentionally clears the field after initial input.

const handleSecretChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
-  if (e.target.value) {
-    setSecretModified(true);
-  }
+  setSecretModified(true);
};

327-328: Consider consolidating default values

The default values for expiresIn and viewLimit are set via the defaultValue prop, but it would be more consistent to set them in the defaultValues object in the useForm hook.

const {
  control,
  reset,
  handleSubmit,
  watch,
  formState: { isSubmitting }
} = useForm<FormData>({
  resolver: zodResolver(schema),
  defaultValues: {
    secret: value || "",
+   expiresIn: DEFAULT_EXPIRES_IN,
+   viewLimit: DEFAULT_VIEW_LIMIT,
+   ...(isPublic ? {} : { accessType: SecretSharingAccessType.Organization })
  },
  mode: "onChange"
});

Then update the Controller components:

<Controller
  control={control}
  name="expiresIn"
- defaultValue={DEFAULT_EXPIRES_IN}
  render={...}
/>

<Controller
  control={control}
  name="viewLimit"
- defaultValue={DEFAULT_VIEW_LIMIT}
  render={...}
/>

Also applies to: 343-344

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3493453 and d08da57.

📒 Files selected for processing (1)
  • frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx (11 hunks)
🔇 Additional comments (11)
frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx (11)

30-31: Good use of constants instead of magic numbers

Replacing hardcoded values with named constants improves code readability and maintainability.


56-58: Well-structured state management for new features

The new state variables clearly define their purpose:

  • isSecretVisible for controlling secret visibility
  • passwordConfirmation for tracking the confirmation field
  • secretModified for validating only after user interaction

This approach creates a better user experience by providing appropriate validation timing.


82-84: Good use of form watching

Using watch to monitor form fields enables reactive UI updates based on field values, which is necessary for the password confirmation and secret visibility features.


95-98: Good implementation of secret masking

The computed value properly handles both visible and hidden states, including edge cases where the secret might be empty.


99-104: Good form validation logic

The validation variables clearly define various states and edge cases for password validation, which improves user experience by providing immediate feedback.


129-136: Improved form reset implementation

The form reset logic properly clears all relevant fields and resets to default values after submission, enhancing the user experience when creating multiple secrets.


191-234: Great implementation of secret visibility toggle and copy protection

This implementation addresses several important UX concerns:

  1. Allows users to hide sensitive data to prevent shoulder surfing
  2. Prevents copying hidden text via keyboard shortcuts and context menu
  3. Maintains a clear visual indication of the current visibility state

This aligns perfectly with the PR objectives.


257-262: Good UX consideration for password fields

Automatically clearing the confirmation field when the password is emptied prevents confusion and maintains consistency between the fields.


268-322: Excellent password confirmation implementation

The password confirmation field implementation:

  1. Dynamically appears only when needed
  2. Provides excellent visual feedback with color-coded borders and icons
  3. Shows helpful error messages for mismatched passwords
  4. Uses smooth animations for better user experience

This is a significant UX improvement.


380-381: Nice dynamic button styling

Changing the button variant based on its disabled state provides clear visual feedback to users about form validity.


407-419: Comprehensive state reset when sharing another secret

The button handler properly resets all state variables and form fields, ensuring a clean slate for creating another secret.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx (1)

115-115: Bug: Potential type inconsistency.

Converting expiresIn from string to number should be done consistently. Consider using Number() at the point where the value is stored rather than at the point of use.

- const expiresAt = new Date(Date.now() + Number(expiresIn));
+ const numericExpiresIn = Number(expiresIn);
+ const expiresAt = new Date(Date.now() + numericExpiresIn);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d08da57 and a794334.

📒 Files selected for processing (1)
  • frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx (11 hunks)
🔇 Additional comments (13)
frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx (13)

30-31: Good addition of constants to replace magic numbers!

Using constants for default values (DEFAULT_EXPIRES_IN and DEFAULT_VIEW_LIMIT) improves code maintainability and readability by eliminating magic numbers.


56-58: Well-structured state variables for the new features.

These new state variables effectively support the UX improvements mentioned in the PR objectives:

  • isSecretVisible controls the secret visibility toggle
  • passwordConfirmation enables password validation
  • secretModified helps with proper form validation feedback

85-87: Good use of form watching.

Using watch is the correct approach to respond to form field changes without requiring additional state variables for these values.


88-95: Clean implementation of event handlers.

The handlers effectively track whether the secret has been modified, which is important for proper validation feedback.


96-104: Well-structured computed values for validation.

The computed values provide clear conditions for various UI states:

  • Secret visibility display
  • Password validation logic
  • Submit button state

This approach keeps the template code clean and easy to understand.


122-122: Good use of undefined for default value.

Using undefined when the view limit is set to default is a clean approach that avoids unnecessary processing.


129-136: Proper form reset implementation.

The form reset logic now properly resets all fields including the new password confirmation field. Using the constants for default values ensures consistency.


187-188: Improved error handling for secret field.

Using secretModified to conditionally show errors prevents premature error messages before the user has interacted with the field, improving the user experience.


192-238: Great implementation of the secret visibility toggle!

This implementation successfully addresses the PR objective to allow hiding secrets. Key features:

  1. Toggle button with appropriate icons
  2. Asterisk masking for hidden secrets
  3. Prevention of copy/paste when hidden (security feature)
  4. Context menu prevention when hidden (security feature)

These security measures help prevent shoulder surfing as mentioned in the PR objectives.


262-267: Good UX improvement in password field.

Automatically clearing the password confirmation when the password field is emptied ensures the fields stay in sync and prevents confusion.


273-326: Excellent password confirmation implementation!

This implementation provides:

  1. Smooth animation for showing/hiding the field
  2. Clear visual feedback with color-coded borders
  3. Helpful validation icons
  4. Informative error messages for mismatched passwords

The conditional rendering based on password presence is a good UX pattern.


404-405: Good visual feedback for button state.

Changing both the disabled state and variant of the button based on validation provides clear visual feedback to users about when they can submit the form.


431-443: Complete reset functionality for sharing another secret.

The reset logic properly handles all state variables and form fields, ensuring a clean slate for the next secret.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx (1)

296-304: Consider extracting border color logic to a separate function.

The conditional border color logic is complex and nested within the JSX. It would be clearer and more maintainable if extracted to a separate function.

-containerClassName={
-  password && passwordConfirmation
-    ? (password === passwordConfirmation ? "border-green-500" : "border-red-500")
-    : (password && !passwordConfirmation)
-      ? "border-amber-500 animate-pulse"
-      : "border-mineshaft-600"
-}
+containerClassName={getPasswordConfirmationBorderClass(password, passwordConfirmation)}

Add this function before the return statement:

const getPasswordConfirmationBorderClass = (pwd: string, pwdConfirm: string) => {
  if (pwd && pwdConfirm) {
    return pwd === pwdConfirm ? "border-green-500" : "border-red-500";
  }
  if (pwd && !pwdConfirm) {
    return "border-amber-500 animate-pulse";
  }
  return "border-mineshaft-600";
};
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a794334 and a243c5f.

📒 Files selected for processing (1)
  • frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx (11 hunks)
🔇 Additional comments (16)
frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx (16)

3-3: Added FontAwesome icons for enhanced UI functionality.

The addition of faEye, faEyeSlash, and faExclamationTriangle icons enhances the user interface by providing visual indicators for secret visibility and validation states.


30-31: Good practice: Magic numbers replaced with named constants.

Replacing magic numbers with named constants improves code readability and maintainability. The default values for expire time and view limit are now clearly defined.


56-58: New state variables enhance user experience.

The addition of these state variables improves functionality:

  • isSecretVisible controls whether the secret is displayed or hidden
  • passwordConfirmation provides validation for passwords
  • secretModified tracks user interaction for appropriate error messaging

These changes directly support the PR objectives of improving UX and enhancing security.


72-72: Form field monitoring improves interactive validation.

Using the watch function to monitor password and secret fields enables real-time validation and UI updates, creating a more responsive user experience.

Also applies to: 85-86


88-95: Handlers tracking user interaction improve form feedback.

These handlers ensure the application knows when a user has interacted with the secret field, which allows for better timing of validation messages and improves the overall form experience.


96-99: Secret visibility toggle implemented correctly.

The computed displayed secret logic correctly implements the "hide secret" functionality mentioned in the PR objectives, preventing shoulder surfing by masking the secret content when toggled.


100-103: Form validation logic ensures data integrity.

The password validation logic is comprehensive, checking for:

  • Password matching
  • Incomplete password fields
  • Presence of secret content

This improves the quality of submitted data and prevents potential user errors.


114-116: Improved type conversion for form values.

Explicit conversion of string values to numbers ensures correct data types are used when creating the shared secret, preventing potential type-related bugs.

Also applies to: 122-122


129-136: Complete form reset after submission.

The form reset now properly handles all fields, including the new password confirmation field, ensuring a clean slate for creating a new secret.


192-238: Enhanced secret input with visibility toggle and security features.

The secret textarea now includes:

  1. A visibility toggle button
  2. Prevention of copy/paste when the secret is hidden
  3. Disabled context menu when the secret is hidden
  4. Visual feedback through border highlighting

These changes directly fulfill the PR objectives of enhancing security and improving UX.


213-226: Security enhancement: Prevented copy/paste of hidden secrets.

The implementation correctly prevents both keyboard shortcuts and context menu actions for copying and pasting when the secret is hidden, effectively addressing the security improvement mentioned in the PR objectives.


262-267: Password field clears confirmation when emptied.

When the password field is emptied, the confirmation field is also cleared, maintaining consistency in the form state and preventing validation confusion.


273-326: Password confirmation provides excellent visual feedback.

The implemented password confirmation field:

  1. Appears/disappears dynamically based on password field content
  2. Uses color-coded borders to indicate match status
  3. Shows appropriate icons for different states
  4. Provides clear error messages

This implementation significantly improves form validation UX.


404-405: Dynamic submit button state improves user feedback.

The submit button now dynamically changes its appearance and disabled state based on form validation, providing clear feedback about when the form can be submitted.


431-443: Complete state reset when sharing another secret.

The "Share Another Secret" button now properly resets all form fields and state variables, ensuring a clean experience when users want to share multiple secrets.


204-208:

❓ Verification inconclusive

Verify field update logic when secret is not visible.

When isSecretVisible is false, the field's value change handler doesn't execute, which is intentional for preventing editing while hidden. However, you might want to ensure users understand they need to make the secret visible before editing.


🏁 Script executed:

#!/bin/bash
# Check if there are any UI messages or tooltips explaining how to edit when secret is hidden
rg -A 3 -B 3 "isSecretVisible.*false" --glob "*.tsx" --glob "*.ts"

Length of output: 68


Clarify User Guidance for Editing Hidden Secret

The code intentionally skips updating the field when isSecretVisible is false, preventing users from editing while the secret is hidden. However, our automated search did not reveal any UI messages or tooltips informing users that they must unhide the secret to enable editing. Please manually verify that the UI provides clear guidance to users under this condition. If not, consider adding an explicit message or tooltip to improve the UX.

  • Location: frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx (lines 204–208)
  • Key Concern: Ensure that when the secret is hidden, users are informed they need to make it visible before editing.

@beaukuhn beaukuhn changed the title Feat/Improve UX and functionality of the secret share page Improve UX and functionality of the secret share page Mar 28, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx (1)

99-107: Well-structured validation logic and computed properties.

Breaking down complex conditionals into named boolean variables significantly improves code readability. This approach makes the validation logic easier to understand and maintain.

However, there's a redundant Boolean cast that can be simplified.

-  const isPasswordConfirmationMissing = Boolean(password) && !Boolean(passwordConfirmation);
+  const isPasswordConfirmationMissing = Boolean(password) && !passwordConfirmation;
🧰 Tools
🪛 Biome (1.9.4)

[error] 103-103: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a243c5f and 9dd2e50.

📒 Files selected for processing (1)
  • frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx (11 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx

[error] 103-103: Avoid redundant Boolean call

It is not necessary to use Boolean call when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant Boolean call

(lint/complexity/noExtraBooleanCast)

🔇 Additional comments (10)
frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx (10)

30-31: Good use of constants instead of magic numbers.

Using constants to replace magic numbers improves code readability and maintainability. Creating DEFAULT_EXPIRES_IN and DEFAULT_VIEW_LIMIT makes the code easier to understand and modify in the future.


56-58: Well-structured state variables for enhanced functionality.

The addition of these state variables reflects good React patterns:

  • isSecretVisible provides toggle functionality for the secret's visibility
  • passwordConfirmation enables password matching validation
  • secretModified adds better UX by waiting until user interaction before showing validation errors

These align perfectly with the PR's objective to improve UX and security.


85-85: Effective use of React Hook Form's 'watch' functionality.

Using watch to track multiple form fields is more efficient than implementing multiple event handlers. This approach reduces boilerplate and keeps the component's state in sync with the form.


87-94: Good event handling design.

Separating the event handlers for blur and change provides clear separation of concerns. Setting secretModified only after user interaction prevents premature validation errors, improving user experience.


95-97: Clever implementation of secret masking.

The computed value approach for displaying either the actual secret or masked characters is elegant and effective. This implementation successfully addresses the PR objective of hiding sensitive information to prevent shoulder surfing.


196-242: Excellent implementation of the secret visibility toggle and copy protection.

This implementation successfully addresses multiple PR objectives:

  1. The eye icon toggle for showing/hiding the secret
  2. Prevention of copying hidden text via keyboard shortcuts
  3. Prevention of copying hidden text via right-click context menu

The relative positioning of the toggle button is also well-implemented for a clean UI.


266-271: Smart UX improvement for password field.

Clearing the password confirmation when the password field is emptied prevents confusion and ensures the fields stay in sync. This is a thoughtful enhancement to the form's usability.


277-331: Excellent implementation of the confirm password field.

This implementation addresses a key PR objective with several nice features:

  1. Smooth animation when showing/hiding the confirmation field
  2. Clear visual indicators for field state (amber for missing, red for mismatch, green for match)
  3. Helpful error messages and icons that guide the user

The conditional styling provides excellent visual feedback to users, making the form more intuitive.


409-410: Enhanced submit button feedback.

Disabling the submit button when validation fails provides immediate feedback to users. The variant change also provides visual cues about form validity, which improves overall UX.


436-448: Comprehensive reset functionality.

The enhanced reset logic ensures all state variables are properly reset when sharing another secret. This prevents state leakage between form submissions and maintains a consistent user experience.

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