-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e4ad1cd
commit 1da0287
Showing
320 changed files
with
5,005 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
exercises/06.honeypot/02.solution.util/app/utils/honeypot.server.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import { Honeypot } from 'remix-utils/honeypot/server' | ||
|
||
export const honeypot = new Honeypot({ | ||
validFromFieldName: process.env.TESTING ? undefined : null, | ||
validFromFieldName: null, | ||
}) |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Remix Utils |
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import os from 'node:os' | ||
import { cssBundleHref } from '@remix-run/css-bundle' | ||
import { json, type LinksFunction } from '@remix-run/node' | ||
import { | ||
Link, | ||
Links, | ||
LiveReload, | ||
Meta, | ||
Outlet, | ||
Scripts, | ||
ScrollRestoration, | ||
useLoaderData, | ||
type MetaFunction, | ||
} from '@remix-run/react' | ||
import faviconAssetUrl from './assets/favicon.svg' | ||
import { GeneralErrorBoundary } from './components/error-boundary.tsx' | ||
import { KCDShop } from './kcdshop.tsx' | ||
import fontStylestylesheetUrl from './styles/font.css' | ||
import tailwindStylesheetUrl from './styles/tailwind.css' | ||
import { getEnv } from './utils/env.server.ts' | ||
|
||
export const links: LinksFunction = () => { | ||
return [ | ||
{ rel: 'icon', type: 'image/svg+xml', href: faviconAssetUrl }, | ||
{ rel: 'stylesheet', href: fontStylestylesheetUrl }, | ||
{ rel: 'stylesheet', href: tailwindStylesheetUrl }, | ||
cssBundleHref ? { rel: 'stylesheet', href: cssBundleHref } : null, | ||
].filter(Boolean) | ||
} | ||
|
||
export async function loader() { | ||
// 🐨 get the honeypot props from the honeypot object and add them to this | ||
// object. | ||
return json({ username: os.userInfo().username, ENV: getEnv() }) | ||
} | ||
|
||
function Document({ children }: { children: React.ReactNode }) { | ||
return ( | ||
<html lang="en" className="h-full overflow-x-hidden"> | ||
<head> | ||
<Meta /> | ||
<meta charSet="utf-8" /> | ||
<meta name="viewport" content="width=device-width,initial-scale=1" /> | ||
<Links /> | ||
</head> | ||
<body className="flex h-full flex-col justify-between bg-background text-foreground"> | ||
{children} | ||
<ScrollRestoration /> | ||
<Scripts /> | ||
<KCDShop /> | ||
<LiveReload /> | ||
</body> | ||
</html> | ||
) | ||
} | ||
|
||
function App() { | ||
const data = useLoaderData<typeof loader>() | ||
return ( | ||
<Document> | ||
<header className="container mx-auto py-6"> | ||
<nav className="flex justify-between"> | ||
<Link to="/"> | ||
<div className="font-light">epic</div> | ||
<div className="font-bold">notes</div> | ||
</Link> | ||
<Link className="underline" to="/signup"> | ||
Signup | ||
</Link> | ||
</nav> | ||
</header> | ||
|
||
<div className="flex-1"> | ||
<Outlet /> | ||
</div> | ||
|
||
<div className="container mx-auto flex justify-between"> | ||
<Link to="/"> | ||
<div className="font-light">epic</div> | ||
<div className="font-bold">notes</div> | ||
</Link> | ||
<p>Built with ♥️ by {data.username}</p> | ||
</div> | ||
<div className="h-5" /> | ||
<script | ||
dangerouslySetInnerHTML={{ | ||
__html: `window.ENV = ${JSON.stringify(data.ENV)}`, | ||
}} | ||
/> | ||
</Document> | ||
) | ||
} | ||
|
||
export default function AppWithProviders() { | ||
// 💰 you'll need this const data = useLoaderData<typeof loader>() | ||
// 🐨 render the HoneypotProvider here and pass the honeypot props | ||
return <App /> | ||
} | ||
|
||
export const meta: MetaFunction = () => { | ||
return [ | ||
{ title: 'Epic Notes' }, | ||
{ name: 'description', content: `Your own captain's log` }, | ||
] | ||
} | ||
|
||
export function ErrorBoundary() { | ||
return ( | ||
<Document> | ||
<div className="flex-1"> | ||
<GeneralErrorBoundary /> | ||
</div> | ||
</Document> | ||
) | ||
} |
File renamed without changes.
58 changes: 58 additions & 0 deletions
58
exercises/06.honeypot/03.problem.provider/app/routes/_auth+/signup.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { | ||
redirect, | ||
type DataFunctionArgs, | ||
type MetaFunction, | ||
} from '@remix-run/node' | ||
import { Form } from '@remix-run/react' | ||
import { HoneypotInputs } from 'remix-utils/honeypot/react' | ||
import { SpamError } from 'remix-utils/honeypot/server' | ||
import { Button } from '#app/components/ui/button.tsx' | ||
import { Input } from '#app/components/ui/input.tsx' | ||
import { Label } from '#app/components/ui/label.tsx' | ||
import { honeypot } from '#app/utils/honeypot.server.ts' | ||
|
||
export async function action({ request }: DataFunctionArgs) { | ||
const formData = await request.formData() | ||
try { | ||
honeypot.check(formData) | ||
} catch (error) { | ||
if (error instanceof SpamError) { | ||
throw new Response('Form not submitted properly', { status: 400 }) | ||
} | ||
throw error | ||
} | ||
// we'll implement signup later | ||
return redirect('/') | ||
} | ||
|
||
export default function SignupRoute() { | ||
return ( | ||
<div className="container flex min-h-full flex-col justify-center pb-32 pt-20"> | ||
<div className="mx-auto w-full max-w-lg"> | ||
<div className="flex flex-col gap-3 text-center"> | ||
<h1 className="text-h1">Welcome aboard!</h1> | ||
<p className="text-body-md text-muted-foreground"> | ||
Please enter your details. | ||
</p> | ||
</div> | ||
<Form | ||
method="POST" | ||
className="mx-auto flex min-w-[368px] max-w-sm flex-col gap-4" | ||
> | ||
<HoneypotInputs /> | ||
<div> | ||
<Label htmlFor="email-input">Email</Label> | ||
<Input autoFocus id="email-input" name="email" type="email" /> | ||
</div> | ||
<Button className="w-full" type="submit"> | ||
Create an account | ||
</Button> | ||
</Form> | ||
</div> | ||
</div> | ||
) | ||
} | ||
|
||
export const meta: MetaFunction = () => { | ||
return [{ title: 'Setup Epic Notes Account' }] | ||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
48 changes: 48 additions & 0 deletions
48
exercises/06.honeypot/03.problem.provider/app/utils/env.server.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { z } from 'zod' | ||
|
||
const schema = z.object({ | ||
NODE_ENV: z.enum(['production', 'development', 'test'] as const), | ||
}) | ||
|
||
declare global { | ||
namespace NodeJS { | ||
interface ProcessEnv extends z.infer<typeof schema> {} | ||
} | ||
} | ||
|
||
export function init() { | ||
const parsed = schema.safeParse(process.env) | ||
|
||
if (parsed.success === false) { | ||
console.error( | ||
'❌ Invalid environment variables:', | ||
parsed.error.flatten().fieldErrors, | ||
) | ||
|
||
throw new Error('Invalid envirmonment variables') | ||
} | ||
} | ||
|
||
/** | ||
* This is used in both `entry.server.ts` and `root.tsx` to ensure that | ||
* the environment variables are set and globally available before the app is | ||
* started. | ||
* | ||
* NOTE: Do *not* add any environment variables in here that you do not wish to | ||
* be included in the client. | ||
* @returns all public ENV variables | ||
*/ | ||
export function getEnv() { | ||
return { | ||
MODE: process.env.NODE_ENV, | ||
} | ||
} | ||
|
||
type ENV = ReturnType<typeof getEnv> | ||
|
||
declare global { | ||
var ENV: ENV | ||
interface Window { | ||
ENV: ENV | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
exercises/06.honeypot/03.problem.provider/app/utils/honeypot.server.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { Honeypot } from 'remix-utils/honeypot/server' | ||
|
||
export const honeypot = new Honeypot({ | ||
// 🐨 set this to process.env.TESTING ? undefined : null so it's disabled during tests | ||
validFromFieldName: null, | ||
}) |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Oops, something went wrong.