fix(content): owner never pays for their own files; purchased serves from cache
- serve_content takes owner_session: a validated operator session skips the availability/paid gates (Availability::Nobody stays delisted); the cookie is re-validated in the content handler, same discipline as the model proxy - the Tor proxy serves already-purchased items from the local content_owned cache with Range slicing (206) instead of re-hitting the seller's 402 — the buyer-side store exists so an owned item is never bought twice, and its cards were rendering as permanent placeholders - adapter: 'own'-scope items never render locked (a locked card suppresses the playable URL — the placeholder-only grid the operator reported) - broker: normalize 'purchased' OwnedRpcItems per item with the seller's onion, and group 'peers' items per seller onion, so buildMediaUrl gets a peerOnion and card URLs stop coming out empty Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -314,7 +314,12 @@ function buildMediaUrl(item: ArchyContentItem, opts: AdaptContentOptions): strin
|
||||
|
||||
export function adaptToFilm(item: ArchyContentItem, opts: AdaptContentOptions): Film {
|
||||
const priceSats = paidPriceSats(item.access)
|
||||
const locked = priceSats !== null
|
||||
// 'own' items are served to the authenticated owner by the node's
|
||||
// owner-bypass (`serve_content`) even when they're listed paid for
|
||||
// buyers — the operator never pays for their own files, so never lock
|
||||
// them (a locked card suppresses the playable URL, which is exactly the
|
||||
// placeholder-only grid the operator reported).
|
||||
const locked = opts.source !== 'own' && priceSats !== null
|
||||
const sourceType = FILM_SOURCE_TYPE[opts.source]
|
||||
return {
|
||||
id: item.id,
|
||||
@@ -348,7 +353,12 @@ export function adaptToFilm(item: ArchyContentItem, opts: AdaptContentOptions):
|
||||
*/
|
||||
export function adaptToImage(item: ArchyContentItem, opts: AdaptContentOptions): ImageItem {
|
||||
const priceSats = paidPriceSats(item.access)
|
||||
const locked = priceSats !== null
|
||||
// 'own' items are served to the authenticated owner by the node's
|
||||
// owner-bypass (`serve_content`) even when they're listed paid for
|
||||
// buyers — the operator never pays for their own files, so never lock
|
||||
// them (a locked card suppresses the playable URL, which is exactly the
|
||||
// placeholder-only grid the operator reported).
|
||||
const locked = opts.source !== 'own' && priceSats !== null
|
||||
const title = stripExtension(item.filename || '')
|
||||
return {
|
||||
id: item.id,
|
||||
@@ -366,7 +376,12 @@ export function adaptToImage(item: ArchyContentItem, opts: AdaptContentOptions):
|
||||
|
||||
export function adaptToSong(item: ArchyContentItem, opts: AdaptContentOptions): Song {
|
||||
const priceSats = paidPriceSats(item.access)
|
||||
const locked = priceSats !== null
|
||||
// 'own' items are served to the authenticated owner by the node's
|
||||
// owner-bypass (`serve_content`) even when they're listed paid for
|
||||
// buyers — the operator never pays for their own files, so never lock
|
||||
// them (a locked card suppresses the playable URL, which is exactly the
|
||||
// placeholder-only grid the operator reported).
|
||||
const locked = opts.source !== 'own' && priceSats !== null
|
||||
const sourceType = SONG_SOURCE_TYPE[opts.source]
|
||||
return {
|
||||
id: item.id,
|
||||
@@ -391,7 +406,12 @@ export function adaptToSong(item: ArchyContentItem, opts: AdaptContentOptions):
|
||||
* rather than a song. */
|
||||
export function adaptToPodcast(item: ArchyContentItem, opts: AdaptContentOptions): Podcast {
|
||||
const priceSats = paidPriceSats(item.access)
|
||||
const locked = priceSats !== null
|
||||
// 'own' items are served to the authenticated owner by the node's
|
||||
// owner-bypass (`serve_content`) even when they're listed paid for
|
||||
// buyers — the operator never pays for their own files, so never lock
|
||||
// them (a locked card suppresses the playable URL, which is exactly the
|
||||
// placeholder-only grid the operator reported).
|
||||
const locked = opts.source !== 'own' && priceSats !== null
|
||||
const sourceType = PODCAST_SOURCE_TYPE[opts.source]
|
||||
return {
|
||||
id: item.id,
|
||||
|
||||
Reference in New Issue
Block a user