Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: implenment aunthentication function to protect Page components #154

Merged
55 changes: 55 additions & 0 deletions src/handlers/protect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
export {default as getKindeServerSession} from '../session/index';
import {redirect} from 'next/navigation';

/**
* A higher-order function that wraps a page component and adds protection logic.
* @param {import('react').ReactNode} page - The page component to be protected.
* @param {Object} config - The configuration options for the protection logic.
* @param {string} config.redirect - The redirect path if the user is not authenticated or does not have the required role or permissions.
* @param {string[]} config.role - The required role(s) for accessing the protected page.
* @param {string|string[]} config.permissions - The required permission(s) for accessing the protected page.
* @param {number} config.statusCode - The status code for the redirect response.
* @returns {Function} - The protected page component.
*/

const protectPage =
(page, config = {redirect: '/api/login', statusCode: 302}) =>
async (props) => {
const {isAuthenticated, getAccessToken, getPermission, getPermissions} =
kinde();
const isSignedIn = await isAuthenticated();

if (!isSignedIn) {
return redirect(config.redirect, {statusCode});
}

if (config.role) {
const token = await getAccessToken();
const roles = token?.roles;
if (!roles || !config.role.some((role) => roles.includes(role))) {
return redirect(config.redirect, {statusCode});
}
}

if (typeof config.permissions === 'string') {
const hasPermission = await getPermission(config.permissions);
if (!hasPermission) {
return redirect(config.redirect, {statusCode});
}
}

if (Array.isArray(config.permissions)) {
const permissions = await getPermissions();
if (
!config.permissions.some((permission) =>
permissions.includes(permission)
)
) {
return redirect(config.redirect, {statusCode});
}
}

return page(props);
};

export default protectPage;
1 change: 1 addition & 0 deletions src/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export {
} from '../components/index';
export {createKindeManagementAPIClient} from '../api-client';
export {default as handleAuth} from '../handlers/auth';
export {default as protectPage} from '../handlers/protect';