Skip to content
This repository was archived by the owner on Dec 18, 2024. It is now read-only.

Commit 6980adf

Browse files
authored
feat: add the ability to skip loading profiles from SessionProvider (#695)
This is useful when using the React SDK to build a start/provisioning app, where the user will be able to login, but won't yet have a profile or WebID
1 parent 8405688 commit 6980adf

File tree

4 files changed

+74
-12
lines changed

4 files changed

+74
-12
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
44

5+
## Unreleased
6+
7+
- Added the ability to prevent the automatic loading of WebID's and Profiles from SessionProvider, this is useful when building provisioning applications where the user has logged in, but doesn't yet have a WebID or Pod or Profile documents.
8+
59
## 2.8.1 ( October 10, 2022)
610

711
- Upgrade Inrupt SDKs to latest versions

src/context/sessionContext/index.test.tsx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import {
3131
onSessionRestore,
3232
} from "@inrupt/solid-client-authn-browser";
3333

34+
import { getProfileAll } from "@inrupt/solid-client";
35+
3436
import { SessionContext, SessionProvider } from ".";
3537

3638
jest.mock("@inrupt/solid-client-authn-browser");
@@ -217,6 +219,42 @@ describe("SessionContext functionality", () => {
217219
expect(mockedClientModule.getProfileAll).toHaveBeenCalled();
218220
});
219221

222+
it("allows skipping fetching the user's profile if logging in succeeds", async () => {
223+
(handleIncomingRedirect as jest.Mock).mockResolvedValueOnce({
224+
webId: "https://some.webid",
225+
});
226+
227+
(getProfileAll as jest.Mock).mockResolvedValue({
228+
webIdProfile: null,
229+
altProfileAll: [],
230+
});
231+
232+
const session = {
233+
info: {
234+
isLoggedIn: true,
235+
webId: "https://fakeurl.com/me",
236+
},
237+
on: jest.fn(),
238+
} as any;
239+
240+
(getDefaultSession as jest.Mock).mockReturnValue(session);
241+
242+
const screen = render(
243+
<SessionProvider skipLoadingProfile>
244+
<ChildComponent />
245+
</SessionProvider>
246+
);
247+
await waitFor(async () => {
248+
expect(screen.getByTestId("profile").textContent).toBe(
249+
"No profile found"
250+
);
251+
});
252+
253+
expect(screen.getByTestId("profile").textContent).toBe("No profile found");
254+
expect(getProfileAll).not.toHaveBeenCalled();
255+
expect(handleIncomingRedirect).toHaveBeenCalled();
256+
});
257+
220258
it("uses the login and logout functions from session", async () => {
221259
(handleIncomingRedirect as jest.Mock).mockResolvedValueOnce(null);
222260

src/context/sessionContext/index.tsx

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ export interface ISessionProvider {
7575
restorePreviousSession?: boolean;
7676
/** @since 2.3.0 */
7777
onSessionRestore?: (url: string) => void;
78+
/**
79+
* @since unreleased
80+
* @experimental
81+
* */
82+
skipLoadingProfile?: boolean;
7883
}
7984

8085
/**
@@ -86,6 +91,7 @@ export const SessionProvider = ({
8691
onError,
8792
sessionRequestInProgress: defaultSessionRequestInProgress,
8893
restorePreviousSession,
94+
skipLoadingProfile,
8995
onSessionRestore,
9096
}: ISessionProvider): ReactElement => {
9197
const restoreSession =
@@ -119,18 +125,19 @@ export const SessionProvider = ({
119125
url: window.location.href,
120126
restorePreviousSession: restoreSession,
121127
})
122-
.then((sessionInfo) =>
128+
.then(async (sessionInfo) => {
129+
if (skipLoadingProfile === true) {
130+
return;
131+
}
132+
123133
// If handleIncomingRedirect logged the session in, we know what the current
124134
// user's WebID is.
125-
sessionInfo?.webId !== undefined
126-
? getProfileAll(sessionInfo?.webId, {
127-
fetch: session.fetch,
128-
})
129-
: undefined
130-
)
131-
.then((foundProfile) => {
132-
if (foundProfile !== undefined) {
133-
setProfile(foundProfile);
135+
if (sessionInfo?.webId !== undefined) {
136+
const profiles = await getProfileAll(sessionInfo?.webId, {
137+
fetch: session.fetch,
138+
});
139+
140+
setProfile(profiles);
134141
}
135142
})
136143
.catch((error: Error) => {
@@ -149,7 +156,14 @@ export const SessionProvider = ({
149156
// TODO force a refresh
150157
setSession(getDefaultSession());
151158
});
152-
}, [session, sessionId, onError, currentLocation, restoreSession]);
159+
}, [
160+
session,
161+
sessionId,
162+
onError,
163+
currentLocation,
164+
restoreSession,
165+
skipLoadingProfile,
166+
]);
153167

154168
const contextLogin = async (options: Parameters<typeof login>[0]) => {
155169
setSessionRequestInProgress(true);

stories/authentication/sessionProvider.stories.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
*/
2121

2222
import React, { ReactElement, useContext, useState } from "react";
23+
import { ComponentMeta } from "@storybook/react";
24+
2325
import {
2426
SessionContext,
2527
SessionProvider,
@@ -65,8 +67,12 @@ export default {
6567
description: `Function to be called on session restore. It is invoked with the URL of the refreshed page as its parameter`,
6668
control: { type: null },
6769
},
70+
skipLoadingProfile: {
71+
description: `**Experimental:** When set to true, prevents the SessionProvider from automatically loading the WebID / Profiles`,
72+
defaultValue: false,
73+
},
6874
},
69-
};
75+
} as ComponentMeta<typeof SessionProvider>;
7076

7177
function Dashboard(): ReactElement {
7278
const { session, sessionRequestInProgress } = useContext(SessionContext);

0 commit comments

Comments
 (0)