╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Login.zig ────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
187 } 188 189 fn submit(self: *View, allocator: std.mem.Allocator) !void { 190 const box = &self.center.child.box; 191 const username_input = &box.children.values()[username_index].widget.text_input; 192 const password_input = &box.children.values()[password_index].widget.text_input; 193 194 const username = try username_input.text(allocator); 195 defer allocator.free(username); 196 197 const password = try password_input.text(allocator); 198 defer allocator.free(password); 199 200 if (comptime wasm) { 201 // no DB cursor available on the wasm render path 202 try self.rememberFailure(.unknown_user, username); 203 return; 204 } 205 206 const haxy_moment = self.session.haxy_moment orelse { 207 // no DB context (e.g. wasm/web rendering path); treat as unknown. 208 try self.rememberFailure(.unknown_user, username); 209 return; 210 }; 211 212 const result = try evt.User.verifyCredentials(evt.AdminDB, evt.admin_repo_opts.hash, haxy_moment, self.session.arena, username, password); 213 switch (result) { 214 .unknown_user => { 215 try self.rememberFailure(.unknown_user, username); 216 return; 217 }, 218 .wrong_password => { 219 try self.rememberFailure(.wrong_password, username); 220 return; 221 }, 222 .success => |user_id| { 223 // dupe user_id into the arena so the session can hold a stable slice 224 const user_id_stable = try self.session.arena.allocator().dupe(u8, &user_id); 225 self.session.data.user_id = user_id_stable; 226 227 // adopt the user's name and persisted prefs 228 try self.session.loadUser(); 229 230 // wipe the entered credentials so they don't linger if the 231 // user returns to this page after logging out 232 username_input.clear(allocator); 233 password_input.clear(allocator); 234 235 // leave the auth tab for the page it belongs to, where the 236 // web's /login redirect also lands 237 try self.session.navigate(self.session.data.current_page.pageRoot()); 238 }, 239 } 240 } 241 242 fn rememberFailure(self: *View, failure: ui.Session.FormFeedback.LoginFailure, username: []const u8) !void { 243 self.session.data.form_feedback = .{ .login = .{ 244 .failure = failure, 245 .username = try self.session.arena.allocator().dupe(u8, username), 246 } }; 247 } 248 }; 249