UserComponents

src/components/user/ — SelectUser · LoginSwap · TwoFactor · InactivityOverlay
Authentication High 7 usos

Grupo de componentes de autenticação e controle de sessão. Implementa o fluxo "swap de sessão" — permite a um agente trocar para outro usuário/atendente sem fazer login completo. O fluxo segue 3 etapas sequenciais: seleção de usuário → senha → TOTP (se habilitado). InactivityOverlay é montado programaticamente via new Vue().

1. SelectUser
popup 1050×470px
2. LoginSwap
popup 500×300px
3. TwoFactor
popup 500×250px
startNewSession()
nova sessão ativa

Seleção de Atendente

Popup de largura estendida (1050px no uso real). Exibe lista paginada de atendentes com avatar, status online/offline, departamento e filtros rápidos. O clique em uma linha chama setState(false, 'loginSwap', user).

Selecionar Atendente
Atendente Departamento Status
MA
Maria Souza
Suporte Online
JO
João Oliveira
Vendas Online
AC
Ana Costa
Financeiro Offline
4 por página
Real Index.vue:91
<!-- SelectUser -->
<select-user
  :active="loginSwap.states.selectUser"
  @setState="(value, next, user) => setState(value, 'selectUser', next, { user: user, response: null, validated: false })"
/>

Login Rápido

Popup compacto (500×300px). O atendente selecionado é passado via prop :user. Dispara auth/fastLogin. Se openTwoFactory estiver ativo no response, o próximo passo é twoFactor.

Estado normal
Estado de erro
Real Index.vue:95
<!-- LoginSwap -->
<login-swap
  :user="loginSwap.data.user"
  :active="loginSwap.states.loginSwap"
  @setState="(value, next, response, validated) => setState(value, 'loginSwap', next, { user: null, response: response, validated: validated })"
/>

Código TOTP

Popup compacto (500×250px). Aparece apenas quando o response do fastLogin tem openTwoFactory=true. Se o usuário fechar sem validar e oldSessionToken existir, restoreOldSession() é chamado.

Autenticação de Dois Fatores
Digite o código de 6 dígitos
Código gerado pelo Google Authenticator
Real Index.vue:99
<!-- TwoFactor (swap de sessão) -->
<two-factor
  :response="loginSwap.data.response"
  :active="loginSwap.states.twoFactor"
  @setState="(value, response, validated) => setState(value, 'twoFactor', null, { user: null, response: response, validated: validated })"
/>

Overlay de Inatividade

Montado programaticamente via new Vue() — nunca como tag no template. Cria 4 painéis fixed que cobrem a tela inteira exceto ao redor do elemento #__lock_element.

4 painéis fixed cobrindo a tela exceto #__lock_element
#__lock_element input visível
Montagem programática:
const overlay = new Vue({ render: (create) => create(InactivityOverlay) });
overlay.$mount();
document.querySelector('#app').insertBefore(overlay.$el, ...);
Sintético montagem programática
<!-- InactivityOverlay é montado via new Vue(), não como tag. -->
<!-- const overlay = new Vue({ render: (create) => create(InactivityOverlay) }); -->
<!-- overlay.$mount(); -->
<!-- document.querySelector('#app').insertBefore(overlay.$el, ...); -->

API

SelectUser

Prop / EventoTipoDescrição
:activeBooleanControla visibilidade do popup
@setState(value, next, user)Emitido ao selecionar atendente

LoginSwap

Prop / EventoTipoDescrição
:activeBooleanControla visibilidade do popup
:userObjectUsuário selecionado no passo anterior
@setState(value, next, response, validated)Emitido após tentativa de login

TwoFactor

Prop / EventoTipoDescrição
:activeBooleanControla visibilidade do popup
:responseObject|nullResponse do fastLogin com token temporário
@setState(value, response, validated)Emitido após validação TOTP

InactivityOverlay

ItemValor
PropsNenhuma
EventosNenhum
UsoMontagem programática via new Vue()

State management — loginSwap no pai

ChaveTipoValores
loginSwap.states.selectUserBooleantrue quando popup 1 está aberto
loginSwap.states.loginSwapBooleantrue quando popup 2 está aberto
loginSwap.states.twoFactorBooleantrue quando popup 3 está aberto
loginSwap.data.userObject|nullAtendente selecionado
loginSwap.data.responseObject|nullResponse do fastLogin
loginSwap.data.validatedBooleanSe TOTP foi validado

Session actions (TwoFactor)

AçãoO que faz
startNewSession()disconnect() WebSocket + commit SET_TENANT_METADATA + UPDATE_USER_INFO + dispatch layout/navMenuItems
restoreOldSession()user.disconnected() + SET_BEARER(oldSessionToken) + user.connected()

Usado em

Arquivo
src/App.vue
src/layouts/components/navbar/TheNavbarVertical.vue
src/views/chat-attendance/Index.vue
src/views/chat-attendance/NewIndex.vue
src/layouts/components/vertical-nav-menu/VerticalNavMenu.vue

Dependências

vs-popup, vs-input, vs-button, vs-icon, vs-avatar, vs-table, vs-pagination, $vs.notify, vx-table, auth/fastLogin, user/twoFactorActivity, user/fetchPaginatedUsersCustom, role/fetch, userDepartment/fetch