diff --git a/README.md b/README.md index 77951b4..2a38e05 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ This Turborepo includes the following packages and apps: - `@repo/ui`: shared UI components for frontend use. - A dummy React UI library (which contains `` and `` components) - And shadcn/ui components (which contains ` + + + + + + + + {children} + + + ); } diff --git a/apps/next-template/src/middleware.ts b/apps/next-template/src/middleware.ts new file mode 100644 index 0000000..800429b --- /dev/null +++ b/apps/next-template/src/middleware.ts @@ -0,0 +1,28 @@ +import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server"; + +const isProtectedRoute = createRouteMatcher(["/clerk(.*)"]); + +export default clerkMiddleware(async (auth, req) => { + // Uncomment the following line to enable Clerk's default behavior | Redirect to sign-in page if the user is not authenticated + // if (isProtectedRoute(req)) await auth.protect(); + + // More control over authentication flow + const { userId, redirectToSignIn } = await auth(); + + if (!userId && isProtectedRoute(req)) { + // Add custom logic to run before redirecting + console.log( + "User is not authenticated, redirecting to sign-in page..." + ); + return redirectToSignIn(); + } +}); + +export const config = { + matcher: [ + // Skip Next.js internals and all static files, unless found in search params + "/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)", + // Always run for API routes + "/(api|trpc)(.*)", + ], +}; diff --git a/apps/remix-template/.env.example b/apps/remix-template/.env.example new file mode 100644 index 0000000..379149b --- /dev/null +++ b/apps/remix-template/.env.example @@ -0,0 +1,2 @@ +CLERK_PUBLISHABLE_KEY= +CLERK_SECRET_KEY= \ No newline at end of file diff --git a/apps/remix-template/app/root.tsx b/apps/remix-template/app/root.tsx index 5fc8e46..b6d7be6 100644 --- a/apps/remix-template/app/root.tsx +++ b/apps/remix-template/app/root.tsx @@ -6,9 +6,15 @@ import { ScrollRestoration, } from "@remix-run/react"; import { Analytics } from "@vercel/analytics/react"; + import "@repo/ui/styles/styles.css"; import "@repo/ui/styles/global.css"; +import type { LoaderFunction } from "@remix-run/node"; +import { rootAuthLoader } from "@clerk/remix/ssr.server"; +import { ClerkApp } from "@clerk/remix"; +export const loader: LoaderFunction = (args) => rootAuthLoader(args); + export function Layout({ children }: { children: React.ReactNode }) { return ( @@ -31,6 +37,8 @@ export function Layout({ children }: { children: React.ReactNode }) { ); } -export default function App() { +export function App() { return ; } + +export default ClerkApp(App); diff --git a/apps/remix-template/app/routes/clerk._index.tsx b/apps/remix-template/app/routes/clerk._index.tsx new file mode 100644 index 0000000..89ed32d --- /dev/null +++ b/apps/remix-template/app/routes/clerk._index.tsx @@ -0,0 +1,40 @@ +import { SignInButton, UserButton, SignedIn, SignedOut } from "@clerk/remix"; +import { + Card, + CardContent, + CardHeader, + CardTitle, +} from "@repo/ui/components/card"; +import { Button } from "@repo/ui/components/button"; + +export default function Index() { + return ( +
+ + + Welcome + + + +
+

+ You are signed in! +

+ +
+
+ +
+

+ You are signed out +

+ + + +
+
+
+
+
+ ); +} diff --git a/apps/remix-template/app/routes/clerk.tsx b/apps/remix-template/app/routes/clerk.tsx new file mode 100644 index 0000000..15c1afe --- /dev/null +++ b/apps/remix-template/app/routes/clerk.tsx @@ -0,0 +1,24 @@ +import { SignInButton, UserButton, SignedIn, SignedOut } from "@clerk/remix"; +import { Button } from "@repo/ui/components/button"; +import { Outlet } from "@remix-run/react"; + +export default function Index() { + return ( +
+
+
+ + + + + + + + +
+
+ + +
+ ); +} diff --git a/apps/remix-template/package.json b/apps/remix-template/package.json index ff13669..c1f947a 100644 --- a/apps/remix-template/package.json +++ b/apps/remix-template/package.json @@ -11,10 +11,12 @@ "lint": "eslint app/ --max-warnings 0" }, "dependencies": { + "@clerk/remix": "^4.8.1", "@radix-ui/react-slot": "^1.2.3", "@remix-run/node": "^2.15.2", "@remix-run/react": "^2.15.2", "@remix-run/server-runtime": "^2.15.2", + "@repo/auth": "*", "@repo/ui": "*", "@vercel/analytics": "^1.5.0", "@vercel/remix": "2.16.6", diff --git a/apps/vite-template/.env.example b/apps/vite-template/.env.example new file mode 100644 index 0000000..a32bad2 --- /dev/null +++ b/apps/vite-template/.env.example @@ -0,0 +1 @@ +VITE_CLERK_PUBLISHABLE_KEY= \ No newline at end of file diff --git a/apps/vite-template/package.json b/apps/vite-template/package.json index c039e03..cdc9fe0 100644 --- a/apps/vite-template/package.json +++ b/apps/vite-template/package.json @@ -10,6 +10,7 @@ "lint": "eslint src/ --max-warnings 0" }, "dependencies": { + "@clerk/clerk-react": "^5.32.0", "@repo/ui": "*", "react": "^18.3.1", "react-dom": "^18.3.1" diff --git a/apps/vite-template/src/app/index.tsx b/apps/vite-template/src/app/index.tsx index 70d0076..ad4be23 100644 --- a/apps/vite-template/src/app/index.tsx +++ b/apps/vite-template/src/app/index.tsx @@ -10,33 +10,66 @@ import { CardHeader, CardTitle, } from "@repo/ui/components/card"; +import { + SignedIn, + SignedOut, + SignInButton, + UserButton, +} from "@clerk/clerk-react"; function App() { return ( -
-

- Admin
- Kitchen Sink -

- - - - shadcn/ui Card Example - - - - - -

- Built With{" "} - - Turborepo - - {" & "} - - Vite - -

+
+
+
+ + + + + + + + +
+
+ +
+

+ Admin
+ Kitchen Sink +

+ + + + + shadcn/ui Card Example + + + + + + + + + Clerk Authentication Example + + + You are signed out! + You are signed in! + + + +

+ Built With{" "} + + Turborepo + + {" & "} + + Vite + +

+
); } diff --git a/apps/vite-template/src/main.tsx b/apps/vite-template/src/main.tsx index 4582464..04b9577 100644 --- a/apps/vite-template/src/main.tsx +++ b/apps/vite-template/src/main.tsx @@ -2,15 +2,26 @@ import React from "react"; import { createRoot } from "react-dom/client"; import App from "./app"; import "./index.css"; +import { ClerkProvider } from "@clerk/clerk-react"; + +const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY; + +if (!PUBLISHABLE_KEY) { + throw new Error( + "VITE_PUBLISHABLE_KEY is not defined. Please set it in your environment variables." + ); +} const el = document.getElementById("root"); if (el) { - const root = createRoot(el); - root.render( - - - - ); + const root = createRoot(el); + root.render( + + + + + + ); } else { - throw new Error("Could not find root element"); + throw new Error("Could not find root element"); } diff --git a/package-lock.json b/package-lock.json index cf44244..e1ab148 100644 --- a/package-lock.json +++ b/package-lock.json @@ -125,6 +125,7 @@ "apps/next-template": { "version": "0.0.0", "dependencies": { + "@clerk/nextjs": "^6.22.0", "@repo/logger": "*", "@repo/ui": "*", "next": "^15.3.0", @@ -166,10 +167,12 @@ "apps/remix-template": { "version": "0.0.0", "dependencies": { + "@clerk/remix": "^4.8.1", "@radix-ui/react-slot": "^1.2.3", "@remix-run/node": "^2.15.2", "@remix-run/react": "^2.15.2", "@remix-run/server-runtime": "^2.15.2", + "@repo/auth": "*", "@repo/ui": "*", "@vercel/analytics": "^1.5.0", "@vercel/remix": "2.16.6", @@ -274,6 +277,7 @@ "apps/vite-template": { "version": "0.0.0", "dependencies": { + "@clerk/clerk-react": "^5.32.0", "@repo/ui": "*", "react": "^18.3.1", "react-dom": "^18.3.1" @@ -1034,6 +1038,146 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "license": "MIT" }, + "node_modules/@clerk/backend": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@clerk/backend/-/backend-2.1.0.tgz", + "integrity": "sha512-Ltb3IzdGeahM1Jr+u0UAVnVjEIYXUsq9/mTb1adolsOc9oR2LCKHE7rTRnmkwY8y+IwCzXVuywIYW+zLTk47+Q==", + "license": "MIT", + "dependencies": { + "@clerk/shared": "^3.9.7", + "@clerk/types": "^4.60.1", + "cookie": "1.0.2", + "snakecase-keys": "8.0.1", + "tslib": "2.8.1" + }, + "engines": { + "node": ">=18.17.0" + } + }, + "node_modules/@clerk/backend/node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@clerk/clerk-react": { + "version": "5.32.0", + "resolved": "https://registry.npmjs.org/@clerk/clerk-react/-/clerk-react-5.32.0.tgz", + "integrity": "sha512-RdipOVBdbUbFaDb8kF3EzhJw0eh5LPxSWWRTu4k+pOdRB1gzETiToLchj5nDWFkl8qW/uL4gQbZH+Pfc7izO0A==", + "license": "MIT", + "dependencies": { + "@clerk/shared": "^3.9.7", + "@clerk/types": "^4.60.1", + "tslib": "2.8.1" + }, + "engines": { + "node": ">=18.17.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-0", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0" + } + }, + "node_modules/@clerk/nextjs": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/@clerk/nextjs/-/nextjs-6.22.0.tgz", + "integrity": "sha512-Lh+hq4iuvuSgiWSDHDM9BAM8+YZU/wtADGo2TAU7FBVEZ6I3SwyXo5JEY4F7s30TpH3kS9qC/Ye3YA6VIOOu7Q==", + "license": "MIT", + "dependencies": { + "@clerk/backend": "^2.1.0", + "@clerk/clerk-react": "^5.32.0", + "@clerk/shared": "^3.9.7", + "@clerk/types": "^4.60.1", + "server-only": "0.0.1", + "tslib": "2.8.1" + }, + "engines": { + "node": ">=18.17.0" + }, + "peerDependencies": { + "next": "^13.5.7 || ^14.2.25 || ^15.2.3", + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-0", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0" + } + }, + "node_modules/@clerk/remix": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@clerk/remix/-/remix-4.8.1.tgz", + "integrity": "sha512-QOK9tuijOrAzRDo8Cy+d4PqQfVChXr93+RyozI1gLlCOwTVtJHhlxUhWeR3hg+w+QRmuilSgv99odGwaEre4WQ==", + "license": "MIT", + "dependencies": { + "@clerk/backend": "^2.1.0", + "@clerk/clerk-react": "^5.32.0", + "@clerk/shared": "^3.9.7", + "@clerk/types": "^4.60.1", + "cookie": "0.7.2", + "tslib": "2.8.1" + }, + "engines": { + "node": ">=18.17.0" + }, + "peerDependencies": { + "@remix-run/react": "^2.0.0", + "@remix-run/server-runtime": "^2.0.0", + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-0", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0", + "react-router": "^6.0.0" + } + }, + "node_modules/@clerk/remix/node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@clerk/shared": { + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/@clerk/shared/-/shared-3.9.7.tgz", + "integrity": "sha512-D3iuzuDoadK6BKb7qFZEH332z4Sl5mxLuHMf8rKdIMHuOu1RQK0RqFJtKPcFvDxq0RvJ9MC+rK24P2Sa2tOoNA==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@clerk/types": "^4.60.1", + "dequal": "2.0.3", + "glob-to-regexp": "0.4.1", + "js-cookie": "3.0.5", + "std-env": "^3.9.0", + "swr": "^2.3.3" + }, + "engines": { + "node": ">=18.17.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-0", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/@clerk/types": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@clerk/types/-/types-4.60.1.tgz", + "integrity": "sha512-Lbt0/Q9W9BJtGz1IITdmeqal7y1zp9EaxOEMvsTEDhOxKf/0F/M1d0gJmHEU0puQzYPp9zJsIWC2yJjbgy3Y3Q==", + "license": "MIT", + "dependencies": { + "csstype": "3.1.3" + }, + "engines": { + "node": ">=18.17.0" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -3525,6 +3669,10 @@ "web-streams-polyfill": "^3.1.1" } }, + "node_modules/@repo/auth": { + "resolved": "packages/auth", + "link": true + }, "node_modules/@repo/eslint-config": { "resolved": "packages/config-eslint", "link": true @@ -7663,6 +7811,16 @@ "node": ">=12" } }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/dotenv": { "version": "16.5.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz", @@ -9409,6 +9567,12 @@ "node": ">= 6" } }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "license": "BSD-2-Clause" + }, "node_modules/globals": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/globals/-/globals-16.2.0.tgz", @@ -11333,6 +11497,15 @@ "node": ">=10" } }, + "node_modules/js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -11936,6 +12109,15 @@ "loose-envify": "cli.js" } }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -11994,6 +12176,18 @@ "tmpl": "1.0.5" } }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/markdown-extensions": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz", @@ -13363,6 +13557,16 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -15276,6 +15480,12 @@ "node": ">= 0.8.0" } }, + "node_modules/server-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz", + "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==", + "license": "MIT" + }, "node_modules/set-cookie-parser": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", @@ -15509,6 +15719,42 @@ "node": ">=8" } }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/snakecase-keys": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-8.0.1.tgz", + "integrity": "sha512-Sj51kE1zC7zh6TDlNNz0/Jn1n5HiHdoQErxO8jLtnyrkJW/M5PrI7x05uDgY3BO7OUQYKCvmeMurW6BPUdwEOw==", + "license": "MIT", + "dependencies": { + "map-obj": "^4.1.0", + "snake-case": "^3.0.4", + "type-fest": "^4.15.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/snakecase-keys/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -15636,6 +15882,12 @@ "node": ">= 0.8" } }, + "node_modules/std-env": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", + "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", + "license": "MIT" + }, "node_modules/stdin-discarder": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", @@ -16097,6 +16349,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swr": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.3.tgz", + "integrity": "sha512-dshNvs3ExOqtZ6kJBaAsabhPdHyeY4P2cKwRCniDVifBMoG/SVI7tfLWqPXriVspf2Rg4tPzXJTnwaihIeFw2A==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -17880,6 +18145,15 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", + "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", @@ -19062,6 +19336,11 @@ "url": "https://github.com/sponsors/wooorm" } }, + "packages/auth": { + "name": "@repo/auth", + "version": "0.0.0", + "license": "MIT" + }, "packages/config-eslint": { "name": "@repo/eslint-config", "version": "0.0.0", diff --git a/packages/auth/README.md b/packages/auth/README.md new file mode 100644 index 0000000..f418299 --- /dev/null +++ b/packages/auth/README.md @@ -0,0 +1,5 @@ +# @repo/auth + +Helper tools package for Clerk authentication. As of now, this helper package is not being used anywhere in the repo. + +Due to Clerk's implementations for different frameworks, each app (Next.js, Remix, etc.) have its own Clerk setup. This package is intended to provide shared utilities and types that can be used across these implementations. diff --git a/packages/auth/helpers.ts b/packages/auth/helpers.ts new file mode 100644 index 0000000..625ec6b --- /dev/null +++ b/packages/auth/helpers.ts @@ -0,0 +1,3 @@ +export function hasRole(userRoles: string[], role: string): boolean { + return userRoles.includes(role); +} diff --git a/packages/auth/index.ts b/packages/auth/index.ts new file mode 100644 index 0000000..836ce67 --- /dev/null +++ b/packages/auth/index.ts @@ -0,0 +1,2 @@ +export * from "./roles"; +export * from "./helpers"; diff --git a/packages/auth/package.json b/packages/auth/package.json new file mode 100644 index 0000000..77eabf1 --- /dev/null +++ b/packages/auth/package.json @@ -0,0 +1,12 @@ +{ + "name": "@repo/auth", + "version": "0.0.0", + "author": "Afiq Zudin Hadi", + "private": true, + "license": "MIT", + "main": "index.ts", + "type": "module", + "exports": { + "./indext.ts": "./index.ts" + } +} diff --git a/packages/auth/roles.ts b/packages/auth/roles.ts new file mode 100644 index 0000000..04c1a9d --- /dev/null +++ b/packages/auth/roles.ts @@ -0,0 +1,5 @@ +export const ROLES = Object.freeze({ + SUPER_ADMIN: "super_admin", + ADMIN: "admin", + USER: "user", +}); diff --git a/packages/auth/tsconfig.json b/packages/auth/tsconfig.json new file mode 100644 index 0000000..b745739 --- /dev/null +++ b/packages/auth/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "@repo/typescript-config/base.json", + "compilerOptions": { + "lib": ["dom", "ES2015"], + "sourceMap": true, + "types": ["jest", "node"], + "baseUrl": ".", + "paths": { + "@repo/auth/index.ts": ["./index.ts"] + } + }, + "include": [".", "src"], + "exclude": ["dist", "build", "node_modules"] +}