This commit is contained in:
Benjamin Toby 2026-03-11 04:16:51 +00:00
parent 33044fae23
commit 2e0009e3ca
13 changed files with 152 additions and 10 deletions

View File

@ -0,0 +1,18 @@
import { Fragment, useContext } from "react";
import { AppContext } from "@/src/pages/_app";
import Divider from "@/twui/components/layout/Divider";
import AdminHero from "@/src/components/general/admin/hero";
export default function Main() {
const { pageProps } = useContext(AppContext);
return (
<Fragment>
<AdminHero
title={`Users`}
description={<>All Users in this deployment</>}
/>
<Divider />
</Fragment>
);
}

View File

@ -37,6 +37,10 @@ const schema = {
fieldName: "is_super_admin", fieldName: "is_super_admin",
dataType: "INTEGER", dataType: "INTEGER",
}, },
{
fieldName: "all_deployment_access",
dataType: "INTEGER",
},
], ],
}, },
{ {

View File

@ -23,6 +23,7 @@ export type NSQLITE_TEST_DB_USERS = {
image?: string; image?: string;
password?: string; password?: string;
is_super_admin?: number; is_super_admin?: number;
all_deployment_access?: number;
} }
export type NSQLITE_TEST_DB_USERS_PORTS = { export type NSQLITE_TEST_DB_USERS_PORTS = {

View File

@ -1,15 +1,15 @@
import { NextApiResponse } from "next"; import { NextApiResponse } from "next";
import { ServerResponse } from "http"; import { ServerResponse } from "http";
import NSQLite from "@moduletrace/nsqlite"; import NSQLite from "@moduletrace/nsqlite";
import { NSQLITE_TEST_DB_USERS, NSQLiteTables } from "../db/types"; import { NSQLITE_TEST_DB_USERS, NSQLiteTables } from "../../db/types";
import { User } from "../types"; import { User } from "../../types";
import { setCookie } from "./cookies-actions"; import { setCookie } from "../../utils/cookies-actions";
import { EJSON } from "../exports/client-exports"; import { EJSON } from "../../exports/client-exports";
import encrypt from "@moduletrace/datasquirel/dist/package-shared/functions/dsql/encrypt"; import encrypt from "@moduletrace/datasquirel/dist/package-shared/functions/dsql/encrypt";
import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types"; import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types";
import hashPassword from "@moduletrace/datasquirel/dist/package-shared/functions/dsql/hashPassword"; import hashPassword from "@moduletrace/datasquirel/dist/package-shared/functions/dsql/hashPassword";
import dayjs from "dayjs"; import dayjs from "dayjs";
import grabCookieNames from "./grab-cookie-names"; import grabCookieNames from "../../utils/grab-cookie-names";
type Params = { type Params = {
res: NextApiResponse | ServerResponse; res: NextApiResponse | ServerResponse;
@ -103,6 +103,7 @@ export default async function loginUser({
logged_in_status: true, logged_in_status: true,
image: fetched_user.image, image: fetched_user.image,
image_thumbnail: fetched_user.image, image_thumbnail: fetched_user.image,
super_admin: fetched_user.is_super_admin ? 1 : 0,
}; };
const payload_string = EJSON.stringify(logged_in_user_payload); const payload_string = EJSON.stringify(logged_in_user_payload);

View File

@ -0,0 +1,36 @@
import { NextApiResponse } from "next";
import { ServerResponse } from "http";
import { deleteCookie } from "../../utils/cookies-actions";
import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types";
import grabCookieNames from "../../utils/grab-cookie-names";
type Params = {
res: NextApiResponse | ServerResponse;
};
export default async function logoutUser({
res,
}: Params): Promise<APIResponseObject> {
const { auth_key_cookie_name, csrf_cookie_name } = grabCookieNames();
deleteCookie(res, [
{
name: auth_key_cookie_name,
options: {
path: "/",
domain: process.env.DOMAIN,
},
},
{
name: csrf_cookie_name,
options: {
path: "/",
domain: process.env.DOMAIN,
},
},
]);
return {
success: true,
};
}

View File

@ -19,7 +19,7 @@ type Params = {
props?: PagePropsType; props?: PagePropsType;
propsFn?: ( propsFn?: (
params: PropsFnParams, params: PropsFnParams,
) => Promise<PagePropsType | false | string>; ) => Promise<Omit<PagePropsType, "user"> | false | string>;
}; };
const { TURBOCI_DEPLOYMENT_ID_FILE } = grabDirNames(); const { TURBOCI_DEPLOYMENT_ID_FILE } = grabDirNames();

View File

@ -0,0 +1,32 @@
import { AppContext } from "@/src/pages/_app";
import Dropdown from "@/twui/components/elements/Dropdown";
import LinkList from "@/twui/components/elements/LinkList";
import LucideIcon from "@/twui/components/elements/lucide-icon";
import Img from "@/twui/components/layout/Img";
import Row from "@/twui/components/layout/Row";
import Span from "@/twui/components/layout/Span";
import { useContext } from "react";
export default function HeaderUser() {
const { pageProps } = useContext(AppContext);
const { user } = pageProps;
return (
<Dropdown
target={
<Row>
<Img
circle
size={25}
src={user.image_thumbnail}
alt={`${user.first_name} Image`}
/>
<Span>{user.first_name}</Span>
<LucideIcon name="ChevronDown" size={17} />
</Row>
}
>
<LinkList />
</Dropdown>
);
}

View File

@ -0,0 +1,25 @@
import Main from "@/src/components/pages/admin/users";
import defaultAdminProps from "@/src/functions/pages/admin/default-admin-props";
import Layout from "@/src/layouts/admin";
import { GetServerSideProps } from "next";
export default function AdminDashboard() {
return (
<Layout>
<Main />
</Layout>
);
}
export const getServerSideProps: GetServerSideProps = async (ctx) => {
return await defaultAdminProps({
ctx,
async propsFn({ user, props }) {
if (!user.super_admin) {
return `/admin`;
}
return {};
},
});
};

View File

@ -1,5 +1,5 @@
import { APIReqObject } from "@/src/types"; import { APIReqObject } from "@/src/types";
import loginUser from "@/src/utils/login-user"; import loginUser from "@/src/functions/auth/login-user";
import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types"; import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types";
import type { NextApiRequest, NextApiResponse } from "next"; import type { NextApiRequest, NextApiResponse } from "next";

View File

@ -1,6 +1,6 @@
import { NSQLITE_TEST_DB_USERS, NSQLiteTables } from "@/src/db/types"; import { NSQLITE_TEST_DB_USERS, NSQLiteTables } from "@/src/db/types";
import { APIReqObject } from "@/src/types"; import { APIReqObject } from "@/src/types";
import loginUser from "@/src/utils/login-user"; import loginUser from "@/src/functions/auth/login-user";
import hashPassword from "@moduletrace/datasquirel/dist/package-shared/functions/dsql/hashPassword"; import hashPassword from "@moduletrace/datasquirel/dist/package-shared/functions/dsql/hashPassword";
import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types"; import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types";
import NSQLite from "@moduletrace/nsqlite"; import NSQLite from "@moduletrace/nsqlite";

23
src/pages/auth/logout.tsx Normal file
View File

@ -0,0 +1,23 @@
import logoutUser from "@/src/functions/auth/logout-user";
import Layout from "@/src/layouts/login";
import H2 from "@/twui/components/layout/H2";
import { GetServerSideProps } from "next";
export default function LogoutPage() {
return (
<Layout>
<H2>Loging out ...</H2>
</Layout>
);
}
export const getServerSideProps: GetServerSideProps = async (ctx) => {
await logoutUser({ res: ctx.res });
return {
redirect: {
destination: `/login`,
statusCode: 307,
},
};
};

View File

@ -4,7 +4,9 @@ import useAppInit from "../hooks/use-app-init";
import { ServerWebSocket } from "bun"; import { ServerWebSocket } from "bun";
import { ChildProcess } from "child_process"; import { ChildProcess } from "child_process";
export type User = DATASQUIREL_LoggedInUser & {}; export type User = DATASQUIREL_LoggedInUser & {
super_admin?: 0 | 1;
};
export const CloudProviders = [ export const CloudProviders = [
{ {

View File

@ -70,7 +70,7 @@ export function updateCookie(
export function deleteCookie( export function deleteCookie(
res: http.ServerResponse, res: http.ServerResponse,
cookies: Cookie[], cookies: Pick<Cookie, "name" | "options">[],
): void { ): void {
setCookie( setCookie(
res, res,