-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathwithPasswordProtect.tsx
More file actions
87 lines (74 loc) · 2.17 KB
/
Copy pathwithPasswordProtect.tsx
File metadata and controls
87 lines (74 loc) · 2.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import React, { ElementType, useEffect, useState } from 'react';
import { NextPageContext } from 'next';
import { useAmp } from 'next/amp';
import type { AppProps } from 'next/app';
import { NextRouter, useRouter } from 'next/router';
import {
LoginComponent as DefaultLoginComponent,
LoginComponentProps,
} from './LoginComponent';
interface PasswordProtectHOCOptions {
/* @default /api/passwordCheck */
checkApiUrl?: string;
/* @default /api/login */
loginApiUrl?: string;
loginComponent?: ElementType;
loginComponentProps?: Omit<LoginComponentProps, 'apiUrl'>;
bypassProtection?: (route: NextRouter) => boolean;
}
/// TODO: improve App typing
export const withPasswordProtect = (
App: any,
options?: PasswordProtectHOCOptions,
) => {
const ProtectedApp = ({ Component, pageProps, ...props }: AppProps) => {
const isAmp = useAmp();
const [isAuthenticated, setAuthenticated] = useState<undefined | boolean>(
undefined,
);
const router = useRouter();
const checkIfLoggedIn = async () => {
try {
const res = await fetch(options?.checkApiUrl || '/api/passwordCheck', {
credentials: 'include',
});
if (res.status === 200) {
setAuthenticated(true);
} else {
setAuthenticated(false);
}
} catch (e) {
setAuthenticated(false);
}
};
useEffect(() => {
checkIfLoggedIn();
}, []);
if (isAuthenticated === undefined) {
return null;
}
const bypassProtection = options?.bypassProtection?.(router) ?? false;
if (isAuthenticated || bypassProtection) {
return <App Component={Component} pageProps={pageProps} {...props} />;
}
// AMP is not yet supported
if (isAmp) {
return null;
}
const LoginComponent: ElementType =
options?.loginComponent || DefaultLoginComponent;
return (
<LoginComponent
apiUrl={options?.loginApiUrl}
{...(options?.loginComponentProps || {})}
/>
);
};
ProtectedApp.getInitialProps = async (ctx: NextPageContext) => {
if (App.getInitialProps) {
return App.getInitialProps(ctx);
}
return {};
};
return ProtectedApp;
};