╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Login.zig ────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
198 pub fn getFocus(self: *View) *Focus { 199 return self.center.getFocus(); 200 } 201 202 pub fn getSelectedIndex(self: View) ?usize { 203 const child_id = self.center.child.box.focus.child_id orelse return null; 204 return self.indexOf(child_id); 205 } 206 207 fn indexOf(self: View, child_id: usize) ?usize { 208 for (self.nav_ids, 0..) |id, i| { 209 if (id == child_id) return i; 210 } 211 return null; 212 } 213 214 fn submit(self: *View, allocator: std.mem.Allocator, root_focus: *Focus) !void { 215 if (comptime wasm) { 216 // no DB cursor available on the wasm render path 217 self.session.data.login_failure = .unknown_user; 218 return; 219 } 220 221 const box = &self.center.child.box; 222 const username_input = &box.children.values()[username_index].widget.text_input; 223 const password_input = &box.children.values()[password_index].widget.text_input; 224 225 const username = try username_input.text(allocator); 226 defer allocator.free(username); 227 228 const password = try password_input.text(allocator); 229 defer allocator.free(password); 230 231 const haxy_moment = self.session.haxy_moment orelse { 232 // no DB context (e.g. wasm/web rendering path); treat as unknown. 233 self.session.data.login_failure = .unknown_user; 234 return; 235 }; 236 237 const result = try evt.User.verifyCredentials(evt.AdminDB, evt.admin_repo_opts.hash, haxy_moment, self.session.arena, username, password); 238 switch (result) { 239 .unknown_user => { 240 self.session.data.login_failure = .unknown_user; 241 return; 242 }, 243 .wrong_password => { 244 self.session.data.login_failure = .wrong_password; 245 return; 246 }, 247 .success => |user_id| { 248 // dupe user_id into the arena so the session can hold a stable slice 249 const user_id_stable = try self.session.arena.allocator().dupe(u8, &user_id); 250 self.session.data.user_id = user_id_stable; 251 self.session.data.login_failure = null; 252 253 // adopt the user's persisted prefs 254 try self.session.loadUserPrefs(); 255 256 // wipe the entered credentials so they don't linger if the 257 // user returns to this page after logging out 258 username_input.clear(allocator); 259 password_input.clear(allocator); 260 261 // jump focus back to the users tab — the login button we 262 // just pressed is about to be hidden by the tab-label swap 263 try root_focus.setFocus(self.success_redirect_tab_id); 264 }, 265 } 266 } 267 }; 268