Skip to content

Commit 3d93e13

Browse files
committed
fix: Correct Parenting for Solid-PREP Notifications
Parent path is correctly determined only for non root resources. Parent notifications are only generated when resources have a parent.
1 parent 7b23e57 commit 3d93e13

File tree

1 file changed

+58
-44
lines changed

1 file changed

+58
-44
lines changed

lib/handlers/notify.js

+58-44
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ const ALLOWED_RDF_MIME_TYPES = [
1111
'text/turtle'
1212
]
1313

14+
function getParent (path) {
15+
if (path === '' || path === '/') return
16+
const parent = libPath.dirname(path)
17+
if (parent === '/') return
18+
return `${parent}/`
19+
}
20+
1421
function getActivity (method) {
1522
if (method === 'DELETE') {
1623
return 'Delete'
@@ -34,11 +41,7 @@ function handler (req, res, next) {
3441
const { method } = req
3542
const { statusCode } = res
3643
const eventID = res.getHeader('event-id')
37-
38-
const parent = `${libPath.dirname(req.path)}/`
39-
const parentID = res.setEventID(parent)
4044
const fullUrl = new URL(req.path, `${req.protocol}://${req.hostname}/`)
41-
const parentUrl = new URL(parent, fullUrl)
4245

4346
// Date is a hack since node does not seem to provide access to send date.
4447
// Date needs to be shared with parent notification
@@ -48,53 +51,64 @@ function handler (req, res, next) {
4851
// If the resource itself newly created,
4952
// it could not have been subscribed for notifications already
5053
if (!((method === 'PUT' || method === 'PATCH') && statusCode === 201)) {
51-
trigger({
52-
generateNotification (
53-
negotiatedFields
54-
) {
55-
const mediaType = negotiatedFields['content-type']
54+
try {
55+
trigger({
56+
generateNotification (
57+
negotiatedFields
58+
) {
59+
const mediaType = negotiatedFields['content-type']
5660

57-
if (ALLOWED_RDF_MIME_TYPES.includes(mediaType?.[0])) {
58-
return `${headerTemplate(negotiatedFields)}\r\n${solidRDFTemplate({
59-
activity: getActivity(method),
60-
eventID,
61-
object: String(fullUrl),
62-
date: eventDate,
63-
// We use eTag as a proxy for state for now
64-
state: res.getHeader('ETag'),
65-
mediaType
66-
})}`
67-
} else {
68-
return defaultNotification({
69-
...(res.method === 'POST') && { location: res.getHeader('Content-Location') }
70-
})
61+
if (ALLOWED_RDF_MIME_TYPES.includes(mediaType?.[0])) {
62+
return `${headerTemplate(negotiatedFields)}\r\n${solidRDFTemplate({
63+
activity: getActivity(method),
64+
eventID,
65+
object: String(fullUrl),
66+
date: eventDate,
67+
// We use eTag as a proxy for state for now
68+
state: res.getHeader('ETag'),
69+
mediaType
70+
})}`
71+
} else {
72+
return defaultNotification({
73+
...(res.method === 'POST') && { location: res.getHeader('Content-Location') }
74+
})
75+
}
7176
}
72-
}
73-
})
77+
})
78+
} catch (error) {
79+
// Failed notification message
80+
}
7481
}
7582

7683
// Write a notification to parent container
7784
// POST in Solid creates a child resource
78-
if (method !== 'POST') {
79-
trigger({
80-
path: parent,
81-
generateNotification (
82-
negotiatedFields
83-
) {
84-
const mediaType = negotiatedFields['content-type']
85-
if (ALLOWED_RDF_MIME_TYPES.includes(mediaType?.[0])) {
86-
return `${headerTemplate(negotiatedFields)}\r\n${solidRDFTemplate({
87-
activity: getParentActivity(method, statusCode),
88-
eventID: parentID,
89-
date: eventDate,
90-
object: String(parentUrl),
91-
target: statusCode === 201 ? String(fullUrl) : undefined,
92-
eTag: undefined,
93-
mediaType
94-
})}`
85+
const parent = getParent(req.path)
86+
if (parent && method !== 'POST') {
87+
try {
88+
const parentID = res.setEventID(parent)
89+
const parentUrl = new URL(parent, fullUrl)
90+
trigger({
91+
path: parent,
92+
generateNotification (
93+
negotiatedFields
94+
) {
95+
const mediaType = negotiatedFields['content-type']
96+
if (ALLOWED_RDF_MIME_TYPES.includes(mediaType?.[0])) {
97+
return `${headerTemplate(negotiatedFields)}\r\n${solidRDFTemplate({
98+
activity: getParentActivity(method, statusCode),
99+
eventID: parentID,
100+
date: eventDate,
101+
object: String(parentUrl),
102+
target: statusCode === 201 ? String(fullUrl) : undefined,
103+
eTag: undefined,
104+
mediaType
105+
})}`
106+
}
95107
}
96-
}
97-
})
108+
})
109+
} catch (error) {
110+
// Failed notification message
111+
}
98112
}
99113

100114
next()

0 commit comments

Comments
 (0)