mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-04-11 18:17:36 -04:00
Set Google Auth
This commit is contained in:
@@ -61,6 +61,7 @@ Run the following commands to set up your database and Prisma schema:
|
||||
|
||||
```bash
|
||||
npx prisma migrate dev --name init
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ import {useSession, signOut} from "next-auth/react";
|
||||
export default function Header() {
|
||||
const {data: session} = useSession();
|
||||
|
||||
console.log(session);
|
||||
|
||||
return (
|
||||
<header className="w-full bg-white shadow-md py-4 px-8">
|
||||
<nav className="flex justify-between items-center">
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// import { prisma } from "@/lib/prisma";
|
||||
import bcrypt from "bcryptjs";
|
||||
import { NextResponse } from "next/server";
|
||||
import prisma from "@/lib/prisma";
|
||||
import { prisma }from "@/lib/prisma";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
try {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import prisma from "@/lib/prisma";
|
||||
import { prisma }from "@/lib/prisma";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
export async function GET(request: Request) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export const dynamic = "force-dynamic"; // This disables SSG and ISR
|
||||
|
||||
import prisma from "@/lib/prisma";
|
||||
import { prisma }from "@/lib/prisma";
|
||||
import { notFound, redirect } from "next/navigation";
|
||||
|
||||
export default async function Post({ params }: { params: Promise<{ id: string }> }) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {redirect} from "next/navigation";
|
||||
import Link from "next/link";
|
||||
import prisma from "@/lib/prisma";
|
||||
import { prisma }from "@/lib/prisma";
|
||||
import {checkPostTableExists} from "@/lib/db-utils";
|
||||
|
||||
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
export const dynamic = "force-dynamic"; // This disables SSG and ISR
|
||||
|
||||
import prisma from "@/lib/prisma";
|
||||
import { redirect } from "next/navigation";
|
||||
import Form from "next/form";
|
||||
|
||||
export default function NewUser() {
|
||||
async function createUser(formData: FormData) {
|
||||
"use server";
|
||||
|
||||
const name = formData.get("name") as string;
|
||||
const email = formData.get("email") as string;
|
||||
|
||||
await prisma.user.create({
|
||||
data: { name, email, password: "" }, // password will be added by NextAuth
|
||||
});
|
||||
|
||||
redirect("/");
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="max-w-2xl mx-auto p-6 bg-white rounded-lg shadow-md mt-12">
|
||||
<h1 className="text-3xl font-bold mb-6">Create New User</h1>
|
||||
<Form action={createUser} className="space-y-6">
|
||||
<div>
|
||||
<label htmlFor="name" className="block text-lg font-medium mb-2">Name</label>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
name="name"
|
||||
placeholder="Enter user name ..."
|
||||
className="w-full px-4 py-2 border rounded-lg"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="email" className="flex text-lg font-medium mb-2 items-center">
|
||||
Email
|
||||
<span className="ml-2 px-2 py-1 text-xs font-semibold text-white bg-gray-500 rounded-lg">
|
||||
Required
|
||||
</span>
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
required
|
||||
placeholder="Enter user email ..."
|
||||
className="w-full px-4 py-2 border rounded-lg"
|
||||
/>
|
||||
</div>
|
||||
<button type="submit" className="w-full bg-blue-500 text-white py-3 rounded-lg hover:bg-blue-600">
|
||||
Create User
|
||||
</button>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
32
auth.ts
32
auth.ts
@@ -1,8 +1,9 @@
|
||||
import CredentialsProvider from "next-auth/providers/credentials";
|
||||
import GoogleProvider from "next-auth/providers/google";
|
||||
import { type NextAuthOptions } from "next-auth";
|
||||
import prisma from "@/lib/prisma";
|
||||
import {type NextAuthOptions} from "next-auth";
|
||||
import bcrypt from "bcryptjs";
|
||||
import { PrismaAdapter } from "@next-auth/prisma-adapter";
|
||||
import {prisma} from "@/lib/prisma"
|
||||
|
||||
export const authOptions = {
|
||||
providers: [
|
||||
@@ -13,9 +14,9 @@ export const authOptions = {
|
||||
CredentialsProvider({
|
||||
name: "credentials",
|
||||
credentials: {
|
||||
email: { label: "Email", type: "email" },
|
||||
name: { label: "Name", type: "name" },
|
||||
password: { label: "Password", type: "password" },
|
||||
email: {label: "Email", type: "email"},
|
||||
name: {label: "Name", type: "name"},
|
||||
password: {label: "Password", type: "password"},
|
||||
},
|
||||
async authorize(credentials) {
|
||||
if (!credentials?.email || !credentials?.password) {
|
||||
@@ -23,7 +24,7 @@ export const authOptions = {
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { email: credentials.email },
|
||||
where: {email: credentials.email},
|
||||
});
|
||||
|
||||
if (!user || !user.password) {
|
||||
@@ -46,12 +47,15 @@ export const authOptions = {
|
||||
pages: {
|
||||
signIn: "/login",
|
||||
},
|
||||
callbacks: {
|
||||
async jwt({ token, user }) {
|
||||
return { ...token, id: token.id ?? user?.id };
|
||||
},
|
||||
async session({ session, token }) {
|
||||
return { ...session, user: { ...session.user, id: token.id } };
|
||||
},
|
||||
},
|
||||
adapter: PrismaAdapter(prisma),
|
||||
debug: process.env.NODE_ENV === "development",
|
||||
secret: process.env.NEXTAUTH_SECRET,
|
||||
// callbacks: {
|
||||
// async jwt({ token, user }) {
|
||||
// return { ...token, id: token.id ?? user?.id };
|
||||
// },
|
||||
// async session({ session, token }) {
|
||||
// return { ...session, user: { ...session.user, id: token.id } };
|
||||
// },
|
||||
// },
|
||||
} satisfies NextAuthOptions;
|
||||
@@ -1,6 +1,6 @@
|
||||
"use server";
|
||||
|
||||
import prisma from "@/lib/prisma";
|
||||
import { prisma }from "@/lib/prisma";
|
||||
|
||||
/**
|
||||
* Checks if the Post table exists in the database
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
import { withAccelerate } from '@prisma/extension-accelerate'
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
|
||||
const prisma = new PrismaClient().$extends(withAccelerate())
|
||||
const globalForPrisma = global as unknown as { prisma: PrismaClient };
|
||||
|
||||
const globalForPrisma = global as unknown as { prisma: typeof prisma }
|
||||
export const prisma =
|
||||
globalForPrisma.prisma ||
|
||||
new PrismaClient({
|
||||
log: ["query"],
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
|
||||
|
||||
export default prisma
|
||||
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
|
||||
|
||||
85
package-lock.json
generated
85
package-lock.json
generated
@@ -9,12 +9,14 @@
|
||||
"version": "0.1.0",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@auth/prisma-adapter": "^2.10.0",
|
||||
"@next-auth/prisma-adapter": "^1.0.7",
|
||||
"@prisma/client": "^6.12.0",
|
||||
"@prisma/extension-accelerate": "^2.0.2",
|
||||
"bcryptjs": "^3.0.2",
|
||||
"lucide-react": "^0.503.0",
|
||||
"next": "^15.4.4",
|
||||
"next-auth": "^4.24.11",
|
||||
"next-auth": "^4.24.7",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-icons": "^5.5.0"
|
||||
@@ -46,6 +48,78 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@auth/prisma-adapter": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@auth/prisma-adapter/-/prisma-adapter-2.10.0.tgz",
|
||||
"integrity": "sha512-EliOQoTjGK87jWWqnJvlQjbR4PjQZQqtwRwPAe108WwT9ubuuJJIrL68aNnQr4hFESz6P7SEX2bZy+y2yL37Gw==",
|
||||
"dependencies": {
|
||||
"@auth/core": "0.40.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@prisma/client": ">=2.26.0 || >=3 || >=4 || >=5 || >=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@auth/prisma-adapter/node_modules/@auth/core": {
|
||||
"version": "0.40.0",
|
||||
"resolved": "https://registry.npmjs.org/@auth/core/-/core-0.40.0.tgz",
|
||||
"integrity": "sha512-n53uJE0RH5SqZ7N1xZoMKekbHfQgjd0sAEyUbE+IYJnmuQkbvuZnXItCU7d+i7Fj8VGOgqvNO7Mw4YfBTlZeQw==",
|
||||
"dependencies": {
|
||||
"@panva/hkdf": "^1.2.1",
|
||||
"jose": "^6.0.6",
|
||||
"oauth4webapi": "^3.3.0",
|
||||
"preact": "10.24.3",
|
||||
"preact-render-to-string": "6.5.11"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@simplewebauthn/browser": "^9.0.1",
|
||||
"@simplewebauthn/server": "^9.0.2",
|
||||
"nodemailer": "^6.8.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@simplewebauthn/browser": {
|
||||
"optional": true
|
||||
},
|
||||
"@simplewebauthn/server": {
|
||||
"optional": true
|
||||
},
|
||||
"nodemailer": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@auth/prisma-adapter/node_modules/jose": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-6.0.12.tgz",
|
||||
"integrity": "sha512-T8xypXs8CpmiIi78k0E+Lk7T2zlK4zDyg+o1CZ4AkOHgDg98ogdP2BeZ61lTFKFyoEwJ9RgAgN+SdM3iPgNonQ==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/panva"
|
||||
}
|
||||
},
|
||||
"node_modules/@auth/prisma-adapter/node_modules/oauth4webapi": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.6.0.tgz",
|
||||
"integrity": "sha512-OwXPTXjKPOldTpAa19oksrX9TYHA0rt+VcUFTkJ7QKwgmevPpNm9Cn5vFZUtIo96FiU6AfPuUUGzoXqgOzibWg==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/panva"
|
||||
}
|
||||
},
|
||||
"node_modules/@auth/prisma-adapter/node_modules/preact": {
|
||||
"version": "10.24.3",
|
||||
"resolved": "https://registry.npmjs.org/preact/-/preact-10.24.3.tgz",
|
||||
"integrity": "sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/preact"
|
||||
}
|
||||
},
|
||||
"node_modules/@auth/prisma-adapter/node_modules/preact-render-to-string": {
|
||||
"version": "6.5.11",
|
||||
"resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.5.11.tgz",
|
||||
"integrity": "sha512-ubnauqoGczeGISiOh6RjX0/cdaF8v/oDXIjO85XALCQjwQP+SB4RDXXtvZ6yTYSjG+PC1QRP2AhPgCEsM2EvUw==",
|
||||
"peerDependencies": {
|
||||
"preact": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz",
|
||||
@@ -1152,6 +1226,15 @@
|
||||
"@tybys/wasm-util": "^0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@next-auth/prisma-adapter": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@next-auth/prisma-adapter/-/prisma-adapter-1.0.7.tgz",
|
||||
"integrity": "sha512-Cdko4KfcmKjsyHFrWwZ//lfLUbcLqlyFqjd/nYE2m3aZ7tjMNUjpks47iw7NTCnXf+5UWz5Ypyt1dSs1EP5QJw==",
|
||||
"peerDependencies": {
|
||||
"@prisma/client": ">=2.26.0 || >=3",
|
||||
"next-auth": "^4"
|
||||
}
|
||||
},
|
||||
"node_modules/@next/env": {
|
||||
"version": "15.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-15.4.4.tgz",
|
||||
|
||||
@@ -10,12 +10,14 @@
|
||||
"postinstall": "npx prisma generate --no-engine"
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth/prisma-adapter": "^2.10.0",
|
||||
"@next-auth/prisma-adapter": "^1.0.7",
|
||||
"@prisma/client": "^6.12.0",
|
||||
"@prisma/extension-accelerate": "^2.0.2",
|
||||
"bcryptjs": "^3.0.2",
|
||||
"lucide-react": "^0.503.0",
|
||||
"next": "^15.4.4",
|
||||
"next-auth": "^4.24.11",
|
||||
"next-auth": "^4.24.7",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-icons": "^5.5.0"
|
||||
|
||||
@@ -1,30 +1,26 @@
|
||||
// This is your Prisma schema file,
|
||||
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||||
|
||||
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
|
||||
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "sqlite"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
name String?
|
||||
email String @unique
|
||||
password String
|
||||
id String @id @default(cuid())
|
||||
name String?
|
||||
email String? @unique
|
||||
password String? // <-- Add this for email/password auth
|
||||
emailVerified DateTime?
|
||||
image String?
|
||||
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
// Optional for WebAuthn support
|
||||
Authenticator Authenticator[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model Account {
|
||||
@@ -41,6 +37,9 @@ model Account {
|
||||
id_token String?
|
||||
session_state String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([provider, providerAccountId])
|
||||
@@ -51,6 +50,32 @@ model Session {
|
||||
sessionToken String @unique
|
||||
userId String
|
||||
expires DateTime
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model VerificationToken {
|
||||
identifier String
|
||||
token String
|
||||
expires DateTime
|
||||
|
||||
@@unique([identifier, token])
|
||||
}
|
||||
|
||||
// Optional for WebAuthn support
|
||||
model Authenticator {
|
||||
credentialID String @unique
|
||||
userId String
|
||||
providerAccountId String
|
||||
credentialPublicKey String
|
||||
counter Int
|
||||
credentialDeviceType String
|
||||
credentialBackedUp Boolean
|
||||
transports String?
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
@@id([userId, credentialID])
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import bcrypt from 'bcryptjs';
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
// Create 5 users with hashed passwords
|
||||
const users = await Promise.all([
|
||||
prisma.user.create({
|
||||
data: {
|
||||
|
||||
Reference in New Issue
Block a user