98 lines
2.9 KiB
TypeScript
98 lines
2.9 KiB
TypeScript
/**
|
|
* Object modification and deletion utilities
|
|
* Only the author (pubkey) who published the original note can modify or delete it
|
|
*
|
|
* Access rules:
|
|
* - Modification: Only the author (event.pubkey === userPubkey) can modify
|
|
* - Deletion: Only the author (event.pubkey === userPubkey) can delete
|
|
* - Read access: All users can read previews, paid content requires payment verification
|
|
*/
|
|
|
|
import type { Event } from 'nostr-tools'
|
|
import { extractTagsFromEvent } from './nostrTagSystem'
|
|
import { canModifyObject, getNextVersion } from './versionManager'
|
|
|
|
/**
|
|
* Check if user can modify an object
|
|
* Only the author (pubkey) who published the original note can modify it
|
|
*/
|
|
export function canUserModifyObject(event: Event, userPubkey: string): boolean {
|
|
return canModifyObject(event, userPubkey)
|
|
}
|
|
|
|
/**
|
|
* Build an update event (new version)
|
|
* Increments version and keeps the same hash ID
|
|
*/
|
|
export async function buildUpdateEvent(
|
|
originalEvent: Event,
|
|
updatedData: Record<string, unknown>,
|
|
userPubkey: string
|
|
): Promise<Event | null> {
|
|
// Check if user can modify
|
|
if (!canUserModifyObject(originalEvent, userPubkey)) {
|
|
throw new Error('Only the author can modify this object')
|
|
}
|
|
|
|
const tags = extractTagsFromEvent(originalEvent)
|
|
const nextVersion = getNextVersion([originalEvent])
|
|
|
|
// Build new event with incremented version
|
|
// The hash ID stays the same, only version changes
|
|
const newTags = originalEvent.tags.map((tag) => {
|
|
if (tag[0] === 'version') {
|
|
return ['version', nextVersion.toString()]
|
|
}
|
|
return tag
|
|
})
|
|
|
|
// Remove hidden tag if present (object is being updated, not deleted)
|
|
const filteredTags = newTags.filter((tag) => !(tag[0] === 'hidden' && tag[1] === 'true'))
|
|
|
|
return {
|
|
...originalEvent,
|
|
tags: filteredTags,
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
// Content and other fields should be updated by the caller
|
|
} as Event
|
|
}
|
|
|
|
/**
|
|
* Build a delete event (hide object)
|
|
* Sets hidden=true and increments version
|
|
*/
|
|
export async function buildDeleteEvent(
|
|
originalEvent: Event,
|
|
userPubkey: string
|
|
): Promise<Event | null> {
|
|
// Check if user can modify
|
|
if (!canUserModifyObject(originalEvent, userPubkey)) {
|
|
throw new Error('Only the author can delete this object')
|
|
}
|
|
|
|
const tags = extractTagsFromEvent(originalEvent)
|
|
const nextVersion = getNextVersion([originalEvent])
|
|
|
|
// Build new event with hidden=true and incremented version
|
|
const newTags = originalEvent.tags.map((tag) => {
|
|
if (tag[0] === 'version') {
|
|
return ['version', nextVersion.toString()]
|
|
}
|
|
if (tag[0] === 'hidden') {
|
|
return ['hidden', 'true']
|
|
}
|
|
return tag
|
|
})
|
|
|
|
// Add hidden tag if not present
|
|
if (!newTags.some((tag) => tag[0] === 'hidden')) {
|
|
newTags.push(['hidden', 'true'])
|
|
}
|
|
|
|
return {
|
|
...originalEvent,
|
|
tags: newTags,
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
} as Event
|
|
}
|