diff --git a/.prettierrc b/.prettierrc new file mode 100755 index 0000000..d9bd310 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,14 @@ +{ + "trailingComma": "none", + "tabWidth": 2, + "semi": false, + "singleQuote": true, + "bracketSpacing": true, + "arrowParens": "avoid", + "overrides": [ + { + "files": "*.js, *.vue, *.css, *.scss", + "excludeFiles": "**/dist/**, **/node_modules/**" + } + ] +} diff --git a/apollo.config.js b/apollo.config.js index 103dadb..d77fc84 100644 --- a/apollo.config.js +++ b/apollo.config.js @@ -1,9 +1,9 @@ module.exports = { client: { - includes: ["web/src/**/*.{js,jsx,ts,tsx,vue,gql}"], + includes: ['web/src/**/*.{js,jsx,ts,tsx,vue,gql}'], service: { - name: "ifms-pti-srv", - url: "http://localhost:4000/graphql", - }, - }, -}; + name: 'ifms-pti-srv', + url: 'http://localhost:4000/graphql' + } + } +} diff --git a/docker-compose.yml b/docker-compose.yml index 99d9e0e..87780dd 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,5 @@ version: '3' -services: +services: postgres: image: postgres:latest restart: 'no' @@ -10,7 +10,7 @@ services: - 'postgres:/var/lib/postgresql/data' ports: - '5432:5432' - + pgadmin: image: dpage/pgadmin4:latest restart: 'no' diff --git a/server/.prettierrc b/server/.prettierrc index fea0d7d..d9bd310 100755 --- a/server/.prettierrc +++ b/server/.prettierrc @@ -5,5 +5,10 @@ "singleQuote": true, "bracketSpacing": true, "arrowParens": "avoid", - "excludeFiles": "dist/**" + "overrides": [ + { + "files": "*.js, *.vue, *.css, *.scss", + "excludeFiles": "**/dist/**, **/node_modules/**" + } + ] } diff --git a/server/README.md b/server/README.md index 15a336e..ce94620 100755 --- a/server/README.md +++ b/server/README.md @@ -1,4 +1,5 @@ # Portal de TI - Server + Servidor de API GraphQL para o Portal de TI do IFMS ## Requisitos @@ -8,30 +9,35 @@ Servidor de API GraphQL para o Portal de TI do IFMS - Docker Compose ## Desenvolvimento -~~~ + +``` cp .env.example .env -~~~ +``` + Altere as variáveis de ambiente em `.env` -~~~ +``` docker-compose up -d npm run prisma-deploy # Rodar sempre que alterar o schema npm run dev -~~~ +``` ## Compilar para produção -~~~ + +``` npm run prisma-deploy npm run build -~~~ +``` ## Produção -Não é recomendado usar o arquivo .env em produção. + +Não é recomendado usar o arquivo .env em produção. Configure as variáveis de ambiente no servidor. -~~~ +``` npm start -~~~ +``` --- -Desenvolvido pelo SERTI Ponta Porã \ No newline at end of file + +Desenvolvido pelo SERTI Ponta Porã diff --git a/server/prisma/migrations/20220614120906_usage_fields/migration.sql b/server/prisma/migrations/20220614120906_usage_fields/migration.sql new file mode 100644 index 0000000..8696fac --- /dev/null +++ b/server/prisma/migrations/20220614120906_usage_fields/migration.sql @@ -0,0 +1,29 @@ +/* + Warnings: + + - The `uptime` column on the `AccessPoint` table would be dropped and recreated. This will lead to data loss if there is data in the column. + - The `uptime` column on the `WifiDevice` table would be dropped and recreated. This will lead to data loss if there is data in the column. + - You are about to drop the column `avgSignal` on the `WifiStats` table. All the data in the column will be lost. + - You are about to drop the column `maxSignal` on the `WifiStats` table. All the data in the column will be lost. + - You are about to drop the column `minSignal` on the `WifiStats` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "AccessPoint" ADD COLUMN "usage" BIGINT, +DROP COLUMN "uptime", +ADD COLUMN "uptime" INTEGER; + +-- AlterTable +ALTER TABLE "WifiDevice" DROP COLUMN "uptime", +ADD COLUMN "uptime" INTEGER, +ALTER COLUMN "usage" SET DATA TYPE BIGINT; + +-- AlterTable +ALTER TABLE "WifiStats" DROP COLUMN "avgSignal", +DROP COLUMN "maxSignal", +DROP COLUMN "minSignal", +ADD COLUMN "avgSignalStrength" INTEGER, +ADD COLUMN "maxSignalStrength" INTEGER, +ADD COLUMN "minSignalStrength" INTEGER, +ALTER COLUMN "avgUsage" SET DATA TYPE BIGINT, +ALTER COLUMN "sumUsage" SET DATA TYPE BIGINT; diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma index 8da4283..dea2530 100644 --- a/server/prisma/schema.prisma +++ b/server/prisma/schema.prisma @@ -89,13 +89,13 @@ model WifiDevice { notes String? essid String? - uptime String? + uptime Int? apName String? signalStrength Int? frequency String? protocol String? speed Int? - usage Int? + usage BigInt? status Status? createdAt DateTime @default(now()) @@ -160,12 +160,14 @@ model AccessPoint { notes String? inventoryTag String? - uptime String? + uptime Int? controller String? model String? ip String? clients Int? + usage BigInt? + encryptedSshUser String? encryptedSshPassword String? @@ -182,9 +184,9 @@ model WifiStats { clients Int? - avgSignal Int? - minSignal Int? - maxSignal Int? + avgSignalStrength Int? + minSignalStrength Int? + maxSignalStrength Int? avgSpeed Int? minSpeed Int? @@ -193,8 +195,8 @@ model WifiStats { avgClientUptime Int? maxClientUptime Int? - avgUsage Int? - sumUsage Int? + avgUsage BigInt? + sumUsage BigInt? accessPointId Int accessPoint AccessPoint @relation("wifistats_to_ap", fields: [accessPointId], references: [id]) diff --git a/server/src/classes/User.js b/server/src/classes/User.js index f887897..665f5b2 100755 --- a/server/src/classes/User.js +++ b/server/src/classes/User.js @@ -392,8 +392,9 @@ class User { }) logSuccess({ - message: `Importado ${index + 1}/${allAdUsers.length} (${user.sAMAccountName - }) ${user.displayName}`, + message: `Importado ${index + 1}/${allAdUsers.length} (${ + user.sAMAccountName + }) ${user.displayName}`, data: dbUser }) } @@ -402,11 +403,12 @@ class User { logSuccess({ tags: ['user', 'AD'], - message: `${allAdUsers.length - } usuários importados do Active Directory em ${( - (endTime - startTime) / - 1000 - ).toFixed(2)}s` + message: `${ + allAdUsers.length + } usuários importados do Active Directory em ${( + (endTime - startTime) / + 1000 + ).toFixed(2)}s` }) return allAdUsers.length diff --git a/server/src/cronTasks.js b/server/src/cronTasks.js index c665cd4..78455d0 100644 --- a/server/src/cronTasks.js +++ b/server/src/cronTasks.js @@ -5,7 +5,10 @@ import { User } from './classes/User' import { deleteOldLogs, logInfo, logSuccess } from './lib/logger' import { updateAccessPoints } from './lib/accessPoints' - +import { + deleteOldStats, + generateStatsForAllAccessPoints +} from './lib/wifiStats' // WARNING! All crontasks are blocking! Do not await inside it @@ -41,4 +44,12 @@ cron.schedule('0 0 2 * * *', () => { cron.schedule('0 */2 * * * *', () => { updateAccessPoints().catch(console.log) -}) \ No newline at end of file +}) + +cron.schedule('0 */5 * * * *', () => { + generateStatsForAllAccessPoints() +}) + +cron.schedule('0 0 2 * * *', () => { + deleteOldStats() +}) diff --git a/server/src/index.js b/server/src/index.js index 6565d72..33d7449 100755 --- a/server/src/index.js +++ b/server/src/index.js @@ -1,4 +1,4 @@ -import { } from 'dotenv/config' +import {} from 'dotenv/config' import './utils/capitalize' import './utils/contains' import './utils/cycle' diff --git a/server/src/lib/accessPoints.js b/server/src/lib/accessPoints.js index 4cf3af4..6f20eaf 100644 --- a/server/src/lib/accessPoints.js +++ b/server/src/lib/accessPoints.js @@ -1,5 +1,5 @@ import prisma from '../prisma' -import { ACCESS_POINTS_UPDATED, pubsub } from '../pubsub' + import { getAccessPoints as getCiscoAccessPoints } from './ciscoController' import { logInfo, logSuccess } from './logger' import { getAccessPoints as getUnifiAccessPoints } from './unifiController' @@ -50,7 +50,7 @@ export async function updateAccessPoints() { } }, data: { - uptime: "-1" + uptime: -1 } }) diff --git a/server/src/lib/ciscoController.js b/server/src/lib/ciscoController.js index 1ee1f86..1021c02 100644 --- a/server/src/lib/ciscoController.js +++ b/server/src/lib/ciscoController.js @@ -103,7 +103,7 @@ export async function getOnlineWifiDevices() { lastSeen: now, essid: client.SSID, ip: client.IP, - uptime: client.UT.toString(), + uptime: +client.UT, apName: client.AP, status: client.ST == 'Online' ? 'ONLINE' : 'OFFLINE', controller: 'Cisco', @@ -143,14 +143,15 @@ export function getAccessPoints() { clearTimeout(timeout) const restructuredAccessPoints = accessPoints.map( - ({ Nm, Mc, Md, Ut, A4, Cl }) => ({ + ({ Nm, Mc, Md, Ut, A4, Cl, Vm }) => ({ mac: Mc, hostname: Nm, - uptime: Ut.toString(), + uptime: +Ut, controller: 'Cisco', model: Md, ip: A4, - clients: Cl + clients: +Cl, + usage: +Vm }) ) diff --git a/server/src/lib/logger.js b/server/src/lib/logger.js index 998a169..c3543a5 100644 --- a/server/src/lib/logger.js +++ b/server/src/lib/logger.js @@ -20,7 +20,8 @@ async function log( const entryTags = tags.length ? ` [${tags}] ` : '' console.log( - `${color}[${format(now, 'HH:mm:ss')}]${entryTags ? entryTags : '' + `${color}[${format(now, 'HH:mm:ss')}]${ + entryTags ? entryTags : '' }\x1b[0m${message}` ) diff --git a/server/src/lib/paloalto.js b/server/src/lib/paloalto.js index 8840feb..f3d99dc 100644 --- a/server/src/lib/paloalto.js +++ b/server/src/lib/paloalto.js @@ -105,8 +105,9 @@ async function updateUserIdMappings() { logSuccess({ tags: ['paloalto', 'user-id'], - message: `Foram mapeados ${devices.length} user-ids em ${pAHost.description || pAHost.cidr - } em ${((endTime - startTime) / 1000).toFixed(2)}s.`, + message: `Foram mapeados ${devices.length} user-ids em ${ + pAHost.description || pAHost.cidr + } em ${((endTime - startTime) / 1000).toFixed(2)}s.`, data: devices }) @@ -114,8 +115,9 @@ async function updateUserIdMappings() { } catch (e) { logError({ tags: ['paloalto', 'user-id'], - message: `Erro atualizando user-id mappings em ${pAHost.description || pAHost.cidr - }: ${e.message}` + message: `Erro atualizando user-id mappings em ${ + pAHost.description || pAHost.cidr + }: ${e.message}` }) //console.log(e) // Do not add e to log DB for security reasons... diff --git a/server/src/lib/unifiController.js b/server/src/lib/unifiController.js index 28c84f9..f90a7de 100644 --- a/server/src/lib/unifiController.js +++ b/server/src/lib/unifiController.js @@ -187,7 +187,7 @@ export async function getOnlineWifiDevices() { lastSeen: new Date(client.last_seen * 1000), essid: client.essid, ip: client.ip, - uptime: client.uptime.toString(), + uptime: +client.uptime, apName: accessPoints[0].find(ap => ap.mac === client.ap_mac).name, status: 'ONLINE', controller: 'UniFi', @@ -209,14 +209,15 @@ export async function getAccessPoints() { const accessPoints = await unifiController.getAccessDevices('default') const restructuredAccessPoints = accessPoints[0].map( - ({ mac, model, ip, uptime, name, num_sta }) => ({ + ({ mac, model, ip, uptime, name, num_sta, bytes }) => ({ mac, hostname: name, - uptime: uptime ? uptime.toString() : "-1", + uptime: uptime ? +uptime : -1, controller: 'UniFi', model, ip, - clients: num_sta + clients: num_sta, + usage: +bytes }) ) diff --git a/server/src/lib/wifiDevices.js b/server/src/lib/wifiDevices.js index dc08335..b86d253 100644 --- a/server/src/lib/wifiDevices.js +++ b/server/src/lib/wifiDevices.js @@ -20,8 +20,9 @@ let working = false const wifiControllers = [unifiController, ciscoController] async function getOnlineDevices() { - - const onlineDevicesPromises = wifiControllers.map(wifiController => wifiController.getOnlineWifiDevices()) + const onlineDevicesPromises = wifiControllers.map(wifiController => + wifiController.getOnlineWifiDevices() + ) const onlineDevices = (await Promise.all(onlineDevicesPromises)).flat() @@ -86,10 +87,10 @@ async function updateDB(onlineDevices) { const user = device.user ? { - connect: { - sAMAccountName: device.user.replace('IFMS\\', '').toLowerCase() + connect: { + sAMAccountName: device.user.replace('IFMS\\', '').toLowerCase() + } } - } : undefined const hostname = device.hostname || mockHostName(device) @@ -184,17 +185,16 @@ function updateDevicesInfo() { onlineDevices.length > 0 ? resolve( - `${onlineDevices.length} atualizados em ${Math.floor( - endTime - startTime - )}ms, DB em ${Math.floor(endTimeDB - startTimeDB)}ms` - ) + `${onlineDevices.length} atualizados em ${Math.floor( + endTime - startTime + )}ms, DB em ${Math.floor(endTimeDB - startTimeDB)}ms` + ) : reject('Não há dispositivos conectados no momento.') pubsub.publish(USER_PRESENCE_UPDATED, { userPresenceUpdated: onlineDevices.length }) - const updatedDbAccessPoints = await prisma.accessPoint.findMany({ include: { wifiDevices: { @@ -205,12 +205,17 @@ function updateDevicesInfo() { } }) - pubsub.publish(ACCESS_POINTS_UPDATED, { accessPointsUpdated: updatedDbAccessPoints }) + pubsub.publish(ACCESS_POINTS_UPDATED, { + accessPointsUpdated: updatedDbAccessPoints + }) logSuccess({ tags: ['wifiDevices'], message: `${onlineDevices.length} dispositivos Wi-Fi atualizados em - ${((endTime - startTime) / 1000).toFixed(2)}s. BD em ${((endTimeDB - startTimeDB) / 1000).toFixed(2)}s` + ${((endTime - startTime) / 1000).toFixed(2)}s. BD em ${( + (endTimeDB - startTimeDB) / + 1000 + ).toFixed(2)}s` }) } catch (e) { logError({ @@ -229,7 +234,8 @@ function updateDevicesInfo() { // Delete devices that are offline for more than OLD_DEVICES_THRESHOLD_IN_DAYS days async function deleteOldDevices() { - const oldDevicesThresholdInMilliseconds = OLD_DEVICES_THRESHOLD_IN_DAYS * 24 * 60 * 60 * 1000 + const oldDevicesThresholdInMilliseconds = + OLD_DEVICES_THRESHOLD_IN_DAYS * 24 * 60 * 60 * 1000 const oldDevices = await prisma.wifiDevice.deleteMany({ where: { diff --git a/server/src/lib/wifiStats.js b/server/src/lib/wifiStats.js index d7d13f2..5597a66 100644 --- a/server/src/lib/wifiStats.js +++ b/server/src/lib/wifiStats.js @@ -1,13 +1,17 @@ -import prisma from "../prisma"; +import prisma from '../prisma' +import { logError, logSuccess } from './logger' +import { subDays } from 'date-fns' -generateStatsForAccessPoint(1) +const DAYS_TO_KEEP = 90 -async function generateStatsForAccessPoint(accessPointId) { +async function generateStatsForAccessPoint(mac) { const timestamp = new Date() - const stats = await prisma.wifiDevice.aggregate({ + const dbStats = await prisma.wifiDevice.aggregate({ where: { - accessPointId, + accessPoint: { + mac + }, status: 'ONLINE' }, _count: { @@ -16,41 +20,84 @@ async function generateStatsForAccessPoint(accessPointId) { _avg: { signalStrength: true, speed: true, - usage: true + usage: true, + uptime: true }, _max: { signalStrength: true, speed: true, - usage: true + usage: true, + uptime: true }, _min: { signalStrength: true, - speed: true, - + speed: true + }, + _sum: { + usage: true } }) - console.log(timestamp, stats) + const stats = { + timestamp: timestamp.toISOString(), + clients: dbStats._count._all, + + avgSignalStrength: Math.floor(dbStats._avg.signalStrength, 0), + minSignalStrength: dbStats._min.signalStrength, + maxSignalStrength: dbStats._max.signalStrength, + + avgSpeed: Math.floor(dbStats._avg.speed, 0), + minSpeed: dbStats._min.speed || 0, + maxSpeed: dbStats._max.speed || 0, + + avgClientUptime: Math.floor(dbStats._avg.uptime, 0), + maxClientUptime: dbStats._max.uptime || 0, + + avgUsage: Math.floor(dbStats._avg.usage, 0), + sumUsage: dbStats._sum.usage || 0 + } + + await prisma.wifiStats.create({ + data: { + ...stats, + accessPoint: { connect: { mac } } + } + }) } - // id Int @id @default(autoincrement()) - // timestamp DateTime @default(now()) +export async function generateStatsForAllAccessPoints() { + try { + const accessPoints = await prisma.accessPoint.findMany() - // clients Int? + for (const accessPoint of accessPoints) { + await generateStatsForAccessPoint(accessPoint.mac) + } - // avgSignal Int? - // minSignal Int? - // maxSignal Int? + logSuccess({ + tags: ['wifiStats', 'generateStatsForAllAccessPoints'], + message: `Estatísticas geradas para ${accessPoints.length} access points` + }) + } catch (e) { + console.log(e) + logError({ + tags: ['wifiStats', 'generateStatsForAllAccessPoints'], + message: 'Erro ao gerar estatísticas para todos os access points', + data: e + }) + } +} - // avgSpeed Int? - // minSpeed Int? - // maxSpeed Int? +export async function deleteOldStats() { + try { + const stats = await prisma.wifiStats.deleteMany({ + where: { timestamp: { lt: subDays(new Date(), DAYS_TO_KEEP) } } + }) - // avgClientUptime Int? - // maxClientUptime Int? - - // avgUsage Int? - // sumUsage Int? - - // accessPointId Int - // accessPoint AccessPoint @relation("wifistats_to_ap", fields: [accessPointId], references: [id]) \ No newline at end of file + logSuccess({ + tags: ['wifiStats', 'deleteOldStats'], + message: `${stats.count} estatísticas com mais de ${DAYS_TO_KEEP} dias deletadas.` + }) + } catch (e) { + console.log(e) + } +} diff --git a/server/src/resolvers/AccessPoint.js b/server/src/resolvers/AccessPoint.js index 7663d49..0ce6a98 100644 --- a/server/src/resolvers/AccessPoint.js +++ b/server/src/resolvers/AccessPoint.js @@ -1,11 +1,10 @@ -import prisma from "../prisma"; -import { getSubnetInfo } from "../utils/subnetInfo"; +import prisma from '../prisma' +import { getSubnetInfo } from '../utils/subnetInfo' export const AccessPoint = { updatedAt: (parent, data, context, info) => parent.updatedAt?.toISOString(), async clients(parent, data, context, info) { - const clientsCount = await prisma.wifiDevice.count({ where: { status: 'ONLINE', @@ -15,8 +14,9 @@ export const AccessPoint = { } }) - return clientsCount; + return clientsCount }, - subnetInfo: parent => getSubnetInfo(parent.ip) + subnetInfo: parent => getSubnetInfo(parent.ip), + usage: (parent, data, context, info) => parent.usage.toString() } diff --git a/server/src/resolvers/Mutation/addPAHost.js b/server/src/resolvers/Mutation/addPAHost.js index 0846925..871db65 100644 --- a/server/src/resolvers/Mutation/addPAHost.js +++ b/server/src/resolvers/Mutation/addPAHost.js @@ -22,4 +22,4 @@ export async function addPAHost( }) return host -} \ No newline at end of file +} diff --git a/server/src/resolvers/Mutation/createResetToken.js b/server/src/resolvers/Mutation/createResetToken.js index d277779..928c789 100644 --- a/server/src/resolvers/Mutation/createResetToken.js +++ b/server/src/resolvers/Mutation/createResetToken.js @@ -2,4 +2,4 @@ import { ResetToken } from '../../classes/ResetToken' export async function createResetToken(parent, { data }, { auth }) { return ResetToken.createToken(data.username, auth.sAMAccountName) -} \ No newline at end of file +} diff --git a/server/src/resolvers/Mutation/delPAHost.js b/server/src/resolvers/Mutation/delPAHost.js index b567ecd..4fb6a6e 100644 --- a/server/src/resolvers/Mutation/delPAHost.js +++ b/server/src/resolvers/Mutation/delPAHost.js @@ -7,4 +7,4 @@ export async function delPAHost(parent, { id }, { auth }) { throw new Error('Você não pode apagar o host de outro usuário') return prisma.pAHost.delete({ where: { id } }) -} \ No newline at end of file +} diff --git a/server/src/resolvers/Mutation/deleteExpiredTokens.js b/server/src/resolvers/Mutation/deleteExpiredTokens.js index f3f3abf..c8391ab 100644 --- a/server/src/resolvers/Mutation/deleteExpiredTokens.js +++ b/server/src/resolvers/Mutation/deleteExpiredTokens.js @@ -2,4 +2,4 @@ import { ResetToken } from '../../classes/ResetToken' export async function deleteExpiredTokens() { return `Tokens deletados ${await ResetToken.deleteExpiredTokens()}` -} \ No newline at end of file +} diff --git a/server/src/resolvers/Mutation/importUsers.js b/server/src/resolvers/Mutation/importUsers.js index 4b9c34b..3319c6d 100644 --- a/server/src/resolvers/Mutation/importUsers.js +++ b/server/src/resolvers/Mutation/importUsers.js @@ -3,4 +3,4 @@ import { User } from '../../classes/User' export async function importUsers() { User.importAllUsers() return 'A importação está sendo feita. Isso pode demorar alguns minutos.' -} \ No newline at end of file +} diff --git a/server/src/resolvers/Mutation/index.js b/server/src/resolvers/Mutation/index.js index 75fb585..2804d29 100644 --- a/server/src/resolvers/Mutation/index.js +++ b/server/src/resolvers/Mutation/index.js @@ -11,7 +11,6 @@ import { delPAHost } from './delPAHost' import { updateAccessPoint } from './updateAccessPoint' const Mutation = { - login, updatePassword, replacePassword, diff --git a/server/src/resolvers/Mutation/login.js b/server/src/resolvers/Mutation/login.js index 3072784..ebbf79b 100644 --- a/server/src/resolvers/Mutation/login.js +++ b/server/src/resolvers/Mutation/login.js @@ -2,4 +2,4 @@ import { User } from '../../classes/User' export async function login(parent, { data }) { return User.login(data.username, data.password) -} \ No newline at end of file +} diff --git a/server/src/resolvers/Mutation/replacePassword.js b/server/src/resolvers/Mutation/replacePassword.js index f616183..cb43509 100644 --- a/server/src/resolvers/Mutation/replacePassword.js +++ b/server/src/resolvers/Mutation/replacePassword.js @@ -8,4 +8,4 @@ export async function replacePassword(parent, { data }, { auth }) { }) return replaceADPassword(data.username, data.newPassword) -} \ No newline at end of file +} diff --git a/server/src/resolvers/Mutation/replaceStudentPassword.js b/server/src/resolvers/Mutation/replaceStudentPassword.js index 93ff306..f767ce0 100644 --- a/server/src/resolvers/Mutation/replaceStudentPassword.js +++ b/server/src/resolvers/Mutation/replaceStudentPassword.js @@ -15,8 +15,7 @@ export async function replaceStudentPassword(parent, { data }, { auth }) { if (isServant) throw new Error(`Usuário ${data.username} é um servidor`) - if (!isStudent) - throw new Error(`Usuário ${data.username} não é um estudante`) + if (!isStudent) throw new Error(`Usuário ${data.username} não é um estudante`) logInfo({ tags: ['replaceStudentPassword', 'user'], @@ -24,4 +23,4 @@ export async function replaceStudentPassword(parent, { data }, { auth }) { }) return replacePassword(data.username, data.newPassword) -} \ No newline at end of file +} diff --git a/server/src/resolvers/Mutation/updateAccessPoint.js b/server/src/resolvers/Mutation/updateAccessPoint.js index 22ed170..8711a8c 100644 --- a/server/src/resolvers/Mutation/updateAccessPoint.js +++ b/server/src/resolvers/Mutation/updateAccessPoint.js @@ -1,22 +1,37 @@ - import prisma from '../../prisma' import { ACCESS_POINTS_UPDATED, pubsub } from '../../pubsub' import { logError, logInfo } from '../../lib/logger' import { getSubnetInfo } from '../../utils/subnetInfo' -export async function updateAccessPoint(_, { data: { id, name, local, notes } }, { auth },) { - const accessPoint = await prisma.accessPoint.findUnique({ where: { id: parseInt(id) }, }) +export async function updateAccessPoint( + _, + { data: { id, name, local, notes } }, + { auth } +) { + const accessPoint = await prisma.accessPoint.findUnique({ + where: { id: parseInt(id) } + }) if (!accessPoint) throw new Error('Access Point não encontrado') if (getSubnetInfo(accessPoint.ip).shortName !== auth.campus) { logError({ tags: ['accessPointEdited', 'accessPoints'], - message: `O usuário ${auth.displayName} (${auth.sAMAccountName}) tentou atualizar as informações do - AP ${accessPoint.name || accessPoint.hostname}, mas não tinha permissão.` + message: `O usuário ${auth.displayName} (${ + auth.sAMAccountName + }) tentou atualizar as informações do + AP ${ + accessPoint.name || accessPoint.hostname + }, mas não tinha permissão.` }) - throw new Error(`O AP ${accessPoint.name || accessPoint.hostname} não está na rede do campus ${auth.campus}. Você só pode editar APs da rede do seu campus.`) + throw new Error( + `O AP ${ + accessPoint.name || accessPoint.hostname + } não está na rede do campus ${ + auth.campus + }. Você só pode editar APs da rede do seu campus.` + ) } const updatedAccessPoint = await prisma.accessPoint.update({ @@ -26,7 +41,11 @@ export async function updateAccessPoint(_, { data: { id, name, local, notes } }, logInfo({ tags: ['accessPointEdited', 'accessPoints'], - message: `O usuário ${auth.displayName} (${auth.sAMAccountName}) atualizou as informações do AP ${updatedAccessPoint.name || updatedAccessPoint.hostname}`, + message: `O usuário ${auth.displayName} (${ + auth.sAMAccountName + }) atualizou as informações do AP ${ + updatedAccessPoint.name || updatedAccessPoint.hostname + }`, data: updatedAccessPoint }) @@ -39,4 +58,4 @@ export async function updateAccessPoint(_, { data: { id, name, local, notes } }, }) return updatedAccessPoint -} \ No newline at end of file +} diff --git a/server/src/resolvers/Mutation/updatePassword.js b/server/src/resolvers/Mutation/updatePassword.js index 69546cb..8518096 100644 --- a/server/src/resolvers/Mutation/updatePassword.js +++ b/server/src/resolvers/Mutation/updatePassword.js @@ -1,3 +1,3 @@ export async function updatePassword(parent, { data }, { auth }) { return auth.updatePassword(data.oldPassword, data.newPassword) -} \ No newline at end of file +} diff --git a/server/src/resolvers/Mutation/useResetToken.js b/server/src/resolvers/Mutation/useResetToken.js index bf36190..0e821d3 100644 --- a/server/src/resolvers/Mutation/useResetToken.js +++ b/server/src/resolvers/Mutation/useResetToken.js @@ -2,4 +2,4 @@ import { ResetToken } from '../../classes/ResetToken' export async function useResetToken(parent, { data }) { return ResetToken.useToken(data.token, data.newPassword) -} \ No newline at end of file +} diff --git a/server/src/resolvers/Query/logs.js b/server/src/resolvers/Query/logs.js index d07514a..e99bbee 100644 --- a/server/src/resolvers/Query/logs.js +++ b/server/src/resolvers/Query/logs.js @@ -16,9 +16,9 @@ export async function logs(parent, { search, dateIn, dateOut, limit = 100 }) { }, OR: search ? [ - { message: { contains: search, mode: 'insensitive' } }, - { tags: { contains: search, mode: 'insensitive' } } - ] + { message: { contains: search, mode: 'insensitive' } }, + { tags: { contains: search, mode: 'insensitive' } } + ] : undefined }, orderBy: { timestamp: 'desc' }, diff --git a/server/src/resolvers/Query/userPresence.js b/server/src/resolvers/Query/userPresence.js index fe6c7b6..a7e680f 100644 --- a/server/src/resolvers/Query/userPresence.js +++ b/server/src/resolvers/Query/userPresence.js @@ -18,7 +18,9 @@ export async function userPresence(_, { search, onlyServants }) { if (onlyServants) usersWithWifiDevices = usersWithWifiDevices.filter( - ({ extensionAttribute2 }) => extensionAttribute2 == 'Técnico-administrativo' || extensionAttribute2 == 'Docente' + ({ extensionAttribute2 }) => + extensionAttribute2 == 'Técnico-administrativo' || + extensionAttribute2 == 'Docente' ) let filteredUsers = usersWithWifiDevices @@ -28,7 +30,6 @@ export async function userPresence(_, { search, onlyServants }) { const searchTerms = search.split(' ') for (const term of searchTerms) { - filteredUsers = filteredUsers.filter( user => Object.keys(user).some( @@ -37,14 +38,12 @@ export async function userPresence(_, { search, onlyServants }) { user.wifiDevices?.some( device => device.status != 'OFFLINE' && - ( - device.ip?.startsWith(term) || + (device.ip?.startsWith(term) || device.apName?.contains(term) || device.essid?.contains(term) || device.hostname?.contains(term) || device.accessPoint?.name?.contains(term) || - device.accessPoint?.local?.contains(term) - ) + device.accessPoint?.local?.contains(term)) ) ) } @@ -80,9 +79,13 @@ export async function userPresence(_, { search, onlyServants }) { thumbnailPhoto: userPresence.thumbnailPhoto, lastSeen: userPresence.wifiDevices[0].lastSeen, status: userPresence.wifiDevices[0].status, - apName: userPresence.wifiDevices[0].accessPoint?.name || userPresence.wifiDevices[0].apName || userPresence.wifiDevices[0].accessPoint?.hostname, + apName: + userPresence.wifiDevices[0].accessPoint?.name || + userPresence.wifiDevices[0].apName || + userPresence.wifiDevices[0].accessPoint?.hostname, local: userPresence.wifiDevices[0].accessPoint?.local, - campus: getSubnetInfo(userPresence.wifiDevices[0].accessPoint?.ip).shortName + campus: getSubnetInfo(userPresence.wifiDevices[0].accessPoint?.ip) + .shortName })) .slice(0, 200) diff --git a/server/src/resolvers/Query/wifiDevices.js b/server/src/resolvers/Query/wifiDevices.js index 7721bf6..36ad077 100644 --- a/server/src/resolvers/Query/wifiDevices.js +++ b/server/src/resolvers/Query/wifiDevices.js @@ -1,6 +1,9 @@ import prisma from '../../prisma' -export async function wifiDevices(parent, { take = 50, skip = 0, search, sortBy, sortDesc, onlineOnly }) { +export async function wifiDevices( + parent, + { take = 50, skip = 0, search, sortBy, sortDesc, onlineOnly } +) { const mode = 'insensitive' if (!search) search = '' @@ -28,9 +31,7 @@ export async function wifiDevices(parent, { take = 50, skip = 0, search, sortBy, }), data: prisma.wifiDevice.findMany({ where, - orderBy: [ - { [sortBy || 'hostname']: sortDesc ? 'desc' : 'asc' }, - ], + orderBy: [{ [sortBy || 'hostname']: sortDesc ? 'desc' : 'asc' }], include: { user: true, accessPoint: true }, take, skip diff --git a/server/src/resolvers/Query/wifiUsers.js b/server/src/resolvers/Query/wifiUsers.js index dbd9939..64d1270 100644 --- a/server/src/resolvers/Query/wifiUsers.js +++ b/server/src/resolvers/Query/wifiUsers.js @@ -4,8 +4,7 @@ import prisma from '../../prisma' export async function wifiUsers(parent, { take = 10, skip = 0, search }) { const mode = 'insensitive' - if (search === null) - search = undefined + if (search === null) search = undefined const where = { AND: [ @@ -19,7 +18,7 @@ export async function wifiUsers(parent, { take = 10, skip = 0, search }) { accessPoint: { OR: [ { name: { contains: search, mode } }, - { local: { contains: search, mode } }, + { local: { contains: search, mode } } ] } } @@ -27,27 +26,24 @@ export async function wifiUsers(parent, { take = 10, skip = 0, search }) { }, { wifiDevices: { some: { mac: { contains: search, mode } } } }, { wifiDevices: { some: { ip: { contains: search, mode } } } }, - { displayName: { contains: search, mode } }, , - { sAMAccountName: { contains: search, mode } }, + { displayName: { contains: search, mode } }, + , + { sAMAccountName: { contains: search, mode } } ] } ] } - return { - data: - prisma.user.findMany({ - where, - include: { - wifiDevices: true - }, - orderBy: [ - { wifiDevices: { _count: 'desc' } }, - { displayName: 'asc' }], - take, - skip - }), + data: prisma.user.findMany({ + where, + include: { + wifiDevices: true + }, + orderBy: [{ wifiDevices: { _count: 'desc' } }, { displayName: 'asc' }], + take, + skip + }), total: prisma.user.count({ where }) } diff --git a/server/src/resolvers/User.js b/server/src/resolvers/User.js index e28010f..b6fa61b 100755 --- a/server/src/resolvers/User.js +++ b/server/src/resolvers/User.js @@ -20,15 +20,15 @@ const User = { sharedFolders: parent => parent.groups ? parent.groups - .filter(group => group.cn.includes('-Share-')) - .map(group => group.cn.split('-')[2]) + .filter(group => group.cn.includes('-Share-')) + .map(group => group.cn.split('-')[2]) : [], sharedPrinters: parent => parent.groups ? parent.groups - .filter(group => group.cn.includes('-Printer-')) - .map(group => group.cn.split('-')[2]) + .filter(group => group.cn.includes('-Printer-')) + .map(group => group.cn.split('-')[2]) : [], isSuperAdmin: parent => parent.roles.includes('superAdmin'), @@ -62,24 +62,22 @@ const User = { return campus || '--' }, - onlineWifiDevicesCount: (parent, data, { auth }) => prisma.wifiDevice.count({ - where: { - status: 'ONLINE', - user: { id: parent.id } - } - }), + onlineWifiDevicesCount: (parent, data, { auth }) => + prisma.wifiDevice.count({ + where: { + status: 'ONLINE', + user: { id: parent.id } + } + }), - offlineWifiDevicesCount: (parent, data, { auth }) => prisma.wifiDevice.count({ - where: { - OR: [ - { status: 'OFFLINE' }, - { status: 'RECENT' }, - ], - - user: { id: parent.id } - } - }) + offlineWifiDevicesCount: (parent, data, { auth }) => + prisma.wifiDevice.count({ + where: { + OR: [{ status: 'OFFLINE' }, { status: 'RECENT' }], + user: { id: parent.id } + } + }) } export { User } diff --git a/server/src/resolvers/WifiDevice.js b/server/src/resolvers/WifiDevice.js index b5496a2..a162e81 100644 --- a/server/src/resolvers/WifiDevice.js +++ b/server/src/resolvers/WifiDevice.js @@ -15,25 +15,22 @@ const WifiDevice = { }) ).user, - usage: parent => parent.usage < 0 ? parent.usage * -1 : parent.usage, + usage: parent => parent.usage.toString(), accessPoint: async parent => { - try { - const ap = await prisma.accessPoint.findUnique({ where: { hostname: parent.apName } }) - if (ap) - return ap - else - return null - } - catch (e) { + const ap = await prisma.accessPoint.findUnique({ + where: { hostname: parent.apName } + }) + if (ap) return ap + else return null + } catch (e) { logError({ tags: ['wifiDevice', 'accessPoint'], message: `Could not find access point ${parent.apName}`, data: parent }) } - } } diff --git a/server/src/schemaDirectives/AuthDirective.js b/server/src/schemaDirectives/AuthDirective.js index caa0820..105068a 100755 --- a/server/src/schemaDirectives/AuthDirective.js +++ b/server/src/schemaDirectives/AuthDirective.js @@ -25,7 +25,7 @@ class AuthDirective extends SchemaDirectiveVisitor { context.auth = { ...user, - campus: user.extensionAttribute1?.split('-')[0] || '--', + campus: user.extensionAttribute1?.split('-')[0] || '--' } if (user.pwdLastSet.toISOString() === pwdLastSet) { diff --git a/server/src/typeDefs.js b/server/src/typeDefs.js index 9ae5d8d..aededc5 100644 --- a/server/src/typeDefs.js +++ b/server/src/typeDefs.js @@ -3,7 +3,7 @@ import { gql } from 'apollo-server' const typeDefs = gql` type Query { "Returns only a few fields of a user" - basicUser(sAMAccountName: String!): User! + basicUser(sAMAccountName: String!): User! "The authenticated user" me: User! @auth @@ -15,37 +15,37 @@ const typeDefs = gql` limit: Int = 15 "Should return only students?" onlyStudents: Boolean = false - ): [User!] @auth(roles: ["servant"]) + ): [User!] @auth(roles: ["servant"]) "A single user" - user(sAMAccountName: String!): User! - @auth(roles: ["superAdmin"]) + user(sAMAccountName: String!): User! @auth(roles: ["superAdmin"]) "AD groups" groups(where: GroupWhereInput!, limit: Int = 10): [Group!]! - @auth(roles: ["servant"]) + @auth(roles: ["servant"]) "Current stats. Differs from the historical statistics." stats: Stats! "Users who has some device currently connected to Wi-Fi" - userPresence(search: String = "", onlyServants: Boolean = false): [UserPresence!] @auth(roles: ["watcher"]) + userPresence( + search: String = "" + onlyServants: Boolean = false + ): [UserPresence!] @auth(roles: ["watcher"]) "Devices that uses the Wi-Fi" wifiDevices( - search: String = "" + search: String = "" take: Int skip: Int sortBy: WifiDevicesResultSortBy = "signalStrength" - sortDesc: Boolean = false, + sortDesc: Boolean = false onlineOnly: Boolean = false ): WifiDevicesResult! @auth(roles: ["superAdmin"]) "Users that uses the Wi-Fi" - wifiUsers( - search: String = "" - take: Int - skip: Int): WifiUsersResult! @auth(roles: ["superAdmin"]) + wifiUsers(search: String = "", take: Int, skip: Int): WifiUsersResult! + @auth(roles: ["superAdmin"]) "Application Logs" logs( @@ -92,7 +92,7 @@ const typeDefs = gql` "Import all users from Active Directory" importUsers: String! @auth(roles: ["superAdmin"]) - + "Add a PA host" addPAHost(data: AddPAHostInput!): PAHost! @auth(roles: ["superAdmin"]) @@ -239,7 +239,7 @@ const typeDefs = gql` lastSeen: String essid: String ip: String - uptime: String + uptime: Int apName: String status: Status accessPoint: AccessPoint @@ -247,7 +247,7 @@ const typeDefs = gql` frequency: String protocol: String speed: Int - usage: Int + usage: String } "A user that is on the Wi-Fi network reach" @@ -322,6 +322,7 @@ const typeDefs = gql` ip: String clients: Int subnetInfo: SubnetInfo + usage: String createdAt: String updatedAt: String @@ -345,14 +346,14 @@ const typeDefs = gql` shortName: String! name: String! cidr: String! - networkAddress: String! - firstAddress: String! - lastAddress: String! - broadcastAddress: String! + networkAddress: String! + firstAddress: String! + lastAddress: String! + broadcastAddress: String! subnetMask: String! - subnetMaskLength: String! - numHosts: String! - length: String! + subnetMaskLength: String! + numHosts: String! + length: String! } input LoginInput { @@ -405,7 +406,7 @@ const typeDefs = gql` notes: String } - enum WifiDevicesResultSortBy{ + enum WifiDevicesResultSortBy { mac hostname firstSeen @@ -420,7 +421,7 @@ const typeDefs = gql` frequency protocol speed - usage + usage } ` diff --git a/server/src/utils/capitalize.js b/server/src/utils/capitalize.js index bde50ca..09acc5d 100755 --- a/server/src/utils/capitalize.js +++ b/server/src/utils/capitalize.js @@ -1,4 +1,4 @@ -String.prototype.capitalize = function(lower = true) { +String.prototype.capitalize = function (lower = true) { return (lower ? this.toLowerCase() : this).replace(/(?:^|\s)\S/g, a => a.toUpperCase() ) diff --git a/server/src/utils/cycle.js b/server/src/utils/cycle.js index 6b4151d..f2df622 100644 --- a/server/src/utils/cycle.js +++ b/server/src/utils/cycle.js @@ -22,9 +22,9 @@ retrocycle, set, stringify, test */ -if (typeof JSON.decycle !== "function") { +if (typeof JSON.decycle !== 'function') { JSON.decycle = function decycle(object, replacer) { - "use strict"; + 'use strict' // Make a deep copy of an object or array, assuring that there is at most // one instance of each object or array in the resulting structure. The @@ -50,77 +50,73 @@ if (typeof JSON.decycle !== "function") { // the object or array. [NUMBER] or [STRING] indicates a child element or // property. - var objects = new WeakMap(); // object to path mappings + var objects = new WeakMap() // object to path mappings return (function derez(value, path) { - // The derez function recurses through the object, producing the deep copy. - var old_path; // The path of an earlier occurance of value - var nu; // The new object or array + var old_path // The path of an earlier occurance of value + var nu // The new object or array // If a replacer function was provided, then call it to get a replacement value. if (replacer !== undefined) { - value = replacer(value); + value = replacer(value) } // typeof null === "object", so go on if this value is really an object but not // one of the weird builtin objects. if ( - typeof value === "object" - && value !== null - && !(value instanceof Boolean) - && !(value instanceof Date) - && !(value instanceof Number) - && !(value instanceof RegExp) - && !(value instanceof String) + typeof value === 'object' && + value !== null && + !(value instanceof Boolean) && + !(value instanceof Date) && + !(value instanceof Number) && + !(value instanceof RegExp) && + !(value instanceof String) ) { - // If the value is an object or array, look to see if we have already // encountered it. If so, return a {"$ref":PATH} object. This uses an // ES6 WeakMap. - old_path = objects.get(value); + old_path = objects.get(value) if (old_path !== undefined) { - return { $ref: old_path }; + return { $ref: old_path } } // Otherwise, accumulate the unique value and its path. - objects.set(value, path); + objects.set(value, path) // If it is an array, replicate the array. if (Array.isArray(value)) { - nu = []; + nu = [] value.forEach(function (element, i) { - nu[i] = derez(element, path + "[" + i + "]"); - }); + nu[i] = derez(element, path + '[' + i + ']') + }) } else { - // If it is an object, replicate the object. - nu = {}; + nu = {} Object.keys(value).forEach(function (name) { nu[name] = derez( value[name], - path + "[" + JSON.stringify(name) + "]" - ); - }); + path + '[' + JSON.stringify(name) + ']' + ) + }) } - return nu; + return nu } - return value; - }(object, "$")); - }; + return value + })(object, '$') + } } - -if (typeof JSON.retrocycle !== "function") { +if (typeof JSON.retrocycle !== 'function') { JSON.retrocycle = function retrocycle($) { - "use strict"; + 'use strict' // Restore an object that was reduced by decycle. Members whose values are // objects of the form @@ -141,42 +137,42 @@ if (typeof JSON.retrocycle !== "function") { // return JSON.retrocycle(JSON.parse(s)); // produces an array containing a single element which is the array itself. - var px = /^\$(?:\[(?:\d+|"(?:[^\\"\u0000-\u001f]|\\(?:[\\"\/bfnrt]|u[0-9a-zA-Z]{4}))*")\])*$/; - - (function rez(value) { + var px = + /^\$(?:\[(?:\d+|"(?:[^\\"\u0000-\u001f]|\\(?:[\\"\/bfnrt]|u[0-9a-zA-Z]{4}))*")\])*$/ + ;(function rez(value) { // The rez function walks recursively through the object looking for $ref // properties. When it finds one that has a value that is a path, then it // replaces the $ref object with a reference to the value that is found by // the path. - if (value && typeof value === "object") { + if (value && typeof value === 'object') { if (Array.isArray(value)) { value.forEach(function (element, i) { - if (typeof element === "object" && element !== null) { - var path = element.$ref; - if (typeof path === "string" && px.test(path)) { - value[i] = eval(path); + if (typeof element === 'object' && element !== null) { + var path = element.$ref + if (typeof path === 'string' && px.test(path)) { + value[i] = eval(path) } else { - rez(element); + rez(element) } } - }); + }) } else { Object.keys(value).forEach(function (name) { - var item = value[name]; - if (typeof item === "object" && item !== null) { - var path = item.$ref; - if (typeof path === "string" && px.test(path)) { - value[name] = eval(path); + var item = value[name] + if (typeof item === 'object' && item !== null) { + var path = item.$ref + if (typeof path === 'string' && px.test(path)) { + value[name] = eval(path) } else { - rez(item); + rez(item) } } - }); + }) } } - }($)); - return $; - }; -} \ No newline at end of file + })($) + return $ + } +} diff --git a/server/src/utils/saveJSONToFile.js b/server/src/utils/saveJSONToFile.js index cdb7f8e..023559d 100644 --- a/server/src/utils/saveJSONToFile.js +++ b/server/src/utils/saveJSONToFile.js @@ -3,7 +3,7 @@ import fs from 'fs' function saveJSONToFile(json, fileName = 'output.json') { const jsonContent = JSON.stringify(json) - fs.writeFile(fileName, jsonContent, 'utf8', function(err) { + fs.writeFile(fileName, jsonContent, 'utf8', function (err) { if (err) { console.log('An error occured while writing JSON Object to File.') return console.log(err) diff --git a/server/src/utils/subnetInfo.js b/server/src/utils/subnetInfo.js index 38789b8..e4e2271 100644 --- a/server/src/utils/subnetInfo.js +++ b/server/src/utils/subnetInfo.js @@ -5,47 +5,37 @@ const subNetsInfo = [ { shortName: 'RT', name: 'Reitoria', - cidr: '10.0.0.0/16', + cidr: '10.0.0.0/16' }, { shortName: 'RT', name: 'Reitoria', cidr: '10.1.0.0/16', - addresses: [ - { name: 'RNP', ip: '200.19.32.4' } - ] + addresses: [{ name: 'RNP', ip: '200.19.32.4' }] }, { shortName: 'AQ', name: 'Aquidauana', cidr: '10.2.0.0/16', - addresses: [ - { name: 'RNP', ip: '200.19.32.253' } - ] + addresses: [{ name: 'RNP', ip: '200.19.32.253' }] }, { shortName: 'CG', name: 'Campo Grande', cidr: '10.3.0.0/16', - addresses: [ - { name: 'RNP', ip: '200.19.32.120' } - ] + addresses: [{ name: 'RNP', ip: '200.19.32.120' }] }, { shortName: 'CB', name: 'Corumbá', cidr: '10.4.0.0/16', - addresses: [ - { name: 'RNP', ip: '200.19.37.2' } - ] + addresses: [{ name: 'RNP', ip: '200.19.37.2' }] }, { shortName: 'CX', name: 'Coxim', cidr: '10.5.0.0/16', - addresses: [ - { name: 'RNP', ip: '200.19.36.16' } - ], + addresses: [{ name: 'RNP', ip: '200.19.36.16' }] }, { shortName: 'NA', @@ -57,17 +47,13 @@ const subNetsInfo = [ shortName: 'PP', name: 'Ponta Porã', cidr: '10.7.0.0/16', - addresses: [ - { name: 'RNP', ip: '200.19.34.254' } - ] + addresses: [{ name: 'RNP', ip: '200.19.34.254' }] }, { shortName: 'TL', name: 'Três Lagoas', cidr: '10.8.0.0/16', - addresses: [ - { name: 'RNP', ip: '200.19.35.2' } - ] + addresses: [{ name: 'RNP', ip: '200.19.35.2' }] }, { shortName: 'JD', @@ -80,13 +66,11 @@ const subNetsInfo = [ name: 'Naviraí', cidr: '10.10.0.0/16', addresses: [] - }, { shortName: 'DR', name: 'Dourados', - cidr: '10.11.0.0/16' - , + cidr: '10.11.0.0/16', addresses: [] } ] @@ -103,7 +87,6 @@ export function getSubnetInfo(ip) { name: 'Sem rede' } - const subnet = subNets.find(subnet => subnet.contains(ip)) if (!subnet) diff --git a/web/.prettierrc b/web/.prettierrc index 56f3312..cfa2681 100755 --- a/web/.prettierrc +++ b/web/.prettierrc @@ -6,5 +6,10 @@ "bracketSpacing": true, "arrowParens": "avoid", "vueIndentScriptAndStyle": false, - "excludeFiles": "dist/**" + "overrides": [ + { + "files": "*.js, *.vue, *.css, *.scss", + "excludeFiles": "**/dist/**, **/node_modules/**" + } + ] } diff --git a/web/README.md b/web/README.md index 88e592b..ee4cd89 100755 --- a/web/README.md +++ b/web/README.md @@ -1,6 +1,7 @@ # Portal de TI - Web Client ## Desenvolvimento + ``` npm install npm get-schema @@ -8,11 +9,13 @@ npm run serve ``` ### Compilar para produção + ``` npm run build ``` ### Lint + ``` npm run lint -``` \ No newline at end of file +``` diff --git a/web/generated/schema.graphql b/web/generated/schema.graphql index 0c1d9d1..7afedf3 100755 --- a/web/generated/schema.graphql +++ b/web/generated/schema.graphql @@ -3,7 +3,10 @@ directive @auth(roles: [String!]) on FIELD_DEFINITION -directive @cacheControl(maxAge: Int, scope: CacheControlScope) on FIELD_DEFINITION | OBJECT | INTERFACE +directive @cacheControl( + maxAge: Int + scope: CacheControlScope +) on FIELD_DEFINITION | OBJECT | INTERFACE type AuthPayload { user: User! @@ -48,14 +51,23 @@ type Mutation { } type Query { - """Returns only a few fields of User""" + """ + Returns only a few fields of User + """ basicUser(sAMAccountName: String!): User! me: User! - users(where: UserWhereInput!, limit: Int = 15, onlyStudents: Boolean = false): [User!] + users( + where: UserWhereInput! + limit: Int = 15 + onlyStudents: Boolean = false + ): [User!] user(sAMAccountName: String!): User! groups(where: GroupWhereInput!, limit: Int = 10): [Group!]! stats: Stats! - wifiDevices(search: String = "", identifiedOnly: Boolean = true): [WifiDevice]! + wifiDevices( + search: String = "" + identifiedOnly: Boolean = true + ): [WifiDevice]! userPresence(search: String): [UserPresence!] } @@ -91,10 +103,14 @@ input UpdatePasswordInput { newPassword: String! } -"""The `Upload` scalar type represents a file upload.""" +""" +The `Upload` scalar type represents a file upload. +""" scalar Upload -"""A mix between the database User and the Active Directory User""" +""" +A mix between the database User and the Active Directory User +""" type User { id: ID wifiDevices: [WifiDevice!] @@ -175,7 +191,7 @@ type WifiDevice { lastSeen: String essid: String ip: String - uptime: String + uptime: Int apName: String status: Status } diff --git a/web/public/manifest.json b/web/public/manifest.json index 013d4a6..3b557aa 100755 --- a/web/public/manifest.json +++ b/web/public/manifest.json @@ -1,41 +1,41 @@ { - "name": "App", - "icons": [ - { - "src": "\/android-icon-36x36.png", - "sizes": "36x36", - "type": "image\/png", - "density": "0.75" - }, - { - "src": "\/android-icon-48x48.png", - "sizes": "48x48", - "type": "image\/png", - "density": "1.0" - }, - { - "src": "\/android-icon-72x72.png", - "sizes": "72x72", - "type": "image\/png", - "density": "1.5" - }, - { - "src": "\/android-icon-96x96.png", - "sizes": "96x96", - "type": "image\/png", - "density": "2.0" - }, - { - "src": "\/android-icon-144x144.png", - "sizes": "144x144", - "type": "image\/png", - "density": "3.0" - }, - { - "src": "\/android-icon-192x192.png", - "sizes": "192x192", - "type": "image\/png", - "density": "4.0" - } - ] -} \ No newline at end of file + "name": "App", + "icons": [ + { + "src": "/android-icon-36x36.png", + "sizes": "36x36", + "type": "image/png", + "density": "0.75" + }, + { + "src": "/android-icon-48x48.png", + "sizes": "48x48", + "type": "image/png", + "density": "1.0" + }, + { + "src": "/android-icon-72x72.png", + "sizes": "72x72", + "type": "image/png", + "density": "1.5" + }, + { + "src": "/android-icon-96x96.png", + "sizes": "96x96", + "type": "image/png", + "density": "2.0" + }, + { + "src": "/android-icon-144x144.png", + "sizes": "144x144", + "type": "image/png", + "density": "3.0" + }, + { + "src": "/android-icon-192x192.png", + "sizes": "192x192", + "type": "image/png", + "density": "4.0" + } + ] +} diff --git a/web/src/components/DataTables/AccessPointClientsDataTable.vue b/web/src/components/DataTables/AccessPointClientsDataTable.vue index 9a05315..43afbf1 100644 --- a/web/src/components/DataTables/AccessPointClientsDataTable.vue +++ b/web/src/components/DataTables/AccessPointClientsDataTable.vue @@ -102,7 +102,8 @@ export default { diff --git a/web/src/components/DataTables/UserTD.vue b/web/src/components/DataTables/UserTD.vue index d622fa9..a526e91 100644 --- a/web/src/components/DataTables/UserTD.vue +++ b/web/src/components/DataTables/UserTD.vue @@ -37,4 +37,9 @@ export default { } - + diff --git a/web/src/components/DataTables/UserWifiDevicesDataTable.vue b/web/src/components/DataTables/UserWifiDevicesDataTable.vue index d18320f..e5d6e4d 100644 --- a/web/src/components/DataTables/UserWifiDevicesDataTable.vue +++ b/web/src/components/DataTables/UserWifiDevicesDataTable.vue @@ -10,6 +10,8 @@ :items="items" :headers="headers" :search="search" + sort-by="status" + sort-desc calculate-widths > @@ -206,6 +209,7 @@ export default { 'local', 'clients', 'uptime', + 'usage', 'notes' ], allHeaders: [ @@ -214,7 +218,6 @@ export default { { text: 'IP', value: 'ip', width: 80 }, { text: 'MAC', value: 'mac' }, { text: 'Campus', value: 'campus', group: true }, - { text: 'Localização', value: 'local' }, { text: 'Clientes', @@ -228,6 +231,7 @@ export default { text: 'Controladora', value: 'controller' }, + { text: 'Uso', value: 'usage' }, { text: 'Observações', value: 'notes' }, { text: 'Última atualização', value: 'updatedAt', width: 160 } ] @@ -306,6 +310,7 @@ export default { model ip clients + usage createdAt updatedAt @@ -332,6 +337,7 @@ export default { model ip clients + usage createdAt updatedAt