diff --git a/README.md b/README.md
index 8aea1923..e3496ea8 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,9 @@ so typically a hand-written user interface will be chosen over a generic machine
These panes are used in the Data Browser - see mashlib
[https://github.com/linkeddata/mashlib](https://github.com/linkeddata/mashlib)
+When panes are hosted through mashlib and use solid-logic authentication, ensure the refresh worker is served same-origin. The worker export and runtime override contract are documented in solid-logic:
+https://github.com/solidos/solid-logic#worker-asset-and-runtime-configuration
+
Currently the panes available include:
- A default pane which lists the properties of any object
diff --git a/dev/loader.ts b/dev/loader.ts
index 71984bfc..a22f552f 100644
--- a/dev/loader.ts
+++ b/dev/loader.ts
@@ -129,22 +129,22 @@ window.onload = async () => {
console.log('document ready')
// registerPanes((cjsOrEsModule: any) => paneRegistry.register(cjsOrEsModule.default || cjsOrEsModule))
paneRegistry.register(require('contacts-pane'))
- await authSession.handleIncomingRedirect({
- restorePreviousSession: true
- })
- const session = await authSession
- if (!session.info.isLoggedIn) {
+ await solidLogicSingleton.authn.checkUser()
+ const session = authSession
+ const isLoggedIn = session?.info?.isLoggedIn ?? session?.isActive ?? Boolean(session?.webId)
+ if (!isLoggedIn) {
console.log('The user is not logged in')
const loginBanner = document.getElementById('loginBanner');
if (loginBanner) {
loginBanner.innerHTML = '';
}
} else {
- console.log(`Logged in as ${session.info.webId}`)
+ const loggedWebId = session?.info?.webId || session?.webId
+ console.log(`Logged in as ${loggedWebId}`)
const loginBanner = document.getElementById('loginBanner');
if (loginBanner) {
- loginBanner.innerHTML = `Logged in as ${session.info.webId} `;
+ loginBanner.innerHTML = `Logged in as ${loggedWebId} `;
}
}
addLayoutButtons()
@@ -155,8 +155,9 @@ window.logout = () => {
window.location.href = ''
}
window.login = async function () {
- const session = await authSession
- if (!session.info.isLoggedIn) {
+ const session = authSession
+ const isLoggedIn = session?.info?.isLoggedIn ?? session?.isActive ?? Boolean(session?.webId)
+ if (!isLoggedIn) {
const issuer = prompt('Please enter an issuer URI', 'https://solidcommunity.net')
if (issuer) {
await authSession.login({
diff --git a/jest.config.mjs b/jest.config.mjs
index 7d1c1632..a9873594 100644
--- a/jest.config.mjs
+++ b/jest.config.mjs
@@ -19,7 +19,9 @@ export default {
'\\.svg\\?raw$': '/test/__mocks__/fileMock.js',
'\\.(svg)$': '/test/__mocks__/fileMock.js',
'\\.(png|jpe?g|gif|webp|avif)$': '/test/__mocks__/fileMock.js',
- '\\.css$': '/test/__mocks__/styleMock.js'
+ '\\.css$': '/test/__mocks__/styleMock.js',
+ 'solid-logic': '/../solid-logic/src/index.ts',
+ 'solid-oidc-client-browser': '/test/mocks/solid-oidc-client-browser.ts'
},
setupFilesAfterEnv: ['./test/helpers/setup.ts'],
testMatch: ['**/?(*.)+(spec|test).[tj]s?(x)'],
diff --git a/src/mainPage/menu.ts b/src/mainPage/menu.ts
index 028a3fdc..c978cb98 100644
--- a/src/mainPage/menu.ts
+++ b/src/mainPage/menu.ts
@@ -59,7 +59,7 @@ const applyMenuCollapsedState = (navMenu: HTMLElement | null): void => {
updateCollapseButtonPosition(navMenu, collapseBtn)
}
-const isLoggedIn = (): boolean => Boolean(authSession?.info?.isLoggedIn)
+const isLoggedIn = (): boolean => Boolean(authSession?.isActive)
const ensureMenuSkeleton = () => {
menuCollapsed = loadMenuCollapsedState()
diff --git a/test/mocks/solid-oidc-client-browser.ts b/test/mocks/solid-oidc-client-browser.ts
new file mode 100644
index 00000000..69af6043
--- /dev/null
+++ b/test/mocks/solid-oidc-client-browser.ts
@@ -0,0 +1,57 @@
+type Listener = (...args: any[]) => void
+
+class EventEmitterLike {
+ private listeners: Record = {}
+
+ on(event: string, listener: Listener): void {
+ const list = this.listeners[event] || []
+ list.push(listener)
+ this.listeners[event] = list
+ }
+
+ emit(event: string, ...args: any[]): void {
+ const list = this.listeners[event] || []
+ list.forEach(listener => listener(...args))
+ }
+}
+
+export class Session {
+ info: { webId?: string, isLoggedIn: boolean } = { isLoggedIn: false }
+ webId?: string
+ isActive = false
+ events = new EventEmitterLike()
+
+ addEventListener(event: string, listener: Listener): void {
+ this.events.on(event, listener)
+ }
+
+ async handleIncomingRedirect(): Promise {
+ return
+ }
+
+ async handleRedirectFromLogin(): Promise {
+ return
+ }
+
+ async restore(): Promise {
+ return
+ }
+
+ async login(): Promise {
+ return
+ }
+
+ async logout(): Promise {
+ this.info = { isLoggedIn: false }
+ this.webId = undefined
+ this.isActive = false
+ }
+
+ fetch(input: RequestInfo | URL, init?: RequestInit): Promise {
+ return globalThis.fetch(input, init)
+ }
+
+ authFetch(input: RequestInfo | URL, init?: RequestInit): Promise {
+ return globalThis.fetch(input, init)
+ }
+}
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index f3ba4d21..944efc7f 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -57,8 +57,18 @@
] /* List of folders to include type definitions from. */,
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
- "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
- // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
+ "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
+ "preserveSymlinks": true, /* Keep symlinks unresolved to avoid duplicate rdflib type identities in local linked dev. */
+ /* baseUrl + paths below are for local integrated dev only.
+ They force a single rdflib type identity when solid-panes is linked to local solid-logic/solid-ui.
+ Both options are deprecated in TS6+ but remain functional until TS7.
+ See solid-ui README: Local Integrated Development for context. */
+ "ignoreDeprecations": "6.0",
+ "baseUrl": ".",
+ "paths": {
+ "rdflib": ["node_modules/rdflib"],
+ "rdflib/*": ["node_modules/rdflib/*"]
+ }
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */