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 { EJSON } from "@/src/exports/client-exports";
|
||||||
import { PagePropsType, URLQueryType, User } from "@/src/types";
|
import { PagePropsType, URLQueryType, User } from "@/src/types";
|
||||||
|
import grabTurboCiConfig from "@/src/utils/grab-turboci-config";
|
||||||
import parsePageUrl from "@/src/utils/parse-page-url";
|
import parsePageUrl from "@/src/utils/parse-page-url";
|
||||||
import userAuth from "@/src/utils/user-auth";
|
import userAuth from "@/src/utils/user-auth";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
@ -24,9 +25,12 @@ export default async function defaultAdminProps({
|
|||||||
props,
|
props,
|
||||||
propsFn,
|
propsFn,
|
||||||
}: Params): Promise<GetServerSidePropsResult<PagePropsType>> {
|
}: 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 { singleRes: user } = await userAuth({ req });
|
||||||
|
|
||||||
|
const config = grabTurboCiConfig();
|
||||||
|
|
||||||
if (!user?.id) {
|
if (!user?.id) {
|
||||||
return {
|
return {
|
||||||
redirect: {
|
redirect: {
|
||||||
@ -64,6 +68,7 @@ export default async function defaultAdminProps({
|
|||||||
query,
|
query,
|
||||||
user,
|
user,
|
||||||
pageUrl: finalAdminUrl,
|
pageUrl: finalAdminUrl,
|
||||||
|
config,
|
||||||
};
|
};
|
||||||
|
|
||||||
let finalProps = _.merge(props, propsFnProps, defaultPageProps);
|
let finalProps = _.merge(props, propsFnProps, defaultPageProps);
|
||||||
|
|||||||
@ -15,8 +15,8 @@ export default function Layout({ children }: Props) {
|
|||||||
return (
|
return (
|
||||||
<Main className="w-screen h-screen overflow-hidden">
|
<Main className="w-screen h-screen overflow-hidden">
|
||||||
<Section className="w-full h-full">
|
<Section className="w-full h-full">
|
||||||
<Container className="grid-frame section-grid grid-cols-1 h-full">
|
<Container className="grid-frame grid-cols-1 h-full">
|
||||||
<Stack className="w-full justify-between h-full">
|
<Stack className="w-full justify-between h-full grid-cell">
|
||||||
<Stack className="gap-0">
|
<Stack className="gap-0">
|
||||||
<Row>
|
<Row>
|
||||||
<Row className="p-6">
|
<Row className="p-6">
|
||||||
|
|||||||
@ -1,6 +1,16 @@
|
|||||||
import "@/src/styles/globals.css";
|
import "@/src/styles/globals.css";
|
||||||
import type { AppProps } from "next/app";
|
import type { AppProps } from "next/app";
|
||||||
|
import { createContext } from "react";
|
||||||
|
import { PagePropsType, TurboCIAdminAppContextType } from "../types";
|
||||||
|
|
||||||
export default function App({ Component, pageProps }: AppProps) {
|
export const AppContext = createContext<TurboCIAdminAppContextType>(
|
||||||
return <Component {...pageProps} />;
|
{} 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 defaultAdminProps from "@/src/functions/pages/admin/default-admin-props";
|
||||||
import Layout from "@/src/layouts/admin";
|
import Layout from "@/src/layouts/admin";
|
||||||
import { GetServerSideProps } from "next";
|
import { GetServerSideProps } from "next";
|
||||||
|
|||||||
@ -85,3 +85,12 @@
|
|||||||
.turboci-admin-aside-link.active * {
|
.turboci-admin-aside-link.active * {
|
||||||
@apply font-semibold;
|
@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;
|
work_dir?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PagePropsType = {};
|
|
||||||
export type URLQueryType = {};
|
export type URLQueryType = {};
|
||||||
|
|
||||||
|
export type PagePropsType = {
|
||||||
|
config?: TCIGlobalConfig | null;
|
||||||
|
query?: URLQueryType | null;
|
||||||
|
user: User;
|
||||||
|
pageUrl?: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
export type APIReqObject = {
|
export type APIReqObject = {
|
||||||
username?: string;
|
username?: string;
|
||||||
email?: string;
|
email?: string;
|
||||||
@ -201,3 +207,7 @@ export type TurboCISignupFormObject = {
|
|||||||
password?: string;
|
password?: string;
|
||||||
confirmed_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_CONFIG_DIR,
|
||||||
"turboci.json",
|
"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_DIR = path.join(TURBOCI_DIR, ".ssh");
|
||||||
const TURBOCI_SSH_KEY_FILE = path.join(TURBOCI_SSH_DIR, "turboci");
|
const TURBOCI_SSH_KEY_FILE = path.join(TURBOCI_SSH_DIR, "turboci");
|
||||||
@ -19,5 +20,6 @@ export default function grabDirNames() {
|
|||||||
TURBOCI_DIR,
|
TURBOCI_DIR,
|
||||||
TURBOCI_SSH_DIR,
|
TURBOCI_SSH_DIR,
|
||||||
TURBOCI_SSH_KEY_FILE,
|
TURBOCI_SSH_KEY_FILE,
|
||||||
|
TURBOCI_DEPLOYMENT_ID_FILE,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,13 +3,13 @@ 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 { AppData } from "../data/app-data";
|
|
||||||
import { setCookie } from "./cookies-actions";
|
import { setCookie } from "./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";
|
||||||
|
|
||||||
type Params = {
|
type Params = {
|
||||||
res: NextApiResponse | ServerResponse;
|
res: NextApiResponse | ServerResponse;
|
||||||
@ -111,9 +111,11 @@ export default async function loginUser({
|
|||||||
const expiration_date = dayjs(Date.now()).add(7, "days");
|
const expiration_date = dayjs(Date.now()).add(7, "days");
|
||||||
expiration_date.add(7, "days");
|
expiration_date.add(7, "days");
|
||||||
|
|
||||||
|
const { auth_key_cookie_name, csrf_cookie_name } = grabCookieNames();
|
||||||
|
|
||||||
setCookie(res, [
|
setCookie(res, [
|
||||||
{
|
{
|
||||||
name: AppData["AuthCookieName"],
|
name: auth_key_cookie_name,
|
||||||
value: encrypted_payload || "",
|
value: encrypted_payload || "",
|
||||||
options: {
|
options: {
|
||||||
secure: process.env.DOMAIN !== "localhost",
|
secure: process.env.DOMAIN !== "localhost",
|
||||||
@ -123,7 +125,7 @@ export default async function loginUser({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: AppData["AuthCSRFCookieName"],
|
name: csrf_cookie_name,
|
||||||
value: csrf_k,
|
value: csrf_k,
|
||||||
options: {
|
options: {
|
||||||
path: "/",
|
path: "/",
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { NextApiRequest } from "next";
|
import { NextApiRequest } from "next";
|
||||||
import { User } from "../types";
|
import { User } from "../types";
|
||||||
import { IncomingMessage } from "http";
|
import { IncomingMessage } from "http";
|
||||||
import { AppData } from "../data/app-data";
|
|
||||||
import { getCookie } from "./cookies-actions";
|
import { getCookie } from "./cookies-actions";
|
||||||
import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types";
|
import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types";
|
||||||
import decrypt from "@moduletrace/datasquirel/dist/package-shared/functions/dsql/decrypt";
|
import decrypt from "@moduletrace/datasquirel/dist/package-shared/functions/dsql/decrypt";
|
||||||
import { EJSON } from "../exports/client-exports";
|
import { EJSON } from "../exports/client-exports";
|
||||||
|
import grabCookieNames from "./grab-cookie-names";
|
||||||
|
|
||||||
type Params = {
|
type Params = {
|
||||||
req:
|
req:
|
||||||
@ -17,12 +17,13 @@ export default async function userAuth({
|
|||||||
req,
|
req,
|
||||||
}: Params): Promise<APIResponseObject<User>> {
|
}: Params): Promise<APIResponseObject<User>> {
|
||||||
try {
|
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) {
|
if (!key) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
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) {
|
if (!csrf) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
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