╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ web.zig ──────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
748 try file.writeStreamingAll(self.io, user_id); 749 return token_hex; 750 } 751 752 // resolve a cookie's token to its user_id. returns false (logged out) for a 753 // missing, malformed, or unknown token. 754 pub fn lookup(self: SessionStore, token_hex: []const u8, out: *[evt.event_id_size]u8) bool { 755 if (!isToken(token_hex)) return false; 756 const file = self.dir.openFile(self.io, token_hex, .{ .mode = .read_only }) catch return false; 757 defer file.close(self.io); 758 var storage: [evt.event_id_size]u8 = undefined; 759 var file_reader = file.reader(self.io, &storage); 760 file_reader.interface.readSliceAll(out) catch return false; 761 return true; 762 } 763 764 // revoke a session. a no-op for a missing or malformed token. 765 pub fn remove(self: SessionStore, token_hex: []const u8) void { 766 if (!isToken(token_hex)) return; 767 self.dir.deleteFile(self.io, token_hex) catch {}; 768 } 769 770 // a token is exactly token_hex_len hex chars. validating before using the 771 // value as a path keeps attacker-supplied cookies from escaping the 772 // sessions dir (e.g. via "/" or ".." bytes). 773 fn isToken(token_hex: []const u8) bool { 774 if (token_hex.len != token_hex_len) return false; 775 for (token_hex) |c| if (!std.ascii.isHex(c)) return false; 776 return true; 777 } 778 }; 779