Skip to content
Open
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
607f064
fix 403 error when logged in
SharonStrats Mar 15, 2026
64151b4
change 401 not logged in to a msg
SharonStrats Mar 15, 2026
55a2c05
added break after 403
SharonStrats Mar 15, 2026
02b2774
Merge branch 'main' into fix/login-403-logged-in
bourgeoa Mar 20, 2026
e9f087b
Merge branch 'main' into fix/login-403-logged-in
bourgeoa Mar 20, 2026
fbe3371
Merge branch 'main' into fix/login-403-logged-in
SharonStrats May 4, 2026
50b5613
Merge branch 'post-milestone3m' into fix/login-403-logged-in
SharonStrats May 4, 2026
4fe6ab2
fix lint error
SharonStrats May 4, 2026
f27309a
fix login lint
SharonStrats May 4, 2026
5dac8db
test change
SharonStrats May 5, 2026
97e32b0
Potential fix for pull request finding
SharonStrats May 5, 2026
ab89cf5
Potential fix for pull request finding
SharonStrats May 5, 2026
8f043a3
Merge branch 'fix/login-403-logged-in' of https://github.com/SolidOS/…
SharonStrats May 5, 2026
f49e0fd
dedup logic
SharonStrats May 5, 2026
41886e7
Potential fix for pull request finding
SharonStrats May 5, 2026
1ce28f2
Potential fix for pull request finding
SharonStrats May 5, 2026
7de7e4c
Potential fix for pull request finding
SharonStrats May 5, 2026
c3a16a3
handle not logged in no repeat
SharonStrats May 5, 2026
4a9bd3f
401 errors throw
SharonStrats May 5, 2026
0c0c839
Potential fix for pull request finding
SharonStrats May 5, 2026
fd9904a
Potential fix for pull request finding
SharonStrats May 5, 2026
4854ebb
fix: use neutral background for not-logged-in message in handleNotLog…
Copilot May 5, 2026
f6a5180
fix: set preferencesFileError in all error branches of ensureLoadedPr…
Copilot May 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 74 additions & 9 deletions src/login/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ export async function ensureLoadedPreferences (
try {
context = await ensureLoadedProfile(context)

if (!context.me || !context.publicProfile) {
context.preferencesFileError =
context.preferencesFileError || 'Not logged in, so preferences were not loaded.'
return context
}

// console.log('back in Solid UI after logInLoadProfile', context)
const preferencesFile = await loadPreferences(context.me as NamedNode)
if (progressDisplay) {
Expand All @@ -134,27 +140,33 @@ export async function ensureLoadedPreferences (
context.preferencesFile = preferencesFile
} catch (err) {
let m2: string
if (err instanceof UnauthorizedError) {
const errorMessage = err instanceof Error ? err.message : `${err}`
if (err instanceof UnauthorizedError || /(?:status:\s*401\b|unauthorized)/i.test(errorMessage)) {
m2 =
'Oops — you are not authenticated (properly logged in), so SolidOS cannot read your preferences file. Try logging out and then logging back in.'
alert(m2)
'Not logged in, so preferences were not loaded.'
context.preferencesFileError = m2
debug.warn(m2)
return context
Comment thread
SharonStrats marked this conversation as resolved.
Comment on lines +143 to +149
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

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.

Done in commit f6a5180. The SameOriginForbiddenError, NotEditableError, and WebOperationError branches now all set context.preferencesFileError (with the message already assigned to m2), matching the pattern already in place for the 401/unauthorized and CrossOriginForbiddenError branches.

} else if (err instanceof CrossOriginForbiddenError) {
m2 = `Unauthorized: Assuming preference file blocked for origin ${window.location.origin}`
context.preferencesFileError = m2
return context
} else if (err instanceof SameOriginForbiddenError) {
m2 =
'You are not authorized to read your preference file. This may be because you are using an untrusted web app.'
context.preferencesFileError = m2
debug.warn(m2)
return context
} else if (err instanceof NotEditableError) {
m2 =
'You are not authorized to edit your preference file. This may be because you are using an untrusted web app.'
context.preferencesFileError = m2
debug.warn(m2)
return context
} else if (err instanceof WebOperationError) {
m2 =
'You are not authorized to edit your preference file. This may be because you are using an untrusted web app.'
context.preferencesFileError = m2
debug.warn(m2)
} else if (err instanceof FetchError) {
m2 = `Strange: Error ${err.status} trying to read your preference file.${err.message}`
Expand All @@ -177,20 +189,66 @@ export async function ensureLoadedPreferences (
export async function ensureLoadedProfile (
context: AuthenticationContext
): Promise<AuthenticationContext> {
const handleNotLoggedInProfile = (logMessage: (message: string) => void) => {
const notLoggedInMessage = 'Not logged in, so profile was not loaded.'
const notLoggedInMessageKey = 'not-logged-in-profile'
logMessage(notLoggedInMessage)
if (context.div && context.dom) {
const existingMessage = context.div.querySelector(
`[data-login-message="${notLoggedInMessageKey}"]`
)
if (!existingMessage) {
const errorBlock = widgets.errorMessageBlock(context.dom, notLoggedInMessage, 'white')
errorBlock.setAttribute('data-login-message', notLoggedInMessageKey)
context.div.appendChild(errorBlock)
Comment on lines +197 to +203
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

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.

Done in commit 4854ebb. The handleNotLoggedInProfile function now passes 'white' as the background color to widgets.errorMessageBlock, so the "Not logged in" notice renders as a neutral informational message instead of the default error-red (#fee) styling.

}
}
Comment thread
SharonStrats marked this conversation as resolved.
return context
}

if (context.publicProfile) {
return context
} // already done
let logInContext: AuthenticationContext | undefined
try {
const logInContext = await ensureLoggedIn(context)
logInContext = await ensureLoggedIn(context)
if (!logInContext.me) {
Comment thread
SharonStrats marked this conversation as resolved.
const webId = authSession.info?.webId || await authn.checkUser()
if (webId) {
authn.saveUser(webId, logInContext)
}
}
if (!logInContext.me) {
throw new Error('Could not log in')
return handleNotLoggedInProfile(debug.log)
}
context.publicProfile = await loadProfile(logInContext.me)
} catch (err) {
const message = err instanceof Error ? err.message : `${err}`
if (err instanceof UnauthorizedError || /(status:\s*401\b|unauthorized)/i.test(message)) {
return handleNotLoggedInProfile(debug.warn)
}
const loggedInUser = logInContext && logInContext.me
const isNonFatalProfileSideLoadFailure =
!!loggedInUser &&
(
err instanceof CrossOriginForbiddenError ||
err instanceof SameOriginForbiddenError ||
/status:\s*403\b|forbidden/i.test(message) ||
/cancel/i.test(message)
)
if (isNonFatalProfileSideLoadFailure) {
debug.warn(`Unable to load all profile-linked resources; continuing as logged in user: ${message}`)
context.publicProfile = loggedInUser!.doc()
return context
}
if (context.div && context.dom) {
context.div.appendChild(widgets.errorMessageBlock(context.dom, err.message))
context.div.appendChild(widgets.errorMessageBlock(context.dom, message))
}
const loginError = new Error(`Can't log in: ${message}`) as Error & { cause?: unknown }
if (err instanceof Error) {
loginError.cause = err
}
throw new Error(`Can't log in: ${err}`)
throw loginError
}
return context
}
Expand Down Expand Up @@ -784,6 +842,13 @@ export function selectWorkspace (

function displayOptions (context) {
// console.log('displayOptions!', context)
if (!context.preferencesFile) {
Comment thread
SharonStrats marked this conversation as resolved.
say(
context.preferencesFileError || 'Preferences not available.'
)
return
}

async function makeNewWorkspace (_event) {
const row = table.appendChild(dom.createElement('tr'))
const cell = row.appendChild(dom.createElement('td'))
Expand Down Expand Up @@ -1047,11 +1112,11 @@ export function newAppInstance (
* and/or a developer
*/
export async function getUserRoles (): Promise<Array<NamedNode>> {
const sessionInfo = authSession.info
const sessionInfo = authSession.info
if (!sessionInfo?.isLoggedIn || !sessionInfo?.webId) {
return []
}

const currentUser = authn.currentUser()
if (!currentUser) {
return []
Expand Down