feat: login wall, bye yarn pnp

This commit is contained in:
2023-12-30 21:13:23 +00:00
parent 5e67225a7b
commit 5d8d171e88
27 changed files with 1198 additions and 18265 deletions

14788
.pnp.cjs generated

File diff suppressed because one or more lines are too long

2090
.pnp.loader.mjs generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,4 +5,5 @@ packageExtensions:
"drizzle-orm": "*"
"@drizzle-team/studio@*":
dependencies:
"drizzle-orm": "*"
"drizzle-orm": "*"
nodeLinker: node-modules

View File

@@ -26,7 +26,7 @@ const feedbackRateLimit = rateLimit({
})
app.get('/', (req, res) => {
res.send('insert webserver here')
res.send('hi this is the api what did you even expect')
})
app.post('/wh/updateDocsJson', async (req, res) => {

View File

@@ -1,4 +0,0 @@
import 'dotenv/config';
import * as schema from '../dist/schema.js';
declare const _default: import("drizzle-orm/postgres-js").PostgresJsDatabase<typeof schema>;
export default _default;

View File

@@ -1,6 +0,0 @@
import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import 'dotenv/config';
import * as schema from '../dist/schema.js';
const client = postgres(process.env.DATABASE_URL);
export default drizzle(client, { schema });

View File

@@ -1 +0,0 @@
import 'dotenv/config';

View File

@@ -1,15 +0,0 @@
import { drizzle } from "drizzle-orm/postgres-js/driver";
import { migrate } from "drizzle-orm/postgres-js/migrator";
import postgres from "postgres";
import 'dotenv/config';
// this will automatically run needed migrations on the database
const migrationClient = postgres(process.env.DATABASE_URL, { max: 1 });
migrate(drizzle(migrationClient), { migrationsFolder: "./drizzle" })
.then(() => {
console.log("Migrations complete!");
process.exit(0);
})
.catch((err) => {
console.error("Migrations failed!", err);
process.exit(1);
});

View File

@@ -1,347 +0,0 @@
export declare const guideFeedback: import("drizzle-orm/pg-core").PgTableWithColumns<{
name: "guideFeedback";
schema: undefined;
columns: {
id: import("drizzle-orm/pg-core").PgColumn<{
name: "id";
tableName: "guideFeedback";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: true;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
feedback: import("drizzle-orm/pg-core").PgColumn<{
name: "feedback";
tableName: "guideFeedback";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: true;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
route: import("drizzle-orm/pg-core").PgColumn<{
name: "route";
tableName: "guideFeedback";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: true;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
inputText: import("drizzle-orm/pg-core").PgColumn<{
name: "inputText";
tableName: "guideFeedback";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: false;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
};
dialect: "pg";
}>;
export declare const users: import("drizzle-orm/pg-core").PgTableWithColumns<{
name: "user";
schema: undefined;
columns: {
id: import("drizzle-orm/pg-core").PgColumn<{
name: "id";
tableName: "user";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: true;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
name: import("drizzle-orm/pg-core").PgColumn<{
name: "name";
tableName: "user";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: false;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
email: import("drizzle-orm/pg-core").PgColumn<{
name: "email";
tableName: "user";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: true;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
emailVerified: import("drizzle-orm/pg-core").PgColumn<{
name: "emailVerified";
tableName: "user";
dataType: "date";
columnType: "PgTimestamp";
data: Date;
driverParam: string;
notNull: false;
hasDefault: false;
enumValues: undefined;
baseColumn: never;
}, {}, {}>;
image: import("drizzle-orm/pg-core").PgColumn<{
name: "image";
tableName: "user";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: false;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
};
dialect: "pg";
}>;
export declare const accounts: import("drizzle-orm/pg-core").PgTableWithColumns<{
name: "account";
schema: undefined;
columns: {
userId: import("drizzle-orm/pg-core").PgColumn<{
name: "userId";
tableName: "account";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: true;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
type: import("drizzle-orm/pg-core").PgColumn<{
name: "type";
tableName: "account";
dataType: "string";
columnType: "PgText";
data: "email" | "oidc" | "oauth";
driverParam: string;
notNull: true;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
provider: import("drizzle-orm/pg-core").PgColumn<{
name: "provider";
tableName: "account";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: true;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
providerAccountId: import("drizzle-orm/pg-core").PgColumn<{
name: "providerAccountId";
tableName: "account";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: true;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
refresh_token: import("drizzle-orm/pg-core").PgColumn<{
name: "refresh_token";
tableName: "account";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: false;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
access_token: import("drizzle-orm/pg-core").PgColumn<{
name: "access_token";
tableName: "account";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: false;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
expires_at: import("drizzle-orm/pg-core").PgColumn<{
name: "expires_at";
tableName: "account";
dataType: "number";
columnType: "PgInteger";
data: number;
driverParam: string | number;
notNull: false;
hasDefault: false;
enumValues: undefined;
baseColumn: never;
}, {}, {}>;
token_type: import("drizzle-orm/pg-core").PgColumn<{
name: "token_type";
tableName: "account";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: false;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
scope: import("drizzle-orm/pg-core").PgColumn<{
name: "scope";
tableName: "account";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: false;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
id_token: import("drizzle-orm/pg-core").PgColumn<{
name: "id_token";
tableName: "account";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: false;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
session_state: import("drizzle-orm/pg-core").PgColumn<{
name: "session_state";
tableName: "account";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: false;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
};
dialect: "pg";
}>;
export declare const sessions: import("drizzle-orm/pg-core").PgTableWithColumns<{
name: "session";
schema: undefined;
columns: {
sessionToken: import("drizzle-orm/pg-core").PgColumn<{
name: "sessionToken";
tableName: "session";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: true;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
userId: import("drizzle-orm/pg-core").PgColumn<{
name: "userId";
tableName: "session";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: true;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
expires: import("drizzle-orm/pg-core").PgColumn<{
name: "expires";
tableName: "session";
dataType: "date";
columnType: "PgTimestamp";
data: Date;
driverParam: string;
notNull: true;
hasDefault: false;
enumValues: undefined;
baseColumn: never;
}, {}, {}>;
};
dialect: "pg";
}>;
export declare const verificationTokens: import("drizzle-orm/pg-core").PgTableWithColumns<{
name: "verificationToken";
schema: undefined;
columns: {
identifier: import("drizzle-orm/pg-core").PgColumn<{
name: "identifier";
tableName: "verificationToken";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: true;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
token: import("drizzle-orm/pg-core").PgColumn<{
name: "token";
tableName: "verificationToken";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: true;
hasDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
}, {}, {}>;
expires: import("drizzle-orm/pg-core").PgColumn<{
name: "expires";
tableName: "verificationToken";
dataType: "date";
columnType: "PgTimestamp";
data: Date;
driverParam: string;
notNull: true;
hasDefault: false;
enumValues: undefined;
baseColumn: never;
}, {}, {}>;
};
dialect: "pg";
}>;

View File

@@ -1,47 +0,0 @@
import { timestamp, pgTable, text, primaryKey, integer, } from "drizzle-orm/pg-core";
// automata schemas
export const guideFeedback = pgTable("guideFeedback", {
id: text("id").notNull().primaryKey(),
feedback: text("feedback").notNull(),
route: text("route").notNull(),
inputText: text("inputText"),
});
// next-auth schema
export const users = pgTable("user", {
id: text("id").notNull().primaryKey(),
name: text("name"),
email: text("email").notNull(),
emailVerified: timestamp("emailVerified", { mode: "date" }),
image: text("image"),
});
export const accounts = pgTable("account", {
userId: text("userId")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
type: text("type").$type().notNull(),
provider: text("provider").notNull(),
providerAccountId: text("providerAccountId").notNull(),
refresh_token: text("refresh_token"),
access_token: text("access_token"),
expires_at: integer("expires_at"),
token_type: text("token_type"),
scope: text("scope"),
id_token: text("id_token"),
session_state: text("session_state"),
}, (account) => ({
compoundKey: primaryKey(account.provider, account.providerAccountId),
}));
export const sessions = pgTable("session", {
sessionToken: text("sessionToken").notNull().primaryKey(),
userId: text("userId")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
expires: timestamp("expires", { mode: "date" }).notNull(),
});
export const verificationTokens = pgTable("verificationToken", {
identifier: text("identifier").notNull(),
token: text("token").notNull(),
expires: timestamp("expires", { mode: "date" }).notNull(),
}, (vt) => ({
compoundKey: primaryKey(vt.identifier, vt.token),
}));

View File

@@ -5,7 +5,7 @@
"type": "module",
"scripts": {
"dev": "tsc-watch --preserveWatchOutput",
"migrate": "tsc && node dist/migrations.js",
"migrate": "node dist/migrations.js",
"generateMigrations": "drizzle-kit generate:pg --schema ./src/schema.ts",
"build": "tsc"
},

View File

@@ -11,14 +11,22 @@
},
"dependencies": {
"@auth/drizzle-adapter": "^0.3.6",
"@babel/runtime": "^7.23.7",
"@emotion/cache": "^11.11.0",
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@mui/material": "^5.15.2",
"@mui/material-nextjs": "^5.15.0",
"@planetscale/database": "^1.11.0",
"@t3-oss/env-nextjs": "^0.7.1",
"database": "1.0.0",
"drizzle-orm": "^0.29.1",
"next": "^14.0.3",
"next": "^14.0.4",
"next-auth": "^4.24.5",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-icons": "^4.12.0",
"swr": "^2.2.4",
"zod": "^3.22.4"
},
"devDependencies": {

View File

@@ -1,7 +1,8 @@
/** @type {import('prettier').Config & import('prettier-plugin-tailwindcss').PluginOptions} */
const config = {
plugins: ["prettier-plugin-tailwindcss"],
useTabs: true,
tabWidth: 2
};
export default config;

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -1,11 +1,13 @@
import "~/styles/globals.css";
import { AppRouterCacheProvider } from '@mui/material-nextjs/v14-appRouter';
import { Roboto } from "next/font/google";
import { StyledEngineProvider } from '@mui/material/styles';
import NextAuthProvider from "../components/NextAuthProvider";
import { Inter } from "next/font/google";
import NextAuthProvider from "./NextAuthProvider";
const inter = Inter({
subsets: ["latin"],
variable: "--font-sans",
const roboto = Roboto({
weight: ['400'],
variable: '--font-sans',
subsets: ['latin']
});
export const metadata = {
@@ -21,9 +23,13 @@ export default function RootLayout({
}) {
return (
<html lang="en">
<body className={`font-sans ${inter.variable}`}>
<body className={`font-sans ${roboto.variable}`}>
<NextAuthProvider>
{children}
<AppRouterCacheProvider options={{ enableCssLayer: true }}>
<StyledEngineProvider injectFirst>
{children}
</StyledEngineProvider>
</AppRouterCacheProvider>
</NextAuthProvider>
</body>
</html>

View File

@@ -1,37 +1,19 @@
import Link from "next/link";
import { Container } from "@mui/material";
import Authenticated from "~/components/HomePage/Authenticated";
import Unauthenticated from "~/components/HomePage/Unauthenticated";
import NavBar from "~/components/Layout/AppBar";
import { getServerAuthSession } from "~/server/auth";
export default function HomePage() {
return (
<main className="flex min-h-screen flex-col items-center justify-center bg-gradient-to-b from-[#2e026d] to-[#15162c] text-white">
<div className="container flex flex-col items-center justify-center gap-12 px-4 py-16 ">
<h1 className="text-5xl font-extrabold tracking-tight text-white sm:text-[5rem]">
Create <span className="text-[hsl(280,100%,70%)]">T3</span> App
</h1>
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:gap-8">
<Link
className="flex max-w-xs flex-col gap-4 rounded-xl bg-white/10 p-4 text-white hover:bg-white/20"
href="https://create.t3.gg/en/usage/first-steps"
target="_blank"
>
<h3 className="text-2xl font-bold">First Steps </h3>
<div className="text-lg">
Just the basics - Everything you need to know to set up your
database and authentication.
</div>
</Link>
<Link
className="flex max-w-xs flex-col gap-4 rounded-xl bg-white/10 p-4 text-white hover:bg-white/20"
href="https://create.t3.gg/en/introduction"
target="_blank"
>
<h3 className="text-2xl font-bold">Documentation </h3>
<div className="text-lg">
Learn more about Create T3 App, the libraries it uses, and how to
deploy it.
</div>
</Link>
</div>
</div>
</main>
);
export default async function HomePage() {
const session = await getServerAuthSession();
return session ?
<div>
<NavBar />
{/*
// @ts-expect-error https://github.com/mui/material-ui/issues/40370 */}
<Container maxWidth="s">
<Authenticated />
</Container>
</div>
: <Unauthenticated />;
}

View File

@@ -0,0 +1,7 @@
export default async function Authenticated() {
return (
<div>
<p>hi</p>
</div>
);
}

View File

@@ -0,0 +1,11 @@
"use client";
import { Button } from "@mui/material";
import { signIn } from "next-auth/react";
export default function LoginButton() {
return (
<Button variant="outlined" onClick={() => signIn()}>
Login
</Button>
);
}

View File

@@ -0,0 +1,22 @@
import LoginButton from "./LoginButton";
export default async function Unauthenticated() {
return (
<div className="relative">
<div className="absolute top-0 right-0 pt-4 pr-4">
<LoginButton />
</div>
<div className="flex h-screen flex-col items-center justify-center gap-3">
<h1 className="text-6xl">Hey!</h1>
<p className="text-2xl">
You just stomped on the frontend of sern Automata.
</p>
<p className="text-2xl">
It's unfortunately WIP and for security purposes it's behind a login
wall that only the devteam can access.
</p>
<p className="text-3xl">Sorry!</p>
</div>
</div>
);
}

View File

@@ -0,0 +1,164 @@
'use client';
import * as React from 'react';
import AppBar from '@mui/material/AppBar';
import Box from '@mui/material/Box';
import Toolbar from '@mui/material/Toolbar';
import IconButton from '@mui/material/IconButton';
import Typography from '@mui/material/Typography';
import Menu from '@mui/material/Menu';
import { MdMenu } from 'react-icons/md';
import Container from '@mui/material/Container';
import Avatar from '@mui/material/Avatar';
import Button from '@mui/material/Button';
import Tooltip from '@mui/material/Tooltip';
import MenuItem from '@mui/material/MenuItem';
import Logo from '../../../public/croppedlogo.png';
import Image from 'next/image';
import { signOut } from 'next-auth/react';
import { useRouter } from 'next/navigation';
import { useSession } from "next-auth/react"
const pages = ['Home'];
const settings = ['Account', 'Logout'];
export default function NavBar() {
const { data: session } = useSession()
const router = useRouter();
const [anchorElNav, setAnchorElNav] = React.useState<null | HTMLElement>(null);
const [anchorElUser, setAnchorElUser] = React.useState<null | HTMLElement>(null);
const settingLinkHandler = (setting: string) => {
switch (setting) {
case 'Logout':
return void signOut();
case 'Account':
return void router.push('/account');
}
}
const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => {
setAnchorElNav(event.currentTarget);
};
const handleOpenUserMenu = (event: React.MouseEvent<HTMLElement>) => {
setAnchorElUser(event.currentTarget);
};
const handleCloseNavMenu = () => {
setAnchorElNav(null);
};
const handleCloseUserMenu = () => {
setAnchorElUser(null);
};
return (
<div className='pb-2'>
<AppBar position="static">
<Container maxWidth="xl">
<Toolbar disableGutters>
<Image src={Logo} alt='logo' className='h-9 w-fit pr-5' />
<Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}>
<IconButton
size="large"
aria-label="account of current user"
aria-controls="menu-appbar"
aria-haspopup="true"
onClick={handleOpenNavMenu}
color="inherit"
>
<MdMenu />
</IconButton>
<Menu
id="menu-appbar"
anchorEl={anchorElNav}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
open={Boolean(anchorElNav)}
onClose={handleCloseNavMenu}
sx={{
display: { xs: 'block', md: 'none' },
}}
>
{pages.map((page) => (
<MenuItem key={page} onClick={handleCloseNavMenu}>
<Typography textAlign="center">{page}</Typography>
</MenuItem>
))}
</Menu>
</Box>
<Typography
variant="h5"
noWrap
component="a"
href="#app-bar-with-responsive-menu"
sx={{
mr: 2,
display: { xs: 'flex', md: 'none' },
flexGrow: 1,
fontFamily: 'monospace',
fontWeight: 700,
letterSpacing: '.3rem',
color: 'inherit',
textDecoration: 'none',
}}
>
AUTOMATA
</Typography>
<Box sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}>
{pages.map((page) => (
<Button
key={page}
onClick={handleCloseNavMenu}
sx={{ my: 2, color: 'white', display: 'block' }}
>
{page}
</Button>
))}
</Box>
<Box sx={{ flexGrow: 0 }}>
<Tooltip title="Open settings">
<IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}>
<Avatar alt={'Account'} src={session ? session.user.image! : '...'} />
</IconButton>
</Tooltip>
<Menu
sx={{ mt: '45px' }}
id="menu-appbar"
anchorEl={anchorElUser}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
open={Boolean(anchorElUser)}
onClose={handleCloseUserMenu}
>
{settings.map((setting) => (
<MenuItem key={setting} onClick={() => {
handleCloseUserMenu();
settingLinkHandler(setting);
}}>
<Typography textAlign="center">{setting}</Typography>
</MenuItem>
))}
</Menu>
</Box>
</Toolbar>
</Container>
</AppBar>
</div>
);
}

View File

@@ -1,7 +1,7 @@
'use client';
import { SessionProvider } from 'next-auth/react';
import { ReactNode } from 'react';
import type { ReactNode } from 'react';
export default function NextAuthProvider({
children,

View File

@@ -43,6 +43,14 @@ export const authOptions: NextAuthOptions = {
id: user.id,
},
}),
signIn(params) {
const allowedUsers = ['SrIzan10', 'jacoobes', 'Murtarxx', 'EvolutionX-10']
if (!allowedUsers.includes(params.user.name!)) {
return false
} else {
return true
}
},
},
adapter: PostgresJsDrizzleAdapter(db),
providers: [

View File

@@ -1,3 +1,29 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
/*
deactivating the preflight plugin creates an ugly border
on all sides of the screen, so these css values removes them
*/
body,
h1,
h2,
h3,
h4,
h5,
h6,
p,
ul,
ol,
dl,
figure,
blockquote,
fieldset,
legend {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}

View File

@@ -11,4 +11,7 @@ export default {
},
},
plugins: [],
corePlugins: {
preflight: false
}
} satisfies Config;

View File

@@ -10,4 +10,4 @@ services:
volumes:
- ./data:/var/lib/postgresql/data
ports:
- 5432:5432
- 5431:5432

View File

@@ -5,6 +5,7 @@
"repository": "https://github.com/sern-handler/automata.git",
"author": "Izan Gil <66965250+SrIzan10@users.noreply.github.com>",
"license": "MIT",
"type": "module",
"workspaces": [
"apps/*"
],

1825
yarn.lock

File diff suppressed because it is too large Load Diff