From 76a47ad618b82a05c3b8bd415190752985d7ee2c Mon Sep 17 00:00:00 2001 From: Sharon Stratsianis Date: Thu, 19 Mar 2026 07:43:17 +1100 Subject: [PATCH 1/5] error messages --- src/outline/manager.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/outline/manager.js b/src/outline/manager.js index 767a832e..6a9031ad 100644 --- a/src/outline/manager.js +++ b/src/outline/manager.js @@ -2106,11 +2106,16 @@ export default function (context) { const existing = p.querySelector('[data-outline-error-for="' + docUri + '"]') if (existing) return } + const detailStr = typeof detail === 'string' ? detail : (detail && detail.message) || '' + const errorStatus = (errObj && errObj.status) || (detailStr.match(/status:\s*(\d+)/) || [])[1] + const isAuthError = errorStatus === 401 || errorStatus === 403 || + errorStatus === '401' || errorStatus === '403' || + /Unauthorized|Forbidden/.test(detailStr) const message = UI.widgets.errorMessageBlock( dom, - detail, - '#fee', - errObj instanceof Error ? errObj : undefined + isAuthError ? 'You need to log in to see this resource.' : detail, + isAuthError ? '#d8d8d8' : '#fee', + !isAuthError && errObj instanceof Error ? errObj : undefined ) if (docUri) message.setAttribute('data-outline-error-for', docUri) p.appendChild(message) From 30b1a7a5ba01a14235b1bdefd3d2c53386addbcf Mon Sep 17 00:00:00 2001 From: Sharon Stratsianis Date: Thu, 19 Mar 2026 07:43:36 +1100 Subject: [PATCH 2/5] logout and login --- src/mainPage/index.ts | 44 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/src/mainPage/index.ts b/src/mainPage/index.ts index 8c8b5345..15cf9f9b 100644 --- a/src/mainPage/index.ts +++ b/src/mainPage/index.ts @@ -4,16 +4,52 @@ */ import { LiveStore, NamedNode } from 'rdflib' +import { authSession, authn } from 'solid-logic' import { getOutliner } from '../index' import { createHeader } from './header' import { createFooter } from './footer' export default async function initMainPage (store: LiveStore, uri?: string | NamedNode | null) { const outliner = getOutliner(document) - uri = uri || window.location.href - let subject = uri - if (typeof uri === 'string') subject = store.sym(uri) - outliner.GotoSubject(subject, true, undefined, true, undefined) + const hasExplicitUriArg = uri !== undefined && uri !== null + const locationUrl = new URL(window.location.href) + const explicitUriQuery = locationUrl.searchParams.get('uri') + const isLoggedIn = !!(authSession.info && authSession.info.isLoggedIn) + const isBareAppRoot = locationUrl.pathname === '/' && !locationUrl.search && !locationUrl.hash + + if (isBareAppRoot && !hasExplicitUriArg && !explicitUriQuery) { + // At bare app root, avoid fetching '/' as data. If logged in, land on the user's profile instead. + let me = authn.currentUser() + if (isLoggedIn && !me) { + let webId = await authn.checkUser() + if (!webId) { + // Some IdP/session states resolve slightly after app bootstrap. + await new Promise(resolve => setTimeout(resolve, 300)) + webId = await authn.checkUser() + } + if (typeof webId === 'string') { + me = store.sym(webId) + } + } + if (isLoggedIn && me) { + outliner.GotoSubject(me, true, undefined, true, undefined) + } else if (isLoggedIn) { + // Optional override: set localStorage.solidosSafeLandingUri to a public resource URI. + const configuredLandingUri = window.localStorage.getItem('solidosSafeLandingUri') + if (configuredLandingUri) { + const fallbackUrl = new URL(configuredLandingUri, locationUrl.origin) + if (!(fallbackUrl.origin === locationUrl.origin && fallbackUrl.pathname === '/')) { + outliner.GotoSubject(store.sym(fallbackUrl.toString()), true, undefined, true, undefined) + } + } + } + } else { + uri = uri || window.location.href + let subject = uri + if (typeof uri === 'string') subject = store.sym(uri) + outliner.GotoSubject(subject, true, undefined, true, undefined) + } + const header = await createHeader(store, outliner) const footer = createFooter(store) return Promise.all([header, footer]) From 428742d50ba1062fd16f06cfa98ae5515297e2bd Mon Sep 17 00:00:00 2001 From: Sharon Stratsianis Date: Sat, 21 Mar 2026 07:48:32 +1100 Subject: [PATCH 3/5] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/outline/manager.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/outline/manager.js b/src/outline/manager.js index 6a9031ad..0451846a 100644 --- a/src/outline/manager.js +++ b/src/outline/manager.js @@ -2108,8 +2108,9 @@ export default function (context) { } const detailStr = typeof detail === 'string' ? detail : (detail && detail.message) || '' const errorStatus = (errObj && errObj.status) || (detailStr.match(/status:\s*(\d+)/) || [])[1] - const isAuthError = errorStatus === 401 || errorStatus === 403 || - errorStatus === '401' || errorStatus === '403' || + const statusCode = Number(errorStatus) + const isAuthError = + (Number.isFinite(statusCode) && [401, 403].includes(statusCode)) || /Unauthorized|Forbidden/.test(detailStr) const message = UI.widgets.errorMessageBlock( dom, From 13884f3ea440578901b232dfb30ccce846cafa24 Mon Sep 17 00:00:00 2001 From: Sharon Stratsianis Date: Sat, 21 Mar 2026 07:49:08 +1100 Subject: [PATCH 4/5] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/mainPage/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainPage/index.ts b/src/mainPage/index.ts index 15cf9f9b..e8528b43 100644 --- a/src/mainPage/index.ts +++ b/src/mainPage/index.ts @@ -17,7 +17,7 @@ export default async function initMainPage (store: LiveStore, uri?: string | Nam const isLoggedIn = !!(authSession.info && authSession.info.isLoggedIn) const isBareAppRoot = locationUrl.pathname === '/' && !locationUrl.search && !locationUrl.hash - if (isBareAppRoot && !hasExplicitUriArg && !explicitUriQuery) { + if (isBareAppRoot && !hasExplicitUriArg && explicitUriQuery === null) { // At bare app root, avoid fetching '/' as data. If logged in, land on the user's profile instead. let me = authn.currentUser() if (isLoggedIn && !me) { From 5504248bcf8e9ef3187b10f86404a5b47204892e Mon Sep 17 00:00:00 2001 From: Sharon Stratsianis Date: Sat, 21 Mar 2026 07:49:58 +1100 Subject: [PATCH 5/5] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/mainPage/index.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/mainPage/index.ts b/src/mainPage/index.ts index e8528b43..99acf252 100644 --- a/src/mainPage/index.ts +++ b/src/mainPage/index.ts @@ -37,9 +37,16 @@ export default async function initMainPage (store: LiveStore, uri?: string | Nam // Optional override: set localStorage.solidosSafeLandingUri to a public resource URI. const configuredLandingUri = window.localStorage.getItem('solidosSafeLandingUri') if (configuredLandingUri) { - const fallbackUrl = new URL(configuredLandingUri, locationUrl.origin) - if (!(fallbackUrl.origin === locationUrl.origin && fallbackUrl.pathname === '/')) { - outliner.GotoSubject(store.sym(fallbackUrl.toString()), true, undefined, true, undefined) + try { + const fallbackUrl = new URL(configuredLandingUri, locationUrl.origin) + const protocol = fallbackUrl.protocol + // Only allow safe HTTP(S) protocols, and avoid redirecting back to bare app root. + if ((protocol === 'http:' || protocol === 'https:') && + !(fallbackUrl.origin === locationUrl.origin && fallbackUrl.pathname === '/')) { + outliner.GotoSubject(store.sym(fallbackUrl.toString()), true, undefined, true, undefined) + } + } catch { + // Ignore invalid configuredLandingUri values. } } }