Skip to content
Merged
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
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "solid-logic",
"version": "4.0.3",
"version": "4.0.4",
"description": "Core business logic of SolidOS",
"type": "module",
"main": "dist/solid-logic.js",
Expand Down
24 changes: 18 additions & 6 deletions src/typeIndex/typeIndexLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import { newThing } from '../util/utils'
export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic): TypeIndexLogic {
const ns = namespace

function isAbsoluteHttpUri(uri: string | null | undefined): boolean {
return !!uri && (uri.startsWith('https://') || uri.startsWith('http://'))
}

function getRegistrations(instance, theClass) {
return store
.each(undefined, ns.solid('instance'), instance)
Expand Down Expand Up @@ -82,7 +86,7 @@ export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic):
return scopes
}

async function loadCommunityTypeIndexes(user: NamedNode): Promise<TypeIndexScope[][]> {
async function loadCommunityTypeIndexes(user: NamedNode): Promise<TypeIndexScope[]> {
let preferencesFile
try {
preferencesFile = await profileLogic.silencedLoadPreferences(user)
Expand All @@ -96,15 +100,23 @@ export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic):
)
let result = []
for (const org of communities) {
result = result.concat(await loadTypeIndexesFor(org as NamedNode) as any)
if (org.termType !== 'NamedNode' || !isAbsoluteHttpUri((org as NamedNode).uri)) {
debug.warn(`Skipping malformed community node for ${user}: ${org}`)
continue
}
try {
result = result.concat(await loadTypeIndexesFor(org as NamedNode) as any)
} catch (err) {
debug.warn(`Skipping community type indexes for ${(org as NamedNode).uri}: ${err}`)
}
}
return result
}
return [] // No communities
}

async function loadAllTypeIndexes(user: NamedNode) {
return (await loadTypeIndexesFor(user)).concat((await loadCommunityTypeIndexes(user)).flat())
return (await loadTypeIndexesFor(user)).concat(await loadCommunityTypeIndexes(user))
}

async function getScopedAppInstances(klass: NamedNode, user: NamedNode): Promise<ScopedApp[]> {
Expand All @@ -130,10 +142,10 @@ export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic):
function docDirUri(node: NamedNode): string | null {
const doc = node.doc()
const dir = doc.dir()
if (dir?.uri) return dir.uri
if (dir?.uri && isAbsoluteHttpUri(dir.uri)) return dir.uri
const docUri = doc.uri
if (!docUri) {
debug.log(`docDirUri: missing doc uri for ${node?.uri}`)
if (!docUri || !isAbsoluteHttpUri(docUri)) {
debug.log(`docDirUri: missing or non-http(s) doc uri for ${node?.uri}`)
return null
}
const withoutFragment = docUri.split('#')[0]
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export interface InboxLogic {
export interface TypeIndexLogic {
getRegistrations: (instance, theClass) => Node[],
loadTypeIndexesFor: (user: NamedNode) => Promise<Array<TypeIndexScope>>,
loadCommunityTypeIndexes: (user: NamedNode) => Promise<TypeIndexScope[][]>,
loadCommunityTypeIndexes: (user: NamedNode) => Promise<Array<TypeIndexScope>>,
loadAllTypeIndexes: (user: NamedNode) => Promise<Array<TypeIndexScope>>,
getScopedAppInstances: (klass: NamedNode, user: NamedNode) => Promise<ScopedApp[]>,
getAppInstances: (klass: NamedNode) => Promise<NamedNode[]>,
Expand Down
21 changes: 21 additions & 0 deletions test/typeIndexLogic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,27 @@ describe('TypeIndex logic NEW', () => {
const result = await typeIndexLogic.loadCommunityTypeIndexes(alice)
expect(result).toEqual(ClubScopes)
})
it('skips malformed non-NamedNode community entries', async () => {
web[AlicePreferencesFile.uri] = `
${alice} solid:privateTypeIndex ${AlicePrivateTypeIndex};
solid:community ${club};
solid:community "not-a-webid" .
`

const result = await typeIndexLogic.loadCommunityTypeIndexes(alice)
expect(result).toEqual(ClubScopes)
})
it('continues when one community fails to load', async () => {
const brokenCommunity = sym('https://broken.example.com/profile/card.ttl#it')
web[AlicePreferencesFile.uri] = `
${alice} solid:privateTypeIndex ${AlicePrivateTypeIndex};
solid:community ${brokenCommunity};
solid:community ${club} .
`

const result = await typeIndexLogic.loadCommunityTypeIndexes(alice)
expect(result).toEqual(ClubScopes)
})
})

const AliceAndClubScopes = [{'instance': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://alice.example.com/publicStuff/actionItems.ttl#this'}, 'scope': {'agent': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://alice.example.com/profile/card.ttl#me'}, 'index': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://alice.example.com/profile/public-type-index.ttl'}, 'label': 'public'}, 'type': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'http://www.w3.org/2005/01/wf/flow#Tracker'}}, {'instance': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://alice.example.com/project4/issues.ttl#this'}, 'scope': {'agent': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://alice.example.com/profile/card.ttl#me'}, 'index': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://alice.example.com/profile/public-type-index.ttl'}, 'label': 'public'}, 'type': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'http://www.w3.org/2005/01/wf/flow#Tracker'}}, {'instance': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://alice.example.com/privateStuff/ToDo.ttl#this'}, 'scope': {'agent': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://alice.example.com/profile/card.ttl#me'}, 'index': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://alice.example.com/settings/private-type-index.ttl'}, 'label': 'private'}, 'type': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'http://www.w3.org/2005/01/wf/flow#Tracker'}}, {'instance': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://alice.example.com/privateStuff/Goals.ttl#this'}, 'scope': {'agent': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://alice.example.com/profile/card.ttl#me'}, 'index': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://alice.example.com/settings/private-type-index.ttl'}, 'label': 'private'}, 'type': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'http://www.w3.org/2005/01/wf/flow#Tracker'}}, {'instance': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://alice.example.com/privateStuff/workingOn.ttl#this'}, 'scope': {'agent': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://alice.example.com/profile/card.ttl#me'}, 'index': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://alice.example.com/settings/private-type-index.ttl'}, 'label': 'private'}, 'type': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'http://www.w3.org/2005/01/wf/flow#Tracker'}}, {'instance': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://club.example.com/publicStuff/actionItems.ttl#this'}, 'scope': {'agent': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://club.example.com/profile/card.ttl#it'}, 'index': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://club.example.com/profile/public-type-index.ttl'}, 'label': 'public'}, 'type': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'http://www.w3.org/2005/01/wf/flow#Tracker'}}, {'instance': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://club.example.com/project4/clubIssues.ttl#this'}, 'scope': {'agent': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://club.example.com/profile/card.ttl#it'}, 'index': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://club.example.com/profile/public-type-index.ttl'}, 'label': 'public'}, 'type': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'http://www.w3.org/2005/01/wf/flow#Tracker'}}, {'instance': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://club.example.com/privateStuff/ToDo.ttl#this'}, 'scope': {'agent': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://club.example.com/profile/card.ttl#it'}, 'index': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://club.example.com/settings/private-type-index.ttl'}, 'label': 'private'}, 'type': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'http://www.w3.org/2005/01/wf/flow#Tracker'}}, {'instance': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://club.example.com/privateStuff/Goals.ttl#this'}, 'scope': {'agent': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://club.example.com/profile/card.ttl#it'}, 'index': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://club.example.com/settings/private-type-index.ttl'}, 'label': 'private'}, 'type': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'http://www.w3.org/2005/01/wf/flow#Tracker'}}, {'instance': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://club.example.com/privateStuff/tasks.ttl#this'}, 'scope': {'agent': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://club.example.com/profile/card.ttl#it'}, 'index': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'https://club.example.com/settings/private-type-index.ttl'}, 'label': 'private'}, 'type': {'classOrder': 5, 'termType': 'NamedNode', 'value': 'http://www.w3.org/2005/01/wf/flow#Tracker'}}]
Expand Down