From bbc93d12f1ad4223678a694b30819dce393ffb80 Mon Sep 17 00:00:00 2001 From: dipeshrai123 <raidipesh78@gmail.com> Date: Sat, 26 Dec 2020 14:26:26 +0545 Subject: [PATCH 1/3] Server-side redirection --- package-lock.json | 2 +- package.json | 2 +- src/index.tsx | 70 ++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index d92dac1..93f9736 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "next-auth-navigation", - "version": "1.0.2", + "version": "1.0.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 76e525b..726ee88 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "next-auth-navigation", - "version": "1.0.2", + "version": "1.0.3", "description": "NextJS Library for authentication", "main": "dist/index.js", "scripts": { diff --git a/src/index.tsx b/src/index.tsx index bb81fd2..db260ce 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -52,20 +52,28 @@ async function getLogged(context: any) { } } +type OptionType = { + redirectUri?: string; // Referes to: if not logged redirect to redirectUri + authenticatedUri?: string; // Refers to: if logged redirect to authenticatedUri + FallbackComponent?: React.ComponentType; // Referes to: if not logged in Component +}; + // Props for withAuth from getServerSideProps must contain `logged` key export const withAuth = ( WrappedComponent: React.ComponentType, - options?: { - redirectUri?: string; // Referes to: if not logged redirect to redirectUri - FallbackComponent?: React.ComponentType; // Referes to: if not logged in Component - authenticatedUri?: string; // Refers to: if logged redirect to authenticatedUri - } + options?: OptionType ) => { return ({ logged, data }: { logged: any; data: any }) => { const router = useRouter(); const redirectUri = options?.redirectUri; - const FallbackComponent = options?.FallbackComponent; const authenticatedUri = options?.authenticatedUri; + const FallbackComponent = options?.FallbackComponent; + + if (redirectUri && authenticatedUri) { + throw new Error( + "Both redirectUri and authenticatedUri mustn't be set at once." + ); + } React.useEffect(() => { if (!logged && redirectUri) { @@ -87,6 +95,28 @@ export const withAuth = ( }; }; +// Attaching redirection paths in server-side +const attachRedirection = ( + targetObject: object, + { + redirectUri, + authenticatedUri, + logged, + }: { redirectUri?: string; authenticatedUri?: string; logged: boolean } +) => { + if (!logged && redirectUri) { + targetObject["redirect"] = { + destination: redirectUri, + permanent: false, + }; + } else if (logged && authenticatedUri) { + targetObject["redirect"] = { + destination: authenticatedUri, + permanent: false, + }; + } +}; + // Callback function here acts as a `getServerSideProps` function // If callback function is not passed, then it handles basic authentication // only for `logged` key @@ -94,14 +124,25 @@ export const withAuth = ( // Callback function accepts `context` and `data` as first and second args. // data contains all the available cookies in client browser with `logged` key (always). export const withAuthServerSideProps = ( - getServerSideProps: (context: any, data: any) => any + options?: Omit<OptionType, "FallbackComponent">, + getServerSideProps?: (context: any, data: any) => any ) => { return async (context: any) => { const clientData = await getLogged(context); const { logged, ...props } = clientData; + // Redirection uris + const redirectUri = options?.redirectUri; + const authenticatedUri = options?.authenticatedUri; + + if (redirectUri && authenticatedUri) { + throw new Error( + "Both redirectUri and authenticatedUri mustn't be set at once." + ); + } + if (getServerSideProps) { - const { logged, data } = await getServerSideProps(context, clientData); + const data = await getServerSideProps(context, clientData); if (!data) { throw new Error(`Callback function cannot return ${data}`); @@ -111,15 +152,22 @@ export const withAuthServerSideProps = ( throw new Error("Callback function must return props"); } - return { + const returnObject = { props: { logged, data, }, }; + attachRedirection(returnObject, { + logged, + redirectUri, + authenticatedUri, + }); + return returnObject; } - return { + // If callback is not passed create a `props` key for WrappedComponent + const returnObject = { props: { logged, data: { @@ -130,5 +178,7 @@ export const withAuthServerSideProps = ( }, }, }; + attachRedirection(returnObject, { logged, redirectUri, authenticatedUri }); + return returnObject; }; }; From f81d168699f5762b8169f80fa24fca76049a7b02 Mon Sep 17 00:00:00 2001 From: dipeshrai123 <raidipesh78@gmail.com> Date: Sat, 26 Dec 2020 14:51:13 +0545 Subject: [PATCH 2/3] FeedbackComponent option --- src/index.tsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index db260ce..c6bdf2f 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -53,9 +53,10 @@ async function getLogged(context: any) { } type OptionType = { - redirectUri?: string; // Referes to: if not logged redirect to redirectUri + redirectUri?: string; // Refers to: if not logged redirect to redirectUri authenticatedUri?: string; // Refers to: if logged redirect to authenticatedUri - FallbackComponent?: React.ComponentType; // Referes to: if not logged in Component + FallbackComponent?: React.ComponentType; // Refers to: if not logged in Component + FeedbackComponent?: React.ComponentType; // Refers to: Loading / Redirecting component }; // Props for withAuth from getServerSideProps must contain `logged` key @@ -68,6 +69,7 @@ export const withAuth = ( const redirectUri = options?.redirectUri; const authenticatedUri = options?.authenticatedUri; const FallbackComponent = options?.FallbackComponent; + const FeedbackComponent = options?.FeedbackComponent; if (redirectUri && authenticatedUri) { throw new Error( @@ -84,7 +86,11 @@ export const withAuth = ( }, [logged, redirectUri]); if ((!logged && redirectUri) || (logged && authenticatedUri)) { - return <div>Redirecting...</div>; + return FeedbackComponent ? ( + <FeedbackComponent /> + ) : ( + <div>Redirecting...</div> + ); } if (!logged && FallbackComponent) { @@ -124,7 +130,7 @@ const attachRedirection = ( // Callback function accepts `context` and `data` as first and second args. // data contains all the available cookies in client browser with `logged` key (always). export const withAuthServerSideProps = ( - options?: Omit<OptionType, "FallbackComponent">, + options?: Pick<OptionType, "redirectUri" | "authenticatedUri">, getServerSideProps?: (context: any, data: any) => any ) => { return async (context: any) => { From 071fc99012abf990431176e7b11ebb0afb761a90 Mon Sep 17 00:00:00 2001 From: dipeshrai123 <raidipesh78@gmail.com> Date: Sat, 26 Dec 2020 14:56:32 +0545 Subject: [PATCH 3/3] Documentation update --- README.md | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 52fc4d6..a623b3a 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,6 @@ yarn add next-auth-navigation It is a NextJS Library for user authentication in client / server side. It provides basic HOC's that to wrap around pages to authenticate user very easily. - - ## Usage ### Authentication @@ -29,24 +27,20 @@ It is a NextJS Library for user authentication in client / server side. It provi - **withAuth()** and - **withAuthServerSideProps()** +#### withAuth(_Component_, _options?_) - -#### withAuth(_Component_, _options_) - -**withAuth()** accepts a _component_ for which we wan an authentication as a first argument and _options_ as a second argument. _options_ +**withAuth()** accepts a _component_ for which we wan an authentication as a first argument and _options_ as a second argument. _options_ Let us configure the _second argument_. -- **redirectUri** _( optional )_ : If the user is not logged in, user is redirected to path assigned in _redirectUri_, . +- **redirectUri** _( optional )_ : If the user is not logged in, user is redirected to path assigned in _redirectUri_. +- **authenticatedUri** _( optional )_ : If the user is logged in, user is redirected to path assigned in _authenticatedUri_. - **FallbackComponent** _( optional )_ : If the user is not logged in, Fallback component is shown on a page. +- **FeedbackComponent** _( optional )_ : Feedback component is shown when redirecting either on _redirectUri_ or _authenticatedUri_. +#### withAuthServerSideProps(_options?_, _callback?_) - -#### withAuthServerSideProps(callback) - -**withAuthServerSideProps()** is used instead of **getServerSideProps()** function on a page with **withAuth()** hoc. It is used to authenticate user in server-side. **callback** function can be provided which is acts as a **getServerSideProps()** function with _context_ as a first argument and _data_ as a second argument. - - +**withAuthServerSideProps()** is used instead of **getServerSideProps()** function on a page with **withAuth()** hoc. It is used to authenticate user in server-side. **options** is passed as a first optional argument where we can specify _redirectUri_ or _authenticatedUri_ for server-side redirection. **callback** function can be provided as second argument which acts as a **getServerSideProps()** function with _context_ as a first argument and _data_ as a second argument reffering all _cookie data_. **Example** @@ -63,8 +57,6 @@ export default withAuth(Home, { export const getServerSideProps = withAuthServerSideProps(); ``` - - ## License -MIT © [dipeshrai123](https://github.com/dipeshrai123) \ No newline at end of file +MIT © [dipeshrai123](https://github.com/dipeshrai123)