fix issues related to user login and logout

This commit is contained in:
Nuwan 2021-11-11 16:54:00 +05:30
parent 2438e45a1b
commit 4ef2dcdc04
22 changed files with 156 additions and 93 deletions

View File

@ -0,0 +1,31 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Redirect, Route, Switch, withRouter } from 'react-router-dom';
import Login from './Login';
// import Start from './Start';
// import Logout from './Logout';
// import Registration from './Registration';
// import ForgetPassword from './ForgetPassword';
// import PasswordReset from './PasswordReset';
// import ConfirmMail from './ConfirmMail';
// import LockScreen from './LockScreen';
const AuthBasicRoutes = ({ match: { url } }) => (
<Switch>
<Route path={`${url}/login`} exact component={Login} />
{/* <Route path={`${url}/start`} exact component={Start} />
<Route path={`${url}/logout`} exact component={Logout} />
<Route path={`${url}/register`} exact component={Registration} />
<Route path={`${url}/forget-password`} exact component={ForgetPassword} />
<Route path={`${url}/confirm-mail`} exact component={ConfirmMail} />
<Route path={`${url}/password-reset`} exact component={PasswordReset} />
<Route path={`${url}/lock-screen`} exact component={LockScreen} /> */}
{/*Redirect*/}
<Redirect to="/errors/404" />
</Switch>
);
AuthBasicRoutes.propTypes = { match: PropTypes.object.isRequired };
export default withRouter(AuthBasicRoutes);

View File

@ -2,18 +2,25 @@ import React, { Fragment } from 'react';
import { Col, Row } from 'reactstrap'; import { Col, Row } from 'reactstrap';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import LoginForm from '../LoginForm'; import LoginForm from '../LoginForm';
import { useTranslation } from "react-i18next";
//const {t} = useTranslation();
const Login = () => ( const Login = () => (
<Fragment> <Fragment>
<Row className="text-left justify-content-between"> <Row className="text-left justify-content-between">
<Col xs="auto"> <Col xs="auto">
<h5>Sign in</h5> <h5>Sign in</h5>
</Col> </Col>
{/* <Col xs="auto"> <Col xs="auto">
<p className="fs--1 text-600"> <p className="fs--1 text-600">
or <Link to="/authentication/basic/register">create an account</Link> or {' '}
{/* <Link to="/authentication/basic/register">create an account</Link> */}
<a href={`${process.env.REACT_APP_LEGACY_BASE_URL}/signup`}>Sign up</a>
</p> </p>
</Col> */} </Col>
</Row> </Row>
<LoginForm /> <LoginForm />
</Fragment> </Fragment>

View File

@ -1,14 +0,0 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
function JKDashboardLoadingIndicator() {
const {t} = useTranslation();
return (
<div className="spinner-border" role="status">
<span className="sr-only">{t('loading', {ns: 'common'})}...</span>
</div>
)
}
export default JKDashboardLoadingIndicator

View File

@ -10,10 +10,12 @@ import AppContext from '../../context/Context';
import { getPageName } from '../../helpers/utils'; import { getPageName } from '../../helpers/utils';
import useScript from '../../hooks/useScript'; import useScript from '../../hooks/useScript';
import { useDispatch } from "react-redux"; import { useDispatch } from 'react-redux';
import { addMessage } from "../../store/features/textMessagesSlice" import { addMessage } from '../../store/features/textMessagesSlice';
import { add as addNotification } from '../../store/features/notificationSlice'; import { add as addNotification } from '../../store/features/notificationSlice';
import { useAuth } from '../../context/UserAuth';
import Home from './JKHomePage'; import Home from './JKHomePage';
import loadable from '@loadable/component'; import loadable from '@loadable/component';
@ -23,11 +25,13 @@ function JKDashboard() {
const { isFluid, isVertical, navbarStyle } = useContext(AppContext); const { isFluid, isVertical, navbarStyle } = useContext(AppContext);
const isKanban = getPageName('kanban'); const isKanban = getPageName('kanban');
const { isAuthenticated, currentUser, setCurrentUser, logout } = useAuth();
useEffect(() => { useEffect(() => {
DashboardRoutes.preload(); DashboardRoutes.preload();
}, []); }, []);
const dispatch = useDispatch() const dispatch = useDispatch();
const initJKScripts = () => { const initJKScripts = () => {
const app = window.JK.JamKazam(); const app = window.JK.JamKazam();
@ -52,7 +56,7 @@ function JKDashboard() {
registerTextMessageCallback(); registerTextMessageCallback();
registerFriendRequest(); registerFriendRequest();
registerFriendRequestAccepted(); registerFriendRequestAccepted();
} };
const registerTextMessageCallback = () => { const registerTextMessageCallback = () => {
window.JK.JamServer.registerMessageCallback(window.JK.MessageType.TEXT_MESSAGE, function(header, payload) { window.JK.JamServer.registerMessageCallback(window.JK.MessageType.TEXT_MESSAGE, function(header, payload) {
@ -67,29 +71,32 @@ function JKDashboard() {
receiverName: window.currentUser.first_name, receiverName: window.currentUser.first_name,
createdAt: payload.created_at, createdAt: payload.created_at,
sent: true sent: true
} };
dispatch(addMessage(msg)) dispatch(addMessage(msg));
handleNotification(payload, header.type); handleNotification(payload, header.type);
}); });
} };
const registerFriendRequest = () => { const registerFriendRequest = () => {
window.JK.JamServer.registerMessageCallback(window.JK.MessageType.FRIEND_REQUEST, function(header, payload) { window.JK.JamServer.registerMessageCallback(window.JK.MessageType.FRIEND_REQUEST, function(header, payload) {
console.log('registerFriendRequest payload', payload); console.log('registerFriendRequest payload', payload);
console.log('registerFriendRequest header', header); console.log('registerFriendRequest header', header);
handleNotification(payload, header.type); handleNotification(payload, header.type);
}) });
} };
const registerFriendRequestAccepted = () => { const registerFriendRequestAccepted = () => {
window.JK.JamServer.registerMessageCallback(window.JK.MessageType.FRIEND_REQUEST_ACCEPTED, function(header, payload) { window.JK.JamServer.registerMessageCallback(window.JK.MessageType.FRIEND_REQUEST_ACCEPTED, function(
header,
payload
) {
console.log('registerFriendRequestAccepted payload', payload); console.log('registerFriendRequestAccepted payload', payload);
console.log('registerFriendRequestAccepted header', header); console.log('registerFriendRequestAccepted header', header);
handleNotification(payload, header.type); handleNotification(payload, header.type);
}) });
} };
const handleNotification = (payload, type) => { const handleNotification = (payload, type) => {
const notification = { const notification = {
@ -105,32 +112,39 @@ function JKDashboard() {
name: payload.sender_name name: payload.sender_name
}, },
created_at: payload.created_at created_at: payload.created_at
} };
try { try {
dispatch(addNotification(notification)); dispatch(addNotification(notification));
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
};
}
useScript(`${process.env.REACT_APP_LEGACY_BASE_URL}/client_scripts`, initJKScripts); useScript(`${process.env.REACT_APP_LEGACY_BASE_URL}/client_scripts`, initJKScripts);
return ( return (
<div className={isFluid || isKanban ? 'container-fluid' : 'container'}> <>
{isVertical && <NavbarVertical isKanban={isKanban} navbarStyle={navbarStyle} />} {isAuthenticated ? (
<div className={isFluid || isKanban ? 'container-fluid' : 'container'}>
<div className="content"> {isVertical && <NavbarVertical isKanban={isKanban} navbarStyle={navbarStyle} />}
<NavbarTop />
<Switch> <div className="content">
<PrivateRoute path="/" exact component={Home} /> <NavbarTop />
<DashboardRoutes /> <Switch>
</Switch> <PrivateRoute path="/" exact component={Home} />
{!isKanban && <Footer />} <DashboardRoutes />
</Switch>
{!isKanban && <Footer />}
</div>
{/* <SidePanelModal path={location.pathname} /> */}
</div> </div>
{/* <SidePanelModal path={location.pathname} /> */} ) : (
</div> <Switch>
<PrivateRoute path="/" exact component={Home} />
</Switch>
)}
</>
); );
} }

View File

@ -1,5 +1,5 @@
import React, {useEffect} from "react"; import React, {useEffect} from "react";
import { useAuth } from '../../context/AuthContext'; import { useAuth } from '../../context/UserAuth';
import avatar from "../../assets/img/team/avatar.png"; import avatar from "../../assets/img/team/avatar.png";
const JKCurrentUserAvatar = () => { const JKCurrentUserAvatar = () => {

View File

@ -4,13 +4,14 @@ import { DropdownItem, DropdownMenu, DropdownToggle, Dropdown } from 'reactstrap
import { useAuth } from '../../context/UserAuth'; import { useAuth } from '../../context/UserAuth';
import JKProfileAvatar from '../profile/JKProfileAvatar'; import JKProfileAvatar from '../profile/JKProfileAvatar';
import { useCookies } from 'react-cookie'; import { useCookies } from 'react-cookie';
import { useHistory } from "react-router-dom";
const ProfileDropdown = () => { const ProfileDropdown = () => {
const [dropdownOpen, setDropdownOpen] = useState(false); const [dropdownOpen, setDropdownOpen] = useState(false);
const toggle = () => setDropdownOpen(prevState => !prevState); const toggle = () => setDropdownOpen(prevState => !prevState);
const { currentUser, setCurrentUser, logout } = useAuth(); const { isAuthenticated, currentUser, setCurrentUser, logout } = useAuth();
const [cookies, setCookie, removeCookie] = useCookies(['remember_token']); const [cookies, setCookie, removeCookie] = useCookies(['remember_token']);
const history = useHistory();
const handleLogout = async (event) => { const handleLogout = async (event) => {
event.preventDefault(); event.preventDefault();
@ -18,12 +19,13 @@ const ProfileDropdown = () => {
domain: `.${process.env.REACT_APP_ORIGIN}` domain: `.${process.env.REACT_APP_ORIGIN}`
}); });
setCurrentUser(null); setCurrentUser(null);
logout() await logout()
history.push('/')
}; };
return ( return (
<> <>
{currentUser && {isAuthenticated &&
<Dropdown <Dropdown
nav nav
inNavbar inNavbar

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import ProfileAvatar from '../profile/JKProfileAvatar' import ProfileAvatar from '../profile/JKProfileAvatar'
import TimeAgo from '../common/JKTimeAgo'; import TimeAgo from '../common/JKTimeAgo';
import { useAuth } from '../../context/AuthContext'; import { useAuth } from '../../context/UserAuth';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { acceptFriendRequest } from '../../store/features/peopleSlice'; import { acceptFriendRequest } from '../../store/features/peopleSlice';
import { Button } from 'reactstrap'; import { Button } from 'reactstrap';

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useAuth } from '../../context/AuthContext'; import {useAuth} from '../../context/UserAuth';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { removeNotification } from '../../store/features/notificationSlice'; import { removeNotification } from '../../store/features/notificationSlice';
@ -14,9 +14,9 @@ import classNames from 'classnames';
function JKNotification(props) { function JKNotification(props) {
const { description, notification_id } = props.notification const { description, notification_id } = props.notification
const { currentUser } = useAuth();
const dispatch = useDispatch(); const dispatch = useDispatch();
const { currentUser } = useAuth()
const handleOnAccept = () => { const handleOnAccept = () => {
deleteNotification(); deleteNotification();
} }

View File

@ -1,5 +1,5 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { useAuth } from '../../context/AuthContext'; import { useAuth } from '../../context/UserAuth';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { fetchPerson, add as addPerson } from '../../store/features/peopleSlice'; import { fetchPerson, add as addPerson } from '../../store/features/peopleSlice';
import JKMessageButton from '../profile/JKMessageButton'; import JKMessageButton from '../profile/JKMessageButton';

View File

@ -7,7 +7,7 @@ import { isIterableArray } from '../../helpers/utils';
import { fetchNotifications } from '../../store/features/notificationSlice'; import { fetchNotifications } from '../../store/features/notificationSlice';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { useAuth } from '../../context/AuthContext'; import { useAuth } from '../../context/UserAuth';
const JKNotifications = () => { const JKNotifications = () => {
const { currentUser } = useAuth(); const { currentUser } = useAuth();

View File

@ -7,6 +7,7 @@ import { useAuth } from '../../context/UserAuth';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { fetchMessagesByReceiverId, postNewMessage } from '../../store/features/textMessagesSlice'; import { fetchMessagesByReceiverId, postNewMessage } from '../../store/features/textMessagesSlice';
import { isIterableArray } from '../../helpers/utils'; import { isIterableArray } from '../../helpers/utils';
import PropTypes from 'prop-types';
const JKMessageModal = props => { const JKMessageModal = props => {
const { show, setShow, user } = props; const { show, setShow, user } = props;
@ -200,4 +201,10 @@ const JKMessageModal = props => {
); );
}; };
JKMessageModal.propTypes = {
user: PropTypes.object.isRequired,
show: PropTypes.bool.isRequired,
setShow: PropTypes.func.isRequired
};
export default JKMessageModal; export default JKMessageModal;

View File

@ -12,16 +12,17 @@ export default function UserAuth({ children, path }) {
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
useEffect(() => { useEffect(() => {
console.log('checking auth........', path); //console.log('checking auth for', path);
checkAuth(); checkAuth();
}, [path]); }, [path]);
const checkAuth = () => const checkAuth = () =>
checkIsAuthenticated() checkIsAuthenticated()
.then(resp => resp.json())
.then((user) => { .then((user) => {
setIsAuthenticated(true)
setCurrentUser(user)
window.currentUser = user; window.currentUser = user;
setCurrentUser(user)
setIsAuthenticated(true)
}) })
.catch(() => { .catch(() => {
setIsAuthenticated(false) setIsAuthenticated(false)

View File

@ -3,6 +3,7 @@ import { Route, Redirect } from 'react-router-dom';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { UserAuthContext } from '../context/UserAuth'; import { UserAuthContext } from '../context/UserAuth';
//import Loading from '../../views/Loading/Loading'; //import Loading from '../../views/Loading/Loading';
//import Loader from '../components/common/Loader';
const PrivateRoute = ({ component: Component, ...otherProps }) => { const PrivateRoute = ({ component: Component, ...otherProps }) => {
const { isAuthenticated, isLoading } = useContext(UserAuthContext); const { isAuthenticated, isLoading } = useContext(UserAuthContext);
@ -18,7 +19,7 @@ const PrivateRoute = ({ component: Component, ...otherProps }) => {
<Redirect to={otherProps.redirectTo ? otherProps.redirectTo : '/authentication/basic/login'} /> <Redirect to={otherProps.redirectTo ? otherProps.redirectTo : '/authentication/basic/login'} />
) )
) : ( ) : (
// <Loading /> // <Loader animation="grow" variant="primary" />
<span>loading...</span> <span>loading...</span>
) )
} }

View File

@ -1,17 +0,0 @@
import { useAuth } from "../context/AuthContext";
import { Route, Redirect } from "react-router-dom";
const ProtectedRoute = ({component: Component, ...rest}) => {
const {currentUser} = useAuth();
return (
// Show the component only when the user is logged in
// Otherwise, redirect the user to /login page
<Route {...rest} render={props => (
currentUser ?
<Component {...props} />
: <Redirect to={{pathname: '/authentication/basic/start'}} />
)} />
);
};
export default ProtectedRoute;

View File

@ -4,10 +4,12 @@ import { initReactI18next } from "react-i18next";
import commonTranslationsEN from './locales/en/common.json' import commonTranslationsEN from './locales/en/common.json'
import homeTranslationsEN from './locales/en/home.json' import homeTranslationsEN from './locales/en/home.json'
import peopleTranslationsEN from './locales/en/people.json' import peopleTranslationsEN from './locales/en/people.json'
import authTranslationsEN from './locales/en/auth.json'
import commonTranslationsES from './locales/es/common.json' import commonTranslationsES from './locales/es/common.json'
import homeTranslationsES from './locales/es/home.json' import homeTranslationsES from './locales/es/home.json'
import peopleTranslationsES from './locales/es/people.json' import peopleTranslationsES from './locales/es/people.json'
import authTranslationsES from './locales/es/auth.json'
i18n.use(initReactI18next).init({ i18n.use(initReactI18next).init({
fallbackLng: 'en', fallbackLng: 'en',
@ -17,13 +19,15 @@ i18n.use(initReactI18next).init({
//translations: require('./locales/en/translations.json') //translations: require('./locales/en/translations.json')
common: commonTranslationsEN, common: commonTranslationsEN,
home: homeTranslationsEN, home: homeTranslationsEN,
people: peopleTranslationsEN people: peopleTranslationsEN,
auth: authTranslationsEN
}, },
es: { es: {
//translations: require('./locales/es/translations.json') //translations: require('./locales/es/translations.json')
common: commonTranslationsES, common: commonTranslationsES,
home: homeTranslationsES, home: homeTranslationsES,
people: peopleTranslationsES people: peopleTranslationsES,
auth: authTranslationsES
} }
}, },
//ns: ['translations'], //ns: ['translations'],

View File

@ -0,0 +1,4 @@
{
"signup": "Sign up",
"signin": "Sign in"
}

View File

@ -0,0 +1,4 @@
{
"signup": "Sign up",
"signin": "Sign in"
}

View File

@ -3,18 +3,15 @@ import { Card, CardBody, Col, Row } from 'reactstrap';
import Logo from '../components/navbar/Logo'; import Logo from '../components/navbar/Logo';
import Section from '../components/common/Section'; import Section from '../components/common/Section';
import AuthBasicRoutes from '../components/auth/basic/AuthBasicRoutes'; import AuthBasicRoutes from '../components/auth/basic/AuthBasicRoutes';
import UserAuth from '../context/UserAuth';
const AuthBasicLayout = ({location}) => ( const AuthBasicLayout = () => (
<Section className="py-0"> <Section className="py-0">
<Row className="flex-center min-vh-100 py-6"> <Row className="flex-center min-vh-100 py-6">
<Col sm={10} md={8} lg={6} xl={5} className="col-xxl-4"> <Col sm={10} md={8} lg={6} xl={5} className="col-xxl-4">
<Logo /> <Logo />
<Card> <Card>
<CardBody className="fs--1 font-weight-normal p-5"> <CardBody className="fs--1 font-weight-normal p-5">
<UserAuth path={location.pathname}>
<AuthBasicRoutes /> <AuthBasicRoutes />
</UserAuth>
</CardBody> </CardBody>
</Card> </Card>
</Col> </Col>

View File

@ -0,0 +1,25 @@
import React from 'react';
import { Card, CardBody, Col, Row } from 'reactstrap';
import Logo from '../components/navbar/Logo';
import Section from '../components/common/Section';
import AuthBasicRoutes from '../components/auth/basic/JKAuthBasicRoutes';
import UserAuth from '../context/UserAuth';
const AuthBasicLayout = ({location}) => (
<Section className="py-0">
<Row className="flex-center min-vh-100 py-6">
<Col sm={10} md={8} lg={6} xl={5} className="col-xxl-4">
<Logo width="200"/>
<Card>
<CardBody className="fs--1 font-weight-normal p-5">
<UserAuth path={location.pathname}>
<AuthBasicRoutes />
</UserAuth>
</CardBody>
</Card>
</Col>
</Row>
</Section>
);
export default AuthBasicLayout;

View File

@ -8,7 +8,7 @@ import ErrorLayout from './ErrorLayout';
import BuildMeta from "./JKBuildMeta"; import BuildMeta from "./JKBuildMeta";
import loadable from '@loadable/component'; import loadable from '@loadable/component';
const AuthBasicLayout = loadable(() => import('./AuthBasicLayout')); const AuthBasicLayout = loadable(() => import('./JKAuthBasicLayout'));
const Layout = () => { const Layout = () => {
useEffect(() => { useEffect(() => {

View File

@ -3,11 +3,6 @@ import apiFetch from "../helpers/apiFetch";
import { reject } from 'lodash'; import { reject } from 'lodash';
export const checkIsAuthenticated = () => { export const checkIsAuthenticated = () => {
// return new Promise((resolve, reject) => {
// getCurrentUser()
// .then((resp) => resolve(resp.json()))
// .catch((err) => reject(err))
// });
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
apiFetch('/me') apiFetch('/me')
.then(response => resolve(response)) .then(response => resolve(response))
@ -30,7 +25,9 @@ export const authLogin = (credentials) => {
export const authLogout = () => { export const authLogout = () => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
apiFetch('/auths/logout') apiFetch('/auths/logout', {
method: 'DELETE'
})
.then((response) => resolve(response)) .then((response) => resolve(response))
.catch((error) => reject(error)) .catch((error) => reject(error))
}) })

View File

@ -252,7 +252,7 @@ Rails.application.routes.draw do
scope '/api' do scope '/api' do
post '/auths/login' => 'api_auths#login' post '/auths/login' => 'api_auths#login'
post '/auths/logout' => 'api_auths#logout' delete '/auths/logout' => 'api_auths#logout'
# live streams # live streams
match '/live_streams' => 'api_live_streams#index', :via => :get match '/live_streams' => 'api_live_streams#index', :via => :get