Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6c5ca25

Browse files
authored
Update all dependencies. (#48)
2 parents 7477bca + a6ac1d3 commit 6c5ca25

32 files changed

+5658
-1821
lines changed

‎.env.example

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22
POSTGRES_URL=
33
POSTGRES_PRISMA_URL=
44
POSTGRES_URL_NON_POOLING=
5-
POSTGRES_USER=
6-
POSTGRES_HOST=
7-
POSTGRES_PASSWORD=
8-
POSTGRES_DATABASE=
95

106
# Generate one here: https://generate-secret.vercel.app/32 (only required for localhost)
11-
NEXTAUTH_SECRET=
7+
AUTH_SECRET=

‎.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ yarn-error.log*
3434

3535
# vercel
3636
.vercel
37+
.env*.local

‎README.md

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,12 @@
1-
<p align="center">
2-
<a href="https://nextjs-postgres-auth.vercel.app/">
3-
<img src="/public/logo.png" height="96">
4-
<h3 align="center">Next.js Prisma PostgreSQL Auth Starter</h3>
5-
</a>
6-
</p>
1+
# Next.js + PostgreSQL Auth Starter
72

8-
<p align="center">
9-
This is a <a href="https://nextjs.org/">Next.js</a> starter kit that uses <a href="https://next-auth.js.org/">Next-Auth</a> for simple email + password login<br/>
10-
<a href="https://www.prisma.io/">Prisma</a> as the ORM, and a <a href="https://vercel.com/postgres">Vercel Postgres</a> database to persist the data.</p>
11-
12-
<br/>
3+
This is a [Next.js](https://nextjs.org/) starter kit that uses [NextAuth.js](https://next-auth.js.org/) for simple email + password login, [Drizzle](https://orm.drizzle.team) as the ORM, and a [Neon Postgres](https://vercel.com/postgres) database to persist the data.
134

145
## Deploy Your Own
156

167
You can clone & deploy it to Vercel with one click:
178

18-
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?demo-title=Next.js%20Prisma%20PostgreSQL%20Auth%20Starter&demo-description=Simple%20Next.js%2013%20starter%20kit%20that%20uses%20Next-Auth%20for%20auth%20and%20Prisma%20PostgreSQL%20as%20a%20database.&demo-url=https%3A%2F%2Fnextjs-postgres-auth.vercel.app%2F&demo-image=%2F%2Fimages.ctfassets.net%2Fe5382hct74si%2F7rsVQ1ZBSiWe9JGO6FUeZZ%2F210cba91036ca912b2770e0bd5d6cc5d%2Fthumbnail.png&project-name=Next.js%%20Prisma%20PostgreSQL%20Auth%20Starter&repository-name=nextjs-postgres-auth-starter&repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fnextjs-postgres-auth-starter&from=templates&skippable-integrations=1&env=NEXTAUTH_SECRET&envDescription=Generate%20a%20random%20secret%3A&envLink=https://generate-secret.vercel.app/&stores=%5B%7B"type"%3A"postgres"%7D%5D)
9+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?demo-title=Next.js%20Prisma%20PostgreSQL%20Auth%20Starter&demo-description=Simple%20Next.js%2013%20starter%20kit%20that%20uses%20Next-Auth%20for%20auth%20and%20Prisma%20PostgreSQL%20as%20a%20database.&demo-url=https%3A%2F%2Fnextjs-postgres-auth.vercel.app%2F&demo-image=%2F%2Fimages.ctfassets.net%2Fe5382hct74si%2F7rsVQ1ZBSiWe9JGO6FUeZZ%2F210cba91036ca912b2770e0bd5d6cc5d%2Fthumbnail.png&project-name=Next.js%%20Prisma%20PostgreSQL%20Auth%20Starter&repository-name=nextjs-postgres-auth-starter&repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fnextjs-postgres-auth-starter&from=templates&skippable-integrations=1&env=AUTH_SECRET&envDescription=Generate%20a%20random%20secret%3A&envLink=https://generate-secret.vercel.app/&stores=%5B%7B"type"%3A"postgres"%7D%5D)
1910

2011
## Developing Locally
2112

@@ -30,9 +21,7 @@ npx create-next-app nextjs-typescript-starter --example "https://github.com/verc
3021
First, run the development server:
3122

3223
```bash
33-
npm run dev
34-
# or
35-
yarn dev
24+
pnpm dev
3625
```
3726

3827
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

‎app/api/auth/[...nextauth]/route.ts

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1 @@
1-
import NextAuth, { type NextAuthOptions } from "next-auth";
2-
import CredentialsProvider from "next-auth/providers/credentials";
3-
import prisma from "@/lib/prisma";
4-
import { compare } from "bcrypt";
5-
6-
export const authOptions: NextAuthOptions = {
7-
providers: [
8-
CredentialsProvider({
9-
credentials: {
10-
email: { label: "Email", type: "email" },
11-
password: { label: "Password", type: "password" }
12-
},
13-
async authorize(credentials) {
14-
const { email, password } = credentials ?? {}
15-
if (!email || !password) {
16-
throw new Error("Missing username or password");
17-
}
18-
const user = await prisma.user.findUnique({
19-
where: {
20-
email,
21-
},
22-
});
23-
// if user doesn't exist or password doesn't match
24-
if (!user || !(await compare(password, user.password))) {
25-
throw new Error("Invalid username or password");
26-
}
27-
return user;
28-
},
29-
}),
30-
],
31-
};
32-
33-
const handler = NextAuth(authOptions);
34-
35-
export { handler as GET, handler as POST };
1+
export { GET, POST } from 'app/auth';

‎app/api/auth/register/route.ts

Lines changed: 0 additions & 24 deletions
This file was deleted.

‎app/auth.config.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { NextAuthConfig } from 'next-auth';
2+
3+
export const authConfig = {
4+
pages: {
5+
signIn: '/login',
6+
},
7+
providers: [
8+
// added later in auth.ts since it requires bcrypt which is only compatible with Node.js
9+
// while this file is also used in non-Node.js environments
10+
],
11+
callbacks: {
12+
authorized({ auth, request: { nextUrl } }) {
13+
let isLoggedIn = !!auth?.user;
14+
let isOnDashboard = nextUrl.pathname.startsWith('/protected');
15+
16+
if (isOnDashboard) {
17+
if (isLoggedIn) return true;
18+
return false; // Redirect unauthenticated users to login page
19+
} else if (isLoggedIn) {
20+
return Response.redirect(new URL('/protected', nextUrl));
21+
}
22+
23+
return true;
24+
},
25+
},
26+
} satisfies NextAuthConfig;

‎app/auth.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import NextAuth from 'next-auth';
2+
import Credentials from 'next-auth/providers/credentials';
3+
import { compare } from 'bcrypt-ts';
4+
import { getUser } from 'app/db';
5+
import { authConfig } from 'app/auth.config';
6+
7+
export const {
8+
handlers: { GET, POST },
9+
auth,
10+
signIn,
11+
signOut,
12+
} = NextAuth({
13+
...authConfig,
14+
providers: [
15+
Credentials({
16+
async authorize({ email, password }: any) {
17+
let user = await getUser(email);
18+
if (user.length === 0) return null;
19+
let passwordsMatch = await compare(password, user[0].password!);
20+
if (passwordsMatch) return user[0] as any;
21+
},
22+
}),
23+
],
24+
});

‎app/db.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { drizzle } from 'drizzle-orm/postgres-js';
2+
import { pgTable, serial, varchar } from 'drizzle-orm/pg-core';
3+
import { eq } from 'drizzle-orm';
4+
import postgres from 'postgres';
5+
import { genSaltSync, hashSync } from 'bcrypt-ts';
6+
7+
// Optionally, if not using email/pass login, you can
8+
// use the Drizzle adapter for Auth.js / NextAuth
9+
// https://authjs.dev/reference/adapter/drizzle
10+
let client = postgres(`${process.env.POSTGRES_URL!}?sslmode=require`);
11+
let db = drizzle(client);
12+
13+
let users = pgTable('User', {
14+
id: serial('id').primaryKey(),
15+
email: varchar('email', { length: 64 }),
16+
password: varchar('password', { length: 64 }),
17+
});
18+
19+
export async function getUser(email: string) {
20+
return await db.select().from(users).where(eq(users.email, email));
21+
}
22+
23+
export async function createUser(email: string, password: string) {
24+
let salt = genSaltSync(10);
25+
let hash = hashSync(password, salt);
26+
27+
return await db.insert(users).values({ email, password: hash });
28+
}

‎app/form.tsx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
export function Form({
2+
action,
3+
children,
4+
}: {
5+
action: any;
6+
children: React.ReactNode;
7+
}) {
8+
return (
9+
<form
10+
action={action}
11+
className="flex flex-col space-y-4 bg-gray-50 px-4 py-8 sm:px-16"
12+
>
13+
<div>
14+
<label
15+
htmlFor="email"
16+
className="block text-xs text-gray-600 uppercase"
17+
>
18+
Email Address
19+
</label>
20+
<input
21+
id="email"
22+
name="email"
23+
type="email"
24+
placeholder="user@acme.com"
25+
autoComplete="email"
26+
required
27+
className="mt-1 block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 placeholder-gray-400 shadow-sm focus:border-black focus:outline-none focus:ring-black sm:text-sm"
28+
/>
29+
</div>
30+
<div>
31+
<label
32+
htmlFor="password"
33+
className="block text-xs text-gray-600 uppercase"
34+
>
35+
Password
36+
</label>
37+
<input
38+
id="password"
39+
name="password"
40+
type="password"
41+
required
42+
className="mt-1 block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 placeholder-gray-400 shadow-sm focus:border-black focus:outline-none focus:ring-black sm:text-sm"
43+
/>
44+
</div>
45+
{children}
46+
</form>
47+
);
48+
}
File renamed without changes.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /