Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions config/dev-http-subdomain.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"css:config/storage/key-value/resource-store.json",
"css:config/storage/location/pod.json",
"pivot:config/storage/middleware/default.json",
"pivot:config/storage/profile-card-guard.json",
"css:config/util/auxiliary/acl.json",
"css:config/util/identifiers/subdomain.json",

Expand Down
1 change: 1 addition & 0 deletions config/dev-http-suffix.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"css:config/storage/key-value/resource-store.json",
"css:config/storage/location/pod.json",
"pivot:config/storage/middleware/default.json",
"pivot:config/storage/profile-card-guard.json",
"css:config/util/auxiliary/acl.json",
"css:config/util/identifiers/suffix.json",

Expand Down
1 change: 1 addition & 0 deletions config/prod.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"css:config/storage/key-value/resource-store.json",
"css:config/storage/location/pod.json",
"pivot:config/storage/middleware/default.json",
"pivot:config/storage/profile-card-guard.json",
"css:config/util/auxiliary/acl.json",
"css:config/util/identifiers/subdomain.json",
"css:config/util/logging/winston.json",
Expand Down
48 changes: 48 additions & 0 deletions config/storage/profile-card-guard.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"@context": [
"https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld",
"https://linkedsoftwaredependencies.org/bundles/npm/@solid/pivot/^1.0.0/components/context.jsonld"
],
"comment": "Guards the profile card of WebIDs registered on this server, keeping the `solid:oidcIssuer` triple.",
"@graph": [
{
"comment": "Guards registered WebID cards from being deleted or losing their `solid:oidcIssuer` triple.",
"@id": "urn:solid-server:default:ResourceStore_CardGuard",
"@type": "ProfileCardGuard",
"source": { "@id": "urn:solid-server:default:ResourceStore_Converting" },
"webIdStore": { "@id": "urn:solid-server:default:WebIdStore" },
"baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
"converter": { "@id": "urn:solid-server:default:RepresentationConverter" },
"relativeWebIdPaths": [
"/profile/card#me"
]
},
{
"comment": "WebID store that also exposes whether a WebID is registered (hasWebId), as required by the card guard.",
"@type": "Override",
"overrideInstance": { "@id": "urn:solid-server:default:WebIdStore" },
"overrideParameters": {
"@type": "GuardedWebIdStore",
"storage": { "@id": "urn:solid-server:default:AccountStorage" }
}
},
{
"comment": "Insert the card guard between pivot's RDF patching store and the converting store, so PUT/POST as well as PATCH results are all validated.",
"@type": "Override",
"overrideInstance": { "@id": "urn:solid-server:default:ResourceStore_RdfPatching" },
"overrideParameters": {
"@type": "RdfPatchingStore",
"source": { "@id": "urn:solid-server:default:ResourceStore_CardGuard" }
}
},
{
"comment": "Route the internal key-value storage (accounts, WebID links, ...) through the converting store directly, bypassing the guard.",
"@type": "Override",
"overrideInstance": { "@id": "urn:solid-server:default:JsonResourceStorage" },
"overrideParameters": {
"@type": "JsonResourceStorage",
"source": { "@id": "urn:solid-server:default:ResourceStore_Converting" }
}
}
]
}
1 change: 1 addition & 0 deletions config/suffix.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"css:config/storage/key-value/resource-store.json",
"css:config/storage/location/pod.json",
"pivot:config/storage/middleware/default.json",
"pivot:config/storage/profile-card-guard.json",
"css:config/util/auxiliary/acl.json",
"css:config/util/identifiers/suffix.json",
"css:config/util/logging/winston.json",
Expand Down
27 changes: 27 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
],
"dependencies": {
"@inrupt/solid-client-authn-core": "^3.1.1",
"@rdfjs/types": "^1.1.2",
"@solid/community-server": "^7.2.0",
"arrayify-stream": "^2.0.1",
"mashlib": "^2.3.3",
"patch-package": "^8.0.1",
"rdflib": "^2.4.0"
Expand All @@ -47,8 +49,10 @@
"@types/jest": "^30.0.0",
"@types/node-fetch": "^2.6.13",
"componentsjs-generator": "^3.1.2",
"cross-fetch": "^4.1.0",
"jest": "^30.3.0",
"jest-rdf": "^2.0.0",
"n3": "^1.26.0",
"node-fetch": "^3.3.2",
"ts-jest": "^29.4.6",
"typescript": "^5.9.3"
Expand Down
36 changes: 36 additions & 0 deletions src/identity/interaction/webid/util/GuardedWebIdStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {
AccountLoginStorage,
BaseWebIdStore,
WEBID_STORAGE_DESCRIPTION,
WEBID_STORAGE_TYPE,
} from '@solid/community-server';

type WebIdStorage = AccountLoginStorage<{ [WEBID_STORAGE_TYPE]: typeof WEBID_STORAGE_DESCRIPTION }>;

/**
* A {@link BaseWebIdStore} that also determines whether a WebID is registered
* to any account on this server (`hasWebId`).
*
* The card guard needs to know whether a WebID is registered, which the
* upstream WebIdStore does not expose (yet). This subclass keeps the full
* upstream behavior and only adds the exact indexed lookup on the webId index.
*/
export class GuardedWebIdStore extends BaseWebIdStore {
private readonly webIdStorage: WebIdStorage;

// Loosely typed so the Components.js generator does not need to resolve the
// external generic; Components.js does not type-check constructor arguments.
public constructor(storage: any) {
super(storage);
this.webIdStorage = storage as unknown as WebIdStorage;
}

/**
* Determines if the given WebID is registered to an account on this server.
*
* @param webId - WebID to check.
*/
public async hasWebId(webId: string): Promise<boolean> {
return (await this.webIdStorage.find(WEBID_STORAGE_TYPE, { webId })).length > 0;
}
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export * from "./storage/RdfPatchingStore";
export * from './storage/ProfileCardGuard';
export * from "./storage/patch/ThrowingN3Patcher";
export * from './FedcmHttpHandler';
export * from './http/output/PivotResponseWriter';
export * from './identity/interaction/password/MigratedPasswordLoginHandler';
export * from './identity/interaction/webid/util/GuardedWebIdStore';
export * from './identity/PivotOidcHttpHandler';
Loading
Loading