Skip to content

fix: CSP-safe password toggle icon visibility - #17

Merged
HecFranco merged 1 commit into
mainfrom
fix/csp-safe-icon-visibility
Aug 12, 2026
Merged

fix: CSP-safe password toggle icon visibility#17
HecFranco merged 1 commit into
mainfrom
fix/csp-safe-icon-visibility

Conversation

@HecFranco

@HecFranco HecFranco commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replace inline style="display: none" / element.style.display with is-password-visible + rules in toggle_password.css / SCSS so both eye icons are not shown when CSP style-src has a nonce (browsers then ignore 'unsafe-inline').
  • Align demos to the same class toggle (drop Bootstrap d-none) and document upgrade notes in CHANGELOG / UPGRADING / README.

Test plan

  • make test (49 tests OK)
  • Visual check on a host with nonce CSP: only one eye icon at a time; click toggles correctly
  • Confirm hosts still loading asset('css/toggle_password.css', 'nowo_password_toggle') (or SCSS import)

Made with Cursor

Summary by CodeRabbit

  • Bug Fixes

    • Improved password visibility toggles to display the correct eye icon reliably under strict Content Security Policies.
    • Replaced inline icon visibility changes with CSS-based state handling.
  • Documentation

    • Updated usage, upgrade, and changelog documentation for the new password-toggle behavior.
    • Clarified styling requirements for custom themes and strict CSP configurations.

Hide/show eye icons via is-password-visible + stylesheet rules instead of
inline style / element.style.display, which browsers ignore when style-src
includes a nonce.
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The password toggle now controls icon visibility with the is-password-visible class. CSS replaces inline style changes. Symfony demos, documentation, and Twig tests reflect the new behavior.

Changes

Password visibility state

Layer / File(s) Summary
CSS icon state rules
src/Resources/public/css/toggle_password.css, src/Resources/public/css/toggle_password.scss
CSS hides and shows the appropriate eye icon based on is-password-visible.
Toggle state behavior
src/Resources/views/Form/toggle_password_widget.html.twig, demo/*/templates/form/toggle_password_widget.html.twig
Toggle scripts update the state class instead of changing icon styles or d-none classes. Password type and ARIA label updates remain unchanged.
Demo alignment and documentation
demo/*/templates/demo/form.html.twig, README.md, docs/*, tests/Unit/Twig/TogglePasswordWidgetTemplateTest.php
Demos, documentation, upgrade guidance, and tests describe or validate CSS-based icon visibility.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ToggleButton
  participant PasswordInput
  participant TogglePasswordCSS
  participant EyeIcons
  ToggleButton->>PasswordInput: Toggle password type
  ToggleButton->>ToggleButton: Add or remove is-password-visible
  TogglePasswordCSS->>EyeIcons: Apply state-based visibility rules
  ToggleButton->>ToggleButton: Update ARIA label
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: making password-toggle icon visibility CSP-safe.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/csp-safe-icon-visibility

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

@coderabbitai review

@HecFranco
HecFranco merged commit 6f0f0fc into main Aug 12, 2026
23 of 24 checks passed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
demo/symfony7/templates/form/toggle_password_widget.html.twig (1)

11-25: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Add keyboard activation to all demo password toggles.

Each demo control exposes role="button" and tabindex="0" but handles only onclick. Add the same Enter and Space handling used by the core template.

  • demo/symfony7/templates/form/toggle_password_widget.html.twig#L11-L25: add an onkeydown handler.
  • demo/symfony8-php85/templates/form/toggle_password_widget.html.twig#L11-L25: add an onkeydown handler.
  • demo/symfony8/templates/form/toggle_password_widget.html.twig#L11-L25: add an onkeydown handler.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@demo/symfony7/templates/form/toggle_password_widget.html.twig` around lines
11 - 25, Add an onkeydown handler to the password toggle control in
demo/symfony7/templates/form/toggle_password_widget.html.twig lines 11-25,
demo/symfony8-php85/templates/form/toggle_password_widget.html.twig lines 11-25,
and demo/symfony8/templates/form/toggle_password_widget.html.twig lines 11-25.
Reuse the core template’s keyboard behavior so Enter and Space activate the same
password visibility toggle as onclick, including preventing Space’s default page
behavior.
🧹 Nitpick comments (1)
src/Resources/views/Form/toggle_password_widget.html.twig (1)

58-58: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add browser-level coverage for CSS-dependent icon states.

The bundle registers the named asset package conditionally, but the widget does not load the stylesheet. Without toggle_password.css, both icons are visible initially. Test the initial and visible states.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Resources/views/Form/toggle_password_widget.html.twig` at line 58, Add
browser-level coverage for the toggle-password widget’s CSS-dependent icon
states, verifying that only the hidden-password icon is initially visible and
that toggling the control shows the visible-password icon. Ensure the test loads
the toggle_password.css stylesheet and exercises the rendered widget rather than
testing markup alone.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/UPGRADING.md`:
- Around line 5-10: Keep only one “## Unreleased” section in docs/UPGRADING.md
by merging the CSP-safe icon visibility bullets into the existing Unreleased
guidance at the later heading, or consolidating the later content under the new
heading. Preserve the document’s structure and tone, avoid inventing a release
version, and keep the resulting guidance aligned with CHANGELOG.

In `@tests/Unit/Twig/TogglePasswordWidgetTemplateTest.php`:
- Around line 22-23: Strengthen the assertions in
TogglePasswordWidgetTemplateTest so they reject any inline style attribute
containing display: none, regardless of HTML attribute quoting or whitespace,
rather than only the exact Twig string. Use a regex or parsed-attribute
assertion while retaining the existing style.display check.

---

Outside diff comments:
In `@demo/symfony7/templates/form/toggle_password_widget.html.twig`:
- Around line 11-25: Add an onkeydown handler to the password toggle control in
demo/symfony7/templates/form/toggle_password_widget.html.twig lines 11-25,
demo/symfony8-php85/templates/form/toggle_password_widget.html.twig lines 11-25,
and demo/symfony8/templates/form/toggle_password_widget.html.twig lines 11-25.
Reuse the core template’s keyboard behavior so Enter and Space activate the same
password visibility toggle as onclick, including preventing Space’s default page
behavior.

---

Nitpick comments:
In `@src/Resources/views/Form/toggle_password_widget.html.twig`:
- Line 58: Add browser-level coverage for the toggle-password widget’s
CSS-dependent icon states, verifying that only the hidden-password icon is
initially visible and that toggling the control shows the visible-password icon.
Ensure the test loads the toggle_password.css stylesheet and exercises the
rendered widget rather than testing markup alone.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b1bc0485-ff05-4df0-ba1b-1c59cd32be8f

📥 Commits

Reviewing files that changed from the base of the PR and between 8c2991a and bb15d0b.

📒 Files selected for processing (13)
  • README.md
  • demo/symfony7/templates/demo/form.html.twig
  • demo/symfony7/templates/form/toggle_password_widget.html.twig
  • demo/symfony8-php85/templates/demo/form.html.twig
  • demo/symfony8-php85/templates/form/toggle_password_widget.html.twig
  • demo/symfony8/templates/demo/form.html.twig
  • demo/symfony8/templates/form/toggle_password_widget.html.twig
  • docs/CHANGELOG.md
  • docs/UPGRADING.md
  • src/Resources/public/css/toggle_password.css
  • src/Resources/public/css/toggle_password.scss
  • src/Resources/views/Form/toggle_password_widget.html.twig
  • tests/Unit/Twig/TogglePasswordWidgetTemplateTest.php

Comment thread docs/UPGRADING.md
Comment on lines +5 to +10
## Unreleased (CSP-safe icon visibility)

- **Load the bundle CSS** (`asset('css/toggle_password.css', 'nowo_password_toggle')` or import the SCSS). Icon show/hide now depends on `.icon-visible` / `.is-password-visible` rules in that stylesheet.
- **Custom form theme overrides:** if you copied `toggle_password_widget.html.twig`, stop using inline `style.display` / `style: 'display: none'` / Bootstrap `d-none`. Toggle `is-password-visible` on the button (see the bundle widget) and keep both icons in the markup without inline hide styles.
- **Hosts with strict `script-src` (no `'unsafe-inline'`):** the default widget still uses inline `onclick` for Live Component compatibility; override the form theme with a Stimulus (or other non-inline) controller if needed — same as before.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Keep a single Unreleased section.

docs/UPGRADING.md already has another ## Unreleased heading at Line 109. The new section at Line 5 splits current guidance into two locations and makes the upgrade order ambiguous. Merge these bullets into one section or rename the existing future-release section without inventing a version.

As per path instructions, preserve document structure and tone, and keep CHANGELOG and UPGRADING aligned.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/UPGRADING.md` around lines 5 - 10, Keep only one “## Unreleased” section
in docs/UPGRADING.md by merging the CSP-safe icon visibility bullets into the
existing Unreleased guidance at the later heading, or consolidating the later
content under the new heading. Preserve the document’s structure and tone, avoid
inventing a release version, and keep the resulting guidance aligned with
CHANGELOG.

Source: Path instructions

Comment on lines +22 to +23
$this->assertStringNotContainsString('style.display', $content);
$this->assertStringNotContainsString("style: 'display: none'", $content);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Reject all inline display: none forms.

The test only excludes the exact Twig string style: 'display: none'. It does not reject literal HTML such as style="display: none" or spacing and quote variants. Use a regex or parsed-attribute assertion that detects any inline style containing display: none.

As per path instructions, PHPUnit tests for this package must add or update tests for new behaviour and avoid trivial assertions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/Unit/Twig/TogglePasswordWidgetTemplateTest.php` around lines 22 - 23,
Strengthen the assertions in TogglePasswordWidgetTemplateTest so they reject any
inline style attribute containing display: none, regardless of HTML attribute
quoting or whitespace, rather than only the exact Twig string. Use a regex or
parsed-attribute assertion while retaining the existing style.display check.

Source: Path instructions

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