Skip to content

Commit

Permalink
Improve login/signup and create profile page, start
Browse files Browse the repository at this point in the history
  • Loading branch information
srosset81 committed Dec 12, 2022
1 parent 6603dc8 commit 22e5f1c
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 17 deletions.
128 changes: 128 additions & 0 deletions src/frontend/packages/auth-provider/src/components/PodLoginPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import React, { useEffect } from 'react';
import jwtDecode from 'jwt-decode';
import { useNotify, useAuthProvider, Notification } from 'react-admin';
import { ThemeProvider } from '@material-ui/styles';
import { createTheme, makeStyles } from '@material-ui/core/styles';
import { Avatar, Button, Card, CardActions, Typography } from '@material-ui/core';
import LockIcon from '@material-ui/icons/Lock';

const useStyles = makeStyles(theme => ({
main: {
display: 'flex',
flexDirection: 'column',
minHeight: '100vh',
alignItems: 'center',
justifyContent: 'flex-start',
backgroundColor: theme.palette.grey['300']
},
text: {
maxWidth: 300,
textAlign: 'center',
padding: '4px 8px 8px'
},
card: {
minWidth: 300,
marginTop: '6em'
},
lockIconAvatar: {
margin: '1em',
display: 'flex',
justifyContent: 'center'
},
lockIcon: {
backgroundColor: theme.palette.grey['500']
}
}));

const PodLoginPage = ({ theme, history, location, podProviders, text }) => {
const classes = useStyles();
const notify = useNotify();
const authProvider = useAuthProvider();
const searchParams = new URLSearchParams(location.search);

useEffect(() => {
(async () => {
if (searchParams.has('login')) {
if (searchParams.has('error')) {
if (searchParams.get('error') === 'registration.not-allowed') {
notify('auth.message.user_email_not_found', 'error');
} else {
notify('auth.message.bad_request', 'error', { error: searchParams.get('error') });
}
} else if (searchParams.has('token')) {
const token = searchParams.get('token');
const { webId } = jwtDecode(token);
const response = await fetch(webId, {
headers: {
Accept: 'application/json'
}
});
if (!response.ok) {
notify('auth.message.unable_to_fetch_user_data', 'error');
} else {
const data = await response.json();
if (!authProvider.checkUser(data)) {
notify('auth.message.user_not_allowed_to_login', 'error');
history.replace('/login');
} else {
localStorage.setItem('token', token);
if (searchParams.has('new') && searchParams.get('new') === 'true') {
notify('auth.message.new_user_created', 'info');
// TODO allow to attach profile to container ?
} else {
notify('auth.message.user_connected', 'info');
}
history.push('/');
}
}
}
}

if (searchParams.has('logout')) {
localStorage.removeItem('token');
notify('auth.message.user_disconnected', 'info');
history.push('/');
}
})();
}, [searchParams]);

return (
<ThemeProvider theme={createTheme(theme)}>
<div className={classes.main}>
<Card className={classes.card}>
<div className={classes.lockIconAvatar}>
<Avatar className={classes.lockIcon}>
<LockIcon />
</Avatar>
</div>
{text && (
<Typography variant="body2" className={classes.text}>
{text}
</Typography>
)}
{podProviders &&
podProviders.map((podProvider, i) => {
const url = new URL('/auth', podProvider);
if (searchParams.has('signup')) url.searchParams.set('signup', 'true');
url.searchParams.set('redirect', window.location.href);
return (
<CardActions key={i}>
<Button
fullWidth
variant="outlined"
type="submit"
onClick={() => (window.location.href = url.toString())}
>
{url.host}
</Button>
</CardActions>
);
})}
</Card>
</div>
<Notification />
</ThemeProvider>
);
};

export default PodLoginPage;
15 changes: 1 addition & 14 deletions src/frontend/packages/auth-provider/src/components/SignupForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,23 +85,10 @@ const SignupForm = ({ redirectTo, delayBeforeRedirect }) => {
<Form
onSubmit={submit}
validate={validate}
initialValues={{
name: searchParams.get('name'),
email: searchParams.get('email')
}}
initialValues={{ email: searchParams.get('email') }}
render={({ handleSubmit }) => (
<form onSubmit={handleSubmit} noValidate>
<div className={classes.form}>
<div className={classes.input}>
<Field
autoFocus
id="name"
name="name"
component={Input}
label={translate('auth.input.name')}
disabled={loading}
/>
</div>
<div className={classes.input}>
<Field
id="username"
Expand Down
12 changes: 10 additions & 2 deletions src/frontend/packages/auth-provider/src/components/UserMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,16 @@ const UserMenu = ({ logout, ...otherProps }) => {
<RaUserMenu {...otherProps}>
{identity && identity.id !== ''
? [
<ViewProfileMenu webId={identity.id} label={translate('auth.action.view_my_profile')} key="view" />,
<EditProfileMenu webId={identity.id} label={translate('auth.action.edit_my_profile')} key="edit" />,
<ViewProfileMenu
webId={identity?.profileData?.id || identity.id}
label={translate('auth.action.view_my_profile')}
key="view"
/>,
<EditProfileMenu
webId={identity?.profileData?.id || identity.id}
label={translate('auth.action.edit_my_profile')}
key="edit"
/>,
React.cloneElement(logout, { key: 'logout' })
]
: [
Expand Down
1 change: 1 addition & 0 deletions src/frontend/packages/auth-provider/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export { default as ShowActionsWithPermissions } from './crud/show/ShowActionsWi
export { default as PermissionsButton } from './components/PermissionsButton/PermissionsButton';
export { default as AuthDialog } from './components/AuthDialog';
export { default as SsoLoginPage, default as LoginPage } from './components/SsoLoginPage';
export { default as PodLoginPage } from './components/PodLoginPage';
export { default as LocalLoginPage } from './components/LocalLoginPage';
export { default as LogoutButton } from './components/LogoutButton';
export { default as ResourceWithPermissions } from './components/ResourceWithPermissions';
Expand Down
22 changes: 21 additions & 1 deletion src/middleware/packages/auth/services/auth.local.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const AuthLocalService = {
reservedUsernames: [],
webIdSelection: [],
accountSelection: [],
formUrl: null,
mail: {
from: null,
transport: {
Expand Down Expand Up @@ -71,6 +72,18 @@ const AuthLocalService = {

return { token, webId: accountData.webId, newUser: false };
},
async redirectToForm(ctx) {
if (this.settings.formUrl) {
const formUrl = new URL(this.settings.formUrl);
for (let [key, value] of Object.entries(ctx.params)) {
formUrl.searchParams.set(key, value);
}
ctx.meta.$statusCode = 302;
ctx.meta.$location = formUrl.toString();
} else {
throw new Error('No formUrl defined in auth.local settings')
}
},
async resetPassword(ctx) {
const { email } = ctx.params;

Expand Down Expand Up @@ -136,6 +149,13 @@ const AuthLocalService = {
}
};

const formRoute = {
path: '/auth',
aliases: {
'GET /': 'auth.redirectToForm'
}
};

const resetPasswordRoute = {
path: '/auth/reset_password',
aliases: {
Expand All @@ -158,7 +178,7 @@ const AuthLocalService = {
authorization: true
};

const routes = [loginRoute, resetPasswordRoute, setNewPasswordRoute, accountSettingsRoute];
const routes = [loginRoute, formRoute, resetPasswordRoute, setNewPasswordRoute, accountSettingsRoute];

if (this.settings.registrationAllowed) {
return [...routes, signupRoute];
Expand Down

0 comments on commit 22e5f1c

Please sign in to comment.