UNPKG

@zeushq/nextjs-zidentity

Version:

Next.js SDK for signin in with Zeus Identity

127 lines (121 loc) 4.06 kB
import { GetServerSideProps, GetServerSidePropsContext, GetServerSidePropsResult } from 'next'; import { Claims, GetSession } from '../session'; import { assertCtx } from '../utils/assert'; import React, { ComponentType } from 'react'; import { WithPageAuthRequiredOptions as WithPageAuthRequiredCSROptions, WithPageAuthRequiredProps } from '../frontend/with-page-auth-required'; import { withPageAuthRequired as withPageAuthRequiredCSR } from '../frontend'; /** * If you wrap your `getServerSideProps` with {@link WithPageAuthRequired} your props object will be augmented with * the user property, which will be the user's {@link Claims} * * ```js * // pages/profile.js * import { withPageAuthRequired } from '@zeushq/nextjs-zidentity'; * * export default function Profile({ user }) { * return <div>Hello {user.name}</div>; * } * * export const getServerSideProps = withPageAuthRequired(); * ``` * * @category Server */ export type GetServerSidePropsResultWithSession = GetServerSidePropsResult<{ user?: Claims | null; [key: string]: any; }>; /** * A page route that has been augmented with {@link WithPageAuthRequired} * * @category Server */ export type PageRoute = (cts: GetServerSidePropsContext) => Promise<GetServerSidePropsResultWithSession>; /** * If you have a custom returnTo url you should specify it in `returnTo`. * * You can pass in your own `getServerSideProps` method, the props returned from this will be merged with the * user props, eg: * * ```js * // pages/protected-page.js * import { withPageAuthRequired } from '@zeushq/nextjs-zidentity'; * * export default function ProtectedPage({ user, customProp }) { * return <div>Protected content</div>; * } * * export const getServerSideProps = withPageAuthRequired({ * returnTo: '/foo', * async getServerSideProps(ctx) { * return { props: { customProp: 'bar' } }; * } * }); * ``` * * @category Server */ export type WithPageAuthRequiredOptions = { getServerSideProps?: GetServerSideProps; returnTo?: string }; /** * Wrap your `getServerSideProps` with this method to make sure the user is authenticated before visiting the page. * * ```js * // pages/protected-page.js * import { withPageAuthRequired } from '@zeushq/nextjs-zidentity'; * * export default function ProtectedPage() { * return <div>Protected content</div>; * } * * export const getServerSideProps = withPageAuthRequired(); * ``` * * If the user visits `/protected-page` without a valid session, it will redirect the user to the login page. * Then they will be returned to `/protected-page` after login. * * @category Server */ export type WithPageAuthRequired = { (opts?: WithPageAuthRequiredOptions): PageRoute; <P extends WithPageAuthRequiredProps>( Component: ComponentType<P>, options?: WithPageAuthRequiredCSROptions ): React.FC<P>; }; /** * @ignore */ export default function withPageAuthRequiredFactory(loginUrl: string, getSession: GetSession): WithPageAuthRequired { return ( optsOrComponent: WithPageAuthRequiredOptions | ComponentType<WithPageAuthRequiredProps> = {}, csrOpts?: WithPageAuthRequiredCSROptions ): any => { if (typeof optsOrComponent === 'function') { return withPageAuthRequiredCSR(optsOrComponent, csrOpts); } const { getServerSideProps, returnTo } = optsOrComponent; return async (ctx: GetServerSidePropsContext): Promise<GetServerSidePropsResultWithSession> => { assertCtx(ctx); const session = getSession(ctx.req, ctx.res); if (!session?.user) { // 10 - redirect // 9.5.4 - unstable_redirect // 9.4 - res.setHeaders return { redirect: { destination: `${loginUrl}?returnTo=${encodeURIComponent(returnTo || ctx.resolvedUrl)}`, permanent: false } }; } let ret: any = { props: {} }; if (getServerSideProps) { ret = await getServerSideProps(ctx); } return { ...ret, props: { ...ret.props, user: session.user } }; }; }; }