╭ changed ──╮ │src/web.zig│ ╰───────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1047 │ │1048 var author_arena = std.heap.ArenaAllocator.init(allocator); │ │1049 defer author_arena.deinit(); │ │1038 - const author = ((try authorizeWrite(io, allocator, &author_arena, request, host, parts.repo_base, .read)) orelse return).author; │ │1050 + const author = ((try authorizeWrite(io, allocator, &author_arena, request, host, parts.repo_base, .read, parts.thread_kind)) orelse return).author;│ │1051 │ │1052 const form_body = try readFormBody(request, allocator); │ │1053 defer allocator.free(form_body); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1084 var any_repo = try rp.AnyRepo(repo_kind, .{}).open(io, allocator, source.localInitOpts()); │ │1085 defer any_repo.deinit(io, allocator); │ │1086 switch (any_repo) { │ │1075 - inline else => |*repo| event_id_hex = try evt.Comment.create(host.event(), repo_kind, repo.self_repo_opts, io, allocator, repo, &thread_id_hex, &parent_id_hex, body, author), │ │1087 + inline else => |*repo| event_id_hex = evt.Comment.create(host.event(), repo_kind, repo.self_repo_opts, io, allocator, repo, parts.thread_kind, &thread_id_hex, &parent_id_hex, body, author) catch |err| switch (err) {│ │1088 + // the url's thread or parent comment isn't what it claims │ │1089 + error.NotFound => return request.respond(not_found, .{ │ │1090 + .status = .not_found, │ │1091 + .extra_headers = &.{.{ .name = "content-type", .value = "text/plain" }}, │ │1092 + }), │ │1093 + else => |e| return e, │ │1094 + }, │ │1095 } │ │1096 }, │ │1097 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1262 │ │1263 var author_arena = std.heap.ArenaAllocator.init(allocator); │ │1264 defer author_arena.deinit(); │ │1246 - const actor = (try authorizeWrite(io, allocator, &author_arena, request, host, parts.repo_base, .read)) orelse return; │ │1265 + const actor = (try authorizeWrite(io, allocator, &author_arena, request, host, parts.repo_base, .read, parts.kind)) orelse return; │ │1266 const author = actor.author; │ │1267 // an attachment changes the event it hangs off │ │1268 const request_repo = (try requestRepoSource(io, allocator, host, parts.repo_base)) orelse return respondAttachmentParentNotFound(request);│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1288 var any_repo = try rp.AnyRepo(repo_kind, .{}).open(io, allocator, source.localInitOpts()); │ │1289 defer any_repo.deinit(io, allocator); │ │1290 switch (any_repo) { │ │1272 - inline else => |*repo| _ = evt.Attachment.create(host.event(), repo_kind, repo.self_repo_opts, io, allocator, repo, &parent_id_hex, blob, author) catch |err| switch (err) { │ │1291 + inline else => |*repo| _ = evt.Attachment.create(host.event(), repo_kind, repo.self_repo_opts, io, allocator, repo, parts.kind, &parent_id_hex, blob, author) catch |err| switch (err) {│ │1292 error.ParentNotFound => return respondAttachmentParentNotFound(request), │ │1293 else => return err, │ │1294 }, │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1340 var any_repo = try rp.AnyRepo(repo_kind, .{}).open(io, allocator, source.localInitOpts()); │ │1341 defer any_repo.deinit(io, allocator); │ │1342 switch (any_repo) { │ │1324 - inline else => |*repo| try evt.Comment.update(host.event(), repo_kind, repo.self_repo_opts, io, allocator, repo, &thread_id, &comment_id, body, author), │ │1343 + inline else => |*repo| try evt.Comment.update(host.event(), repo_kind, repo.self_repo_opts, io, allocator, repo, parts.thread_kind, &thread_id, &comment_id, body, author),│ │1344 } │ │1345 }, │ │1346 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1371 ) !void { │ │1372 var author_arena = std.heap.ArenaAllocator.init(allocator); │ │1373 defer author_arena.deinit(); │ │1355 - const actor = (try authorizeWrite(io, allocator, &author_arena, request, host, parts.repo_base, .read)) orelse return; │ │1374 + const actor = (try authorizeWrite(io, allocator, &author_arena, request, host, parts.repo_base, .read, parts.thread_kind)) orelse return;│ │1375 const author = actor.author; │ │1376 // edits only reach here for a comment │ │1377 const comment_id = parts.comment_id orelse unreachable; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────╮ │1443 const RemoveParts = struct { │ │1444 repo_base: []const u8, │ │1445 kind: evt.EventKind, │ │1446 + // the thread the removed event is, or belongs to│ │1447 + thread_kind: evt.EventKind, │ │1448 + thread_id: [evt.event_id_size]u8, │ │1449 id: [evt.event_id_size]u8, │ │1450 }; │ │1451 │ ╰───────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────╮ │1456 return .{ │ │1457 .repo_base = parent.repo_base,│ │1458 .kind = .attach, │ │1459 + .thread_kind = parent.kind, │ │1460 + .thread_id = parent.id_bytes, │ │1461 .id = attachment.id, │ │1462 }; │ │1463 } │ ╰────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │1464 if (commentBaseParts(host, base)) |thread| return .{ │ │1465 .repo_base = thread.repo_base, │ │1466 .kind = if (thread.comment_id != null) .comment else thread.thread_kind,│ │1467 + .thread_kind = thread.thread_kind, │ │1468 + .thread_id = thread.thread_id, │ │1469 .id = thread.comment_id orelse thread.thread_id, │ │1470 }; │ │1471 return null; │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1483 │ │1484 var author_arena = std.heap.ArenaAllocator.init(allocator); │ │1485 defer author_arena.deinit(); │ │1460 - const actor = (try authorizeWrite(io, allocator, &author_arena, request, host, parts.repo_base, .read)) orelse return; │ │1486 + const actor = (try authorizeWrite(io, allocator, &author_arena, request, host, parts.repo_base, .read, parts.thread_kind)) orelse return;│ │1487 const author = actor.author; │ │1488 │ │1489 const request_repo = (try requestRepoSource(io, allocator, host, parts.repo_base)) orelse return respondRemoveNotFound(request); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯