╭ changed ────────╮ │src/serve_ssh.zig│ ╰─────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────╮ │239 ui_session.io = io; │ │240 ui_session.users_dir = handler.server.users_dir; │ │241 ui_session.dirty_repos = handler.server.dirty_repos; │ │242 + ui_session.ssh_key = try authorizedKeyLine(session_arena.allocator(), sess.public_key);│ │243 + try ui_session.logInWithSshKey(); │ │244 │ │245 var nav = try ui.Nav.init(allocator, &ui_session); │ │246 defer nav.deinit(allocator); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │608 ) !evt.CommitAuthor { │ │609 const user = (try evt.User.readById(evt.AdminDB, evt.admin_repo_opts.hash, moment, arena, user_id)) orelse unreachable;│ │610 return .{ .name = user.event.name, .email = user.event.email }; │ │611 +} │ │612 + │ │613 +// the authorized_keys line of a pubkey blob: its type, then the blob in base64 │ │614 +fn authorizedKeyLine(allocator: std.mem.Allocator, blob: []const u8) ![]const u8 { │ │615 + var reader = std.Io.Reader.fixed(blob); │ │616 + const key_type = try ssh.takeString(&reader, 64); │ │617 + const encoder = std.base64.standard.Encoder; │ │618 + const line = try allocator.alloc(u8, key_type.len + 1 + encoder.calcSize(blob.len)); │ │619 + @memcpy(line[0..key_type.len], key_type); │ │620 + line[key_type.len] = ' '; │ │621 + _ = encoder.encode(line[key_type.len + 1 ..], blob); │ │622 + return line; │ │623 } │ │624 │ │625 fn writeError(sess: *ssh.SessionCtx, comptime msg: []const u8) !void { │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯