╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ───────────────╮ │src/ui/widget/thread.zig│ ╰────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2501 if (comptime wasm) return; │ │2502 const io = self.session.io orelse return; │ │2503 const src = self.data.repo_source orelse return; │ │2499 - const author = (try self.session.eventAuthor()) orelse return; │ │2504 + const author = ((try self.session.authorize(self.data.identity, .read)) orelse return).author;│ │2505 │ │2506 const form = self.threadForm() orelse return; │ │2507 const title_input = try formField(form, "title"); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2529 .branch => try source.field().text(allocator), │ │2530 }; │ │2531 defer if (source_branch) |branch| allocator.free(branch); │ │2527 - const event_id_hex = Data.create(self.data, self.session, allocator, title, tags, description, target_branch, source_branch) catch |err| { │ │2532 + const event_id_hex = Data.create(self.data, self.session, allocator, author, title, tags, description, target_branch, source_branch) catch |err| {│ │2533 const failure = FeedbackFailure.fromError(err) orelse return err; │ │2534 try self.rememberThreadFeedback(failure, title, tags, description, target_branch); │ │2535 return; │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2584 if (comptime wasm) return; │ │2585 const io = self.session.io orelse return; │ │2586 const entry = self.data.selectedThread() orelse return; │ │2587 + const actor = (try self.session.authorize(self.data.identity, .read)) orelse return;│ │2588 + const author = actor.author; │ │2589 │ │2590 const form = self.threadForm() orelse return; │ │2591 const title_input = try formField(form, "title"); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2609 │ │2610 if (comptime supports_drafts) { │ │2611 if (entryDraft(entry.*)) { │ │2605 - self.data.editDraft(self.session, allocator, entry.id, title, tags, description, target_branch) catch |err| { │ │2612 + self.data.editDraft(self.session, allocator, author, entry.id, title, tags, description, target_branch) catch |err| {│ │2613 const failure = FeedbackFailure.fromError(err) orelse return err; │ │2614 try self.rememberThreadFeedback(failure, title, tags, description, target_branch); │ │2615 return; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────╮ │2621 } │ │2622 │ │2623 const id_bytes = try evt.parseEventId(entry.id); │ │2617 - const author = (try self.session.eventAuthor()) orelse return; │ │2624 + if (!try src.canModify(io, allocator, actor, kind, &id_bytes)) return;│ │2625 │ │2626 switch (src.repo_kind) { │ │2627 inline else => |repo_kind| { │ ╰────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2684 if (comptime wasm) return; │ │2685 const entry = self.data.selectedThread() orelse return; │ │2686 if (!entryDraft(entry.*)) return; │ │2680 - try self.data.publishDraft(self.session, allocator, entry.id); │ │2687 + const author = ((try self.session.authorize(self.data.identity, .read)) orelse return).author;│ │2688 + try self.data.publishDraft(self.session, allocator, author, entry.id); │ │2689 const route = listRoute(self.data.identity, @enumFromInt(0), "", entry.id) orelse return; │ │2690 try self.session.navigate(route); │ │2691 } else unreachable, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2694 const entry = self.data.selectedThread() orelse return; │ │2695 const revision: evt.Patch.MergeRevision = if (button_index > 1) .squash else .source; │ │2696 if (!Data.canMerge(entry.*, self.session) or entry.mergeability.get(revision) != .clean) return; │ │2689 - self.data.mergePatch(self.session, allocator, entry.id, revision) catch |err| switch (err) { │ │2697 + const author = ((try self.session.authorize(self.data.identity, .write)) orelse return).author; │ │2698 + self.data.mergePatch(self.session, allocator, author, entry.id, revision) catch |err| switch (err) { │ │2699 error.MergeConflict, error.MergeCheckUnavailable, error.PatchOutOfDate, error.PatchDataUnavailable => {│ │2700 const route = listRoute(self.data.identity, entryStatus(entry.*), "", entry.id) orelse return; │ │2701 try self.session.navigate(route); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2720 │ │2721 fn removeEvent(self: *This, allocator: std.mem.Allocator, event_kind: evt.EventKind, id: [evt.event_id_size]u8) !void {│ │2722 if (comptime wasm) return; │ │2723 + const actor = (try self.session.authorize(self.data.identity, .read)) orelse return; │ │2724 + const author = actor.author; │ │2725 │ │2726 if (comptime supports_drafts) { │ │2727 const selected = self.data.selectedThread() orelse return; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │2728 if (event_kind == kind and entryDraft(selected.*)) { │ │2718 - try Data.removeDraft(self.session, allocator, &id); │ │2729 + try Data.removeDraft(self.session, allocator, author, &id); │ │2730 const route = draftsRoute(self.data.identity) orelse return;│ │2731 try self.session.navigate(route); │ │2732 return; │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────╮ │2735 │ │2736 const io = self.session.io orelse return; │ │2737 const src = self.data.repo_source orelse return; │ │2727 - const author = (try self.session.eventAuthor()) orelse return; │ │2738 + if (!try src.canModify(io, allocator, actor, event_kind, &id)) return;│ │2739 │ │2740 switch (src.repo_kind) { │ │2741 inline else => |repo_kind| { │ ╰────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯