From 6c1a4556fb18a9dc8c444e3f35a7d4c6b21b1239 Mon Sep 17 00:00:00 2001 From: Sarah Shader Date: Mon, 10 Feb 2025 13:14:27 -0800 Subject: [PATCH 1/9] Add setup script --- package.json | 3 ++- setup.mjs | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 setup.mjs diff --git a/package.json b/package.json index 5c8df57..ad7c0fa 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "dev": "npm-run-all --parallel dev:frontend dev:backend", "dev:frontend": "vite --open", "dev:backend": "convex dev", - "predev": "convex dev --until-success && convex dashboard", + "predev": "convex dev --until-success && convex dev --once --run-sh 'node setup.mjs --once' && convex dashboard", "build": "tsc -b && vite build", "lint": "tsc && eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview" @@ -25,6 +25,7 @@ "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", "@vitejs/plugin-react": "^4.3.4", + "dotenv": "^16.4.7", "eslint": "^9.21.0", "eslint-plugin-react-hooks": "^5.1.0", "eslint-plugin-react-refresh": "^0.4.19", diff --git a/setup.mjs b/setup.mjs new file mode 100644 index 0000000..0ffb1ae --- /dev/null +++ b/setup.mjs @@ -0,0 +1,35 @@ +/** + * This script runs `npx @convex-dev/auth` to help with setting up + * environment variables for Convex Auth. + * + * You can safely delete it and remove it from package.json scripts. + */ + +import fs from "fs"; +import { config as loadEnvFile } from "dotenv"; +import { spawnSync } from "child_process"; + +if (!fs.existsSync(".env.local")) { + // Something is off, skip the script. + process.exit(0); +} + +const config = {}; +loadEnvFile({ path: ".env.local", processEnv: config }); + +const runOnceWorkflow = process.argv.includes("--once"); + +if (runOnceWorkflow && config.SETUP_SCRIPT_RAN !== undefined) { + // The script has already ran once, skip. + process.exit(0); +} + +const result = spawnSync("npx", ["@convex-dev/auth", "--skip-git-check"], { + stdio: "inherit", +}); + +if (runOnceWorkflow) { + fs.writeFileSync(".env.local", `\nSETUP_SCRIPT_RAN=1\n`, { flag: "a" }); +} + +process.exit(result.status); From 669e2c5e967050201164e15882aada20c36bd40c Mon Sep 17 00:00:00 2001 From: Sarah Shader Date: Wed, 5 Feb 2025 17:06:30 -0800 Subject: [PATCH 2/9] Run convex codegen npx convex codegen --- convex/_generated/api.d.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/convex/_generated/api.d.ts b/convex/_generated/api.d.ts index 6a067d5..09899f7 100644 --- a/convex/_generated/api.d.ts +++ b/convex/_generated/api.d.ts @@ -13,6 +13,8 @@ import type { FilterApi, FunctionReference, } from "convex/server"; +import type * as auth from "../auth.js"; +import type * as http from "../http.js"; import type * as myFunctions from "../myFunctions.js"; /** @@ -24,6 +26,8 @@ import type * as myFunctions from "../myFunctions.js"; * ``` */ declare const fullApi: ApiFromModules<{ + auth: typeof auth; + http: typeof http; myFunctions: typeof myFunctions; }>; export declare const api: FilterApi< From 2c12d808d3ca826b6060aa0a0e6a3a5e85a166e9 Mon Sep 17 00:00:00 2001 From: Sarah Shader Date: Wed, 5 Feb 2025 17:07:48 -0800 Subject: [PATCH 3/9] Enable Password provider --- convex/auth.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/convex/auth.ts b/convex/auth.ts index cdfe776..e292e03 100644 --- a/convex/auth.ts +++ b/convex/auth.ts @@ -1,5 +1,6 @@ import { convexAuth } from "@convex-dev/auth/server"; +import { Password } from "@convex-dev/auth/providers/Password"; export const { auth, signIn, signOut, store, isAuthenticated } = convexAuth({ - providers: [], + providers: [Password], }); From 618abe03946ed2d5df17ba70048854d5309f2845 Mon Sep 17 00:00:00 2001 From: Michal Srb Date: Mon, 1 Jul 2024 15:16:06 +0200 Subject: [PATCH 4/9] Add auth tables to schema --- convex/schema.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/convex/schema.ts b/convex/schema.ts index b1bc23e..cae4774 100644 --- a/convex/schema.ts +++ b/convex/schema.ts @@ -1,11 +1,12 @@ import { defineSchema, defineTable } from "convex/server"; import { v } from "convex/values"; +import { authTables } from "@convex-dev/auth/server"; -// The schema is entirely optional. -// You can delete this file (schema.ts) and the -// app will continue to work. +// The schema is normally optional, but Convex Auth +// requires indexes defined on `authTables`. // The schema provides more precise TypeScript types. export default defineSchema({ + ...authTables, numbers: defineTable({ value: v.number(), }), From 7724c091c2ac61324bf9b72f525ab61b0a55ed95 Mon Sep 17 00:00:00 2001 From: Michal Srb Date: Mon, 1 Jul 2024 15:17:38 +0200 Subject: [PATCH 5/9] Add ConvexAuthProvider --- src/main.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main.tsx b/src/main.tsx index 4880906..5f5a1bd 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,14 +1,16 @@ import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; -import { ConvexProvider, ConvexReactClient } from "convex/react"; +import { ConvexAuthProvider } from "@convex-dev/auth/react"; +import { ConvexReactClient } from "convex/react"; import "./index.css"; import App from "./App.tsx"; const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL as string); + createRoot(document.getElementById("root")!).render( - + - + , ); From ddf9cf32425569b5cf04016a916c57afc8be28b5 Mon Sep 17 00:00:00 2001 From: Sarah Shader Date: Wed, 5 Feb 2025 17:53:38 -0800 Subject: [PATCH 6/9] Update myFunctions for Convex Auth --- convex/myFunctions.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/convex/myFunctions.ts b/convex/myFunctions.ts index 0896dc3..a1b7a04 100644 --- a/convex/myFunctions.ts +++ b/convex/myFunctions.ts @@ -1,6 +1,7 @@ import { v } from "convex/values"; import { query, mutation, action } from "./_generated/server"; import { api } from "./_generated/api"; +import { getAuthUserId } from "@convex-dev/auth/server"; // Write your Convex functions in any file inside this directory (`convex`). // See https://docs.convex.dev/functions for more. @@ -21,8 +22,10 @@ export const listNumbers = query({ // Ordered by _creationTime, return most recent .order("desc") .take(args.count); + const userId = await getAuthUserId(ctx); + const user = userId === null ? null : await ctx.db.get(userId); return { - viewer: (await ctx.auth.getUserIdentity())?.name ?? null, + viewer: user?.email ?? null, numbers: numbers.reverse().map((number) => number.value), }; }, From 70052a4c33de41794e9b78f3d72ea9e1a7a67556 Mon Sep 17 00:00:00 2001 From: Sarah Shader Date: Wed, 5 Feb 2025 17:55:18 -0800 Subject: [PATCH 7/9] Add UI for Convex Auth --- src/App.tsx | 102 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 98 insertions(+), 4 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 588725b..2bdbec1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,22 +1,116 @@ "use client"; -import { useMutation, useQuery } from "convex/react"; +import { + Authenticated, + Unauthenticated, + useConvexAuth, + useMutation, + useQuery, +} from "convex/react"; import { api } from "../convex/_generated/api"; +import { useAuthActions } from "@convex-dev/auth/react"; +import { useState } from "react"; export default function App() { return ( <>
- Convex + React + Convex + React + Convex Auth +
-

Convex + React

- +

+ Convex + React + Convex Auth +

+ + + + + +
); } +function SignOutButton() { + const { isAuthenticated } = useConvexAuth(); + const { signOut } = useAuthActions(); + return ( + <> + {isAuthenticated && ( + + )} + + ); +} + +function SignInForm() { + const { signIn } = useAuthActions(); + const [flow, setFlow] = useState<"signIn" | "signUp">("signIn"); + const [error, setError] = useState(null); + return ( +
+

Log in to see the numbers

+
{ + e.preventDefault(); + const formData = new FormData(e.target as HTMLFormElement); + formData.set("flow", flow); + void signIn("password", formData).catch((error) => { + setError(error.message); + }); + }} + > + + + +
+ + {flow === "signIn" + ? "Don't have an account?" + : "Already have an account?"} + + setFlow(flow === "signIn" ? "signUp" : "signIn")} + > + {flow === "signIn" ? "Sign up instead" : "Sign in instead"} + +
+ {error && ( +
+

+ Error signing in: {error} +

+
+ )} +
+
+ ); +} + function Content() { const { viewer, numbers } = useQuery(api.myFunctions.listNumbers, { From fd4952f283725d03307d375bb76b0d7ec9eb106c Mon Sep 17 00:00:00 2001 From: Sarah Shader Date: Wed, 5 Feb 2025 19:28:53 -0800 Subject: [PATCH 8/9] Update README --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0b8c20c..af0a7c4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Welcome to your Convex + React (Vite) app +# Welcome to your Convex + React (Vite) + Convex Auth app This is a [Convex](https://convex.dev/) project created with [`npm create convex`](https://www.npmjs.com/package/create-convex). @@ -7,7 +7,8 @@ After the initial setup (<2 minutes) you'll have a working full-stack app using: - Convex as your backend (database, server logic) - [React](https://react.dev/) as your frontend (web page interactivity) - [Vite](https://vitest.dev/) for optimized web hosting -- [Tailwind](https://tailwindcss.com/) for building great looking accessible UI +- [Tailwind](https://tailwindcss.com/) for building great looking UI +- [Convex Auth](https://labs.convex.dev/auth) for authentication ## Get started @@ -21,9 +22,13 @@ npm run dev If you're reading this README on GitHub and want to use this template, run: ``` -npm create convex@latest -- -t react-vite +npm create convex@latest -- -t react-vite-convexauth ``` +For more information on how to configure Convex Auth, check out the [Convex Auth docs](https://labs.convex.dev/auth/). + +For more examples of different Convex Auth flows, check out this [example repo](https://www.convex.dev/templates/convex-auth). + ## Learn more To learn more about developing your project with Convex, check out: From e051d0df63b1e5b01c6aee977fcc5abbac0a6abf Mon Sep 17 00:00:00 2001 From: Shawn Erquhart Date: Thu, 10 Apr 2025 15:41:22 -0400 Subject: [PATCH 9/9] fix predev script quotes for windows --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ad7c0fa..0c838a5 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "dev": "npm-run-all --parallel dev:frontend dev:backend", "dev:frontend": "vite --open", "dev:backend": "convex dev", - "predev": "convex dev --until-success && convex dev --once --run-sh 'node setup.mjs --once' && convex dashboard", + "predev": "convex dev --until-success && convex dev --once --run-sh \"node setup.mjs --once\" && convex dashboard", "build": "tsc -b && vite build", "lint": "tsc && eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview"