diff --git a/app/api/github/route.ts b/app/api/github/route.ts index be5a6b7..5064466 100644 --- a/app/api/github/route.ts +++ b/app/api/github/route.ts @@ -1,7 +1,7 @@ import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; import createOctokitInstance from "../../../lib/createOctokitInstance"; -import { auth } from "@clerk/nextjs"; +import { auth } from "@clerk/nextjs/server"; /** * Handles GitHub API requests and responses. diff --git a/app/api/star-history/route.ts b/app/api/star-history/route.ts index 7325129..b0dfd3a 100644 --- a/app/api/star-history/route.ts +++ b/app/api/star-history/route.ts @@ -1,6 +1,6 @@ import { NextRequest, NextResponse } from "next/server"; import createOctokitInstance from "../../../lib/createOctokitInstance"; -import { auth } from "@clerk/nextjs"; +import { auth } from "@clerk/nextjs/server"; /** * Fetches stargazers for a GitHub repo from the GitHub API. diff --git a/app/auth/profile/page.tsx b/app/auth/profile/page.tsx index ecdaf79..3c2f69f 100644 --- a/app/auth/profile/page.tsx +++ b/app/auth/profile/page.tsx @@ -11,13 +11,13 @@ import { Tooltip, } from "@radix-ui/themes"; import { useEffect } from "react"; -import { useUser } from "@clerk/nextjs"; import FaqAccordion from "@/components/auth/FaqAccordion"; import { convertUnixTimestampToDate, getSiteUrl } from "@/lib/utils"; import { GoEyeClosed } from "react-icons/go"; import { GoEye } from "react-icons/go"; import Link from "next/link"; import { Endpoints } from "@octokit/types"; +import { useUser } from "@clerk/nextjs"; export default function Page() { const { user } = useUser(); diff --git a/app/layout.tsx b/app/layout.tsx index 79daf74..514bd26 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -89,12 +89,6 @@ export default function RootLayout({ }} > - - - diff --git a/bun.lockb b/bun.lockb index d8a5f69..32c3c15 100644 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/lib/createOctokitInstance.ts b/lib/createOctokitInstance.ts index b9a0fc6..0436da9 100644 --- a/lib/createOctokitInstance.ts +++ b/lib/createOctokitInstance.ts @@ -1,5 +1,5 @@ +import { clerkClient } from "@clerk/nextjs/server"; import { Octokit } from "octokit"; -import { clerkClient } from "@clerk/nextjs"; export default async function createOctokitInstance(userId?: string) { let auth; diff --git a/middleware.ts b/middleware.ts index aac0de8..c2af013 100644 --- a/middleware.ts +++ b/middleware.ts @@ -1,29 +1,16 @@ -import { authMiddleware } from "@clerk/nextjs"; +import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server"; -/** - * Configures authentication middleware with public and ignored routes. - * - * @param config - Configuration object with `publicRoutes` and `ignoredRoutes` arrays. - * `publicRoutes` defines routes that can be accessed while signed out. - * `ignoredRoutes` defines routes that can always be accessed without authentication. - */ -export default authMiddleware({ - // Routes that can be accessed while signed out - publicRoutes: [ - "/", - "/:username", - "/api/github", - "/api/star-history", - "/blog/:postId", - ], - // Routes that can always be accessed, and have - // no authentication information - ignoredRoutes: [""], +const isDashboardRoute = createRouteMatcher(["/dashboard(.*)"]); +const isAdminRoute = createRouteMatcher(["/admin(.*)"]); + +export default clerkMiddleware((auth, req) => { + // Restrict admin route to users with specific role + if (isAdminRoute(req)) auth().protect({ role: "org:admin" }); + + // Restrict dashboard routes to signed in users + if (isDashboardRoute(req)) auth().protect(); }); export const config = { - // Protects all routes, including api/trpc. - // See https://clerk.com/docs/references/nextjs/auth-middleware - // for more information about configuring your Middleware - matcher: ["/((?!.+\\.[\\w]+$|_next).*)", "/", "/(api|trpc)(.*)"], + matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"], }; diff --git a/package.json b/package.json index edeeee3..041b5f5 100644 --- a/package.json +++ b/package.json @@ -9,66 +9,66 @@ "lint": "next lint" }, "dependencies": { - "@clerk/nextjs": "^4.29.9", - "@clerk/themes": "^1.7.9", + "@clerk/nextjs": "^5.1.0", + "@clerk/themes": "1.7.15", "@emotion/react": "^11.11.4", - "@emotion/styled": "^11.11.0", - "@hookform/resolvers": "^3.3.4", - "@mui/material": "^5.15.12", - "@mui/x-charts": "^6.19.5", - "@mui/x-data-grid": "^6.19.6", - "@next/third-parties": "^14.1.0", + "@emotion/styled": "11.11.5", + "@hookform/resolvers": "3.4.2", + "@mui/material": "5.15.18", + "@mui/x-charts": "6.19.8", + "@mui/x-data-grid": "6.19.11", + "@next/third-parties": "14.2.3", "@octokit/types": "^12.6.0", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-select": "^2.0.0", "@radix-ui/themes": "^2.0.3", - "@tanstack/react-table": "^8.12.0", - "@uiw/react-json-view": "^2.0.0-alpha.18", - "@uiw/react-markdown-preview": "^5.0.7", + "@tanstack/react-table": "8.17.3", + "@uiw/react-json-view": "2.0.0-alpha.24", + "@uiw/react-markdown-preview": "5.1.1", "@vercel/analytics": "^1.2.2", "@vercel/speed-insights": "^1.0.10", "class-variance-authority": "^0.7.0", - "clsx": "^2.1.0", + "clsx": "2.1.1", "cmdk": "^0.2.1", - "date-fns": "^3.3.1", + "date-fns": "3.6.0", "gray-matter": "^4.0.3", "install": "^0.13.0", "lodash": "^4.17.21", "lucide-react": "^0.344.0", - "next": "14.1.3", + "next": "^14.2.3", "next-themes": "^0.2.1", "nextjs-google-adsense": "^1.0.0", - "npm": "^10.5.0", - "octokit": "^3.1.2", - "react": "^18.2.0", - "react-day-picker": "^8.10.0", - "react-dom": "^18.2.0", - "react-hook-form": "^7.50.1", - "react-icons": "^5.0.1", - "react-json-view-lite": "^1.2.1", + "npm": "10.8.0", + "octokit": "3.2.1", + "react": "18.3.1", + "react-day-picker": "8.10.1", + "react-dom": "18.3.1", + "react-hook-form": "7.51.5", + "react-icons": "5.2.1", + "react-json-view-lite": "1.4.0", "react-markdown": "^9.0.1", "remark": "^15.0.1", "remark-html": "^16.0.1", - "sonner": "^1.4.3", - "tailwind-merge": "^2.2.1", + "sonner": "1.4.41", + "tailwind-merge": "2.3.0", "tailwindcss-animate": "^1.0.7", - "vaul": "^0.9.0", + "vaul": "0.9.1", "virtua": "^0.28.0", - "zod": "^3.22.4" + "zod": "3.23.8" }, "devDependencies": { - "@types/lodash": "^4.14.202", - "@types/node": "^20.11.25", - "@types/react": "^18.2.57", - "@types/react-dom": "^18.2.19", + "@types/lodash": "4.17.4", + "@types/node": "20.12.12", + "@types/react": "18.3.2", + "@types/react-dom": "18.3.0", "@types/react-window": "^1.8.8", - "autoprefixer": "^10.4.17", + "autoprefixer": "10.4.19", "eslint": "^8.57.0", "eslint-config-next": "14.1.1", - "postcss": "^8.4.35", + "postcss": "8.4.38", "prettier": "^3.2.5", - "prettier-plugin-tailwindcss": "^0.5.11", - "tailwindcss": "^3.4.1", - "typescript": "^5.3.3" + "prettier-plugin-tailwindcss": "0.5.14", + "tailwindcss": "3.4.3", + "typescript": "5.4.5" } -} +} \ No newline at end of file