Updates
This commit is contained in:
parent
3a131cb30c
commit
8491c52639
25
src/components/general/admin/hero.tsx
Normal file
25
src/components/general/admin/hero.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import H1 from "@/twui/components/layout/H1";
|
||||
import Row from "@/twui/components/layout/Row";
|
||||
import Span from "@/twui/components/layout/Span";
|
||||
import Stack from "@/twui/components/layout/Stack";
|
||||
import { ReactNode } from "react";
|
||||
|
||||
type Props = {
|
||||
title: string | ReactNode;
|
||||
description?: string | ReactNode;
|
||||
ctas?: ReactNode;
|
||||
};
|
||||
|
||||
export default function AdminHero({ title, ctas, description }: Props) {
|
||||
return (
|
||||
<Row className="w-full p-10 justify-between">
|
||||
<Stack className="gap-2">
|
||||
<H1 className="admin-h1">{title}</H1>
|
||||
{description ? (
|
||||
<Span variant="faded">{description}</Span>
|
||||
) : null}
|
||||
</Stack>
|
||||
<Row>{ctas}</Row>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
11
src/components/pages/admin/(sections)/summary.tsx
Normal file
11
src/components/pages/admin/(sections)/summary.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import { AppContext } from "@/src/pages/_app";
|
||||
import Row from "@/twui/components/layout/Row";
|
||||
import { useContext } from "react";
|
||||
|
||||
export default function AdminSummary() {
|
||||
const { pageProps } = useContext(AppContext);
|
||||
|
||||
console.log("pageProps", pageProps);
|
||||
|
||||
return <Row></Row>;
|
||||
}
|
||||
19
src/components/pages/admin/index.tsx
Normal file
19
src/components/pages/admin/index.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import Stack from "@/twui/components/layout/Stack";
|
||||
import AdminSummary from "./(sections)/summary";
|
||||
import AdminHero from "../../general/admin/hero";
|
||||
|
||||
export default function Main() {
|
||||
return (
|
||||
<Stack>
|
||||
<AdminHero
|
||||
title={`Dashboard`}
|
||||
description={
|
||||
<>
|
||||
Deployment <code>ad9asd</code>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<AdminSummary />
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import { EJSON } from "@/src/exports/client-exports";
|
||||
import { PagePropsType, URLQueryType, User } from "@/src/types";
|
||||
import grabTurboCiConfig from "@/src/utils/grab-turboci-config";
|
||||
import parsePageUrl from "@/src/utils/parse-page-url";
|
||||
import userAuth from "@/src/utils/user-auth";
|
||||
import _ from "lodash";
|
||||
@ -24,9 +25,12 @@ export default async function defaultAdminProps({
|
||||
props,
|
||||
propsFn,
|
||||
}: Params): Promise<GetServerSidePropsResult<PagePropsType>> {
|
||||
const { req, query, res } = ctx;
|
||||
const { req, res } = ctx;
|
||||
const query: URLQueryType = ctx.query;
|
||||
const { singleRes: user } = await userAuth({ req });
|
||||
|
||||
const config = grabTurboCiConfig();
|
||||
|
||||
if (!user?.id) {
|
||||
return {
|
||||
redirect: {
|
||||
@ -64,6 +68,7 @@ export default async function defaultAdminProps({
|
||||
query,
|
||||
user,
|
||||
pageUrl: finalAdminUrl,
|
||||
config,
|
||||
};
|
||||
|
||||
let finalProps = _.merge(props, propsFnProps, defaultPageProps);
|
||||
|
||||
@ -15,8 +15,8 @@ export default function Layout({ children }: Props) {
|
||||
return (
|
||||
<Main className="w-screen h-screen overflow-hidden">
|
||||
<Section className="w-full h-full">
|
||||
<Container className="grid-frame section-grid grid-cols-1 h-full">
|
||||
<Stack className="w-full justify-between h-full">
|
||||
<Container className="grid-frame grid-cols-1 h-full">
|
||||
<Stack className="w-full justify-between h-full grid-cell">
|
||||
<Stack className="gap-0">
|
||||
<Row>
|
||||
<Row className="p-6">
|
||||
|
||||
@ -1,6 +1,16 @@
|
||||
import "@/src/styles/globals.css";
|
||||
import type { AppProps } from "next/app";
|
||||
import { createContext } from "react";
|
||||
import { PagePropsType, TurboCIAdminAppContextType } from "../types";
|
||||
|
||||
export default function App({ Component, pageProps }: AppProps) {
|
||||
return <Component {...pageProps} />;
|
||||
export const AppContext = createContext<TurboCIAdminAppContextType>(
|
||||
{} as TurboCIAdminAppContextType,
|
||||
);
|
||||
|
||||
export default function App({ Component, pageProps }: AppProps<PagePropsType>) {
|
||||
return (
|
||||
<AppContext.Provider value={{ pageProps }}>
|
||||
<Component {...pageProps} />
|
||||
</AppContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import Main from "@/src/components/pages/home";
|
||||
import Main from "@/src/components/pages/admin";
|
||||
import defaultAdminProps from "@/src/functions/pages/admin/default-admin-props";
|
||||
import Layout from "@/src/layouts/admin";
|
||||
import { GetServerSideProps } from "next";
|
||||
|
||||
@ -85,3 +85,12 @@
|
||||
.turboci-admin-aside-link.active * {
|
||||
@apply font-semibold;
|
||||
}
|
||||
|
||||
.admin-h1 {
|
||||
@apply text-3xl;
|
||||
}
|
||||
|
||||
code {
|
||||
@apply bg-slate-100 dark:bg-white/10 px-3 py-1 rounded-default;
|
||||
@apply my-1;
|
||||
}
|
||||
|
||||
@ -169,9 +169,15 @@ export type ServiceScriptObject = {
|
||||
work_dir?: string;
|
||||
};
|
||||
|
||||
export type PagePropsType = {};
|
||||
export type URLQueryType = {};
|
||||
|
||||
export type PagePropsType = {
|
||||
config?: TCIGlobalConfig | null;
|
||||
query?: URLQueryType | null;
|
||||
user: User;
|
||||
pageUrl?: string | null;
|
||||
};
|
||||
|
||||
export type APIReqObject = {
|
||||
username?: string;
|
||||
email?: string;
|
||||
@ -201,3 +207,7 @@ export type TurboCISignupFormObject = {
|
||||
password?: string;
|
||||
confirmed_password?: string;
|
||||
};
|
||||
|
||||
export type TurboCIAdminAppContextType = {
|
||||
pageProps: PagePropsType;
|
||||
};
|
||||
|
||||
23
src/utils/grab-cookie-names.ts
Normal file
23
src/utils/grab-cookie-names.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import grabDirNames from "./grab-dir-names";
|
||||
|
||||
export default function grabCookieNames() {
|
||||
const { TURBOCI_DEPLOYMENT_ID_FILE } = grabDirNames();
|
||||
|
||||
if (!existsSync(TURBOCI_DEPLOYMENT_ID_FILE)) {
|
||||
throw new Error(`\`${TURBOCI_DEPLOYMENT_ID_FILE}\` does not exist.`);
|
||||
}
|
||||
|
||||
const deployment_id = readFileSync(TURBOCI_DEPLOYMENT_ID_FILE, "utf-8");
|
||||
|
||||
const deplyment_uid_short = deployment_id.split("-").shift();
|
||||
|
||||
if (!deplyment_uid_short) {
|
||||
throw new Error(`Invalid deployment_id`);
|
||||
}
|
||||
|
||||
const auth_key_cookie_name = `turboci-admin-${deplyment_uid_short}-auth-key`;
|
||||
const csrf_cookie_name = `turboci-admin-${deplyment_uid_short}-csrf`;
|
||||
|
||||
return { auth_key_cookie_name, csrf_cookie_name };
|
||||
}
|
||||
@ -8,6 +8,7 @@ export default function grabDirNames() {
|
||||
TURBOCI_CONFIG_DIR,
|
||||
"turboci.json",
|
||||
);
|
||||
const TURBOCI_DEPLOYMENT_ID_FILE = path.join(TURBOCI_DIR, "deployment_id");
|
||||
|
||||
const TURBOCI_SSH_DIR = path.join(TURBOCI_DIR, ".ssh");
|
||||
const TURBOCI_SSH_KEY_FILE = path.join(TURBOCI_SSH_DIR, "turboci");
|
||||
@ -19,5 +20,6 @@ export default function grabDirNames() {
|
||||
TURBOCI_DIR,
|
||||
TURBOCI_SSH_DIR,
|
||||
TURBOCI_SSH_KEY_FILE,
|
||||
TURBOCI_DEPLOYMENT_ID_FILE,
|
||||
};
|
||||
}
|
||||
|
||||
@ -3,13 +3,13 @@ import { ServerResponse } from "http";
|
||||
import NSQLite from "@moduletrace/nsqlite";
|
||||
import { NSQLITE_TEST_DB_USERS, NSQLiteTables } from "../db/types";
|
||||
import { User } from "../types";
|
||||
import { AppData } from "../data/app-data";
|
||||
import { setCookie } from "./cookies-actions";
|
||||
import { EJSON } from "../exports/client-exports";
|
||||
import encrypt from "@moduletrace/datasquirel/dist/package-shared/functions/dsql/encrypt";
|
||||
import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types";
|
||||
import hashPassword from "@moduletrace/datasquirel/dist/package-shared/functions/dsql/hashPassword";
|
||||
import dayjs from "dayjs";
|
||||
import grabCookieNames from "./grab-cookie-names";
|
||||
|
||||
type Params = {
|
||||
res: NextApiResponse | ServerResponse;
|
||||
@ -111,9 +111,11 @@ export default async function loginUser({
|
||||
const expiration_date = dayjs(Date.now()).add(7, "days");
|
||||
expiration_date.add(7, "days");
|
||||
|
||||
const { auth_key_cookie_name, csrf_cookie_name } = grabCookieNames();
|
||||
|
||||
setCookie(res, [
|
||||
{
|
||||
name: AppData["AuthCookieName"],
|
||||
name: auth_key_cookie_name,
|
||||
value: encrypted_payload || "",
|
||||
options: {
|
||||
secure: process.env.DOMAIN !== "localhost",
|
||||
@ -123,7 +125,7 @@ export default async function loginUser({
|
||||
},
|
||||
},
|
||||
{
|
||||
name: AppData["AuthCSRFCookieName"],
|
||||
name: csrf_cookie_name,
|
||||
value: csrf_k,
|
||||
options: {
|
||||
path: "/",
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { NextApiRequest } from "next";
|
||||
import { User } from "../types";
|
||||
import { IncomingMessage } from "http";
|
||||
import { AppData } from "../data/app-data";
|
||||
import { getCookie } from "./cookies-actions";
|
||||
import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types";
|
||||
import decrypt from "@moduletrace/datasquirel/dist/package-shared/functions/dsql/decrypt";
|
||||
import { EJSON } from "../exports/client-exports";
|
||||
import grabCookieNames from "./grab-cookie-names";
|
||||
|
||||
type Params = {
|
||||
req:
|
||||
@ -17,12 +17,13 @@ export default async function userAuth({
|
||||
req,
|
||||
}: Params): Promise<APIResponseObject<User>> {
|
||||
try {
|
||||
const key = getCookie(req, AppData["AuthCookieName"]);
|
||||
const { auth_key_cookie_name, csrf_cookie_name } = grabCookieNames();
|
||||
const key = getCookie(req, auth_key_cookie_name);
|
||||
|
||||
if (!key) {
|
||||
return {
|
||||
success: false,
|
||||
msg: `No ${AppData["AuthCookieName"]} found in request object.`,
|
||||
msg: `No ${auth_key_cookie_name} found in request object.`,
|
||||
};
|
||||
}
|
||||
|
||||
@ -36,12 +37,12 @@ export default async function userAuth({
|
||||
};
|
||||
}
|
||||
|
||||
const csrf = getCookie(req, AppData["AuthCSRFCookieName"]);
|
||||
const csrf = getCookie(req, csrf_cookie_name);
|
||||
|
||||
if (!csrf) {
|
||||
return {
|
||||
success: false,
|
||||
msg: `No ${AppData["AuthCSRFCookieName"]} found in request object.`,
|
||||
msg: `No ${csrf_cookie_name} found in request object.`,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user