Skip to content

Commit

Permalink
fix: Correct Parenting for Solid-PREP Notifications
Browse files Browse the repository at this point in the history
Parent path is correctly determined only for non root resources. Parent notifications are only generated when resources have a parent.
  • Loading branch information
CxRes committed Sep 8, 2024
1 parent 7b23e57 commit 3d93e13
Showing 1 changed file with 58 additions and 44 deletions.
102 changes: 58 additions & 44 deletions lib/handlers/notify.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ const ALLOWED_RDF_MIME_TYPES = [
'text/turtle'
]

function getParent (path) {
if (path === '' || path === '/') return
const parent = libPath.dirname(path)
if (parent === '/') return
return `${parent}/`
}

function getActivity (method) {
if (method === 'DELETE') {
return 'Delete'
Expand All @@ -34,11 +41,7 @@ function handler (req, res, next) {
const { method } = req
const { statusCode } = res
const eventID = res.getHeader('event-id')

const parent = `${libPath.dirname(req.path)}/`
const parentID = res.setEventID(parent)
const fullUrl = new URL(req.path, `${req.protocol}://${req.hostname}/`)
const parentUrl = new URL(parent, fullUrl)

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

if (ALLOWED_RDF_MIME_TYPES.includes(mediaType?.[0])) {
return `${headerTemplate(negotiatedFields)}\r\n${solidRDFTemplate({
activity: getActivity(method),
eventID,
object: String(fullUrl),
date: eventDate,
// We use eTag as a proxy for state for now
state: res.getHeader('ETag'),
mediaType
})}`
} else {
return defaultNotification({
...(res.method === 'POST') && { location: res.getHeader('Content-Location') }
})
if (ALLOWED_RDF_MIME_TYPES.includes(mediaType?.[0])) {
return `${headerTemplate(negotiatedFields)}\r\n${solidRDFTemplate({
activity: getActivity(method),
eventID,
object: String(fullUrl),
date: eventDate,
// We use eTag as a proxy for state for now
state: res.getHeader('ETag'),
mediaType
})}`
} else {
return defaultNotification({
...(res.method === 'POST') && { location: res.getHeader('Content-Location') }
})
}
}
}
})
})
} catch (error) {
// Failed notification message
}
}

// Write a notification to parent container
// POST in Solid creates a child resource
if (method !== 'POST') {
trigger({
path: parent,
generateNotification (
negotiatedFields
) {
const mediaType = negotiatedFields['content-type']
if (ALLOWED_RDF_MIME_TYPES.includes(mediaType?.[0])) {
return `${headerTemplate(negotiatedFields)}\r\n${solidRDFTemplate({
activity: getParentActivity(method, statusCode),
eventID: parentID,
date: eventDate,
object: String(parentUrl),
target: statusCode === 201 ? String(fullUrl) : undefined,
eTag: undefined,
mediaType
})}`
const parent = getParent(req.path)
if (parent && method !== 'POST') {
try {
const parentID = res.setEventID(parent)
const parentUrl = new URL(parent, fullUrl)
trigger({
path: parent,
generateNotification (
negotiatedFields
) {
const mediaType = negotiatedFields['content-type']
if (ALLOWED_RDF_MIME_TYPES.includes(mediaType?.[0])) {
return `${headerTemplate(negotiatedFields)}\r\n${solidRDFTemplate({
activity: getParentActivity(method, statusCode),
eventID: parentID,
date: eventDate,
object: String(parentUrl),
target: statusCode === 201 ? String(fullUrl) : undefined,
eTag: undefined,
mediaType
})}`
}
}
}
})
})
} catch (error) {
// Failed notification message
}
}

next()
Expand Down

0 comments on commit 3d93e13

Please sign in to comment.