Profile (fetched from API)
+User
+{JSON.stringify(user, null, 2)}+
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 21ad2a104..cb62d62d1 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -5,20 +5,20 @@ jobs:
build:
docker:
- image: cimg/node:lts-browsers
- resource_class: xlarge
+ resource_class: 2xlarge
steps:
- checkout
- restore_cache:
- key: dependencies-{{ .Branch }}-{{ checksum "package-lock.json" }}-{{ checksum "examples/kitchen-sink-example/package.json" }}
+ key: dependencies-{{ .Branch }}-{{ checksum "package-lock.json" }}-{{ checksum "example-app/package.json" }}
- run: npm ci
- run:
- name: npm run install:kitchen-sink
+ name: npm run install:example
command: |
if [ -z "$CIRCLE_PR_NUMBER" ]; then
- npm run install:kitchen-sink
+ npm run install:example
fi
- save_cache:
- key: dependencies-{{ .Branch }}-{{ checksum "package-lock.json" }}-{{ checksum "examples/kitchen-sink-example/package.json" }}
+ key: dependencies-{{ .Branch }}-{{ checksum "package-lock.json" }}-{{ checksum "example-app/package.json" }}
paths:
- ~/.npm
- ~/.cache
@@ -29,7 +29,7 @@ jobs:
name: browserstack
command: |
if [ -z "$CIRCLE_PR_NUMBER" ]; then
- npx start-server-and-test 'start:kitchen-sink-local' http://localhost:3000 'browserstack-cypress run --build-name $CIRCLE_BRANCH --no-wrap'
+ npx start-server-and-test 'start:example-local' http://localhost:3000 'browserstack-cypress run --build-name $CIRCLE_BRANCH --no-wrap'
fi
- store_test_results:
path: test-results
@@ -44,6 +44,7 @@ workflows:
context:
- browserstack-env
- ship/node-publish:
+ publish-command: npm publish --tag beta
requires:
- build
context:
@@ -52,4 +53,4 @@ workflows:
filters:
branches:
only:
- - main
+ - beta
diff --git a/.gitignore b/.gitignore
index 798515a77..3831b61df 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,3 +73,6 @@ dist/
# Mac OSX files
.DS_Store
+
+# IDE
+.idea
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 07d6b90b9..52146f5d6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,18 +9,47 @@
**Fixed**
- Clean up erroneous cookies when chunk size decreases [\#1300](https://github.com/auth0/nextjs-auth0/pull/1300) ([adamjmcgrath](https://github.com/adamjmcgrath))
+## [v3.0.0-beta.3](https://github.com/auth0/nextjs-auth0/tree/v3.0.0-beta.3) (2023-06-28)
+[Full Changelog](https://github.com/auth0/nextjs-auth0/compare/v3.0.0-beta.2...v3.0.0-beta.3)
+
+**Added**
+- [SDK-4319] Add support for Edge runtime [\#1269](https://github.com/auth0/nextjs-auth0/pull/1269) ([adamjmcgrath](https://github.com/adamjmcgrath))
+- [SDK-4318] Enable responses from custom middleware [\#1265](https://github.com/auth0/nextjs-auth0/pull/1265) ([adamjmcgrath](https://github.com/adamjmcgrath))
+
## [v2.6.3](https://github.com/auth0/nextjs-auth0/tree/v2.6.3) (2023-06-26)
[Full Changelog](https://github.com/auth0/nextjs-auth0/compare/v2.6.2...v2.6.3)
**Fixed**
- Fix for setting custom cookies in `withMiddlewareAuthRequired` [\#1263](https://github.com/auth0/nextjs-auth0/pull/1263) ([adamjmcgrath](https://github.com/adamjmcgrath))
+
+## [v3.0.0-beta.2](https://github.com/auth0/nextjs-auth0/tree/v3.0.0-beta.2) (2023-06-16)
+[Full Changelog](https://github.com/auth0/nextjs-auth0/compare/v3.0.0-beta.1...v3.0.0-beta.2)
+
+**Fixed**
+- Fix issue where api wrapper was overwriting session update in api [\#1255](https://github.com/auth0/nextjs-auth0/pull/1255) ([adamjmcgrath](https://github.com/adamjmcgrath))
+
+## [v3.0.0-beta.1](https://github.com/auth0/nextjs-auth0/tree/v3.0.0-beta.1) (2023-06-13)
+[Full Changelog](https://github.com/auth0/nextjs-auth0/compare/v3.0.0-beta.0...v3.0.0-beta.1)
+
+**Fixed**
+- Fix request check in node 16 [\#1250](https://github.com/auth0/nextjs-auth0/pull/1250) ([adamjmcgrath](https://github.com/adamjmcgrath))
+
## [v2.6.2](https://github.com/auth0/nextjs-auth0/tree/v2.6.2) (2023-06-09)
[Full Changelog](https://github.com/auth0/nextjs-auth0/compare/v2.6.1...v2.6.2)
**Fixed**
- Fix for handling chunked cookies in edge runtime [\#1236](https://github.com/auth0/nextjs-auth0/pull/1236) ([adamjmcgrath](https://github.com/adamjmcgrath))
+## [v3.0.0-beta.0](https://github.com/auth0/nextjs-auth0/tree/v3.0.0-beta.0) (2023-06-08)
+[Full Changelog](https://github.com/auth0/nextjs-auth0/compare/v2.6.1...v3.0.0-beta.0)
+
+**Added**
+- Support for the App Router.
+
+**⚠️ BREAKING CHANGES**
+- Support for EOL Node versions 12 and 14 has been removed. See the [V3_MIGRATION_GUIDE.md](./V3_MIGRATION_GUIDE.md) for more details.
+
## [v2.6.1](https://github.com/auth0/nextjs-auth0/tree/v2.6.1) (2023-06-06)
[Full Changelog](https://github.com/auth0/nextjs-auth0/compare/v2.6.0...v2.6.1)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 40b23d4b2..c24337e9f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -15,27 +15,14 @@ Please read [Auth0's contribution guidelines](https://github.com/auth0/open-sour
- `npm run build:test`: Do this once to build the test harness for the tests
- `npm test`: Run the unit tests
- `npm run test:watch`: Run the unit tests and watch for changes
-- `npm run install:examples`: Install the examples
-- Setup the examples https://github.com/auth0/nextjs-auth0/tree/main/examples
-- `npm run start:basic`: Run the basic example
-- `npm run start:kitchen-sink`: Run the kitchen sink example
-- `npm run test:kitchen-sink`: Run the E2E tests (you will need to populate the `CYPRESS_USER_EMAIL` and `CYPRESS_USER_PASSWORD` env vars)
-- `npm run test:kitchen-sink:watch`: Run the E2E tests and watch for changes
+- `npm run install:example`: Install the examples
+- Setup the examples https://github.com/auth0/nextjs-auth0/tree/main/example-app
+- `npm run start:example`: Run the example
+- `npm run test:example`: Run the E2E tests (you will need to populate the `CYPRESS_USER_EMAIL` and `CYPRESS_USER_PASSWORD` env vars)
+- `npm run test:example:watch`: Run the E2E tests and watch for changes
## Running examples against a mock openid provider
-Your env vars in `/examples/kitchen-sink-example/.env.local` should look like
-
-```bash
-AUTH0_SECRET=#ANY LONG RANDOM VALUE
-AUTH0_ISSUER_BASE_URL=http://localhost:3000/oidc
-AUTH0_BASE_URL=http://localhost:3000
-AUTH0_CLIENT_ID=testing
-AUTH0_CLIENT_SECRET=testing
-```
-
-Then run one of the commands:
-
-- `start:kitchen-sink-local`: "npm run dev:local --prefix=examples/kitchen-sink-example",
-- `test:kitchen-sink-local`: Run the E2E tests against a mock openid provider
-- `test:kitchen-sink-local:watch`: Run the E2E tests against a mock openid provider and watch for changes
+- `start:example-local`: Run the example app with a mock openid provider
+- `test:example-local`: Run the E2E tests with a mock openid provider
+- `test:example-local:watch`: Run the E2E tests with a mock openid provider and watch for changes
diff --git a/EXAMPLES.md b/EXAMPLES.md
index 8eaa14d69..f211b8236 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -1,6 +1,5 @@
# Examples
-- [Basic Setup](#basic-setup)
- [Create your own instance of the SDK](#create-your-own-instance-of-the-sdk)
- [Customize handlers behavior](#customize-handlers-behavior)
- [Use custom auth urls](#use-custom-auth-urls)
@@ -13,76 +12,9 @@
- [Use with Base Path and Internationalized Routing](#use-with-base-path-and-internationalized-routing)
- [Use a custom session store](#use-a-custom-session-store)
-All examples can be seen running in the [Kitchen Sink example app](./examples/kitchen-sink-example).
+See also the [example app](./example-app).
-## Basic Setup
-
-Configure the required options in an `.env.local` file in the root of your application:
-
-```sh
-AUTH0_SECRET='LONG_RANDOM_VALUE'
-AUTH0_BASE_URL='http://localhost:3000'
-AUTH0_ISSUER_BASE_URL='https://your-tenant.auth0.com'
-AUTH0_CLIENT_ID='CLIENT_ID'
-AUTH0_CLIENT_SECRET='CLIENT_SECRET'
-```
-
-Create a [dynamic API route handler](https://nextjs.org/docs/api-routes/dynamic-api-routes) at `/pages/api/auth/[auth0].js`.
-
-```js
-import { handleAuth } from '@auth0/nextjs-auth0';
-
-export default handleAuth();
-```
-
-This will create the following urls: `/api/auth/login`, `/api/auth/callback`, `/api/auth/logout` and `/api/auth/me`.
-
-Wrap your `pages/_app.jsx` component in the `UserProvider` component.
-
-```jsx
-// pages/_app.jsx
-import React from 'react';
-import { UserProvider } from '@auth0/nextjs-auth0/client';
-
-export default function App({ Component, pageProps }) {
- // You can optionally pass the `user` prop from pages that require server-side
- // rendering to prepopulate the `useUser` hook.
- const { user } = pageProps;
-
- return (
-
{JSON.stringify(user, null, 2)}; + } + return <>>; +} diff --git a/example-app/app/edge-profile-api/page.tsx b/example-app/app/edge-profile-api/page.tsx new file mode 100644 index 000000000..c0c5d9596 --- /dev/null +++ b/example-app/app/edge-profile-api/page.tsx @@ -0,0 +1,23 @@ +'use client'; + +import React, { useState, useEffect } from 'react'; +import { withPageAuthRequired } from '@auth0/nextjs-auth0/client'; + +export default withPageAuthRequired(function ProfileApi() { + const [user, setUser] = useState(); + + useEffect(() => { + (async () => { + const res = await fetch(`${window.location.origin}/api/edge-profile`); + setUser(await res.json()); + })(); + }, []); + + return ( +
{JSON.stringify(user, null, 2)}+
{JSON.stringify({ accessToken: session?.accessToken }, null, 2)}+
{JSON.stringify(session?.user, null, 2)}+
{JSON.stringify(user, null, 2)}+
{JSON.stringify({ accessToken: session?.accessToken }, null, 2)}+
{JSON.stringify(session?.user, null, 2)}+
{JSON.stringify({ accessToken: session?.accessToken }, null, 2)}+
{JSON.stringify(session?.user, null, 2)}+
{JSON.stringify(accessToken, null, 2)}+
{JSON.stringify(session.user, null, 2)}+ > + ); + } + return <>>; +} diff --git a/example-app/components/header.tsx b/example-app/components/header.tsx new file mode 100644 index 000000000..988a5cac2 --- /dev/null +++ b/example-app/components/header.tsx @@ -0,0 +1,126 @@ +import React from 'react'; +import Link from 'next/link'; +import { useUser } from '@auth0/nextjs-auth0/client'; +import { useRouter } from 'next/router'; + +const Header = (): React.ReactElement => { + const { user } = useUser(); + const { pathname } = useRouter(); + const pageName = pathname.split('/').pop(); + + return ( + <> +
{JSON.stringify(user, null, 2)}+
Loading...
; + } + return ( +{JSON.stringify(user, null, 2)}+
{JSON.stringify(user, null, 2)}
{JSON.stringify(user, null, 2)}+
Loading login info...
} - - {error && ( - <> -{error.message}- > - )} - - {user && ( - <> -
{JSON.stringify(user, null, 2)}- > - )} - - {!isLoading && !error && !user && ( - <> -
- To test the login click in Login -
-- Once you have logged in you should be able to click in Protected Page and Logout -
- > - )} -Loading profile...
} - - {error && ( - <> -{error.message}- > - )} - - {user && ( - <> -
{JSON.stringify(user, null, 2)}- > - )} -
{JSON.stringify(session || {}, null, 2)}-
- This is the about page, navigating between this page and Home is always pretty fast. However, when you - navigate to the Profile page it takes more time because it uses SSR to fetch the user first; -
-Loading login info...
} - - {error && ( - <> -{error.message}- > - )} - - {user && ( - <> -
{JSON.stringify(user, null, 2)}- > - )} - - {!isLoading && !error && !user && ( - <> -
- To test the login click in Login -
-- Once you have logged in you should be able to click in Protected Page and Logout -
- > - )} -{JSON.stringify(user, null, 2)}-
{JSON.stringify(user, null, 2)}-
Loading TV shows...
} - - {response && ( - <> -My favourite TV shows:
-- {JSON.stringify( - response.shows.map((s: TVShow) => s.show.name), - null, - 2 - )} -- > - )} - - {error && ( - <> -
Error loading TV shows
-{JSON.stringify(error, null, 2)}- > - )} -
( +export type WithPageAuthRequired =
( Component: ComponentType
, options?: WithPageAuthRequiredOptions ) => React.FC
;
diff --git a/src/config.ts b/src/config.ts
index 45e1d24f5..2bd873b43 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,6 +1,4 @@
-import { IncomingMessage } from 'http';
-import type { AuthorizationParameters as OidcAuthorizationParameters } from 'openid-client';
-import type { LoginOptions } from './auth0-session/config';
+import type { LoginOptions, AuthorizationParameters as OidcAuthorizationParameters } from './auth0-session/config';
import { SessionStore } from './auth0-session/session/stateful-session';
import Session from './session/session';
import { DeepPartial, get as getBaseConfig } from './auth0-session/get-config';
@@ -113,7 +111,7 @@ export interface BaseConfig {
* ```js
* {
* ...
- * getLoginState(req, options) {
+ * getLoginState(options) {
* return {
* returnTo: options.returnTo || req.originalUrl,
* customState: 'foo'
@@ -122,7 +120,7 @@ export interface BaseConfig {
* }
* ```
*/
- getLoginState: (req: IncomingMessage, options: LoginOptions) => Record = GetServerSidePropsRes
* @category Server
*/
export type PageRoute = (
- cts: GetServerSidePropsContext = (
*
* @category Server
*/
-export type WithPageAuthRequiredOptions<
+export type WithPageAuthRequiredPageRouterOptions<
P extends { [key: string]: any } = { [key: string]: any },
Q extends ParsedUrlQuery = ParsedUrlQuery
> = {
@@ -90,13 +109,74 @@ export type WithPageAuthRequiredOptions<
*
* @category Server
*/
-export type WithPageAuthRequired = <
+export type WithPageAuthRequiredPageRouter = <
P extends { [key: string]: any } = { [key: string]: any },
Q extends ParsedUrlQuery = ParsedUrlQuery
>(
- opts?: WithPageAuthRequiredOptions
+ opts?: WithPageAuthRequiredPageRouterOptions
) => PageRoute ;
+/**
+ * Specify the URL to `returnTo` - this is important in app router pages because the server component
+ * won't know the URL of the page.
+ *
+ * @category Server
+ */
+export type WithPageAuthRequiredAppRouterOptions = {
+ returnTo?: string | ((obj: AppRouterPageRouteOpts) => Promise
+ ctx: GetServerSidePropsContext
) => Promise