Skip to content

Commit

Permalink
auth fixes, ran prisma migration
Browse files Browse the repository at this point in the history
  • Loading branch information
Nutlope committed Mar 10, 2023
1 parent e48270e commit 78e3def
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 68 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## Todos left for auth

- test it on deployment URL, make sure reset time is real
- roll it out to prod with instant rollback

# [roomGPT.io](https://roomGPT.io)

This project generates new designs of your room with AI.
Expand Down Expand Up @@ -46,6 +51,12 @@ npm run dev

1. Use `openssl rand -base64 32` to generate NEXTAUTH_SECRET
2. Add DB URL and SHADOW DB URL from Neon
3. Create a new project in console.cloud.google.com
4. Click configure consent screen in API credentials page and click external
5. Add an app name, do not upload logo, add authorized domain
6. Publish app
7. Create credentials -> Oauth client ID
8. Run npx prisma db push && prisma migrate dev && prisma generate

## One-Click Deploy

Expand Down
1 change: 0 additions & 1 deletion pages/api/auth/[...nextauth].ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { PrismaAdapter } from "@next-auth/prisma-adapter";
import prisma from "../../../lib/prismadb";

export const authOptions: NextAuthOptions = {
debug: true,
adapter: PrismaAdapter(prisma),
providers: [
GoogleProvider({
Expand Down
4 changes: 2 additions & 2 deletions pages/api/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ interface ExtendedNextApiRequest extends NextApiRequest {
};
}

// Create a new ratelimiter, that allows 3 requests per 24 hours
// Create a new ratelimiter, that allows 5 requests per 24 hours
const ratelimit = redis
? new Ratelimit({
redis: redis,
limiter: Ratelimit.fixedWindow(3, "1440 m"),
limiter: Ratelimit.fixedWindow(5, "1440 m"),
analytics: true,
})
: undefined;
Expand Down
15 changes: 11 additions & 4 deletions pages/api/remaining.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,18 @@ export default async function handler(
const usedGenerations =
(await redis?.get(`@upstash/ratelimit:${identifier!}:${bucket}`)) || 0;

// it can return null and it also returns the number of generations the user has done, not the number they have left

// TODO: Move this using date-fns on the client-side
// Move this using date-fns on the client-side
const resetDate = new Date();
resetDate.setHours(19, 0, 0, 0);
// Check if the current time is before 7pm EST
if (resetDate.getUTCHours() < 23) {
// 23 is equivalent to 7pm EST in UTC
// If before 7pm EST, set the time to 7pm EST
resetDate.setUTCHours(19, 0, 0, 0);
} else {
// If after 7pm EST, add one day and set the time to 7pm EST
resetDate.setDate(resetDate.getDate() + 1); // Add one day
resetDate.setUTCHours(19, 0, 0, 0);
}
const diff = Math.abs(resetDate.getTime() - new Date().getTime());
const hours = Math.floor(diff / 1000 / 60 / 60);
const minutes = Math.floor(diff / 1000 / 60) - hours * 60;
Expand Down
111 changes: 50 additions & 61 deletions pages/dream.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const Home: NextPage = () => {
);

async function generatePhoto(fileUrl: string) {
await new Promise((resolve) => setTimeout(resolve, 200)); // TODO: See if I even need this
await new Promise((resolve) => setTimeout(resolve, 200));
setLoading(true);
const res = await fetch("/api/generate", {
method: "POST",
Expand All @@ -95,6 +95,7 @@ const Home: NextPage = () => {
if (res.status !== 200) {
setError(response as any);
} else {
mutate();
const rooms =
(JSON.parse(localStorage.getItem("rooms") || "[]") as string[]) || [];
rooms.push(response.id);
Expand All @@ -114,44 +115,70 @@ const Home: NextPage = () => {
<Header photo={session?.user?.image || undefined} />
<main className="flex flex-1 w-full flex-col items-center justify-center text-center px-4 mt-4 sm:mb-0 mb-8">
<a
href="https://dub.sh/hassan-newsletter"
href="https://twitter.com/nutlope/status/1633529333565251595"
target="_blank"
rel="noreferrer"
className="border border-gray-700 rounded-2xl py-2 px-4 text-gray-400 text-sm my-6 duration-300 ease-in-out hover:text-gray-300 transition"
>
<span className="font-semibold">Subscribe to my newsletter</span> to
learn how I built roomGPT
<span className="font-semibold">728,000 rooms</span> generated and
counting
</a>
<h1 className="mx-auto max-w-4xl font-display text-4xl font-bold tracking-normal text-slate-100 sm:text-6xl mb-5">
Generate your <span className="text-blue-600">dream</span> room
</h1>
{status === "authenticated" && data && (
<p className="text-slate-500">
{status === "authenticated" && data && !restoredImage && (
<p className="text-gray-400">
You have{" "}
<span className="font-semibold">
<span className="font-semibold text-gray-300">
{data.remainingGenerations} generations
</span>{" "}
left today. Your generation
{Number(data.remainingGenerations) > 1 ? "s" : ""} will renew in{" "}
<span className="font-semibold">
<span className="font-semibold text-gray-300">
{data.hours} hours and {data.minutes} minutes.
</span>
</p>
)}
{/* {!restoredImage && (
<p className="text-gray-400">
<span className="font-bold text-gray-300">Note:</span> We're
temporarily{" "}
<span className="font-bold text-gray-300">
limiting generations to 3 per day
</span>{" "}
because of high traffic.
</p>
)} */}
<ResizablePanel>
<AnimatePresence mode="wait">
<motion.div className="flex justify-between items-center w-full flex-col mt-4">
{!restoredImage && (
{restoredImage && (
<div>
Here's your remodeled <b>{room.toLowerCase()}</b> in the{" "}
<b>{theme.toLowerCase()}</b> theme!{" "}
</div>
)}
<div
className={`${
restoredLoaded ? "visible mt-6 -ml-8" : "invisible"
}`}
>
<Toggle
className={`${restoredLoaded ? "visible mb-6" : "invisible"}`}
sideBySide={sideBySide}
setSideBySide={(newVal) => setSideBySide(newVal)}
/>
</div>
{restoredLoaded && sideBySide && (
<CompareSlider
original={originalPhoto!}
restored={restoredImage!}
/>
)}
{status === "loading" ? (
<div className="max-w-[670px] h-[250px] flex justify-center items-center">
<Rings
height="100"
width="100"
color="white"
radius="6"
wrapperStyle={{}}
wrapperClass=""
visible={true}
ariaLabel="rings-loading"
/>
</div>
) : status === "authenticated" && !originalPhoto ? (
<>
<div className="space-y-4 w-full max-w-sm">
<div className="flex mt-3 items-center space-x-3">
Expand Down Expand Up @@ -204,53 +231,15 @@ const Home: NextPage = () => {
</p>
</div>
</div>
<UploadDropZone />
</>
)}
{restoredImage && (
<div>
Here's your remodeled <b>{room.toLowerCase()}</b> in the{" "}
<b>{theme.toLowerCase()}</b> theme!{" "}
</div>
)}
<div
className={`${
restoredLoaded ? "visible mt-6 -ml-8" : "invisible"
}`}
>
<Toggle
className={`${restoredLoaded ? "visible mb-6" : "invisible"}`}
sideBySide={sideBySide}
setSideBySide={(newVal) => setSideBySide(newVal)}
/>
</div>
{restoredLoaded && sideBySide && (
<CompareSlider
original={originalPhoto!}
restored={restoredImage!}
/>
)}
{status === "loading" ? (
<div className="max-w-[670px] h-[250px] flex justify-center items-center">
<Rings
height="100"
width="100"
color="black"
radius="6"
wrapperStyle={{}}
wrapperClass=""
visible={true}
ariaLabel="rings-loading"
/>
</div>
) : status === "authenticated" && !originalPhoto ? (
<UploadDropZone />
) : (
!originalPhoto && (
<div className="h-[250px] flex flex-col items-center space-y-6 max-w-[670px] -mt-8">
<div className="max-w-xl text-gray-600">
<div className="max-w-xl text-gray-300">
Sign in below with Google to create a free account and
restore your photos today. You will be able to restore 5
photos per day for free.
redesign your room today. You will be able to do 5
redesigns per day for free.
</div>
<button
onClick={() => signIn("google")}
Expand Down
66 changes: 66 additions & 0 deletions prisma/migrations/20230310013453_initial/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
-- CreateTable
CREATE TABLE "Account" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"type" TEXT NOT NULL,
"provider" TEXT NOT NULL,
"providerAccountId" TEXT NOT NULL,
"refresh_token" TEXT,
"access_token" TEXT,
"expires_at" INTEGER,
"token_type" TEXT,
"scope" TEXT,
"id_token" TEXT,
"session_state" TEXT,

CONSTRAINT "Account_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Session" (
"id" TEXT NOT NULL,
"sessionToken" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"expires" TIMESTAMP(3) NOT NULL,

CONSTRAINT "Session_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL,
"name" TEXT,
"email" TEXT,
"emailVerified" TIMESTAMP(3),
"image" TEXT,

CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "VerificationToken" (
"identifier" TEXT NOT NULL,
"token" TEXT NOT NULL,
"expires" TIMESTAMP(3) NOT NULL
);

-- CreateIndex
CREATE UNIQUE INDEX "Account_provider_providerAccountId_key" ON "Account"("provider", "providerAccountId");

-- CreateIndex
CREATE UNIQUE INDEX "Session_sessionToken_key" ON "Session"("sessionToken");

-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");

-- CreateIndex
CREATE UNIQUE INDEX "VerificationToken_token_key" ON "VerificationToken"("token");

-- CreateIndex
CREATE UNIQUE INDEX "VerificationToken_identifier_token_key" ON "VerificationToken"("identifier", "token");

-- AddForeignKey
ALTER TABLE "Account" ADD CONSTRAINT "Account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Session" ADD CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
3 changes: 3 additions & 0 deletions prisma/migrations/migration_lock.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"

0 comments on commit 78e3def

Please sign in to comment.