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

customRoutes are not allowed for unauthenticated users when the Admin is being used with renderProps #6342

Closed
gabrielperales opened this issue Jun 9, 2021 · 4 comments
Labels

Comments

@gabrielperales
Copy link

What you were expecting:
I have some custom routes like /recoverPassword where I should be able to access when I'm not logged in.

What happened instead:
I can't access that route and instead, it redirects to /login

Steps to reproduce:

  • Create some custom routes
  • Use a function as children on the Admin component
  • Try to access some of your customs routes

Related code:

codesandbox.io/s/epic-kepler-cii3c

  • Meanwhile my version without using renderProps works

codesandbox.io/s/determined-torvalds-l48rl

Other information:
Related issues :

The issue is produced by these lines of the code in ra-core package:

https://github.com/marmelab/react-admin/blob/master/packages/ra-core/src/core/CoreAdminRouter.tsx#L47-L54

I think it shouldn't call doLogout in these https://github.com/marmelab/react-admin/blob/master/packages/ra-core/src/core/CoreAdminRouter.tsx#L82 but I have to do some tests.

Environment

  • React-admin version:
    "version": "3.16.0"

  • React version:
    "version": "17.0.1"

@DanielSanchez94
Copy link

Hello Gabriel, how are you doing?

Look, the only thing I can help you with is share my app.js and my customRoutes.js:

import React from 'react';
import { Admin, Resource } from 'react-admin';
import adapterDataProvider from './auth/adapterDataProvider';
import i18nProvider from './i18n/es';
import categories from './categories';
import sales from './sales';
import sellers from './sellers';
import MyLayout from './globalTheme/MyLayout';
import MyTheme from './globalTheme/MyTheme';
import MyLogoutButton from './globalTheme/MyLogoutButton';
import authProvider from "./auth/authProvider";
import MyLogin from './login/MyLogin';
import NotFound from './globalTheme/NotFound';
import ShopIcon from '@material-ui/icons/Shop';
import ProductCreate from './products/create';
import ProductEdit from './products/edit';
import { ProductList } from './products/products';
import customRoutes from './customRoutes';
import { Redirect } from 'react-router-dom';

const App = ( ) => (
    <Admin 
        title="Simple Comercio"
        theme={ MyTheme } 
        disableTelemetry
        catchAll={ NotFound }
        authProvider= { authProvider }
        i18nProvider={ i18nProvider }
        layout={ MyLayout } 
        dataProvider={ adapterDataProvider } 
        loginPage={ MyLogin } 
        customRoutes={ customRoutes }
        logoutButton={MyLogoutButton}
    >
        { permissions => { 
            switch (true) {
                case (!permissions) :
                    return [];
                case (permissions.hasOwnProperty('admin')) :
                    return [
                        <Resource name="product" 
                            options={{ label: 'Productos', permissions: permissions }} 
                            list={ ProductList } 
                            icon={ ShopIcon }
                            edit={ ProductEdit }
                            create={ ProductCreate }/>,
                        <Resource {...categories} />,
                        <Resource {...sellers} />,]
                case (permissions.seller) :
                    return [
                        <Resource name="product" 
                            options={{ label: 'Productos', permissions: permissions }} 
                            list={ ProductList } 
                            create={ ProductCreate } 
                            edit={ ProductEdit } 
                            icon={ ShopIcon }/>,
                        <Resource {...categories} />,
                        <Resource {...sales} />, ]
                case (permissions.hasOwnProperty('seller') && !permissions.seller) :
                    return [ <Redirect to="/seller-pending" /> ]
                default: 
                    return [<Redirect to="/role-option" />];
            }
        }}
    </Admin>
)



export default App;
import * as React from "react";
import { Route } from 'react-router-dom';
import SignUpForm from './login/SignUpForm';
import ForgotPasswordForm from './login/ForgotPasswordForm';
import ResetPasswordForm from './login/ResetPasswordForm';
import SellerForm from './login/SellerForm';
import RoleOption from "./login/RoleOption";
import SellerPending from "./login/SellerPending";
import Dashboard from "./dashboard/dashboard";
import PathOption from './login/PathOption';
import {ProfileEdit} from "./profile/ProfileEdit";

const customRoutes = [     
    <Route 
        exact 
        path='/' 
        component={(props) => <PathOption {...props} />}
        noLayout
    />,
    <Route
        exact
        path="/signup"
        component={(props) => <SignUpForm {...props} />}
        noLayout
    />,
    <Route
        exact
        path="/forgot-password"
        component={(props) => <ForgotPasswordForm {...props} />}
        noLayout
    />,
    <Route
        exact
        path="/reset-password"
        component={(props) => <ResetPasswordForm {...props} />}
        noLayout
    />,
    <Route
        exact
        path="/seller-form"
        component={(props) => <SellerForm {...props} />}
        noLayout
    />,
    <Route
        exact
        path="/role-option"
        component={(props) => <RoleOption {...props} />}
        noLayout
    />,
    <Route
        exact
        path="/seller-pending"
        component={(props) => <SellerPending {...props} />}
        noLayout
    />,
    <Route
        exact
        path="/home"
        component={(props) => <Dashboard {...props} />}
    />,
    <Route
        key="profile"
        path="/profile"
        component={(props) => <ProfileEdit {...props} />} 
    />,
    
];

export default customRoutes;

Pay close attention to the noLayout, and also note that when you need to have an authenticated view that is not a resource, you can use useAuthenticated.

Hopefully this information can be of use to you, greetings.

@gabrielperales
Copy link
Author

I think I know what is happening. I think the issue is related to the authProvider, which is throwing an error when it is trying to the permissions when the user is not authenticated and it shouldn't

@djhi
Copy link
Contributor

djhi commented Jun 11, 2021

Thanks for the detailed report.

@djhi djhi added the bug label Jun 11, 2021
@djhi
Copy link
Contributor

djhi commented Jun 11, 2021

@gabrielperales In https://codesandbox.io/s/epic-kepler-cii3c, an error is happening because the authProvider.getPermissions return undefined, so calling permission.hasOwnProperty("admin") in the Admin render function fails which leads to a logout. It should return an empty object instead or you should check for the permissions object not being undefined first.

See https://codesandbox.io/s/beautiful-lalande-5z7b0?file=/src/App.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants