Manage User Profile#
Per the Solid WebID Profile specification, a Solid profile describes an agent and can consist of a WebID Profile document and extended profile document(s).
For example, starting in version ESS 2.0, Inrupt’s ESS and PodSpaces creates both a WebID Profile (upon creation of the WebID) and an extended profile (upon creation of the Pod). This extended profile is discoverable from the WebID Profile.
WebID Profile#
A WebID is a unique URL that identifies an agent in the Solid ecosystem. Dereferencing the WebID yields the publicly readable WebID Profile. A WebID Profile is an RDF Resource that contains data about the user.
Important
Although an RDF Resource, the WebID Profile is not necessarily hosted on a Solid Pod and may not necessarily be a Solid Resource per the Solid Protocol. As such, Solid applications cannot rely on the Solid Protocol to read and write the WebID profile.
For example, starting in version ESS 2.0, Inrupt’s ESS or PodSpaces WebIDs dereference to WebID Profiles that that are not hosted on a Solid Pod. ESS/PodSpaces places restrictions on WebID Profile modifications, including which applications can perform modifications. To read these WebID Profiles, applications must make unauthenticated requests.
Extended Profiles#
Like the WebID Profile, an extended profile is also an RDF Resource that contains data about the user. However, the extended profile is hosted on a Solid Pod and is a Solid Resource per the Solid Protocol. That is, applications can rely on the Solid Protocol to read and write the extended profile.
Unlike the WebID Profile, which is publicly readable, read and write access to the extended profile is managed as user would manage access to any other Solid Resource in the Pod.
For example, the extended profile created by Inrupt’s ESS/PodSpaces is private (read and writable by the agent only) by default.
Read WebID Profile and Extended Profiles#
The @inrupt/solid-client
library provides getProfileAll to
perform the fetch of the WebID Profile and the linked extended profiles.
Note
Because an extended profile is a Solid Resource, it is possible to use getSolidDataset to get a specific extended profile. However, since the app would need to introspect the WebID Profile to get the extended profile’s URL, which is already handled by getProfileAll, prefer using getProfileAll for extended profile as well.
The returned the WebID Profile and the extended profiles can be introspected using the read functions for SolidDataset.
Returns the WebID profile (as a SolidDataset) and the linked extended profiles (as an array of SolidDatasets).
|
|
Gets a data entity/Thing from a WebID Profile or extended profile. |
|
Get all data entities/Things from a WebID Profile or extended profile. |
|
Gets the value(s) for the specified Property from a Thing. For a list of the |
Example#
The following example gets the WebID profile and the linked extended profile.
import { getDefaultSession, fetch } from "@inrupt/solid-client-authn-browser";
import {
getSourceUrl,
getThing,
getThingAll,
getUrlAll,
getSourceUrl
} from "@inrupt/solid-client";
import { SOLID } from "@inrupt/vocab-solid";
// Note: Login code has been omitted for brevity.
async function getMyProfiles(webId) {
try {
// 1. Get WebID of the logged in user.
// The example assumes the user is logged in.
// As such, getDefaultSession().info.webId is NOT null and
// fetch (associated with the default Session) is an authenticated fetch.
const webId = getDefaultSession().info.webId;
// 2. Get the WebID Profile and the extended profiles listed in the WebID Profile.
//
// - For WebID Profile, getProfileAll performs an unauthenticated fetch.
// - For extended profiles, getProfileAll performs either:
// - an unauthenticated fetch of the extended profiles if
// the passed in fetch is omitted or fetch is unauthenticated,
// - authenticated fetch if the passed in fetch is authenticated.
const profiles = await getProfileAll(
webId,
{ fetch }
);
// Step 3. Read from the WebID profile.
// - Get the WebID profile from the returned profiles.
// - Read the WebID Profile as a Thing.
// - Read the OpenID Provider(s) listed in the WebID Profile.
const webIDProfileSolidDataset = profiles.webIdProfile;
const webIdThing = getThing(webIDProfileSolidDataset, webId);
const issuers = getUrlAll(webIdThing, SOLID.oidcIssuer);
// ...
// Step 4. Read from the extended profiles.
// - Get the array of extended profiles from the returned profiles.
// - Loop through the extended profiles.
const extendedProfilesSolidDatasets = profiles.altProfileAll;
extendedProfilesSolidDatasets.forEach((extendedProfileSolidDataset) => {
console.log(getSourceUrl(extendedProfileSolidDataset));
const thingsInExtendedProfile = getThingAll(extendedProfileSolidDataset);
thingsInExtendedProfile.forEach((thing) => {
// .. do something
});
})
} catch (error) {
//...
}
}
Update Extended Profiles#
WebID Profile may not be a Solid resource. As such, Solid applications cannot rely on the Solid Protocol to read and write the WebID Profile. In addition, the modification of WebID Profile may be governed by other restrictions, such that an arbitrary Solid applications cannot perform the modification.
Instead, Solid applications writing user profile data should target extended profiles. Extended profiles are Solid resources. As such, Solid applications can rely on the Solid Protocol to read and write extended profiles, and users can manage read and write access to their extended profiles like any other Solid resource.
For example, WebIDs created by ESS/PodSpaces dereference to WebID Profiles that that are not hosted on a Solid Pod. Furthermore, ESS/PodSpaces places restrictions on WebID Profile modifications, including which applications can perform modifications. To support the modification of user data (as well as managing access control of that data) , ESS/PodSpaces creates a default extended profile.
To write update extended profiles, Solid applications can use the same functions as they would to write any SolidDatasets. For example:
To add/update/remove Things to the extended profile SolidDataset. |
|
To set the value(s) for the specified Property for a Thing. For a list of the |
|
To remove value(s) for the specified Property from a Thing. For a list of the |
|
To save an existing extended profile. |
Example#
The following example gets the extended profile linked from a WebID Profile and updates the extended profile. The example assumes only 1 extended profile.
import { getDefaultSession, fetch } from "@inrupt/solid-client-authn-browser";
import {
getProfileAll,
getSourceUrl,
getThing,
setUrl,
setThing,
saveSolidDatasetAt,
} from "@inrupt/solid-client";
import { FOAF, RDF } from "@inrupt/vocab-common-rdf";
// Note: Login code has been omitted for brevity. See the Prerequisite section above.
// ...
async function updateExtendedProfile() {
try {
// 1. Get WebID of the logged in user.
// The example assumes the user is logged in.
// As such, getDefaultSession().info.webId is NOT null and
// fetch (associated with the default Session) is an authenticated fetch.
const webId = getDefaultSession().info.webId;
// 2. Get the WebID Profile and the extended profiles listed in the WebID Profile.
//
// - For WebID Profile, getProfileAll performs an unauthenticated fetch.
// - For extended profiles, getProfileAll performs either:
// - an unauthenticated fetch of the extended profiles if
// the passed in fetch is omitted or fetch is unauthenticated,
// - authenticated fetch if the passed in fetch is authenticated.
const profiles = await getProfileAll(webId, { fetch });
// Step 3. Write to the extended profile.
// The example assumes only 1 extended profile.
// a. Get the extended profile.
// b. Get the user data Thing (identified by the user's WebID) contained in the extended profile.
// c. Set a Property to this user data.
// d. Update the myExtendedProfile with the new Property
// e. Save the updated extended profile
let myExtendedProfile = profiles.altProfileAll[0];
let userDataThing = getThing(myExtendedProfile, webId);
userDataThing = setUrl(
userDataThing,
"https://some.property",
"https://some.value"
);
myExtendedProfile = setThing(
myExtendedProfile,
userDataThing
);
await saveSolidDatasetAt(
getSourceUrl(myExtendedProfile),
myExtendedProfile,
{ fetch: fetch } // fetch from authenticated Session
);
} catch (error) {
//...
}
}