import fs from "fs";
import type { ServiceMethodFactory } from "@ethicdevs/react-monolith";
import { User } from "@prisma/client";
import type { UsersServiceDeps } from "./types";
const SSH_RSA_KEY_REGEXP =
/^ssh-rsa AAAA[0-9A-Za-z+\/]+[=]{0,3} ([^@]+@[^@]+)$/i;
const addUserSSHKey: ServiceMethodFactory<
UsersServiceDeps,
[User, string, string],
Promise<boolean>
> = ({ request }) => {
return async (user, name, key) => {
if (key.match(SSH_RSA_KEY_REGEXP) == null) {
throw new Error(
"Invalid public key. Please provide a valid SSH RSA public key."
);
}
const existingKey = await request.prisma.userSSHKey.findFirst({
where: {
key: key,
},
});
if (existingKey != null) {
throw new Error(
"Public key is already registered. Please use another one."
);
}
const userKey = await request.prisma.userSSHKey.create({
data: {
name: name,
key: key,
user: {
connect: {
id: user.id,
},
},
},
});
if (userKey == null) {
return false;
}
let line = "";
line += `command="ssh_command ${user.username}",`;
line += "no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ";
line += `${key}\n`;
fs.appendFileSync("/home/git/.ssh/authorized_keys", line, {
encoding: "utf8",
});
return true;
};
};
export default addUserSSHKey;