From 7d1b5ceb0d79ab8428750f68e7f105bf662696b0 Mon Sep 17 00:00:00 2001 From: Shubbu03 Date: Mon, 23 Jun 2025 22:10:15 +0530 Subject: Completed the getVideoInfo func according to the comment specified --- apps/web/src/lib/ffmpeg-utils.ts | 52 ++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 13 deletions(-) (limited to 'apps/web/src/lib') diff --git a/apps/web/src/lib/ffmpeg-utils.ts b/apps/web/src/lib/ffmpeg-utils.ts index 56085a21..de203fd6 100644 --- a/apps/web/src/lib/ffmpeg-utils.ts +++ b/apps/web/src/lib/ffmpeg-utils.ts @@ -102,26 +102,52 @@ export const getVideoInfo = async (videoFile: File): Promise<{ fps: number; }> => { const ffmpeg = await initFFmpeg(); - + const inputName = 'input.mp4'; - + // Write input file await ffmpeg.writeFile(inputName, new Uint8Array(await videoFile.arrayBuffer())); - - // Get video info + + // Capture FFmpeg stderr output + let ffmpegOutput = ''; + const listener = (data: string) => { + ffmpegOutput += data; + }; + ffmpeg.on('log', ({ message }) => listener(message)); + + // Run ffmpeg to get info (stderr will contain the info) await ffmpeg.exec(['-i', inputName, '-f', 'null', '-']); - - // Note: In a real implementation, you'd parse the FFmpeg output - // For now, we'll return default values and enhance this later - + + // Remove listener + // (No off() method in ffmpeg.wasm, so this is a no-op, but included for clarity) + // Cleanup await ffmpeg.deleteFile(inputName); - + + // Parse output for duration, resolution, and fps + // Example: Duration: 00:00:10.00, start: 0.000000, bitrate: 1234 kb/s + // Example: Stream #0:0: Video: h264 (High), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 30 fps, 30 tbr, 90k tbn, 60 tbc + + const durationMatch = ffmpegOutput.match(/Duration: (\d+):(\d+):([\d.]+)/); + let duration = 0; + if (durationMatch) { + const [, h, m, s] = durationMatch; + duration = parseInt(h) * 3600 + parseInt(m) * 60 + parseFloat(s); + } + + const videoStreamMatch = ffmpegOutput.match(/Video:.* (\d+)x(\d+)[^,]*, ([\d.]+) fps/); + let width = 0, height = 0, fps = 0; + if (videoStreamMatch) { + width = parseInt(videoStreamMatch[1]); + height = parseInt(videoStreamMatch[2]); + fps = parseFloat(videoStreamMatch[3]); + } + return { - duration: 10, // Placeholder - would parse from FFmpeg output - width: 1920, // Placeholder - height: 1080, // Placeholder - fps: 30 // Placeholder + duration, + width, + height, + fps }; }; -- cgit v1.3.1 From 6a701ee8c064a4652db475c93ee89c3ffe112986 Mon Sep 17 00:00:00 2001 From: Shubbu03 Date: Mon, 23 Jun 2025 22:22:43 +0530 Subject: better error handling --- apps/web/src/lib/ffmpeg-utils.ts | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'apps/web/src/lib') diff --git a/apps/web/src/lib/ffmpeg-utils.ts b/apps/web/src/lib/ffmpeg-utils.ts index de203fd6..ae0c267b 100644 --- a/apps/web/src/lib/ffmpeg-utils.ts +++ b/apps/web/src/lib/ffmpeg-utils.ts @@ -108,18 +108,26 @@ export const getVideoInfo = async (videoFile: File): Promise<{ // Write input file await ffmpeg.writeFile(inputName, new Uint8Array(await videoFile.arrayBuffer())); - // Capture FFmpeg stderr output + // Capture FFmpeg stderr output with a one-time listener pattern let ffmpegOutput = ''; + let listening = true; const listener = (data: string) => { - ffmpegOutput += data; + if (listening) ffmpegOutput += data; }; ffmpeg.on('log', ({ message }) => listener(message)); // Run ffmpeg to get info (stderr will contain the info) - await ffmpeg.exec(['-i', inputName, '-f', 'null', '-']); + try { + await ffmpeg.exec(['-i', inputName, '-f', 'null', '-']); + } catch (error) { + listening = false; + await ffmpeg.deleteFile(inputName); + console.error('FFmpeg execution failed:', error); + throw new Error('Failed to extract video info. The file may be corrupted or in an unsupported format.'); + } - // Remove listener - // (No off() method in ffmpeg.wasm, so this is a no-op, but included for clarity) + // Disable listener after exec completes + listening = false; // Cleanup await ffmpeg.deleteFile(inputName); @@ -220,4 +228,4 @@ export const extractAudio = async ( await ffmpeg.deleteFile(outputName); return blob; -}; \ No newline at end of file +}; \ No newline at end of file -- cgit v1.3.1 From 8bcd226bdb4eb3468df0590dbe6d3d8d68b2acbd Mon Sep 17 00:00:00 2001 From: Deepanshu Mishra Date: Mon, 23 Jun 2025 22:51:34 +0530 Subject: Added google auth and some auth page ui optimisations --- apps/web/.env.example | 6 +- apps/web/src/app/auth/login/page.tsx | 134 ++++++++++++++++++++-------- apps/web/src/app/auth/signup/page.tsx | 163 ++++++++++++++++++++++++---------- apps/web/src/components/header.tsx | 4 +- apps/web/src/components/icons.tsx | 22 +++++ apps/web/src/lib/auth-client.ts | 2 +- apps/web/src/lib/auth.ts | 6 ++ 7 files changed, 254 insertions(+), 83 deletions(-) create mode 100644 apps/web/src/components/icons.tsx (limited to 'apps/web/src/lib') diff --git a/apps/web/.env.example b/apps/web/.env.example index 8477646c..0b4c649b 100644 --- a/apps/web/.env.example +++ b/apps/web/.env.example @@ -7,9 +7,13 @@ DATABASE_URL="postgresql://opencut:opencutthegoat@localhost:5432/opencut" BETTER_AUTH_URL=http://localhost:3000 BETTER_AUTH_SECRET=your-secret-key-here +#Google Clients +GOOGLE_CLIENT_ID= +GOOGLE_CLIENT_SECRET= + # Development Environment NODE_ENV=development # Redis UPSTASH_REDIS_REST_URL=http://localhost:8079 -UPSTASH_REDIS_REST_TOKEN=example_token \ No newline at end of file +UPSTASH_REDIS_REST_TOKEN=example_token diff --git a/apps/web/src/app/auth/login/page.tsx b/apps/web/src/app/auth/login/page.tsx index 5eadb85c..ebf2eb3f 100644 --- a/apps/web/src/app/auth/login/page.tsx +++ b/apps/web/src/app/auth/login/page.tsx @@ -1,7 +1,7 @@ "use client"; -import { useSearchParams, useRouter } from "next/navigation"; -import { authClient } from "@/lib/auth-client"; +import { useRouter } from "next/navigation"; +import { signIn } from "@/lib/auth-client"; import { Button } from "@/components/ui/button"; import { Card, @@ -13,81 +13,145 @@ import { import { Suspense, useState } from "react"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; +import { Separator } from "@/components/ui/separator"; import Link from "next/link"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; +import { ArrowLeft, Loader2 } from "lucide-react"; +import { GoogleIcon } from "@/components/icons"; function LoginForm() { - const searchParams = useSearchParams(); const router = useRouter(); - const redirectUrl = searchParams.get("redirect"); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [error, setError] = useState(null); + const [isEmailLoading, setIsEmailLoading] = useState(false); + const [isGoogleLoading, setIsGoogleLoading] = useState(false); const handleLogin = async () => { setError(null); - const { error } = await authClient.signIn.email({ + setIsEmailLoading(true); + + const { error } = await signIn.email({ email, password, }); if (error) { setError(error.message || "An unexpected error occurred."); + setIsEmailLoading(false); return; } - router.push(redirectUrl || "/"); + router.push("/editor"); + }; + + const handleGoogleLogin = async () => { + setError(null); + setIsGoogleLoading(true); + + try { + await signIn.social({ + provider: "google", + }); + router.push("/editor"); + } catch (error) { + setError("Failed to sign in with Google. Please try again."); + setIsGoogleLoading(false); + } }; + const isAnyLoading = isEmailLoading || isGoogleLoading; + return ( -
+
{error && ( Error {error} )} -
- - setEmail(e.target.value)} - /> + + +
+
+ +
+
+ Or continue with +
-
- - setPassword(e.target.value)} - /> +
+
+ + setEmail(e.target.value)} + disabled={isAnyLoading} + className="h-11" + /> +
+
+ + setPassword(e.target.value)} + disabled={isAnyLoading} + className="h-11" + /> +
+
-
); } export default function LoginPage() { + const router = useRouter(); + return ( -
- - - Login - - Enter your email and password to login. +
+ + + + Welcome back + + Sign in to your account to continue - - Loading...
}> + + + +
}> -
+
Don't have an account?{" "} - + Sign up
diff --git a/apps/web/src/app/auth/signup/page.tsx b/apps/web/src/app/auth/signup/page.tsx index f328851c..3d125a07 100644 --- a/apps/web/src/app/auth/signup/page.tsx +++ b/apps/web/src/app/auth/signup/page.tsx @@ -1,7 +1,7 @@ "use client"; -import { useSearchParams, useRouter } from "next/navigation"; -import { authClient } from "@/lib/auth-client"; +import { useRouter } from "next/navigation"; +import { signUp, signIn } from "@/lib/auth-client"; import { Button } from "@/components/ui/button"; import { Card, @@ -13,21 +13,26 @@ import { import { Suspense, useState } from "react"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; +import { Separator } from "@/components/ui/separator"; import Link from "next/link"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; +import { Loader2, ArrowLeft } from "lucide-react"; +import { GoogleIcon } from "@/components/icons"; function SignUpForm() { - const searchParams = useSearchParams(); const router = useRouter(); - const redirectUrl = searchParams.get("redirect"); const [name, setName] = useState(""); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [error, setError] = useState(null); + const [isEmailLoading, setIsEmailLoading] = useState(false); + const [isGoogleLoading, setIsGoogleLoading] = useState(false); const handleSignUp = async () => { setError(null); - const { error } = await authClient.signUp.email({ + setIsEmailLoading(true); + + const { error } = await signUp.email({ name, email, password, @@ -35,70 +40,138 @@ function SignUpForm() { if (error) { setError(error.message || "An unexpected error occurred."); + setIsEmailLoading(false); return; } - router.push(redirectUrl || "/"); + router.push("/auth/login"); + }; + + const handleGoogleSignUp = async () => { + setError(null); + setIsGoogleLoading(true); + + try { + await signIn.social({ + provider: "google", + }); + + router.push("/editor"); + } catch (error) { + setError("Failed to sign up with Google. Please try again."); + setIsGoogleLoading(false); + } }; + const isAnyLoading = isEmailLoading || isGoogleLoading; + return ( -
+
{error && ( Error {error} )} -
- - setName(e.target.value)} - /> -
-
- - setEmail(e.target.value)} - /> + + + +
+
+ +
+
+ Or continue with +
-
- - setPassword(e.target.value)} - /> + +
+
+ + setName(e.target.value)} + disabled={isAnyLoading} + className="h-11" + /> +
+
+ + setEmail(e.target.value)} + disabled={isAnyLoading} + className="h-11" + /> +
+
+ + setPassword(e.target.value)} + disabled={isAnyLoading} + className="h-11" + /> +
+
-
); } export default function SignUpPage() { + const router = useRouter(); + return ( -
- - - Sign Up - Create an account to get started. +
+ + + + + Create your account + + Get started with your free account today + - - Loading...
}> + + + +
}> -
+
Already have an account?{" "} - - Login + + Sign in
diff --git a/apps/web/src/components/header.tsx b/apps/web/src/components/header.tsx index 004863d9..109d022e 100644 --- a/apps/web/src/components/header.tsx +++ b/apps/web/src/components/header.tsx @@ -5,8 +5,10 @@ import Image from "next/image"; import { Button } from "./ui/button"; import { ArrowRight } from "lucide-react"; import { HeaderBase } from "./header-base"; +import { useSession } from "@/lib/auth-client"; export function Header() { + const { data: session } = useSession(); const leftContent = ( OpenCut Logo @@ -21,7 +23,7 @@ export function Header() { GitHub - + diff --git a/apps/web/src/components/landing/hero.tsx b/apps/web/src/components/landing/hero.tsx index f2c70f5d..b2320030 100644 --- a/apps/web/src/components/landing/hero.tsx +++ b/apps/web/src/components/landing/hero.tsx @@ -7,6 +7,7 @@ import { ArrowRight } from "lucide-react"; import Link from "next/link"; import { useState } from "react"; import { useToast } from "@/hooks/use-toast"; +import { ghStars } from "@/lib/fetchGhStars"; interface HeroProps { signupCount: number; @@ -16,6 +17,7 @@ export function Hero({ signupCount }: HeroProps) { const [email, setEmail] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); const { toast } = useToast(); + const stars = ghStars(); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); @@ -152,7 +154,7 @@ export function Hero({ signupCount }: HeroProps) { href="https://github.com/OpenCut-app/OpenCut" className="text-foreground underline" > - GitHub + GitHub {stars}+
diff --git a/apps/web/src/lib/fetchGhStars.ts b/apps/web/src/lib/fetchGhStars.ts new file mode 100644 index 00000000..de3e2e80 --- /dev/null +++ b/apps/web/src/lib/fetchGhStars.ts @@ -0,0 +1,20 @@ +async function getStars(): Promise { + const res = await fetch("https://api.github.com/repos/OpenCut-app/OpenCut", { + // Cache for 1 hour (3600 seconds) + next: { revalidate: 3600 }, + }); + + const data = await res.json(); + const count = data.stargazers_count; + + if (count >= 1_000_000) + return (count / 1_000_000).toFixed(1).replace(/\.0$/, "") + "M"; + if (count >= 1_000) + return (count / 1_000).toFixed(1).replace(/\.0$/, "") + "k"; + return count.toString(); +} + +export async function ghStars() { + const stars = await getStars(); + return stars; +} -- cgit v1.3.1 From 57e42e2c4539949e93b71f1125e0c0eecb2fb5e8 Mon Sep 17 00:00:00 2001 From: Dipanshu Rawat <144578298+Jaydeeprawat17@users.noreply.github.com> Date: Tue, 24 Jun 2025 02:06:55 +0530 Subject: ref: fetch api function --- apps/web/src/components/header.tsx | 21 +++++++++++++--- apps/web/src/components/landing/hero.tsx | 21 ++++++++++++---- apps/web/src/lib/fetchGhStars.ts | 41 +++++++++++++++++++------------- 3 files changed, 60 insertions(+), 23 deletions(-) (limited to 'apps/web/src/lib') diff --git a/apps/web/src/components/header.tsx b/apps/web/src/components/header.tsx index cada527f..82e0bc55 100644 --- a/apps/web/src/components/header.tsx +++ b/apps/web/src/components/header.tsx @@ -6,12 +6,27 @@ import { Button } from "./ui/button"; import { ArrowRight } from "lucide-react"; import { HeaderBase } from "./header-base"; import { useSession } from "@/lib/auth-client"; -import { ghStars } from "@/lib/fetchGhStars"; +import { getStars } from "@/lib/fetchGhStars"; import { Star } from "lucide-react"; +import { useEffect, useState } from "react"; export function Header() { - const stars = ghStars(); const { data: session } = useSession(); + const [star, setStar] = useState(""); + + useEffect(() => { + const fetchStars = async () => { + try { + const data = await getStars(); + setStar(data); + } catch (err) { + console.error("Failed to fetch GitHub stars", err); + } + }; + + fetchStars(); + }, []); + const leftContent = ( OpenCut Logo @@ -28,7 +43,7 @@ export function Header() { > GitHub - {stars}+ + {star}+ diff --git a/apps/web/src/components/landing/hero.tsx b/apps/web/src/components/landing/hero.tsx index b2320030..5d9f3f10 100644 --- a/apps/web/src/components/landing/hero.tsx +++ b/apps/web/src/components/landing/hero.tsx @@ -5,19 +5,32 @@ import { Button } from "../ui/button"; import { Input } from "../ui/input"; import { ArrowRight } from "lucide-react"; import Link from "next/link"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { useToast } from "@/hooks/use-toast"; -import { ghStars } from "@/lib/fetchGhStars"; +import { getStars } from "@/lib/fetchGhStars"; interface HeroProps { signupCount: number; } export function Hero({ signupCount }: HeroProps) { + const [star, setStar] = useState(); const [email, setEmail] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); const { toast } = useToast(); - const stars = ghStars(); + + useEffect(() => { + const fetchStars = async () => { + try { + const data = await getStars(); + setStar(data); + } catch (err) { + console.error("Failed to fetch GitHub stars", err); + } + }; + + fetchStars(); + }, []); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); @@ -154,7 +167,7 @@ export function Hero({ signupCount }: HeroProps) { href="https://github.com/OpenCut-app/OpenCut" className="text-foreground underline" > - GitHub {stars}+ + GitHub {star}+
diff --git a/apps/web/src/lib/fetchGhStars.ts b/apps/web/src/lib/fetchGhStars.ts index de3e2e80..e0236840 100644 --- a/apps/web/src/lib/fetchGhStars.ts +++ b/apps/web/src/lib/fetchGhStars.ts @@ -1,20 +1,29 @@ -async function getStars(): Promise { - const res = await fetch("https://api.github.com/repos/OpenCut-app/OpenCut", { - // Cache for 1 hour (3600 seconds) - next: { revalidate: 3600 }, - }); +export async function getStars(): Promise { + try { + const res = await fetch( + "https://api.github.com/repos/OpenCut-app/OpenCut", + { + next: { revalidate: 3600 }, + } + ); - const data = await res.json(); - const count = data.stargazers_count; + if (!res.ok) { + throw new Error(`GitHub API error: ${res.status} ${res.statusText}`); + } + const data = await res.json(); + const count = data.stargazers_count; - if (count >= 1_000_000) - return (count / 1_000_000).toFixed(1).replace(/\.0$/, "") + "M"; - if (count >= 1_000) - return (count / 1_000).toFixed(1).replace(/\.0$/, "") + "k"; - return count.toString(); -} + if (typeof count !== "number") { + throw new Error("Invalid stargazers_count from GitHub API"); + } -export async function ghStars() { - const stars = await getStars(); - return stars; + if (count >= 1_000_000) + return (count / 1_000_000).toFixed(1).replace(/\.0$/, "") + "M"; + if (count >= 1_000) + return (count / 1_000).toFixed(1).replace(/\.0$/, "") + "k"; + return count.toString(); + } catch (error) { + console.error("Failed to fetch GitHub stars:", error); + return "1.5k"; + } } -- cgit v1.3.1 From e2872005fb0963988730317a2fdb4dce39ee47b5 Mon Sep 17 00:00:00 2001 From: Hyteq Date: Tue, 24 Jun 2025 11:27:19 +0300 Subject: feat: initial auth package --- apps/web/src/lib/db/index.tsx | 14 --------- apps/web/src/lib/db/schema.ts | 69 ------------------------------------------- 2 files changed, 83 deletions(-) delete mode 100644 apps/web/src/lib/db/index.tsx delete mode 100644 apps/web/src/lib/db/schema.ts (limited to 'apps/web/src/lib') diff --git a/apps/web/src/lib/db/index.tsx b/apps/web/src/lib/db/index.tsx deleted file mode 100644 index b66c6e39..00000000 --- a/apps/web/src/lib/db/index.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { drizzle } from "drizzle-orm/node-postgres"; -import { Pool } from "pg"; -import * as schema from "./schema"; - -const pool = new Pool({ - connectionString: process.env.DATABASE_URL, - max: 3, - idleTimeoutMillis: 10000, - connectionTimeoutMillis: 15000, - query_timeout: 20000, - statement_timeout: 20000, -}); - -export const db = drizzle(pool, { schema }); diff --git a/apps/web/src/lib/db/schema.ts b/apps/web/src/lib/db/schema.ts deleted file mode 100644 index 7c38724a..00000000 --- a/apps/web/src/lib/db/schema.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { pgTable, text, timestamp, boolean } from "drizzle-orm/pg-core"; - -export const users = pgTable("users", { - id: text("id").primaryKey(), - name: text("name").notNull(), - email: text("email").notNull().unique(), - emailVerified: boolean("email_verified") - .$defaultFn(() => false) - .notNull(), - image: text("image"), - createdAt: timestamp("created_at") - .$defaultFn(() => /* @__PURE__ */ new Date()) - .notNull(), - updatedAt: timestamp("updated_at") - .$defaultFn(() => /* @__PURE__ */ new Date()) - .notNull(), -}).enableRLS(); - -export const sessions = pgTable("sessions", { - id: text("id").primaryKey(), - expiresAt: timestamp("expires_at").notNull(), - token: text("token").notNull().unique(), - createdAt: timestamp("created_at").notNull(), - updatedAt: timestamp("updated_at").notNull(), - ipAddress: text("ip_address"), - userAgent: text("user_agent"), - userId: text("user_id") - .notNull() - .references(() => users.id, { onDelete: "cascade" }), -}).enableRLS(); - -export const accounts = pgTable("accounts", { - id: text("id").primaryKey(), - accountId: text("account_id").notNull(), - providerId: text("provider_id").notNull(), - userId: text("user_id") - .notNull() - .references(() => users.id, { onDelete: "cascade" }), - accessToken: text("access_token"), - refreshToken: text("refresh_token"), - idToken: text("id_token"), - accessTokenExpiresAt: timestamp("access_token_expires_at"), - refreshTokenExpiresAt: timestamp("refresh_token_expires_at"), - scope: text("scope"), - password: text("password"), - createdAt: timestamp("created_at").notNull(), - updatedAt: timestamp("updated_at").notNull(), -}).enableRLS(); - -export const verifications = pgTable("verifications", { - id: text("id").primaryKey(), - identifier: text("identifier").notNull(), - value: text("value").notNull(), - expiresAt: timestamp("expires_at").notNull(), - createdAt: timestamp("created_at").$defaultFn( - () => /* @__PURE__ */ new Date() - ), - updatedAt: timestamp("updated_at").$defaultFn( - () => /* @__PURE__ */ new Date() - ), -}).enableRLS(); - -export const waitlist = pgTable("waitlist", { - id: text("id").primaryKey(), - email: text("email").notNull().unique(), - createdAt: timestamp("created_at") - .$defaultFn(() => /* @__PURE__ */ new Date()) - .notNull(), -}).enableRLS(); -- cgit v1.3.1 From d25e1eaa1d83617cecba822ac0fb24fe61bb3a08 Mon Sep 17 00:00:00 2001 From: Hyteq Date: Tue, 24 Jun 2025 11:29:15 +0300 Subject: feat: migrated packages properly, using packages in web app --- apps/web/package.json | 2 ++ apps/web/src/app/api/auth/[...all]/route.ts | 2 +- apps/web/src/components/auth-form.tsx | 2 +- apps/web/src/components/header.tsx | 2 +- apps/web/src/lib/auth-client.ts | 4 ---- apps/web/src/lib/auth.ts | 29 ---------------------------- bun.lockb | Bin 200656 -> 201960 bytes 7 files changed, 5 insertions(+), 36 deletions(-) delete mode 100644 apps/web/src/lib/auth-client.ts delete mode 100644 apps/web/src/lib/auth.ts (limited to 'apps/web/src/lib') diff --git a/apps/web/package.json b/apps/web/package.json index b66a8eeb..ed08734e 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -19,6 +19,8 @@ "@ffmpeg/util": "^0.12.2", "@hello-pangea/dnd": "^18.0.1", "@hookform/resolvers": "^3.9.1", + "@opencut/auth": "workspace:*", + "@opencut/db": "workspace:*", "@types/pg": "^8.15.4", "@upstash/ratelimit": "^2.0.5", "@upstash/redis": "^1.35.0", diff --git a/apps/web/src/app/api/auth/[...all]/route.ts b/apps/web/src/app/api/auth/[...all]/route.ts index 1fb57443..393fb7e7 100644 --- a/apps/web/src/app/api/auth/[...all]/route.ts +++ b/apps/web/src/app/api/auth/[...all]/route.ts @@ -1,4 +1,4 @@ -import { auth } from "@/lib/auth"; +import { auth } from "@opencut/auth/server"; import { toNextJsHandler } from "better-auth/next-js"; export const { POST, GET } = toNextJsHandler(auth); \ No newline at end of file diff --git a/apps/web/src/components/auth-form.tsx b/apps/web/src/components/auth-form.tsx index 3dd56036..72bddd3d 100644 --- a/apps/web/src/components/auth-form.tsx +++ b/apps/web/src/components/auth-form.tsx @@ -1,7 +1,7 @@ "use client"; import { useRouter } from "next/navigation"; -import { signUp, signIn } from "@/lib/auth-client"; +import { signUp, signIn } from "@opencut/auth/client"; import { Button } from "@/components/ui/button"; import { Card, diff --git a/apps/web/src/components/header.tsx b/apps/web/src/components/header.tsx index 9f842b24..d1e0518f 100644 --- a/apps/web/src/components/header.tsx +++ b/apps/web/src/components/header.tsx @@ -5,7 +5,7 @@ import Image from "next/image"; import { Button } from "./ui/button"; import { ArrowRight } from "lucide-react"; import { HeaderBase } from "./header-base"; -import { useSession } from "@/lib/auth-client"; +import { useSession } from "@opencut/auth/client"; import { getStars } from "@/lib/fetchGhStars"; import { Star } from "lucide-react"; import { useEffect, useState } from "react"; diff --git a/apps/web/src/lib/auth-client.ts b/apps/web/src/lib/auth-client.ts deleted file mode 100644 index 1ab4e636..00000000 --- a/apps/web/src/lib/auth-client.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { createAuthClient } from "better-auth/react"; -export const { signIn, signUp, useSession } = createAuthClient({ - baseURL: process.env.NEXT_PUBLIC_BETTER_AUTH_URL!, -}); diff --git a/apps/web/src/lib/auth.ts b/apps/web/src/lib/auth.ts deleted file mode 100644 index d0175c97..00000000 --- a/apps/web/src/lib/auth.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { betterAuth } from "better-auth"; -import { drizzleAdapter } from "better-auth/adapters/drizzle"; -import { db } from "./db"; - -export const auth = betterAuth({ - database: drizzleAdapter(db, { - provider: "pg", - usePlural: true, - }), - secret: process.env.BETTER_AUTH_SECRET!, - user: { - deleteUser: { - enabled: true, - }, - }, - emailAndPassword: { - enabled: true, - }, - socialProviders: { - google: { - clientId: process.env.GOOGLE_CLIENT_ID as string, - clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, - }, - }, - appName: "OpenCut", - trustedOrigins: ["http://localhost:3000"], -}); - -export type Auth = typeof auth; diff --git a/bun.lockb b/bun.lockb index 2f51e8f2..2871b5e6 100644 Binary files a/bun.lockb and b/bun.lockb differ -- cgit v1.3.1