╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Login.zig ────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
170 return; 171 } 172 } 173 } 174 }, 175 else => {}, 176 } 177 } 178 179 const username_input = &box.children.values()[username_index].widget.text_input; 180 const password_input = &box.children.values()[password_index].widget.text_input; 181 const username_len_before = username_input.content.items.len; 182 const password_len_before = password_input.content.items.len; 183 184 if (box.children.getIndex(child_id)) |idx| { 185 try box.children.values()[idx].widget.input(allocator, key, root_focus); 186 } 187 188 if (username_input.content.items.len != username_len_before or 189 password_input.content.items.len != password_len_before) 190 { 191 // any edit clears the failure flag so the "(invalid)" label 192 // doesn't linger after the user has typed a correction. 193 self.session.data.login_failure = null; 194 } 195 } 196 197 pub fn clearGrid(self: *View) void { 198 self.center.clearGrid(); 199 } 200 201 pub fn getGrid(self: View) ?Grid { 202 return self.center.getGrid(); 203 } 204 205 pub fn getFocus(self: *View) *Focus { 206 return self.center.getFocus(); 207 } 208 209 pub fn getSelectedIndex(self: View) ?usize { 210 const child_id = self.center.child.box.focus.child_id orelse return null; 211 return self.indexOf(child_id); 212 } 213 214 fn indexOf(self: View, child_id: usize) ?usize { 215 for (self.nav_ids, 0..) |id, i| { 216 if (id == child_id) return i; 217 } 218 return null; 219 } 220 221 fn submit(self: *View, allocator: std.mem.Allocator, root_focus: *Focus) !void { 222 if (comptime wasm) { 223 // no DB cursor available on the wasm render path 224 self.session.data.login_failure = .unknown_user; 225 return; 226 } 227 228 const box = &self.center.child.box; 229 const username_input = &box.children.values()[username_index].widget.text_input; 230 const password_input = &box.children.values()[password_index].widget.text_input; 231 232 const username = try username_input.text(allocator); 233 defer allocator.free(username); 234 235 const password = try password_input.text(allocator); 236 defer allocator.free(password); 237 238 const haxy_moment = self.session.haxy_moment orelse { 239 // no DB context (e.g. wasm/web rendering path); treat as unknown. 240 self.session.data.login_failure = .unknown_user; 241 return; 242 }; 243 244 const result = try evt.User.verifyCredentials(evt.AdminDB, evt.admin_repo_opts.hash, haxy_moment, self.session.arena, username, password); 245 switch (result) { 246 .unknown_user => { 247 self.session.data.login_failure = .unknown_user; 248 return; 249 }, 250 .wrong_password => { 251 self.session.data.login_failure = .wrong_password; 252 return; 253 }, 254 .success => |user_id| { 255 // dupe user_id into the arena so the session can hold a stable slice 256 const user_id_stable = try self.session.arena.allocator().dupe(u8, &user_id); 257 self.session.data.user_id = user_id_stable; 258 self.session.data.login_failure = null; 259 260 // adopt the user's persisted prefs 261 try self.session.loadUserPrefs(); 262 263 // wipe the entered credentials so they don't linger if the 264 // user returns to this page after logging out 265 username_input.clear(allocator); 266 password_input.clear(allocator); 267 268 // jump focus back to the users tab — the login button we 269 // just pressed is about to be hidden by the tab-label swap 270 try root_focus.setFocus(self.success_redirect_tab_id); 271 }, 272 } 273 } 274 }; 275