Skip to content

Commit 782aaae

Browse files
author
codebyps
committed
πŸ±β€πŸ authentication added
1 parent aae16d0 commit 782aaae

File tree

24 files changed

+2088
-110
lines changed

24 files changed

+2088
-110
lines changed

β€Ž.env

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@
44
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
55
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
66

7-
DATABASE_URL="mongodb+srv://playground:[email protected]/shotr"
8-
NEXT_URL="http://localhost:3000"
7+
DATABASE_URL="mongodb+srv://playground:[email protected]/linkey-dev"
8+
9+
NEXT_PUBLIC_URL="http://localhost:3000"
10+
11+
NEXTAUTH_URL="http://localhost:3000"
12+
13+
NEXTAUTH_SECRET="duisvbfuyfduifhgwyfvopiguy"
14+
GOOGLE_CLIENT_ID="621190539158-gltjuld8dprl0ku38511fuo0t7vg2if2.apps.googleusercontent.com"
15+
GOOGLE_CLIENT_SECRET="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"
16+
GITHUB_ID="813d1b3a99d692651e70"
17+
GITHUB_SECRET="5e6b6e46968f2198eaf1cd599992238ba458b1b9"
18+
19+
920
REDIRECT_URL="https://linkey-ss.onrender.com/"

β€ŽContext/AuthContext.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
"use client";
2+
3+
import { SessionProvider } from "next-auth/react";
4+
5+
export interface AuthContextProps {
6+
children: React.ReactNode;
7+
}
8+
9+
export default function AuthContext({ children }: AuthContextProps) {
10+
return <SessionProvider>{children}</SessionProvider>;
11+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import bcrypt from "bcrypt";
2+
import NextAuth, { AuthOptions, Session } from "next-auth";
3+
import CredentialsProvider from "next-auth/providers/credentials";
4+
import GithubProvider from "next-auth/providers/github";
5+
import GoogleProvider from "next-auth/providers/google";
6+
import { PrismaAdapter } from "@next-auth/prisma-adapter";
7+
8+
import prisma from "@/lib/prisma";
9+
10+
export const authOptions: AuthOptions = {
11+
adapter: PrismaAdapter(prisma),
12+
providers: [
13+
GithubProvider({
14+
clientId: process.env.GITHUB_ID as string,
15+
clientSecret: process.env.GITHUB_SECRET as string,
16+
}),
17+
GoogleProvider({
18+
clientId: process.env.GOOGLE_CLIENT_ID as string,
19+
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
20+
}),
21+
CredentialsProvider({
22+
name: "credentials",
23+
credentials: {
24+
email: { label: "email", type: "text" },
25+
password: { label: "password", type: "password" },
26+
},
27+
async authorize(credentials) {
28+
if (!credentials?.email || !credentials?.password) {
29+
throw new Error("Invalid credentials");
30+
}
31+
32+
const user = await prisma.user.findUnique({
33+
where: {
34+
email: credentials.email,
35+
},
36+
});
37+
38+
if (!user || !user?.hashedPassword) {
39+
throw new Error("Invalid credentials");
40+
}
41+
42+
const isCorrectPassword = await bcrypt.compare(
43+
credentials.password,
44+
user.hashedPassword
45+
);
46+
47+
if (!isCorrectPassword) {
48+
throw new Error("Invalid credentials");
49+
}
50+
51+
return user;
52+
},
53+
}),
54+
],
55+
56+
callbacks: {
57+
async jwt({ token, user }) {
58+
/* Step 1: update the token based on the user object */
59+
if (user) {
60+
token.id = user.id;
61+
token.username = user.username;
62+
token.name = user.name;
63+
token.email = user.email;
64+
token.image = user.image;
65+
token.bio = user.bio;
66+
token.emailVerified = user.emailVerified;
67+
}
68+
return token;
69+
},
70+
async session({ session, token }) {
71+
/* Step 2: update the session.user based on the token object */
72+
if (token && session.user) {
73+
session.user.id = token.id;
74+
session.user.username = token.username;
75+
session.user.name = token.name;
76+
session.user.email = token.email;
77+
session.user.image = token.image;
78+
session.user.bio = token.bio;
79+
session.user.emailVerified = token.emailVerified;
80+
}
81+
return session;
82+
},
83+
},
84+
85+
debug: process.env.NODE_ENV === "development",
86+
session: {
87+
strategy: "jwt",
88+
},
89+
secret: process.env.NEXTAUTH_SECRET,
90+
pages: {
91+
signIn: "/auth",
92+
signOut: "/auth",
93+
// error: "/global-error", // Error code passed in query string as ?error=
94+
},
95+
};
96+
97+
const handler = NextAuth(authOptions);
98+
99+
export { handler as GET, handler as POST };

β€Žapp/api/register/route.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import bcrypt from "bcrypt";
2+
3+
import prisma from "@/lib/prisma";
4+
import { NextResponse } from "next/server";
5+
6+
export async function POST(request: Request) {
7+
const body = await request.json();
8+
const { email, name, password } = body;
9+
10+
const hashedPassword = await bcrypt.hash(password, 12);
11+
12+
const user = await prisma.user.create({
13+
data: {
14+
email,
15+
name,
16+
hashedPassword,
17+
},
18+
});
19+
20+
return NextResponse.json(user);
21+
}

β€Žapp/api/short/route.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,14 @@ export async function POST(request: NextRequest) {
1616
return result;
1717
}
1818

19-
const { longUrl, shortUrl } = await request.json();
19+
const { longUrl, shortUrl, userId } = await request.json();
20+
21+
if (!userId) {
22+
return NextResponse.json({
23+
error: "You are not authorized to make shot link",
24+
status: 400,
25+
});
26+
}
2027

2128
const reservedWords = [
2229
"priyanshu",
@@ -75,6 +82,7 @@ export async function POST(request: NextRequest) {
7582
shortUrl: shotID,
7683
longUrl: longUrl as string,
7784
clicks: 0,
85+
user: userId,
7886
},
7987
});
8088
console.log(res);

β€Žapp/auth/page.tsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import React from "react";
2+
import AuthForm from "../components/AuthForm";
3+
4+
export const metadata = {
5+
title: "Get Authentication",
6+
};
7+
const Auth = () => {
8+
return (
9+
<div
10+
className="
11+
flex
12+
min-h-full
13+
max-h-screen
14+
flex-col
15+
justify-center
16+
py-12
17+
sm:px-6
18+
lg:px-8
19+
bg-gray-100
20+
"
21+
>
22+
<div className="sm:mx-auto sm:w-full sm:max-w-md">
23+
<h2
24+
className="
25+
mt-6
26+
text-center
27+
text-3xl
28+
font-bold
29+
tracking-tight
30+
text-gray-900
31+
"
32+
>
33+
Sign in to your account
34+
</h2>
35+
</div>
36+
<AuthForm />
37+
</div>
38+
);
39+
};
40+
41+
export default Auth;

0 commit comments

Comments
Β (0)