Repository: auth0/nextjs-auth0
Pull request #800 (2022-09-01 02:18:28)

Allow to override the `user` prop in server-side rendered pages [SDK-3560]
<!--
❗ For general support or usage questions, use the Auth0 Community forums or raise a support ticket.

By submitting a pull request to this repository, you agree to the terms within the Auth0 Code of Conduct: https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md.
-->

- [X] All new/changed/fixed functionality is covered by tests (or N/A)
- [X] I have added documentation for all new/changed functionality (or N/A)

<!--
❗ All the above items are required. Pull requests with an incomplete or missing checklist will be closed.
-->

### 📋 Changes

This PR updates the server-side `withPageAuthRequired` such as if the developer passes their own `user` prop, it does not get overridden with the one from the SDK.

### 📎 References

Fixes https://github.com/auth0/nextjs-auth0/issues/722

### 🎯 Testing

A couple of unit tests were added. The changes were also tested manually using the kitchen sink sample app, for both object and promise-based props.

**This code**
<img width="429" alt="Screen Shot 2022-08-31 at 23 10 30" src="https://user-images.githubusercontent.com/5055789/187817888-3d372278-d772-4ac7-9005-0f3722da7dbc.png">

**Results in**
<img width="234" alt="Screen Shot 2022-08-31 at 22 41 09" src="https://user-images.githubusercontent.com/5055789/187817945-faaccb97-90f7-41d9-97ce-e724ad9baeac.png">


Patch:
diff --git a/src/helpers/with-page-auth-required.ts b/src/helpers/with-page-auth-required.ts
index f5d01d7f..80c6b18e 100644
--- a/src/helpers/with-page-auth-required.ts
+++ b/src/helpers/with-page-auth-required.ts
@@ -128,9 +128,9 @@ export default function withPageAuthRequiredFactory(
         ret = await getServerSideProps(ctx);
       }
       if (ret.props instanceof Promise) {
-        return { ...ret, props: ret.props.then((props: any) => ({ ...props, user: session.user })) };
+        return { ...ret, props: ret.props.then((props: any) => ({ user: session.user, ...props })) };
       }
-      return { ...ret, props: { ...ret.props, user: session.user } };
+      return { ...ret, props: { user: session.user, ...ret.props } };
     };
   };
 }


Test patch:
diff --git a/tests/helpers/with-page-auth-required.test.ts b/tests/helpers/with-page-auth-required.test.ts
index 4dee56cf..78797b7a 100644
--- a/tests/helpers/with-page-auth-required.test.ts
+++ b/tests/helpers/with-page-auth-required.test.ts
@@ -51,6 +51,32 @@ describe('with-page-auth-required ssr', () => {
     expect(spy).toHaveBeenCalledWith(expect.objectContaining({ req: expect.anything(), res: expect.anything() }));
   });
 
+  test('allow to override the user prop', async () => {
+    const baseUrl = await setup(withoutApi, {
+      withPageAuthRequiredOptions: {
+        async getServerSideProps() {
+          return { props: { user: { sub: 'foo' } } };
+        }
+      }
+    });
+    const cookieJar = await login(baseUrl);
+    const { data } = await get(baseUrl, '/protected', { cookieJar, fullResponse: true });
+    expect(data).toMatch(/Protected Page.*foo/);
+  });
+
+  test('allow to override the user prop when using aync props', async () => {
+    const baseUrl = await setup(withoutApi, {
+      withPageAuthRequiredOptions: {
+        async getServerSideProps() {
+          return { props: Promise.resolve({ user: { sub: 'foo' } }) };
+        }
+      }
+    });
+    const cookieJar = await login(baseUrl);
+    const { data } = await get(baseUrl, '/protected', { cookieJar, fullResponse: true });
+    expect(data).toMatch(/Protected Page.*foo/);
+  });
+
   test('use a custom login url', async () => {
     process.env.NEXT_PUBLIC_AUTH0_LOGIN = '/api/foo';
     const baseUrl = await setup(withoutApi);