Updates
This commit is contained in:
parent
5131e22c69
commit
3663d91aa6
@ -0,0 +1,38 @@
|
|||||||
|
import { useContext } from "react";
|
||||||
|
import { AppContext } from "@/src/pages/_app";
|
||||||
|
import Button from "@/twui/components/layout/Button";
|
||||||
|
import LucideIcon from "@/twui/components/elements/lucide-icon";
|
||||||
|
import useStatus from "@/twui/components/hooks/useStatus";
|
||||||
|
import downloadFile from "@/src/utils/download-file";
|
||||||
|
|
||||||
|
export default function DownloadPrivateSSHKey() {
|
||||||
|
const { pageProps } = useContext(AppContext);
|
||||||
|
const { deployment_user, deployment } = pageProps;
|
||||||
|
|
||||||
|
const { loading, setLoading } = useStatus();
|
||||||
|
|
||||||
|
if (!deployment_user?.id) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const is_super_admin = Boolean(deployment_user.is_super_admin);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
title="Download Private Key"
|
||||||
|
variant="outlined"
|
||||||
|
beforeIcon={<LucideIcon name="Download" size={20} />}
|
||||||
|
loading={loading}
|
||||||
|
onClick={() => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
downloadFile({
|
||||||
|
file_name: `${deployment_user.username}-private-key`,
|
||||||
|
url: `/api/admin/download-private-ssh-key?user_id=${deployment_user.id}`,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Download Private Key
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -42,7 +42,7 @@ export default function SSHConnection() {
|
|||||||
</Span>
|
</Span>
|
||||||
</Stack>
|
</Stack>
|
||||||
<TurboCICodeBlock
|
<TurboCICodeBlock
|
||||||
content={`ssh -N -L -i /path/to/ssh/key ${deployment_user.username}@${deployment?.relay_server_ip}`}
|
content={`ssh -N -L 3773:localhost:80 -i /path/to/ssh/key ${deployment_user.username}@${deployment?.relay_server_ip}`}
|
||||||
mode="sh"
|
mode="sh"
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
@ -59,7 +59,9 @@ export default function SSHConnection() {
|
|||||||
<Button
|
<Button
|
||||||
title="Download Private Key"
|
title="Download Private Key"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
beforeIcon={<LucideIcon name="Download" />}
|
beforeIcon={
|
||||||
|
<LucideIcon name="Download" size={20} />
|
||||||
|
}
|
||||||
>
|
>
|
||||||
Download Private Key
|
Download Private Key
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
46
src/pages/api/admin/download-private-ssh-key.ts
Normal file
46
src/pages/api/admin/download-private-ssh-key.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import loginUser from "@/src/functions/auth/login-user";
|
||||||
|
import { NSQLITE_TURBOCI_ADMIN_USERS } from "@/src/db/types";
|
||||||
|
import userAuth from "@/src/utils/user-auth";
|
||||||
|
import NSQLite from "@moduletrace/nsqlite";
|
||||||
|
import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types";
|
||||||
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
import { APIReqObject } from "@/src/types";
|
||||||
|
|
||||||
|
export default async function handler(
|
||||||
|
req: NextApiRequest,
|
||||||
|
res: NextApiResponse<APIResponseObject>,
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
if (req.method !== "POST") {
|
||||||
|
return res.json({
|
||||||
|
success: false,
|
||||||
|
msg: "Wrong Method",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const { singleRes: user } = await userAuth({ req });
|
||||||
|
|
||||||
|
if (!user?.id || !user.super_admin) {
|
||||||
|
return res.json({
|
||||||
|
success: false,
|
||||||
|
msg: "Unauthorized",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const { user_id } = req.query as APIReqObject;
|
||||||
|
|
||||||
|
const target_user_res =
|
||||||
|
await NSQLite.select<NSQLITE_TURBOCI_ADMIN_USERS>({
|
||||||
|
table: "users",
|
||||||
|
targetId: user_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
const target_user = target_user_res.singleRes;
|
||||||
|
|
||||||
|
const updated = await loginUser({ res, user_id: user.id });
|
||||||
|
|
||||||
|
return res.json(updated);
|
||||||
|
} catch (error: any) {
|
||||||
|
return res.json({ success: false, msg: error.message });
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/utils/download-file.ts
Normal file
15
src/utils/download-file.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import downloadFromFetchRes from "./download-from-fetch-res";
|
||||||
|
|
||||||
|
export default async function downloadFile({
|
||||||
|
url,
|
||||||
|
file_name,
|
||||||
|
}: {
|
||||||
|
url: string;
|
||||||
|
file_name: string;
|
||||||
|
}) {
|
||||||
|
let file: Response;
|
||||||
|
|
||||||
|
file = await fetch(url);
|
||||||
|
|
||||||
|
downloadFromFetchRes({ res: file, file_name });
|
||||||
|
}
|
||||||
20
src/utils/download-from-fetch-res.ts
Normal file
20
src/utils/download-from-fetch-res.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
type Params = {
|
||||||
|
res: Response;
|
||||||
|
file_name: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async function downloadFromFetchRes({ res, file_name }: Params) {
|
||||||
|
const blob = await res.blob();
|
||||||
|
const downloadableUrl = URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.href = downloadableUrl;
|
||||||
|
link.download = file_name;
|
||||||
|
link.style.display = "none";
|
||||||
|
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
|
||||||
|
URL.revokeObjectURL(downloadableUrl);
|
||||||
|
document.body.removeChild(link);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user