╭ changed ──╮ │src/web.zig│ ╰───────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2272 const file = try self.dir.createFile(self.io, &token_hex, .{}); │ │2273 defer file.close(self.io); │ │2274 try file.writeStreamingAll(self.io, user_id); │ │2275 + return token_hex; │ │2276 + } │ │2277 + │ │2278 + fn createFlash(self: SessionStore, allocator: std.mem.Allocator, value: ui.Session.FormFeedback) ![token_hex_len]u8 {│ │2279 + var token: [evt.event_id_size]u8 = undefined; │ │2280 + self.io.random(&token); │ │2281 + const token_hex = std.fmt.bytesToHex(token, .lower); │ │2282 + const file = try self.flash_dir.createFile(self.io, &token_hex, .{}); │ │2283 + errdefer self.flash_dir.deleteFile(self.io, &token_hex) catch {}; │ │2284 + defer file.close(self.io); │ │2285 + │ │2286 + var json: std.Io.Writer.Allocating = .init(allocator); │ │2287 + defer json.deinit(); │ │2288 + try std.json.Stringify.value(value, .{}, &json.writer); │ │2289 + try file.writeStreamingAll(self.io, json.written()); │ │2290 return token_hex; │ │2291 + } │ │2292 + │ │2293 + fn takeFlash(self: SessionStore, allocator: std.mem.Allocator, token_hex: []const u8) ?ui.Session.FormFeedback { │ │2294 + if (!isToken(token_hex)) return null; │ │2295 + const file = self.flash_dir.openFile(self.io, token_hex, .{ .mode = .read_only }) catch return null; │ │2296 + defer self.flash_dir.deleteFile(self.io, token_hex) catch {}; │ │2297 + defer file.close(self.io); │ │2298 + │ │2299 + var storage: [4096]u8 = undefined; │ │2300 + var reader = file.reader(self.io, &storage); │ │2301 + const bytes = reader.interface.allocRemaining(allocator, .limited(512 * 1024)) catch return null; │ │2302 + return std.json.parseFromSliceLeaky(ui.Session.FormFeedback, allocator, bytes, .{}) catch null; │ │2303 } │ │2304 │ │2305 // resolve a cookie's token to its user_id. returns false (logged out) for a │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯