Enhance the Next.js higher-order authentication component by including extra data in the return

Below is the code snippet I am working with:

export const requireAuth = (gssp: GetServerSideProps) => {
  return async (ctx: GetServerSidePropsContext) => {
    const { req } = ctx;
    let session = null;

    if (req?.headers?.cookie) {
      session = await getSession(req?.headers?.cookie);
    };

    if (!session) {
      return {
        redirect: {
          permanent: false,
          destination: '/login',
        },
      };
    };
    return await gssp(ctx);
  };
};

I am trying to figure out how to also include the session in await gssp(ctx). As I am new to NextJS, I have not been able to find any relevant information on this.

The current approach allows me to use this component as follows:

export const getServerSideProps: GetServerSideProps = requireAuth(async _ctx => {
  let account;
  let stats = {};

  if (_ctx?.req?.headers?.cookie) {
    account = await getSession(_ctx?.req?.headers?.cookie);
  }

  try {
    const X = fetchSomeData...;
  } catch (error) {
    console.log('Pages/Index Fetching Error: ', error);
  }

  return {
    props: {
      account: account,
      data: X,
      navbar: true,
      footer: true,
    },
  };
});

This method allows for additional logic on the page where it is implemented, in comparison to other methods like HOC.

Is there a way to include the session in the main requireAuth component instead of fetching it on each individual page?

Answer №1

By manipulating the higher-order function, you can determine what is passed to the actual gssp function. For example, you can easily pass the session within the ctx object.

export const requireAuth = (gssp: GetServerSidePropsWithSession) => {
    return async (ctx: GetServerSidePropsContext) => {
        const { req } = ctx;
        const session = req?.headers?.cookie ? await getSession(req?.headers?.cookie) : null;

        if (!session) {
            return {
                redirect: { permanent: false, destination: '/login' }
            };
        };

        const ctxWithSession = { ...ctx, session };

        return await gssp(ctxWithSession);
    };
};

Subsequently, you can access the session within your getServerSideProps code.

interface GetServerSidePropsContextWithSession extends GetServerSidePropsContext {
    session?: Session;
}

type GetServerSidePropsWithSession<P extends { [key: string]: any } = { [key: string]: any }> = (
    context: GetServerSidePropsContextWithContext
) => Promise<GetServerSidePropsResult<P>>;

export const getServerSideProps: GetServerSidePropsWithSession = requireAuth(async _ctx => {
    const account = _ctx.session;
        
    // Remaining code...
});

It is important to note that you must extend the GetServerSideProps type to include the session field.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Combining different types and "currying" or partial application APIs in a unique way

Here is an interface that I am working with: interface IFactory<T> extends Function { (...args: any[]): (((...args: any[]) => T)|T); } After implementing the following code snippet, an error occurred: ts] Type '((...args: any[]) => ...

The issue arises when a Next.js application is hosted behind an Nginx Ingress with TLS, causing the CSS, styling

I have successfully deployed a NextJS application in my AKS cluster. The deployment configuration looks like this: apiVersion: apps/v1 kind: Deployment metadata: name: applicationName spec: replicas: 1 selector: matchLabels: app: applicatio ...

The onNodeContextMenuSelect function does not seem to be functioning properly within the p-tree

<p-tree [value]="files" selectionMode="single" (onNodeContextMenuSelect)="showContect($event)" > </p-tree> Whenever I right click, the event doesn't seem to be triggering. Instead, the default browser c ...

Do interfaces in Typescript require nested properties to be mandatory?

My interface contains a nested object: export interface Person { PersonWrapper: { name: string; address: string email?: string; } } When attempting to create an object from this interface, it appears that name is not mandat ...

What is the method for generating a data type from an array of strings using TypeScript?

Is there a more efficient way to create a TypeScript type based on an array of strings without duplicating values in an Enum declaration? I am using version 2.6.2 and have a long array of colors that I want to convert into a type. Here is what I envision: ...

searchByTextContentUnderListItemAnchorTag

I would like to utilize the getByRole function for writing my test. However, I am encountering issues when using linkitem or 'link' as the role. It seems that I cannot find the desired element. // encountered error TestingLibraryElementError: The ...

Tips for creating type-safe assertion functions in TypeScript

In TypeScript 3.7, a new feature allows the writing of "assertion functions." One example is shown below: export type TOfferAttrName = keyof typeof offerAttrMap; export const assertIsOfferAttrName = (name: string): asserts name is TOfferAttrName => { ...

OpenAPI implementation in NestJS that emphasizes the use of reusable parameters

Is it possible to reuse common parameters in the implementation of NestJS OpenAPI/Swagger? This feature would prevent me from having to clutter my endpoint with repetitive @ApiImplicitQuery decorators. ...

Encountering build errors in .xproj file when working with Type Script in ASP.Net Core

I recently started working on a new ASP.Net Core project and decided to integrate Angular 2 and Type Script by following a blog post tutorial. However, upon adding a Type Script file to my project, I encountered several build errors from the xproj file. h ...

Updating the mat-icon in a row when a button is clicked

I am currently working on implementing the mat-table in my project. I am facing an issue where I need to change the mat-icon of a button based on a click event, but I only want this change to apply to a single row in the table. At the moment, I am able to ...

Axios encountered an error: request could not be completed due to error code 500

https://github.com/Elliott-Chong/chatpdf-yt/issues/43 Here is the GitHub link to the specific issue. The error that occurred is as follows: FileUpload.tsx:22 POST http://localhost:3000/api/createchat 500 (Internal Server Error) mutationFn @ FileUp ...

What purpose does a cast serve when used on a return type that is defined generically?

Consider this straightforward property access function export function accessProperty<T, K extends keyof T, P extends T[K]>(name: K, v: T): P { return v[name] as P } What is the significance of the cast as P in this context? I experimented with ...

Is it possible to use the HostListener in Angular 7 to detect any scroll event occurring on a specific element within a webpage?

I am developing a breadcrumb bar component in Angular 7 that should dynamically hide and show based on user scrolling behavior. To achieve this, I created a directive to track the scroll position of the container element. While my code for capturing the s ...

efficiently managing errors in a Nest Jest microservice with RabbitMQ

https://i.sstatic.net/sUGm1.png There seems to be an issue with this microservice, If I throw an exception in the users Service, it should be returned back to the gateway and then to the client However, this is not happening! The client only sees the de ...

Selecting logic depending on the request body in NestJS

Currently, my controller looks like the following: @Controller("workflow") export class TaskWorkflowController { public constructor( private readonly jobApplicationActivityWorkflow: JobApplicationActivityService ) {} @Post("/:job- ...

What is the method for importing a JavaScript file into my TypeScript file?

Recently, I've encountered an issue while working with Typescript and angular 2. I have built an EncryptionService that looks like this: import {Injectable} from 'angular2/core'; import './lib/hmac256-enc64'; @Injectable() ...

What is a sleek method for including a key and value pair to an object using an array?

In a project using angular2/typescript, I am working with an array of objects that contain key/value pairs from a database. These values are then displayed in a table on the UI using ag-grid-ng2. The table headers are dynamic and set in the database. One ...

When attempting to transfer data from the parent component to child components, the data is appearing as undefined in the display

I have been working on passing data from a parent component to child components, but I keep encountering an issue where the data is showing as undefined. Below is the code snippet: Parent Component In this section, I have declared the variable part_data ...

class-validator: ensures the correct number of digits are present in numeric values

Seeking assistance on validating the number of digits for numeric values using class-validator. Specifically, I want my entity to only accept numbers with 6 digits for a certain property. For example: const user1 = new User(); user1.code = 123456 // should ...

Error 404 is encountered during the deployment of NEXTJS to Docker, although it does not occur in the

Strangely, I am encountering a 404 error on my route that is functioning properly locally. Here is my current next.config: const nextConfig = { reactStrictMode: true, experimental: { appDir: true, output: 'standalone', } } Packag ...