diff --git a/src/helpers/with-page-auth-required.ts b/src/helpers/with-page-auth-required.ts
index e356bacf3..2be641b45 100644
--- a/src/helpers/with-page-auth-required.ts
+++ b/src/helpers/with-page-auth-required.ts
@@ -36,7 +36,7 @@ export type PageRoute
= (
) => Promise>;
/**
- * Objects containing the route parameters and search parameters of th page.
+ * Objects containing the route parameters and search parameters of the page.
*
* @category Server
*/
@@ -50,7 +50,7 @@ export type AppRouterPageRouteOpts = {
*
* @category Server
*/
-export type AppRouterPageRoute = (obj: AppRouterPageRouteOpts) => Promise;
+export type AppRouterPageRoute = (obj: PageProps) => Promise;
/**
* If you have a custom returnTo url you should specify it in `returnTo`.
@@ -124,8 +124,8 @@ export type WithPageAuthRequiredPageRouter = <
*
* @category Server
*/
-export type WithPageAuthRequiredAppRouterOptions = {
- returnTo?: string | ((obj: AppRouterPageRouteOpts) => Promise | string);
+export type WithPageAuthRequiredAppRouterOptions = {
+ returnTo?: string | ((obj: PageProps) => Promise | string);
};
/**
@@ -136,7 +136,7 @@ export type WithPageAuthRequiredAppRouterOptions = {
* // app/protected-page/page.js
* import { withPageAuthRequired } from '@auth0/nextjs-auth0';
*
- * export default function withPageAuthRequired(ProtectedPage() {
+ * export default withPageAuthRequired(function ProtectedPage() {
* return Protected content
;
* }, { returnTo: '/protected-page' });
* ```
@@ -155,7 +155,7 @@ export type WithPageAuthRequiredAppRouterOptions = {
* // app/protected-page/[slug]/page.js
* import { withPageAuthRequired } from '@auth0/nextjs-auth0';
*
- * export default function withPageAuthRequired(ProtectedPage() {
+ * export default withPageAuthRequired(function ProtectedPage({ params }: { params: { slug: string } ) {
* return Protected content
;
* }, {
* returnTo({ params }) {
@@ -166,10 +166,17 @@ export type WithPageAuthRequiredAppRouterOptions = {
*
* @category Server
*/
-export type WithPageAuthRequiredAppRouter = (
- fn: AppRouterPageRoute,
- opts?: WithPageAuthRequiredAppRouterOptions
-) => AppRouterPageRoute;
+export type WithPageAuthRequiredAppRouter = <
+ T extends {
+ params: T['params'] extends undefined ? undefined : { [K in keyof T['params']]: string };
+ searchParams: T['searchParams'] extends undefined
+ ? undefined
+ : { [K in keyof T['searchParams']]: string | undefined };
+ }
+>(
+ fn: (obj: T) => Promise,
+ opts?: WithPageAuthRequiredAppRouterOptions
+) => AppRouterPageRoute;
/**
* Protects Page router pages {@link WithPageAuthRequiredPageRouter} or
@@ -190,8 +197,8 @@ export default function withPageAuthRequiredFactory(
const pageRouteHandler = pageRouteHandlerFactory(getConfig, sessionCache);
return ((
- fnOrOpts?: WithPageAuthRequiredPageRouterOptions | AppRouterPageRoute,
- opts?: WithPageAuthRequiredAppRouterOptions
+ fnOrOpts?: WithPageAuthRequiredPageRouterOptions | AppRouterPageRoute,
+ opts?: WithPageAuthRequiredAppRouterOptions
) => {
if (typeof fnOrOpts === 'function') {
return appRouteHandler(fnOrOpts, opts);
diff --git a/tests/helpers/with-page-auth-required.test.ts b/tests/helpers/with-page-auth-required.test.ts
index 32944969e..77e932b14 100644
--- a/tests/helpers/with-page-auth-required.test.ts
+++ b/tests/helpers/with-page-auth-required.test.ts
@@ -1,14 +1,68 @@
+import { expectTypeOf } from 'expect-type';
+import { NextResponse } from 'next/server';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
-import { NextResponse } from 'next/server';
import { URL } from 'url';
-import { login, setup, teardown } from '../fixtures/setup';
+import { initAuth0 } from '../../src';
+import { get } from '../auth0-session/fixtures/helpers';
import { login as appRouterLogin } from '../fixtures/app-router-helpers';
import { withApi, withoutApi } from '../fixtures/default-settings';
-import { get } from '../auth0-session/fixtures/helpers';
-import { initAuth0 } from '../../src';
+import { login, setup, teardown } from '../fixtures/setup';
describe('with-page-auth-required ssr', () => {
+ describe('typed app route', () => {
+ let redirect: jest.Mock;
+
+ beforeEach(() => {
+ jest.doMock('next/headers', () => ({ cookies: () => new NextResponse().cookies }));
+ jest.doMock('next/navigation', () => {
+ const navigation = jest.requireActual('next/navigation');
+ redirect = jest.fn(navigation.redirect);
+ return {
+ ...navigation,
+ redirect
+ };
+ });
+ });
+
+ test('basic with params', async () => {
+ const instance = initAuth0(withApi);
+ const handler = instance.withPageAuthRequired(
+ ({ params }: { params: { lang: string; slug: string } }) =>
+ Promise.resolve(React.createElement('div', {}, `${params.lang}/${params.slug}`)),
+ { returnTo: '/foo' }
+ );
+ expectTypeOf(handler).parameter(0).toMatchTypeOf<{ params: { lang: string } }>();
+ });
+
+ test('basic with search param', async () => {
+ const instance = initAuth0(withApi);
+ const handler = instance.withPageAuthRequired(
+ ({ searchParams }: { searchParams: { limit: string | undefined } }) =>
+ Promise.resolve(React.createElement('div', {}, `${searchParams.limit}`)),
+ { returnTo: '/foo' }
+ );
+ expectTypeOf(handler).parameter(0).toMatchTypeOf<{ searchParams: { limit: string | undefined } }>();
+ });
+
+ test('basic with params and search param', async () => {
+ const instance = initAuth0(withApi);
+ const handler = instance.withPageAuthRequired(
+ ({
+ searchParams,
+ params: { lang }
+ }: {
+ params: { lang: string };
+ searchParams: { limit: string | undefined };
+ }) => Promise.resolve(React.createElement('div', {}, `${lang}${searchParams.limit}`)),
+ { returnTo: ({ params, searchParams }) => `/foo/${params.lang}?limit=${searchParams.limit}` }
+ );
+ expectTypeOf(handler)
+ .parameter(0)
+ .toMatchTypeOf<{ params: { lang: string }; searchParams: { limit: string | undefined } }>();
+ });
+ });
+
describe('app route', () => {
let redirect: jest.Mock;