Authenticate UI

This commit is contained in:
Deluan
2020-01-20 09:54:29 -05:00
parent 6785d616d0
commit e717d99780
14 changed files with 313 additions and 22 deletions
+7 -3
View File
@@ -1,13 +1,17 @@
// in src/App.js
import React from 'react'
import { Admin, Resource } from 'react-admin'
import jsonServerProvider from 'ra-data-json-server'
import dataProvider from './dataProvider'
import authProvider from './authProvider'
import { Login } from './layout'
import user from './user'
const dataProvider = jsonServerProvider('/app/api')
const App = () => (
<Admin dataProvider={dataProvider} loginPage={Login}>
<Admin
dataProvider={dataProvider}
authProvider={authProvider}
loginPage={Login}
>
<Resource name="user" {...user} />
</Admin>
)
+71
View File
@@ -0,0 +1,71 @@
import jwtDecode from 'jwt-decode'
const authProvider = {
login: ({ username, password }) => {
const request = new Request('/app/login', {
method: 'POST',
body: JSON.stringify({ username, password }),
headers: new Headers({ 'Content-Type': 'application/json' })
})
return fetch(request)
.then((response) => {
if (response.status < 200 || response.status >= 300) {
throw new Error(response.statusText)
}
return response.json()
})
.then((response) => {
// Validate token
jwtDecode(response.token)
localStorage.setItem('token', response.token)
localStorage.setItem('name', response.name)
localStorage.setItem('username', response.username)
return response
})
.catch((error) => {
if (
error.message === 'Failed to fetch' ||
error.stack === 'TypeError: Failed to fetch'
) {
throw new Error('errors.network_error')
}
throw new Error(error)
})
},
logout: () => {
removeItems()
return Promise.resolve()
},
checkAuth: () => {
try {
const expireTime = jwtDecode(localStorage.getItem('token')).exp * 1000
const now = new Date().getTime()
return now < expireTime ? Promise.resolve() : Promise.reject()
} catch (e) {
return Promise.reject()
}
},
checkError: (error) => {
const { status } = error
// TODO Remove 403?
if (status === 401 || status === 403) {
removeItems()
return Promise.reject()
}
return Promise.resolve()
},
getPermissions: (params) => Promise.resolve()
}
const removeItems = () => {
localStorage.removeItem('token')
localStorage.removeItem('name')
localStorage.removeItem('username')
}
export default authProvider
+23
View File
@@ -0,0 +1,23 @@
import { fetchUtils } from 'react-admin'
import jsonServerProvider from 'ra-data-json-server'
const httpClient = (url, options = {}) => {
if (!options.headers) {
options.headers = new Headers({ Accept: 'application/json' })
}
const token = localStorage.getItem('token')
if (token) {
options.headers.set('Authorization', `Bearer ${token}`)
}
return fetchUtils.fetchJson(url, options).then((response) => {
const token = response.headers.get('authorization')
if (token) {
localStorage.setItem('token', token)
}
return response
})
}
const dataProvider = jsonServerProvider('/app/api', httpClient)
export default dataProvider
+3
View File
@@ -5,13 +5,16 @@ import {
TextInput,
PasswordInput,
required,
email,
SimpleForm
} from 'react-admin'
const UserCreate = (props) => (
<Create {...props}>
<SimpleForm redirect="list">
<TextInput source="userName" validate={[required()]} />
<TextInput source="name" validate={[required()]} />
<TextInput source="email" validate={[required(), email()]} />
<PasswordInput source="password" validate={[required()]} />
<BooleanInput source="isAdmin" initialValue={false} />
</SimpleForm>
+3
View File
@@ -6,6 +6,7 @@ import {
PasswordInput,
Edit,
required,
email,
SimpleForm
} from 'react-admin'
@@ -15,7 +16,9 @@ const UserTitle = ({ record }) => {
const UserEdit = (props) => (
<Edit title={<UserTitle />} {...props}>
<SimpleForm>
<TextInput source="userName" validate={[required()]} />
<TextInput source="name" validate={[required()]} />
<TextInput source="email" validate={[required(), email()]} />
<PasswordInput source="password" validate={[required()]} />
<BooleanInput source="isAdmin" initialValue={false} />
<DateField source="lastLoginAt" />
+2 -3
View File
@@ -23,7 +23,7 @@ const UserList = (props) => {
return (
<List
{...props}
sort={{ field: 'name', order: 'ASC' }}
sort={{ field: 'userName', order: 'ASC' }}
exporter={false}
filters={<UserFilter />}
>
@@ -34,9 +34,8 @@ const UserList = (props) => {
/>
) : (
<Datagrid rowClick="edit">
<TextField source="name" />
<TextField source="userName" />
<BooleanField source="isAdmin" />
<DateField source="lastLoginAt" locales="pt-BR" />
<DateField source="lastAccessAt" locales="pt-BR" />
<DateField source="updatedAt" locales="pt-BR" />
</Datagrid>