adobe / adobe/aem-sidekick

Expose Sidekick auth state as a reflected boolean attribute on <aem-sidekick>

Open
#896 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
4
Forks
11
Avg merge
1d 5h
Merged PRs (30d)
7

Description


### Summary

Would the team consider exposing the Sidekick's authenticated state to the host page as a reflected boolean attribute, e.g. ,
mirroring appStore.isAuthenticated()? This would give page-world code a documented, synchronous, observable way to read auth state.

(Filing at @rofe's suggestion from the #aem-sidekick discussion.)

### Use case

Milo / MEP ships preview tooling on adobe.com (an authoring overlay) that should only render for signed-in authors. To decide whether to show it, our code
running in the page's main world needs to know whether an author is currently signed into Sidekick.

To be clear on scope: this is preview-tooling UX, not a security control. It only decides whether an author sees a dev overlay. It guards no protected
content, audience data, or privileged action, and it runs only in a preview flag. So we're after a state signal, not an authorization mechanism.

### Current approach, and why it's fragile

There's no page-world-visible auth signal today, so we detect login by traversing the Sidekick's internal shadow DOM:

sk.shadowRoot > plugin-action-bar (shadowRoot) > login-button#user

keying on the not-authorized class, plus a MutationObserver for logout. It works and is prod-validated, but it depends entirely on undocumented shadow
internals. Any refactor of the action bar or login button can silently break it, and we'd only find out from a production report.

### Why a network check doesn't work from page-world code

The suggested alternative was a request to admin.hlx.page/profile (200 logged in / 401 logged out). We tested it from www.adobe.com while signed in:

- Page-world fetch('https://admin.hlx.page/profile', { credentials: 'include' }) returns 401.
- Request headers show no Cookie sent: auth_token is first-party to admin.hlx.page, and from the page's main world that's a third-party context, so the
browser won't send it.
- The extension's own /profile call returns 200 on the same page (it has host-permission cookie access), confirming the session is valid.

So no method or endpoint variant fixes it; the blocker is cross-origin cookie access, not the request shape. A page-world signal is the only thing that works.

### Proposed solution (rough sketch)

A reflected boolean attribute on the host element:

```
// in the AEMSidekick LitElement
@property({ type: Boolean, reflect: true, attribute: 'logged-in' })
accessor loggedIn = false;

// driven from the store, alongside the existing theme reaction
reaction(
() => this.appStore.isAuthenticated(),
(authenticated) => { this.loggedIn = authenticated; },
{ fireImmediately: true },
);
```

Consumers then read and observe it without touching internals:

sk.hasAttribute('logged-in');
new MutationObserver(...).observe(sk, { attributes: true, attributeFilter: ['logged-in'] });

It'd be intentionally one-way (store drives the attribute), so it stays a read-only status reflection rather than a new auth surface.

Happy to help however's most useful: put up a PR, or just leave it with you. Whatever fits the team's preference.

Contributor guide

Open the contributing guide

Research direction

Start at the AEMSidekick LitElement and trace the existing theme reaction to see how appStore.isAuthenticated() is observed. Confirm the reflected logged-in state is initialized and updated on authentication changes, then verify that page-world consumers can read and observe the attribute without relying on shadow DOM internals.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
frontend
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.