google / google/site-kit-wp

Read the intent arguments on the dashboard screen

Open
#13,465 2 comments 0 reactions 0 assignees View on GitHub
P1 Team S Type: Enhancement
Dominant language
JavaScript
Stars
1.4k
Forks
383
Avg merge
4d 14h
Merged PRs (30d)
77

Description

## Feature Description

The Site Kit dashboard screen already turns query arguments into a choice of what the page renders. When `slug` and `reAuth=true` are present, `Screens.php` passes the module slug to the page as the `data-setup-module-slug` attribute on `#js-googlesitekit-main-dashboard`, and the JavaScript renders the module setup flow instead of the dashboard.

Intents arrive the same way, with two arguments an external Google surface puts on the link: `intent`, which says which instruction this is, and `code`, the one-time value that identifies one instance of it. This issue makes the dashboard screen read them. When both are present, the current user has the Site Kit setup permission, and the intent is registered and available, the screen emits `data-intent-slug` and `data-intent-code` on the same container. The registry it resolves `intent` against is added in #13464.

Everything else falls through to the ordinary dashboard with both attributes empty. An intent ID the plugin does not recognise is the normal case for a user whose plugin is older than the intent, and ending the request with an error would tell that person nothing they can act on. The `code` argument is a common name that other plugins may already use in their own admin links, so it is only read once `intent` is present and recognised.

Link to the design doc: https://docs.google.com/document/d/1-8aikH7EzELWZCFuava3izGfhUVPiOFE3Oww4czjTW0/edit?tab=t.0

---------------

_Do not alter or remove anything below. The following sections will be managed by moderators only._

## Acceptance criteria

* Opening `admin.php?page=googlesitekit-dashboard&intent=ads-conversion-tracking&code=abc123` as a user with the `googlesitekit_setup` capability, with `adsConversionTrackingIntent` enabled, renders `#js-googlesitekit-main-dashboard` with `data-intent-slug="ads-conversion-tracking"` and `data-intent-code="abc123"`.
* Both attributes are empty and the ordinary dashboard renders when:
* `intent` is missing;
* `code` is missing;
* `intent` names an intent that is not registered, or one whose intent reports itself unavailable, including `ads-conversion-tracking` while `adsConversionTrackingIntent` is off;
* the current user does not have the `googlesitekit_setup` capability, including a view-only dashboard user.
* Opening the dashboard screen with `code` but no `intent` renders the ordinary dashboard with both attributes empty.
* An unknown or unavailable `intent` value never ends the request with `wp_die()` or a redirect.
* An `intent` or `code` value containing `">alert(1)` renders as text inside the attribute value and executes nothing.
* `data-setup-module-slug` keeps its current behaviour: `slug` with `reAuth=true` still renders the module setup flow, and an inactive module slug still ends the request with the existing 403 message.

## Implementation Brief

* [ ] In `includes/Core/Admin/Screens.php`:
* Add a private `$intents` property holding a `Google\Site_Kit\Core\Intents\Intents` instance (added in #13464), assigned from a new final constructor argument after `Authentication $authentication`.
* In the `render_callback` of the `googlesitekit-dashboard` screen, inside the branch that renders `#js-googlesitekit-main-dashboard`, read `intent` and `code` from `INPUT_GET` with `$context->input()->filter()` and pass each through `htmlspecialchars()`, the same way `slug` is read today.
* Start `$intent_slug` and `$intent_code` as empty strings. Set them to the two values read above only when all four of these hold: `intent` is not empty, `code` is not empty, `current_user_can( Permissions::SETUP )` is true, and `$this->intents->get_intent( $intent )` returns an intent rather than `null`.
* Add `data-intent-slug=""` and `data-intent-code=""` to the `#js-googlesitekit-main-dashboard` element, next to `data-setup-module-slug`.
* Do not add any `wp_die()` or redirect for an unknown or unavailable intent. Leave the `$setup_module_slug` branch, including its existing 403 `wp_die()` for a module that is not active, exactly as it is.

* [ ] In `includes/Plugin.php`:
* Pass the `$intents` instance to the `Core\Admin\Screens` constructor.

### Test Coverage

* Add cases to `tests/phpunit/integration/Core/Admin/ScreensTest.php` covering the rendered `#js-googlesitekit-main-dashboard` markup for a user with the `googlesitekit_setup` capability and `adsConversionTrackingIntent` enabled:
* `intent=ads-conversion-tracking` and `code=abc123` produce `data-intent-slug="ads-conversion-tracking"` and `data-intent-code="abc123"`;
* both attributes are empty when `intent` is missing, when `code` is missing, when `intent` names an intent that was never registered, and when `intent` names an intent whose `is_available()` returns `false`, including `ads-conversion-tracking` with the flag off;
* both attributes are empty for a user without the `googlesitekit_setup` capability;
* an `intent` or `code` value containing `">alert(1)` is escaped in the attribute value;
* an unknown `intent` renders the page instead of ending the request;
* `slug` with `reAuth=true` still fills `data-setup-module-slug`, and an inactive module slug still ends the request with the 403 message.

## QA Brief

* Nothing visible to test. After issue passing CR/MR it can go to approaval

## Changelog entry

* N/A

Contributor guide

Open the contributing guide

Research direction

Start in includes/Core/Admin/Screens.php and trace the dashboard render callback, then inspect how includes/Plugin.php constructs Screens and how intent lookup is provided by the registry from #13464. Run the relevant integration coverage in tests/phpunit/integration/Core/Admin/ScreensTest.php; done means the specified intent attributes render only for valid, available intents and permitted users, unsafe values are escaped, unknown intents fall through, and existing module setup behavior remains intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
php, wordpress
Domain
backend, testing
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.