{
diff --git a/src/components/pages/admin/users/deployment-user/(sections)/ssh-connection.tsx b/src/components/pages/admin/users/deployment-user/(sections)/ssh-connection.tsx
new file mode 100644
index 0000000..d0458a9
--- /dev/null
+++ b/src/components/pages/admin/users/deployment-user/(sections)/ssh-connection.tsx
@@ -0,0 +1,51 @@
+import { useContext } from "react";
+import { AppContext } from "@/src/pages/_app";
+import Stack from "@/twui/components/layout/Stack";
+import H2 from "@/twui/components/layout/H2";
+import Span from "@/twui/components/layout/Span";
+import RemoteCodeBlock from "@/twui/components/elements/RemoteCodeBlock";
+import SingleLineCodeBlock from "@/twui/components/elements/SingleLineCodeBlock";
+import TurboCICodeBlock from "@/src/components/general/code-block";
+import H3 from "@/twui/components/layout/H3";
+
+export default function SSHConnection() {
+ const { pageProps } = useContext(AppContext);
+ const { deployment_user, deployment } = pageProps;
+
+ if (!deployment_user?.id) {
+ return null;
+ }
+
+ const is_super_admin = Boolean(deployment_user.is_super_admin);
+
+ return (
+ <>
+
+ Connection
+
+ Use these information to connect this user to the Relay
+ server
+
+
+
+
+
+
+ Admin Port Forwarding
+
+
+ Use these information to connect this user to the
+ Relay server
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/src/components/pages/admin/users/deployment-user/index.tsx b/src/components/pages/admin/users/deployment-user/index.tsx
index fccca18..44a5bd9 100644
--- a/src/components/pages/admin/users/deployment-user/index.tsx
+++ b/src/components/pages/admin/users/deployment-user/index.tsx
@@ -7,6 +7,7 @@ import Row from "@/twui/components/layout/Row";
import SignupForm from "../../../auth/signup/(partials)/signup-form";
import Stack from "@/twui/components/layout/Stack";
import DeleteDeplotmentUserButton from "./(partials)/delete-deployment-user-button";
+import SSHConnection from "./(sections)/ssh-connection";
export default function Main() {
const { pageProps } = useContext(AppContext);
@@ -43,6 +44,8 @@ export default function Main() {
+
+
);
}
diff --git a/src/components/pages/auth/signup/(partials)/signup-form-password.tsx b/src/components/pages/auth/signup/(partials)/signup-form-password.tsx
new file mode 100644
index 0000000..8c7863b
--- /dev/null
+++ b/src/components/pages/auth/signup/(partials)/signup-form-password.tsx
@@ -0,0 +1,57 @@
+import Input from "@/twui/components/form/Input";
+import useSignupForm from "../(hooks)/use-signup-form";
+
+type Props = ReturnType
;
+
+export default function SignupFormPassword({
+ isPasswordConfirmed,
+ newUser,
+ setNewUser,
+ setIsPasswordConfirmed,
+}: Props) {
+ const is_password_valid = Boolean(
+ isPasswordConfirmed &&
+ Boolean(newUser.password?.match(/./)) &&
+ Boolean(newUser.confirmed_password?.match(/./)),
+ );
+
+ return (
+ <>
+ {
+ setNewUser((prev) => ({
+ ...prev,
+ password: v,
+ }));
+ }}
+ validity={{
+ isValid:
+ !Boolean(newUser.password?.match(/./)) ||
+ !Boolean(newUser.confirmed_password?.match(/./))
+ ? true
+ : is_password_valid,
+ msg: `Passwords don't match`,
+ }}
+ required
+ showLabel
+ />
+ {
+ setNewUser((prev) => ({
+ ...prev,
+ confirmed_password: v,
+ }));
+
+ setIsPasswordConfirmed(v == newUser.password);
+ }}
+ showLabel
+ />
+ >
+ );
+}
diff --git a/src/components/pages/auth/signup/(partials)/signup-form.tsx b/src/components/pages/auth/signup/(partials)/signup-form.tsx
index 4f7cc44..a555e5f 100644
--- a/src/components/pages/auth/signup/(partials)/signup-form.tsx
+++ b/src/components/pages/auth/signup/(partials)/signup-form.tsx
@@ -5,9 +5,9 @@ import useSignupForm from "../(hooks)/use-signup-form";
import fetchApi from "@/twui/components/utils/fetch/fetchApi";
import { APIReqObject } from "@/src/types";
import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types";
-import { useEffect } from "react";
import { NSQLITE_TURBOCI_ADMIN_USERS } from "@/src/db/types";
import { twMerge } from "tailwind-merge";
+import SignupFormPassword from "./signup-form-password";
type Props = {
new_deployment_user?: boolean;
@@ -18,6 +18,7 @@ export default function SignupForm({
new_deployment_user,
existing_user,
}: Props) {
+ const init = useSignupForm({ new_deployment_user, existing_user });
const {
newUser,
setNewUser,
@@ -26,7 +27,7 @@ export default function SignupForm({
isPasswordConfirmed,
setIsPasswordConfirmed,
pageProps,
- } = useSignupForm({ new_deployment_user, existing_user });
+ } = init;
const is_password_valid = Boolean(
isPasswordConfirmed &&
@@ -80,7 +81,7 @@ export default function SignupForm({
required
showLabel
/>
- {pageProps.user.id ? (
+ {pageProps.user?.id && !existing_user?.is_super_admin ? (
) : null}
- {existing_user?.id ? null : (
- <>
- {
- setNewUser((prev) => ({
- ...prev,
- password: v,
- }));
- }}
- validity={{
- isValid:
- !Boolean(newUser.password?.match(/./)) ||
- !Boolean(
- newUser.confirmed_password?.match(/./),
- )
- ? true
- : is_password_valid,
- msg: `Passwords don't match`,
- }}
- required
- showLabel
- />
- {
- setNewUser((prev) => ({
- ...prev,
- confirmed_password: v,
- }));
-
- setIsPasswordConfirmed(v == newUser.password);
- }}
- showLabel
- />
- >
- )}
+ {existing_user?.id ? null : }
diff --git a/src/functions/deployment-users/delete-deployment-user.ts b/src/functions/deployment-users/delete-deployment-user.ts
index 66d7aad..98155e2 100644
--- a/src/functions/deployment-users/delete-deployment-user.ts
+++ b/src/functions/deployment-users/delete-deployment-user.ts
@@ -17,8 +17,6 @@ export default async function deleteDeploymentUser({ user_id }: Params) {
targetId: _n(user_id),
});
- console.log("target_user_res", target_user_res);
-
const target_user = target_user_res.singleRes;
if (
@@ -31,6 +29,8 @@ export default async function deleteDeploymentUser({ user_id }: Params) {
const { username } = target_user;
+ console.log("username", username);
+
const { force_command_file, sshd_config_file } = grabDeploymentUserDirNames(
{ user: target_user },
);
@@ -38,12 +38,13 @@ export default async function deleteDeploymentUser({ user_id }: Params) {
let cmd = `/bin/bash << 'TURBOCIHEREDOC'\n`;
// cmd += `userdel -r ${username}\n`;
- cmd += `killall -u ${username}\n`;
- cmd += `deluser --remove-all-files ${username}\n`;
+ // cmd += `pkill -u ${username} || echo "User Deleted!"\n`;
+ cmd += `deluser --remove-all-files ${username} || echo "User Deleted!"\n`;
cmd += `rm -f ${force_command_file}\n`;
cmd += `rm -f ${sshd_config_file}\n`;
- cmd += `Match User ${username}\n`;
+
+ cmd += `TURBOCIHEREDOC\n`;
execSync(cmd);
diff --git a/src/functions/deployment-users/setup-deployment-user.ts b/src/functions/deployment-users/setup-deployment-user.ts
index 1421d97..b0da6de 100644
--- a/src/functions/deployment-users/setup-deployment-user.ts
+++ b/src/functions/deployment-users/setup-deployment-user.ts
@@ -18,11 +18,13 @@ export default async function setupDeploymentUser({ user_id }: Params) {
targetId: _n(user_id),
});
- console.log("target_user_res", target_user_res);
-
const target_user = target_user_res.singleRes;
- if (!target_user?.id || !target_user.username) {
+ if (
+ !target_user?.id ||
+ !target_user.username ||
+ target_user.is_super_admin
+ ) {
return;
}
@@ -42,7 +44,7 @@ export default async function setupDeploymentUser({ user_id }: Params) {
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 += `ssh-keygen -t ed25519 -f "${ssh_key_file}" -N "" -C "${username}@$(hostname)"\n`;
cmd += `cp "${ssh_key_file}.pub" "${ssh_dir}/authorized_keys"\n`;
cmd += `chown -R "${username}:${username}" "${ssh_dir}"\n`;
diff --git a/src/layouts/admin/(data)/links.ts b/src/layouts/admin/(data)/links.ts
index 46066b1..54f5a30 100644
--- a/src/layouts/admin/(data)/links.ts
+++ b/src/layouts/admin/(data)/links.ts
@@ -1,25 +1,34 @@
+import { User } from "@/src/types";
import { TWUI_LINK_LIST_LINK_OBJECT } from "@/twui/components/elements/LinkList";
-export const AdminAsideLinks: (
- | TWUI_LINK_LIST_LINK_OBJECT
- | TWUI_LINK_LIST_LINK_OBJECT[]
- | undefined
-)[] = [
- {
- title: "Dashboard",
- url: "/admin",
- strict: true,
- },
- {
- title: "Services",
- url: "/admin/services",
- },
- {
- title: "Users",
- url: "/admin/users",
- },
- {
- title: "Settings",
- url: "/admin/settings",
- },
-];
+type Params = { user?: User };
+
+export function AdminAsideLinks({ user }: Params) {
+ const links: (
+ | TWUI_LINK_LIST_LINK_OBJECT
+ | TWUI_LINK_LIST_LINK_OBJECT[]
+ | undefined
+ )[] = [
+ {
+ title: "Dashboard",
+ url: "/admin",
+ strict: true,
+ },
+ {
+ title: "Services",
+ url: "/admin/services",
+ },
+ user?.super_admin
+ ? {
+ title: "Users",
+ url: "/admin/users",
+ }
+ : undefined,
+ {
+ title: "Settings",
+ url: "/admin/settings",
+ },
+ ];
+
+ return links;
+}
diff --git a/src/layouts/admin/index.tsx b/src/layouts/admin/index.tsx
index 12cda46..f0d12a8 100644
--- a/src/layouts/admin/index.tsx
+++ b/src/layouts/admin/index.tsx
@@ -2,16 +2,18 @@ import LinkList from "@/twui/components/elements/LinkList";
import Main from "@/twui/components/layout/Main";
import Row from "@/twui/components/layout/Row";
import Stack from "@/twui/components/layout/Stack";
-import { Fragment, PropsWithChildren } from "react";
+import { Fragment, PropsWithChildren, useContext } from "react";
import { AdminAsideLinks } from "./(data)/links";
import Header from "./header";
import { twMerge } from "tailwind-merge";
-import Spacer from "@/twui/components/layout/Spacer";
import Head from "next/head";
+import { AppContext } from "@/src/pages/_app";
type Props = PropsWithChildren & {};
export default function Layout({ children }: Props) {
+ const { pageProps } = useContext(AppContext);
+
return (
@@ -26,7 +28,7 @@ export default function Layout({ children }: Props) {
{
- return await defaultAdminProps({ ctx });
+ return await defaultAdminProps({
+ ctx,
+ async propsFn({ user }) {
+ if (!user.id) {
+ return `/admin`;
+ }
+
+ const users_res = await NSQLite.select(
+ {
+ table: "users",
+ targetId: user.id,
+ },
+ );
+
+ if (!users_res.singleRes?.id) {
+ return `/admin/users`;
+ }
+
+ return {
+ deployment_user: users_res.singleRes,
+ };
+ },
+ });
};
diff --git a/src/pages/admin/users/[deployment_user_id]/index.tsx b/src/pages/admin/users/[deployment_user_id]/index.tsx
index 1086a7a..69bac06 100644
--- a/src/pages/admin/users/[deployment_user_id]/index.tsx
+++ b/src/pages/admin/users/[deployment_user_id]/index.tsx
@@ -29,6 +29,10 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => {
},
);
+ if (!users_res.singleRes?.id) {
+ return `/admin/users`;
+ }
+
return {
deployment_user: users_res.singleRes,
};
diff --git a/src/pages/api/auth/signup.ts b/src/pages/api/auth/signup.ts
index b6f57ab..17ababa 100644
--- a/src/pages/api/auth/signup.ts
+++ b/src/pages/api/auth/signup.ts
@@ -73,7 +73,7 @@ export default async function handler(
email,
password: new_user_password,
is_super_admin: user?.id ? 0 : 1,
- username: slugify(username),
+ username: username ? slugify(username) : undefined,
},
],
table: "users",
@@ -90,20 +90,31 @@ export default async function handler(
(typeof NSQLiteTables)[number]
>({
table: "users",
- query: {
- query: {
- is_super_admin: { value: "1" },
- },
- },
+ targetId: new_user_id,
});
const newly_inserted_user = newly_inserted_user_res.singleRes;
if (!newly_inserted_user?.id) {
+ console.log("newly_inserted_user_res", newly_inserted_user_res);
throw new Error(`Couldn't Find Newly inserted user.`);
}
+ if (user?.id && !newly_inserted_user.username) {
+ const newly_inserted_user_res = await NSQLite.delete<
+ NSQLITE_TURBOCI_ADMIN_USERS,
+ (typeof NSQLiteTables)[number]
+ >({
+ table: "users",
+ targetId: newly_inserted_user?.id,
+ });
+
+ throw new Error(`Couldn't set Newly inserted user username.`);
+ }
+
if (user?.id) {
+ console.log("newly_inserted_user", newly_inserted_user);
+
await setupDeploymentUser({ user_id: newly_inserted_user.id });
return res.json({