ibex
ibex copied to clipboard
Support for Multiple User PODs
A Solid user can reference in his Solid profile document more than one storage. For example I've created a user with the webId:
https://darcy-ibex-spoterme.solid.community/profile/card#me
The profile document of this user looks like this:
@prefix : <#>.
@prefix solid: <http://www.w3.org/ns/solid/terms#>.
@prefix pro: <./>.
@prefix n0: <http://xmlns.com/foaf/0.1/>.
@prefix schem: <http://schema.org/>.
@prefix n1: <http://www.w3.org/ns/auth/acl#>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix inbox: </inbox/>.
@prefix sp: <http://www.w3.org/ns/pim/space#>.
@prefix d: </>.
@prefix d0: <https://spoterme-solid-server.herokuapp.com/darcy-ibex/>.
pro:card a n0:PersonalProfileDocument; n0:maker :me; n0:primaryTopic :me.
:me
a schem:Person, n0:Person;
n1:trustedApp
[ n1:mode n1:Append, n1:Read, n1:Write; n1:origin <http://localhost:8080> ];
ldp:inbox inbox:;
sp:preferencesFile </settings/prefs.ttl>;
sp:storage d:, d0:;
solid:account d:;
solid:privateTypeIndex </settings/privateTypeIndex.ttl>;
solid:publicTypeIndex </settings/publicTypeIndex.ttl>;
n0:name "Darcy Ibex".
Note the triples :me sp:storage d:, d0:;
. d0
references a second user storage, in this case located on the spoter.ME backend instance. Through these PIM storage triples any app can discover all the user storages.
I think it is possible to extend Darcy to support another storage different from the canonical one, which is currently constructed from the webId according to the pattern followed by the NSS server. The app could read the whole list specified with the storage
predicate and select one or all according to the app logic. I've experimented and chosen the spoter.ME storage if present, otherwise the canonical one.
In darcy.js
I wrote a function like this:
...
getPodRoot: async function(webId){
const rdfStore = $rdf.graph();
const fetcher = new $rdf.Fetcher(rdfStore);
const PIM_SPACE = $rdf.Namespace('http://www.w3.org/ns/pim/space#');
await fetcher.load(webId);
const spoterPod = rdfStore.each($rdf.sym(webId), PIM_SPACE('storage')).find(
(s) => {
const userRoot = s.value;
return userRoot.startsWith('https://spoterme-solid-server.herokuapp.com/');
});
return spoterPod ? spoterPod.value : new URL(webId).origin;
},
...
This is a very first draft, the spoter.ME server URL can be also be discovered or read from a configuration in a more mature code. The result from this function can be initially stored in the application state along with the webId
for example in the variable podRoot
and accessed whenever needed for reading and creating posts/comments, main.js
:
...
methods:{
async checkLogin(){
let vm = this;
vm.$store.state.session = await window.solid.auth.currentSession(); //Check if logged in into solid
console.log(vm.$store.state.session);
if(vm.$store.state.session){ //then populate the storage data if logged in
vm.$store.state.loggedIn = true;
vm.$store.state.webID = vm.$store.state.session.webId;
vm.$store.state.podRoot = await darcy.getPodRoot(vm.$store.state.session.webId);
}
}
},
created(){
this.checkLogin()
}
...
I can prepare the spoter.ME server for testing if you like, I could configure it to always have a POD for the user https://darcy-ibex-spoterme.solid.community/profile/card#me
with a public
directory as needed by Darcy. The only restriction in the current setup is that everything in the POD get lost after 30 minutes idle time. After a new server start only the user's POD and the directory public
will be present. We plan to implement in the next weeks an API to allow the creation of user PODs on our server, an application could perform this action on user confirmation.
Hopping this issue to be useful, bests Antonio.