import { NSQLITE_TURBOCI_ADMIN_USERS, NSQLiteTables } from "@/src/db/types"; import { _n } from "@/src/exports/client-exports"; import NSQLite from "@moduletrace/nsqlite"; import { existsSync } from "fs"; type Params = { user_id: string | number; }; export default async function setupDeploymentUser({ user_id }: Params) { const target_user_res = await NSQLite.select< NSQLITE_TURBOCI_ADMIN_USERS, (typeof NSQLiteTables)[number] >({ table: "users", targetId: _n(user_id), }); const target_user = target_user_res.singleRes; if (!target_user?.id) { return; } const { username } = target_user; const user_dir = `/home/${username}`; const ssh_dir = `${user_dir}/.ssh`; const ssh_key_file = `${ssh_dir}/${username}`; const sshd_config_file = `/etc/ssh/sshd_config.d/${username}`; const force_command_file = `/usr/local/bin/turboci-deployment-user-${username}`; if (!existsSync(user_dir)) { let cmd = ``; cmd += `useradd --create-home --shell /bin/bash --comment "TurboCI Deployment user ${username}" ${username}\n`; cmd += `passwd --lock "${username}"\n`; cmd += `mkdir -p "${ssh_dir}"\n`; cmd += `ssh-keygen -t ed25519 -f "${ssh_key_file}" -N ""\n`; cmd += `cp "${ssh_key_file}.pub" "${ssh_dir}/authorized_keys"\n`; cmd += `chown -R "${username}:${username}" "${ssh_dir}"\n`; cmd += `chmod 700 "${ssh_dir}"\n`; cmd += `chmod 600 "${ssh_key_file}"\n`; cmd += `chmod 644 "${ssh_key_file}.pub"\n`; cmd += `chmod 600 "${ssh_dir}/authorized_keys"\n`; cmd += `cat << 'EOF' > ${force_command_file}\n`; cmd += `#!/bin/bash\n`; cmd += `EOF\n`; cmd += `cat << 'EOF' > ${sshd_config_file}\n`; cmd += `Match User ${username}\n`; cmd += ` # Authentication\n`; cmd += ` PasswordAuthentication no\n`; cmd += ` PubkeyAuthentication yes\n`; cmd += ` AuthenticationMethods publickey\n\n`; cmd += ` # Restrict shell / tunneling\n`; cmd += ` AllowTcpForwarding yes\n`; cmd += ` X11Forwarding no\n\n`; cmd += ` # Restrict Commands\n`; cmd += ` ForceCommand ${force_command_file}\n`; cmd += `EOF\n`; } return; }