Skip to content

68 migrate to reactive auth - #71

Open
PreciousOritsedere wants to merge 6 commits into
mainfrom
68-migrate-to-reactive-auth
Open

68 migrate to reactive auth#71
PreciousOritsedere wants to merge 6 commits into
mainfrom
68-migrate-to-reactive-auth

Conversation

@PreciousOritsedere

@PreciousOritsedere PreciousOritsedere commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Addresse #68

Drops @inrupt/solid-client-authn-browser along with the @ldo/solid-react and
solid-react-component wrappers in favour of @solid/reactive-authentication,
which drives sign-in from custom elements rather than a React context we do not
control. The authorization code flow runs in a popup, so it needs a static
callback page to hand the code back to the opener. With solid-react-component
gone there is nothing left for next.config to transpile, and the local
Community Solid Server port becomes configurable so it can move off 3000 when
that port is already taken.
The auth manager owns the token provider and the authenticated fetch, and keeps
the current session outside React so plain modules read the same value the UI
renders. It attaches credentials only to origins the app has opted in, because
the DPoP provider answers any 401 from any host and this app fetches URLs it
does not control. Sign-in accepts either a WebID or a login server, so identify()
asks the profile and OIDC discovery both rather than guessing from the shape of
the URL.
SolidAuthProvider mounts the authorization code element, restores a stored
session on load and exposes login and logout to the tree, taking LdoProvider's
place in the root layout. Components reach it through useSolidAuth, which
throws when called outside the provider so a missing wrapper fails loudly
instead of quietly rendering as signed out.
One field now takes either a WebID or a login server and works out which it is,
so what we remember between visits is the entry the user typed rather than a
choice from a list of identity providers. A profile may name several issuers,
so IssuerPickerDialog asks which to use only when the choice is genuinely
ambiguous. Signing out here cannot end the session at the login server, so
SignedOutNotice offers that door rather than leaving the next person signed
straight back in.
Every helper that talked to a pod went through getAuthenticatedSession(), which
existed only to reach into the inrupt session. They now take the authenticated
fetch from the auth manager, so that facade goes away entirely. Agent gains
oidcIssuers because the login page has to read the issuers a profile advertises
before there is any session at all.
AuthWrapper replaces solid-react-component's AuthGuard on the protected routes
and fails closed: children mount only once a session is confirmed, so nothing
below can fetch before there is anything to authenticate with. The components
underneath read the WebID and the authenticated fetch directly instead of from
the removed provider.
@PreciousOritsedere
PreciousOritsedere force-pushed the 68-migrate-to-reactive-auth branch from 9316350 to 7f85544 Compare August 6, 2026 09:13
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Comment thread package.json
"@inrupt/solid-client-authn-browser": "^3.1.1",
"@ldo/solid-react": "^1.0.0-alpha.33",
"@rdfjs/wrapper": "^0.33.0",
"@solid/reactive-authentication": "github:PreciousOritsedere/reactive-authentication",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This needs to point to a release version of reactive authn before merging

Comment on lines +155 to +171
function writeStoredCredentials(credentials: SolidCredentials): void {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(credentials));
} catch (error) {
// The session still works; it just won't survive a reload.
console.warn("Could not persist the session", error);
}
}

function clearStoredCredentials(): void {
try {
localStorage.removeItem(STORAGE_KEY);
} catch (error) {
// The identity stays on disk until something else clears it.
console.warn("Could not clear the stored session", error);
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should be handled upstream in the reactive authentication library with a LocalStorage store; rather than handling that logic here.

Comment on lines +145 to +153
function readStoredCredentials(): SolidCredentials | null {
try {
const parsed: unknown = JSON.parse(localStorage.getItem(STORAGE_KEY) ?? "null");
return isCredentials(parsed) ? parsed : null;
} catch (error) {
console.warn("Discarding an unreadable stored session", error);
return null;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment on lines +136 to +143
function isCredentials(value: unknown): value is SolidCredentials {
return (
typeof value === "object" &&
value !== null &&
typeof (value as SolidCredentials).webId === "string" &&
typeof (value as SolidCredentials).issuer === "string"
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment on lines +98 to +110
const logout = useCallback(async () => {
const generation = ++generationRef.current;
const previousIssuer = getCurrentSession()?.issuer ?? null;

clearStoredCredentials();
setStatus("restoring");

resetAuthManager();
await buildManager();
if (generationRef.current !== generation) return;
setSignedOutFrom(previousIssuer);
setStatus("anonymous");
}, [buildManager]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This logic should be handled up-stream in the reactive authentication library as we move token storage over there.

Comment on lines +90 to +96
const login = useCallback((next: { webId: string; issuer: string }) => {
generationRef.current++;
setCurrentSession(next);
writeStoredCredentials(next);
setSignedOutFrom(null);
setStatus("authenticated");
}, []);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We should not need to proactively trigger login since this will be triggered reactively by the reactive-authentication package.

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.

2 participants