diff --git a/src/components/general/admin/hero.tsx b/src/components/general/admin/hero.tsx
new file mode 100644
index 0000000..835100d
--- /dev/null
+++ b/src/components/general/admin/hero.tsx
@@ -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 (
+
+
+ {title}
+ {description ? (
+ {description}
+ ) : null}
+
+ {ctas}
+
+ );
+}
diff --git a/src/components/pages/admin/(sections)/summary.tsx b/src/components/pages/admin/(sections)/summary.tsx
new file mode 100644
index 0000000..a093fb7
--- /dev/null
+++ b/src/components/pages/admin/(sections)/summary.tsx
@@ -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
;
+}
diff --git a/src/components/pages/admin/index.tsx b/src/components/pages/admin/index.tsx
new file mode 100644
index 0000000..0efdb34
--- /dev/null
+++ b/src/components/pages/admin/index.tsx
@@ -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 (
+
+
+ Deployment ad9asd
+ >
+ }
+ />
+
+
+ );
+}
diff --git a/src/functions/pages/admin/default-admin-props.ts b/src/functions/pages/admin/default-admin-props.ts
index a0a5614..43bf582 100644
--- a/src/functions/pages/admin/default-admin-props.ts
+++ b/src/functions/pages/admin/default-admin-props.ts
@@ -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> {
- 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);
diff --git a/src/layouts/login/index.tsx b/src/layouts/login/index.tsx
index 13b9d03..848c488 100644
--- a/src/layouts/login/index.tsx
+++ b/src/layouts/login/index.tsx
@@ -15,8 +15,8 @@ export default function Layout({ children }: Props) {
return (
-
-
+
+
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index 4515678..db8882f 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -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 ;
+export const AppContext = createContext(
+ {} as TurboCIAdminAppContextType,
+);
+
+export default function App({ Component, pageProps }: AppProps) {
+ return (
+
+
+
+ );
}
diff --git a/src/pages/admin/index.tsx b/src/pages/admin/index.tsx
index 1a2eda8..78b34aa 100644
--- a/src/pages/admin/index.tsx
+++ b/src/pages/admin/index.tsx
@@ -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";
diff --git a/src/styles/globals.css b/src/styles/globals.css
index ee1d3a1..9a8b1a7 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -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;
+}
diff --git a/src/types/index.ts b/src/types/index.ts
index 1478acb..3b58fa2 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -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;
+};
diff --git a/src/utils/grab-cookie-names.ts b/src/utils/grab-cookie-names.ts
new file mode 100644
index 0000000..6531e78
--- /dev/null
+++ b/src/utils/grab-cookie-names.ts
@@ -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 };
+}
diff --git a/src/utils/grab-dir-names.ts b/src/utils/grab-dir-names.ts
index 94b2cc4..83e68bd 100644
--- a/src/utils/grab-dir-names.ts
+++ b/src/utils/grab-dir-names.ts
@@ -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,
};
}
diff --git a/src/utils/login-user.ts b/src/utils/login-user.ts
index 482de46..d778ba0 100644
--- a/src/utils/login-user.ts
+++ b/src/utils/login-user.ts
@@ -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: "/",
diff --git a/src/utils/user-auth.ts b/src/utils/user-auth.ts
index 84d3c24..050e257 100644
--- a/src/utils/user-auth.ts
+++ b/src/utils/user-auth.ts
@@ -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> {
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.`,
};
}