Added network information

This commit is contained in:
Douglas Barone 2023-10-31 09:23:38 -04:00
parent c2f916ef3f
commit 80388a3ff4
5 changed files with 163 additions and 8 deletions

30
package-lock.json generated
View File

@ -18,6 +18,7 @@
"cors": "^2.8.5", "cors": "^2.8.5",
"express": "^4.18.2", "express": "^4.18.2",
"fast-xml-parser": "^4.3.2", "fast-xml-parser": "^4.3.2",
"ip": "^1.1.8",
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.2",
"ldapts": "^7.0.5", "ldapts": "^7.0.5",
"roboto-fontface": "*", "roboto-fontface": "*",
@ -29,6 +30,7 @@
}, },
"devDependencies": { "devDependencies": {
"@babel/types": "^7.21.4", "@babel/types": "^7.21.4",
"@types/ip": "^1.1.2",
"@types/jsonwebtoken": "^9.0.4", "@types/jsonwebtoken": "^9.0.4",
"@types/node": "^18.15.0", "@types/node": "^18.15.0",
"@types/webfontloader": "^1.6.35", "@types/webfontloader": "^1.6.35",
@ -655,6 +657,15 @@
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.2.tgz", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.2.tgz",
"integrity": "sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==" "integrity": "sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg=="
}, },
"node_modules/@types/ip": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@types/ip/-/ip-1.1.2.tgz",
"integrity": "sha512-WjV3/mz9YSlfU8E88m4ZwvRQmpTjWy4vH8K+cggBUAjmp91wvT1he132Ql8V3CsZz3SYkze3CC3AxhjaD4ZYug==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/jsonwebtoken": { "node_modules/@types/jsonwebtoken": {
"version": "9.0.4", "version": "9.0.4",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.4.tgz", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.4.tgz",
@ -1734,6 +1745,11 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
}, },
"node_modules/ip": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
"integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg=="
},
"node_modules/ipaddr.js": { "node_modules/ipaddr.js": {
"version": "1.9.1", "version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@ -3341,6 +3357,15 @@
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.2.tgz", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.2.tgz",
"integrity": "sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==" "integrity": "sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg=="
}, },
"@types/ip": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@types/ip/-/ip-1.1.2.tgz",
"integrity": "sha512-WjV3/mz9YSlfU8E88m4ZwvRQmpTjWy4vH8K+cggBUAjmp91wvT1he132Ql8V3CsZz3SYkze3CC3AxhjaD4ZYug==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/jsonwebtoken": { "@types/jsonwebtoken": {
"version": "9.0.4", "version": "9.0.4",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.4.tgz", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.4.tgz",
@ -4196,6 +4221,11 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
}, },
"ip": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
"integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg=="
},
"ipaddr.js": { "ipaddr.js": {
"version": "1.9.1", "version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",

View File

@ -24,6 +24,7 @@
"cors": "^2.8.5", "cors": "^2.8.5",
"express": "^4.18.2", "express": "^4.18.2",
"fast-xml-parser": "^4.3.2", "fast-xml-parser": "^4.3.2",
"ip": "^1.1.8",
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.2",
"ldapts": "^7.0.5", "ldapts": "^7.0.5",
"roboto-fontface": "*", "roboto-fontface": "*",
@ -35,6 +36,7 @@
}, },
"devDependencies": { "devDependencies": {
"@babel/types": "^7.21.4", "@babel/types": "^7.21.4",
"@types/ip": "^1.1.2",
"@types/jsonwebtoken": "^9.0.4", "@types/jsonwebtoken": "^9.0.4",
"@types/node": "^18.15.0", "@types/node": "^18.15.0",
"@types/webfontloader": "^1.6.35", "@types/webfontloader": "^1.6.35",

103
src/server/lib/netInfo.ts Normal file
View File

@ -0,0 +1,103 @@
import { z } from 'zod'
import ip from 'ip'
import { db } from '../prisma'
type Network = {
name: string
shortName: string
network: string
}
const networksInfo: Array<Network> = [
{
name: 'Reitoria',
shortName: 'RT',
network: '10.0.0.0/16'
},
{
name: 'Aquidauana',
shortName: 'AQ',
network: '10.2.0.0/16'
},
{
name: 'Campo Grande',
shortName: 'CG',
network: '10.3.0.0/16'
},
{
name: 'Corumbá',
shortName: 'CB',
network: '10.4.0.0/16'
},
{
name: 'Coxim',
shortName: 'CX',
network: '10.5.0.0/16'
},
{
name: 'Nova Andradina',
shortName: 'NA',
network: '10.6.0.0/16'
},
{
name: 'Ponta Porã',
shortName: 'PP',
network: '10.7.0.0/16'
},
{
name: 'Três Lagoas',
shortName: 'TL',
network: '10.8.0.0/16'
},
{
name: 'Jardim',
shortName: 'JD',
network: '10.9.0.0/16'
},
{
name: 'Naviraí',
shortName: 'NV',
network: '10.10.0.0/16'
},
{
name: 'Dourados',
shortName: 'DR',
network: '10.11.0.0/16'
},
{
name: 'Reitoria 2',
shortName: 'RT2',
network: '10.1.0.0/16'
}
]
const networks = networksInfo.map(network => {
return {
...network,
...ip.cidrSubnet(network.network)
}
})
export async function getNetworkForIP(ip: string) {
z.string().ip().parse(ip)
const network = networks.find(network => network.contains(ip))
if (!network) {
return {
name: 'Rede desconhecida',
shortName: '--',
network: '?',
isSupported: false
}
}
const paHosts = await db.paHost.findMany()
const paHost = paHosts.find(paHost => network?.contains(paHost.ip))
return {
...network,
isSupported: !!paHost
}
}

View File

@ -9,6 +9,7 @@ import { PaFirewallService } from './services/PaFirewallService'
import { jwtService } from './lib/jwt' import { jwtService } from './lib/jwt'
import { autoLogin } from './lib/autoLogin' import { autoLogin } from './lib/autoLogin'
import { JwtPayload } from './schemas/JwtPayload' import { JwtPayload } from './schemas/JwtPayload'
import { getNetworkForIP } from './lib/netInfo'
// Created for each request // Created for each request
function createContext({ req, res }: trpcExpress.CreateExpressContextOptions) { function createContext({ req, res }: trpcExpress.CreateExpressContextOptions) {
@ -33,9 +34,16 @@ export const t = initTRPC.context<Context>().create()
const { query, mutation, input } = t.procedure const { query, mutation, input } = t.procedure
export const appRouter = t.router({ export const appRouter = t.router({
myIp: query(({ ctx }) => { myIp: query(async ({ ctx }) => {
if (!ctx.ip) throw new Error('Erro ao obter endereço IP') if (!ctx.ip) throw new Error('Erro ao obter endereço IP')
return ctx.ip const network = await getNetworkForIP(ctx.ip)
return {
name: network?.name,
shortName: network?.shortName,
ip: ctx.ip,
isSupported: network?.isSupported
}
}), }),
login: input( login: input(

View File

@ -3,30 +3,42 @@
<span v-if="!loadingIpAddress"> <span v-if="!loadingIpAddress">
Endereço IP deste dispositivo: Endereço IP deste dispositivo:
<strong> <strong>
<code> <code> {{ netInfo.ip }} ({{ netInfo.name }}) </code>
{{ ipAddress }}
</code>
</strong> </strong>
</span> </span>
<span v-else> <span v-else>
<v-progress-circular indeterminate class="mr-2" /> <v-progress-circular indeterminate class="mr-2" />
Obtendo seu endereço IP... Obtendo seu endereço IP...
</span> </span>
<v-alert
type="error"
v-if="!netInfo.isSupported && !loadingIpAddress"
prominent
class="mt-2"
>
A rede onde seu dispositivo se encontra não é suportada. Entre em contato
com o SERTI do seu câmpus
</v-alert>
</v-alert> </v-alert>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { trpc } from '../trpc' import { trpc } from '../trpc'
const ipAddress = ref('') const netInfo = ref<{
ip: string
name?: string | undefined
shortName?: string | undefined
isSupported?: boolean
}>({ ip: '', name: '', shortName: '' })
const loadingIpAddress = ref(false) const loadingIpAddress = ref(false)
onMounted(async () => { onMounted(async () => {
try { try {
loadingIpAddress.value = true loadingIpAddress.value = true
ipAddress.value = await trpc.myIp.query() netInfo.value = await trpc.myIp.query()
} catch (error: any) { } catch (error: any) {
ipAddress.value = error.message netInfo.value = error.message
} finally { } finally {
loadingIpAddress.value = false loadingIpAddress.value = false
} }