Skip to content

Commit

Permalink
Merge pull request #6 from SamuelMTeixeira/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
SamuelMTeixeira authored Apr 30, 2024
2 parents 5e40c42 + 1f62428 commit 6547d41
Show file tree
Hide file tree
Showing 13 changed files with 94 additions and 84 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
VITE_CLIENT_ID=
VITE_CLIENT_SECRET=
VITE_API_URL=
VITE_WEBSOCKET_URL=
VITE_SERVICES=1,2,3
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [v1.2.2] - 2024-04-30

### Added

- build: add axios-auth-refresh to refresh token automatically and integrate with axios

### Changed

- refactor: unnecessary data when there are no appointment
- refactor: separation of websocket url and api url

### Fixed

- fix: websocket not working with htpps and refresh token interceptor

## [v1.2.1] - 2024-04-02

### Changed
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ Para executar o projeto localmente, siga as etapas abaixo:
*user*: admin
*password*: 123456

Para configurações do serviço e de como gerar o token, consulte a [documentação oficial](https://novosga.org/docs/current/)

Para fazer sair do usuário, basta precionar o comando `ctrl + m` e selecionar a opção sair.

Para configurações do serviço e de como gerar o token, consulte a [documentação oficial do novoSGA](https://novosga.org/docs/current/)

## 🤝 Contribuições
Contribuições são bem-vindas! Sinta-se à vontade para enviar sugestões, relatar problemas ou contribuir diretamente para o desenvolvimento do projeto.
Expand Down
3 changes: 2 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ services:
# Set TimeZone and locale
TZ: 'America/Sao_Paulo'
LANGUAGE: 'pt_BR'

mysqldb:
image: mysql:5.7
restart: always
Expand All @@ -41,4 +42,4 @@ services:
MYSQL_ROOT_PASSWORD: 'MySQL_r00t_P4ssW0rd!'
MYSQL_PASSWORD: 'MySQL_App_P4ssw0rd!'
# Set TimeZone
TZ: 'America/Sao_Paulo'
TZ: 'America/Sao_Paulo'
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-slot": "^1.0.2",
"axios": "^1.6.4",
"axios-auth-refresh": "^3.3.6",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"cmdk": "^1.0.0",
Expand Down
11 changes: 11 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 1 addition & 11 deletions src/components/home/command-actions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
CommandList,
} from '@/components/ui/command'

import { SignOut, GearSix } from '@phosphor-icons/react'
import { SignOut } from '@phosphor-icons/react'

import { useEffect, useState } from 'react'
import { Button } from '../ui/button'
Expand Down Expand Up @@ -53,16 +53,6 @@ export default function CommandActions() {
<span>Sair</span>
</Button>
</CommandItem>

<CommandItem className="aria-selected:bg-background !p-0 !m-0">
<Button
variant={'ghost'}
className="w-full justify-start cursor-default px-2 py-1.5 text-sm font-normal"
>
<GearSix className="mr-2 h-4 w-4" />
<span>Configurações</span>
</Button>
</CommandItem>
</CommandGroup>
</CommandList>
</CommandDialog>
Expand Down
1 change: 1 addition & 0 deletions src/config/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const serverOptions = {
username: import.meta.env.USERNAME || '',
password: import.meta.env.PASSWORD || '',
baseURL: import.meta.env.VITE_API_URL || '',
websocketURL: import.meta.env.VITE_WEBSOCKET_URL || '',
services: import.meta.env.VITE_SERVICES || '1',
}

Expand Down
15 changes: 1 addition & 14 deletions src/hooks/useAuth.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { login, updateToken } from '@/services/auth'
import config from '@/config/server'
import { login } from '@/services/auth'

export default function useAuth() {
const expire_date = new Date(localStorage.getItem('expire_date'))
Expand All @@ -14,22 +13,10 @@ export default function useAuth() {
localStorage.removeItem('expire_date')
}

const refreshToken = async () => {
if (!isTokenExpired) return

await updateToken({
client_id: config.client_id,
client_secret: config.client_secret,
refresh_token: localStorage.getItem('refresh_token'),
})
}

return {
login,
isAuthenticated,
updateToken,
isTokenExpired,
refreshToken,
logout,
}
}
31 changes: 31 additions & 0 deletions src/lib/axios.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import serverOptions from '@/config/server'
import axios from 'axios'
import createAuthRefreshInterceptor from 'axios-auth-refresh'

const url = serverOptions.baseURL

Expand All @@ -19,4 +20,34 @@ axiosInstance.interceptors.request.use(
(error) => Promise.reject(error),
)

const refreshAuthLogic = (failedRequest) => {
const form = new FormData()
form.append('grant_type', 'refresh_token')
form.append('client_id', serverOptions.client_id)
form.append('client_secret', serverOptions.client_secret)
form.append('refresh_token', localStorage.getItem('refresh_token'))

axiosInstance
.post('token', form)
.then((tokenRefreshResponse) => {
localStorage.setItem('token', tokenRefreshResponse.data.access_token)
localStorage.setItem(
'refresh_token',
tokenRefreshResponse.data.refresh_token,
)
failedRequest.response.config.headers['Authorization'] =
'Bearer ' + tokenRefreshResponse.data.token
return Promise.resolve()
})
.catch((error) => {
console.error('Refresh token failed', error)
return Promise.reject(error)
})
.finally(() => {
console.log('Refresh token done')
})
}

createAuthRefreshInterceptor(axiosInstance, refreshAuthLogic)

export default axiosInstance
10 changes: 5 additions & 5 deletions src/lib/socket.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import serverOptions from '@/config/server'
import io from 'socket.io-client'

const socket = io(`${serverOptions.baseURL}:2020`, {
const socket = io(`${serverOptions.websocketURL}`, {
path: '/socket.io',
transports: ['websocket'],
secure: !0,
timeout: 2e3,
timeout: 60e3,
reconnection: !0,
reconnectionDelay: 1e3,
reconnectionDelayMax: 5e3,
reconnectionAttempts: 3,
reconnectionDelay: 80e3,
reconnectionDelayMax: 30e3,
reconnectionAttempts: 50,
})

export default socket
32 changes: 20 additions & 12 deletions src/pages/Home/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,14 @@ export default function Home() {
const { tickets: passwords } = useTicket()
const audioRef = useRef(null)

const { isAuthenticated, refreshToken, isTokenExpired } = useAuth()
const { isAuthenticated } = useAuth()

const fetchRequest = async () => {
setTickets(await passwords())

audioRef.current.play()
}

useEffect(() => refreshToken, [isTokenExpired])

useEffect(() => fetchRequest, [isAuthenticated])

useEffect(() => {
Expand Down Expand Up @@ -68,20 +66,30 @@ export default function Home() {

<div>
<div>
<p
data-testid="guiche"
className="text-5xl text-center font-raleway leading-tight"
>
{`Guichê ${tickets[0]?.guiche || '0'} - Setor ${
tickets[0]?.setor || '...'
}`}
</p>
<div className="flex gap-2 justify-center">
<p
data-testid="guiche"
className="text-5xl text-center font-raleway leading-tight"
>
{tickets[0]?.guiche ? `Guichê ${tickets[0]?.guiche}` : ''}
</p>

<span className="text-5xl font-raleway leading-tight ">
{!!tickets[0]?.guiche && !!tickets[0]?.setor && '-'}
</span>

<p className="text-5xl text-center font-raleway leading-tight">
{tickets[0]?.setor ? `Setor ${tickets[0]?.setor}` : ''}
</p>
</div>

<p
data-testid="prioridade"
className="text-5xl text-center font-raleway leading-tight"
>
{`Atendimento ${tickets[0]?.description || ''}`}
{tickets[0]?.description
? `Atendimento ${tickets[0]?.description}`
: ''}
</p>
</div>

Expand Down
41 changes: 1 addition & 40 deletions src/services/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,43 +51,4 @@ async function login({ client_id, client_secret, username, password }) {
return !!access_token
}

async function updateToken({ client_id, client_secret, refresh_token }) {
console.log('Token expirado, renovando...')
const newToken = await requestNewToken({
client_id,
client_secret,
refresh_token,
})
localStorage.setItem('refresh_token', newToken.refresh_token)
localStorage.setItem('token', newToken.access_token)
const newExpireDate = new Date(Date.now() + newToken.expires_in * 1000)
localStorage.setItem('expire_date', newExpireDate)
}

async function requestNewToken({ client_id, client_secret, refresh_token }) {
const form = new FormData()
form.append('grant_type', 'refresh_token')
form.append('client_id', client_id)
form.append('client_secret', client_secret)
form.append('refresh_token', refresh_token)

return new Promise((resolve, reject) => {
axiosInstance.post('token', form).then(
(response) => {
resolve(response.data)
},
(error) => {
let message = error.message
if (error.response) {
message = error.response.statusText
if (error.response.data && error.response.data.error_description) {
message += ': ' + error.response.data.error_description
}
}
reject(message)
},
)
})
}

export { login, updateToken }
export { login }

0 comments on commit 6547d41

Please sign in to comment.