Skip to content

Commit

Permalink
Run prettier
Browse files Browse the repository at this point in the history
  • Loading branch information
delbaoliveira committed Mar 13, 2024
1 parent 8e53e09 commit c8acf0f
Show file tree
Hide file tree
Showing 11 changed files with 3,368 additions and 1,249 deletions.
20 changes: 10 additions & 10 deletions app/(public)/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { Label } from "@/components/ui/label"
import { Input } from "@/components/ui/input"
import Link from "next/link"
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import { Label } from '@/components/ui/label';
import { Input } from '@/components/ui/input';
import Link from 'next/link';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';

export default function Login() {
return (
<div className="flex items-center w-1/4 px-4 sm:px-6 lg:px-8">
<div className="w-full mx-auto space-y-8">
<div className="flex w-1/4 items-center px-4 sm:px-6 lg:px-8">
<div className="mx-auto w-full space-y-8">
<div className="space-y-2 text-center">
<h1 className="text-3xl font-bold">Login</h1>
<p className="text-gray-500 text-sm">
<p className="text-sm text-gray-500">
Enter your email below to login to your account
</p>
</div>
Expand Down Expand Up @@ -50,13 +50,13 @@ export default function Login() {
</div>

<div className="mt-4 text-center text-sm">
Don&apos;t have an account?{" "}
Don&apos;t have an account?{' '}
<Link className="underline" href="/signup">
Sign up
</Link>
</div>
</form>
</div>
</div>
)
);
}
20 changes: 10 additions & 10 deletions app/(public)/signup/form.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
"use client"
'use client';

import { Label } from "@/components/ui/label"
import { Input } from "@/components/ui/input"
import { Button } from "@/components/ui/button"
import { signup } from "@/lib/auth"
import { useFormState, useFormStatus } from "react-dom"
import { Label } from '@/components/ui/label';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { signup } from '@/lib/auth';
import { useFormState, useFormStatus } from 'react-dom';

export function SignupForm() {
const [state, action] = useFormState(signup, undefined)
const [state, action] = useFormState(signup, undefined);

return (
<form action={action}>
Expand Down Expand Up @@ -42,16 +42,16 @@ export function SignupForm() {
)}
<SignupButton />
</form>
)
);
}

function SignupButton() {
// TODO: Style button pending state
const { pending } = useFormStatus()
const { pending } = useFormStatus();

return (
<Button className="w-full" type="submit">
Register
</Button>
)
);
}
12 changes: 6 additions & 6 deletions app/(public)/signup/page.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import Link from "next/link"
import { SignupForm } from "@/app/(public)/signup/form"
import Link from 'next/link';
import { SignupForm } from '@/app/(public)/signup/form';
export default function Page() {
return (
<div className="flex items-center w-1/4 px-4 sm:px-6 lg:px-8">
<div className="w-full mx-auto space-y-8">
<div className="flex w-1/4 items-center px-4 sm:px-6 lg:px-8">
<div className="mx-auto w-full space-y-8">
<div className="space-y-2 text-center">
<h1 className="text-3xl font-bold">Create an account</h1>
<p className="text-gray-500">Enter your information to get started</p>
</div>
<SignupForm />
<div className="mt-4 text-center text-sm">
Already have an account?{" "}
Already have an account?{' '}
<Link className="underline" href="/login">
Login
</Link>
</div>
</div>
</div>
)
);
}
8 changes: 4 additions & 4 deletions drizzle.config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import "@/drizzle/envConfig"
import { defineConfig } from "drizzle-kit"
import '@/drizzle/envConfig';
import { defineConfig } from 'drizzle-kit';

export default defineConfig({
schema: "./drizzle/schema.ts",
driver: "pg",
schema: './drizzle/schema.ts',
driver: 'pg',
dbCredentials: {
connectionString: process.env.POSTGRES_URL!,
},
Expand Down
10 changes: 5 additions & 5 deletions drizzle/db.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import "@/drizzle/envConfig"
import { drizzle } from "drizzle-orm/vercel-postgres"
import { sql } from "@vercel/postgres"
import { users, NewUser } from "./schema"
import * as schema from "./schema"
import '@/drizzle/envConfig';
import { drizzle } from 'drizzle-orm/vercel-postgres';
import { sql } from '@vercel/postgres';
import { users, NewUser } from './schema';
import * as schema from './schema';

export const db = drizzle(sql, { schema });

Expand Down
38 changes: 19 additions & 19 deletions drizzle/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,33 @@ import {
integer,
timestamp,
time,
} from "drizzle-orm/pg-core"
import { InferInsertModel } from "drizzle-orm"
} from 'drizzle-orm/pg-core';
import { InferInsertModel } from 'drizzle-orm';

export const users = pgTable(
"users",
'users',
{
id: serial("id").primaryKey(),
name: text("name").notNull(),
email: text("email").unique().notNull(),
password: text("password").notNull(),
id: serial('id').primaryKey(),
name: text('name').notNull(),
email: text('email').unique().notNull(),
password: text('password').notNull(),
},
(users) => {
return {
uniqueIdx: uniqueIndex("unique_idx").on(users.email),
}
uniqueIdx: uniqueIndex('unique_idx').on(users.email),
};
},
)
);

export const sessions = pgTable("sessions", {
id: serial("id").primaryKey(),
userId: integer("userId")
export const sessions = pgTable('sessions', {
id: serial('id').primaryKey(),
userId: integer('userId')
.references(() => users.id)
.notNull(),
token: text("token").unique().notNull(),
createdAt: timestamp("created_at").defaultNow().notNull(),
expiresAt: timestamp("expires_at").notNull(),
})
token: text('token').unique().notNull(),
createdAt: timestamp('created_at').defaultNow().notNull(),
expiresAt: timestamp('expires_at').notNull(),
});

export type NewUser = InferInsertModel<typeof users>
export type NewSession = InferInsertModel<typeof sessions>
export type NewUser = InferInsertModel<typeof users>;
export type NewSession = InferInsertModel<typeof sessions>;
4 changes: 2 additions & 2 deletions drizzle/seed.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { insertUser } from "@/drizzle/db"
import { NewUser } from "@/drizzle/schema"
import { insertUser } from '@/drizzle/db';
import { NewUser } from '@/drizzle/schema';

async function main() {
const newUser: NewUser = {
Expand Down
46 changes: 25 additions & 21 deletions lib/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,37 @@
// signing up, logging in, and logging out.
// see `session.ts` for the session management logic.

"use server"
'use server';

import { db } from "@/drizzle/db"
import { users } from "@/drizzle/schema"
import { FormState, LoginFormSchema, SignupFormSchema } from "@/lib/definitions"
import { createSession } from "@/lib/session"
import bcrypt from "bcrypt"
import { db } from '@/drizzle/db';
import { users } from '@/drizzle/schema';
import {
FormState,
LoginFormSchema,
SignupFormSchema,
} from '@/lib/definitions';
import { createSession } from '@/lib/session';
import bcrypt from 'bcrypt';

export async function signup(state: FormState, formData: FormData) {
// 1. Validate form fields
const validatedFields = SignupFormSchema.safeParse({
name: formData.get("name"),
email: formData.get("email"),
password: formData.get("password"),
})
name: formData.get('name'),
email: formData.get('email'),
password: formData.get('password'),
});

// 2. If any form fields are invalid, return early and display errors
if (!validatedFields.success) {
return {
errors: validatedFields.error.flatten().fieldErrors,
}
};
}

// 3. Prepare data for insertion into database
const { name, email, password } = validatedFields.data
const { name, email, password } = validatedFields.data;
// 3.1 Hash the user's password
const hashedPassword = await bcrypt.hash(password, 10)
const hashedPassword = await bcrypt.hash(password, 10);

// 4. Insert the user into the database
try {
Expand All @@ -39,27 +43,27 @@ export async function signup(state: FormState, formData: FormData) {
email,
password: hashedPassword,
})
.returning({ id: users.id })
.returning({ id: users.id });

if (data && data.length > 0) {
const user = data[0]
const user = data[0];
// 5. Create a session for the user
createSession(user.id)
createSession(user.id);
}
} catch (error) {
return {
message: "An error occurred while creating your account.",
}
message: 'An error occurred while creating your account.',
};
}
}

// TODO: Login and logout functionality
export async function login(state: FormState, formData: FormData) {
// 1. Validate form fields
const validatedFields = LoginFormSchema.safeParse({
email: formData.get("email"),
password: formData.get("password"),
})
email: formData.get('email'),
password: formData.get('password'),
});

// 2. If any form fields are invalid, return early and display errors
// 3. Query the database
Expand Down
34 changes: 17 additions & 17 deletions lib/definitions.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
import { z } from "zod"
import { z } from 'zod';

export const SignupFormSchema = z.object({
name: z
.string()
.min(2, { message: "Name must be at least 2 characters long." })
.min(2, { message: 'Name must be at least 2 characters long.' })
.trim(),
email: z.string().email({ message: "Please enter a valid email." }).trim(),
email: z.string().email({ message: 'Please enter a valid email.' }).trim(),
password: z
.string()
.min(8, { message: "Be at least 8 characters long" })
.regex(/[a-zA-Z]/, { message: "Contain at least one letter." })
.regex(/[0-9]/, { message: "Contain at least one number." })
.min(8, { message: 'Be at least 8 characters long' })
.regex(/[a-zA-Z]/, { message: 'Contain at least one letter.' })
.regex(/[0-9]/, { message: 'Contain at least one number.' })
.regex(/[^a-zA-Z0-9]/, {
message: "Contain at least one special character.",
message: 'Contain at least one special character.',
})
.trim(),
})
});

export const LoginFormSchema = z.object({
email: z.string().email({ message: "Please enter a valid email" }),
password: z.string().min(1, { message: "Password field must not be empty" }),
})
email: z.string().email({ message: 'Please enter a valid email' }),
password: z.string().min(1, { message: 'Password field must not be empty' }),
});

export type FormState =
| {
errors?: {
name?: string[]
email?: string[]
password?: string[]
}
message?: string
name?: string[];
email?: string[];
password?: string[];
};
message?: string;
}
| undefined
| undefined;
34 changes: 16 additions & 18 deletions lib/session.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
// this file includes the session management logic for
// creating, verifying, and deleting sessions with server-side tokens.

"server-only"
'server-only';

import { db } from "@/drizzle/db"
import { sessions } from "@/drizzle/schema"
import jwt from "jsonwebtoken"
import { cookies } from "next/headers"
import { db } from '@/drizzle/db';
import { sessions } from '@/drizzle/schema';
import jwt from 'jsonwebtoken';
import { cookies } from 'next/headers';

const secretKey = "yourSecretKey"
const secretKey = 'yourSecretKey';

export async function createSession(id: number) {
const token = jwt.sign({ id }, secretKey, {
expiresIn: "1h",
})
expiresIn: '1h',
});

// Option 1: Storing server-side tokens
const expiresAt = new Date(Date.now() + 60 * 60 * 1000)
const expiresAt = new Date(Date.now() + 60 * 60 * 1000);

const serverToken = await db
.insert(sessions)
Expand All @@ -25,22 +25,20 @@ export async function createSession(id: number) {
token,
expiresAt,
})
.returning({ token: sessions.token })
.returning({ token: sessions.token });

// Option 2: Stateless session
cookies().set("token", token, {
cookies().set('token', token, {
httpOnly: true,
secure: true,
expires: new Date(Date.now() + 3600),
sameSite: "lax",
path: "/",
})
sameSite: 'lax',
path: '/',
});
}

export async function verifySession() {
}
export async function verifySession() {}

export function updateSession() {}

export function deleteSesssion() {
}
export function deleteSesssion() {}
Loading

0 comments on commit c8acf0f

Please sign in to comment.