From aceff15352cdbb010b8b59ce2c8813cd45e856db Mon Sep 17 00:00:00 2001 From: Kevin Gao Date: Wed, 20 Mar 2024 13:53:56 -0700 Subject: [PATCH 1/2] added descope as provider --- react-descope/package.json | 6 ++ .../ConvexProviderWithDescope.test.tsx | 17 ++++++ .../ConvexProviderWithDescope.tsx | 61 +++++++++++++++++++ src/react-descope/index.ts | 6 ++ 4 files changed, 90 insertions(+) create mode 100644 react-descope/package.json create mode 100644 src/react-descope/ConvexProviderWithDescope.test.tsx create mode 100644 src/react-descope/ConvexProviderWithDescope.tsx create mode 100644 src/react-descope/index.ts diff --git a/react-descope/package.json b/react-descope/package.json new file mode 100644 index 0000000..de30aa5 --- /dev/null +++ b/react-descope/package.json @@ -0,0 +1,6 @@ +{ + "main": "../dist/cjs/react-descope/index.js", + "module": "../dist/esm/react-descope/index.js", + "types": "../dist/internal-cjs-types/react-descope/index.d.ts" + } + \ No newline at end of file diff --git a/src/react-descope/ConvexProviderWithDescope.test.tsx b/src/react-descope/ConvexProviderWithDescope.test.tsx new file mode 100644 index 0000000..4adc698 --- /dev/null +++ b/src/react-descope/ConvexProviderWithDescope.test.tsx @@ -0,0 +1,17 @@ +/** + * @jest-environment jsdom + */ +import { test } from "@jest/globals"; +import React from "react"; +import { ConvexProviderWithDescope } from "./ConvexProviderWithDescope.js"; +import { ConvexReactClient } from "../react/index.js"; + +test("Helpers are valid children", () => { + const convex = new ConvexReactClient("https://localhost:3001"); + + const _ = ( + + Hello world + + ); +}); diff --git a/src/react-descope/ConvexProviderWithDescope.tsx b/src/react-descope/ConvexProviderWithDescope.tsx new file mode 100644 index 0000000..09c4709 --- /dev/null +++ b/src/react-descope/ConvexProviderWithDescope.tsx @@ -0,0 +1,61 @@ +import { useSession, useDescope, getSessionToken } from "@descope/react-sdk"; +import React from "react"; + +import { ReactNode, useCallback, useMemo } from "react"; +import { AuthTokenFetcher } from "../browser/sync/client.js"; +import { ConvexProviderWithAuth } from "../react/ConvexAuthState.js"; + +// Until we can import from our own entry points (requires TypeScript 4.7), +// just describe the interface enough to help users pass the right type. +type IConvexReactClient = { + setAuth(fetchToken: AuthTokenFetcher): void; + clearAuth(): void; +}; + +/** + * A wrapper React component which provides a {@link react.ConvexReactClient} + * authenticated with Auth0. + * + * It must be wrapped by a configured `AuthProvider` from `@descope/reack-sdk`. + * + * See [Convex Descope](https://docs.convex.dev/auth/descope) on how to set up + * Convex with Descope. + * + * @public + */ +export function ConvexProviderWithDescope({ + children, + client, +}: { + children: ReactNode; + client: IConvexReactClient; +}) { + return ( + + {children} + + ); +} + +function useAuthFromDescope() { + const { isLoading, isAuthenticated } = useSession(); + const sdk = useDescope(); + + const fetchAccessToken = useCallback(async ({ forceRefreshToken }: { forceRefreshToken: boolean }) => { + try { + if (forceRefreshToken) { + sdk.refresh(); + } + + const token = getSessionToken(); + return token as string; + } catch (error) { + return null; + } + }, []); + + return useMemo( + () => ({ isLoading, isAuthenticated, fetchAccessToken }), + [isLoading, isAuthenticated, fetchAccessToken], + ); +} diff --git a/src/react-descope/index.ts b/src/react-descope/index.ts new file mode 100644 index 0000000..d101f5e --- /dev/null +++ b/src/react-descope/index.ts @@ -0,0 +1,6 @@ +/** + * React login component for use with Descope. + * + * @module + */ +export { ConvexProviderWithDescope } from "./ConvexProviderWithDescope.js"; From 5c61a30aa66446262b93aada220b52b6244a62bc Mon Sep 17 00:00:00 2001 From: Kevin Gao Date: Wed, 20 Mar 2024 14:04:26 -0700 Subject: [PATCH 2/2] added package.json changes --- README.md | 2 ++ package.json | 18 ++++++++++++++++++ .../ConvexProviderWithDescope.tsx | 6 +++--- src/react/ConvexAuthState.tsx | 2 +- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 44375ab..9679552 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ This package includes several entry points for building apps on Convex: React component for authenticating users with Auth0. - [`convex/react-clerk`](https://docs.convex.dev/api/modules/react_clerk): A React component for authenticating users with Clerk. +- [`convex/react-descope`](https://docs.convex.dev/api/modules/react_descope): A + React component for authenticating users with Descope. This package also includes [`convex`](https://docs.convex.dev/using/cli), the command-line interface for managing Convex projects. diff --git a/package.json b/package.json index ce01689..8fefffb 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,16 @@ "import": "./dist/esm/react-clerk/index.js" } }, + "./react-descope": { + "require": { + "types": "./dist/internal-cjs-types/react-descope/index.d.ts", + "require": "./dist/cjs/react-descope/index.js" + }, + "import": { + "types": "./dist/internal-esm-types/react-descope/index.d.ts", + "import": "./dist/esm/react-descope/index.js" + } + }, "./nextjs": { "require": { "types": "./dist/internal-cjs-types/nextjs/index.d.ts", @@ -119,6 +129,9 @@ "react-clerk": [ "./dist/internal-cjs-types/react-clerk/index.d.ts" ], + "react-descope": [ + "./dist/internal-cjs-types/react-descope/index.d.ts" + ], "nextjs": [ "./dist/internal-cjs-types/nextjs/index.d.ts" ], @@ -168,6 +181,7 @@ "peerDependencies": { "@auth0/auth0-react": "^2.0.1", "@clerk/clerk-react": "^4.12.8", + "@descope/react-sdk": "^2.0.10", "react": "^17.0.2 || ^18.0.0", "react-dom": "^17.0.2 || ^18.0.0" }, @@ -183,6 +197,9 @@ }, "@clerk/clerk-react": { "optional": true + }, + "@descope/react-sdk": { + "optional": true } }, "@comment devDependencies": [ @@ -193,6 +210,7 @@ "@auth0/auth0-react": "2.0.1", "@babel/parser": "^7.21.3", "@clerk/clerk-react": "4.18.0", + "@descope/react-sdk": "2.0.10", "@commander-js/extra-typings": "^11.1.0", "@jest/globals": "^28.1.0", "@microsoft/api-extractor": "~7.36.4", diff --git a/src/react-descope/ConvexProviderWithDescope.tsx b/src/react-descope/ConvexProviderWithDescope.tsx index 09c4709..3cee0cc 100644 --- a/src/react-descope/ConvexProviderWithDescope.tsx +++ b/src/react-descope/ConvexProviderWithDescope.tsx @@ -14,9 +14,9 @@ type IConvexReactClient = { /** * A wrapper React component which provides a {@link react.ConvexReactClient} - * authenticated with Auth0. + * authenticated with Descope. * - * It must be wrapped by a configured `AuthProvider` from `@descope/reack-sdk`. + * It must be wrapped by a configured `AuthProvider` from `@descope/react-sdk`. * * See [Convex Descope](https://docs.convex.dev/auth/descope) on how to set up * Convex with Descope. @@ -46,7 +46,7 @@ function useAuthFromDescope() { if (forceRefreshToken) { sdk.refresh(); } - + const token = getSessionToken(); return token as string; } catch (error) { diff --git a/src/react/ConvexAuthState.tsx b/src/react/ConvexAuthState.tsx index a3c95ea..5c5329c 100644 --- a/src/react/ConvexAuthState.tsx +++ b/src/react/ConvexAuthState.tsx @@ -48,7 +48,7 @@ export function useConvexAuth(): { if (authContext === undefined) { throw new Error( "Could not find `ConvexProviderWithAuth` (or `ConvexProviderWithClerk` " + - "or `ConvexProviderWithAuth0`) " + + "or `ConvexProviderWithAuth0`" + "or `ConvexProviderWithDescope`) " + "as an ancestor component. This component may be missing, or you " + "might have two instances of the `convex/react` module loaded in your " + "project.",