diff --git a/server/prisma/migrations/20220829163049_enable_ap_delete/migration.sql b/server/prisma/migrations/20220829163049_enable_ap_delete/migration.sql
new file mode 100644
index 0000000..6a2618b
--- /dev/null
+++ b/server/prisma/migrations/20220829163049_enable_ap_delete/migration.sql
@@ -0,0 +1,5 @@
+-- DropForeignKey
+ALTER TABLE "AccessPointStats" DROP CONSTRAINT "AccessPointStats_accessPointId_fkey";
+
+-- AddForeignKey
+ALTER TABLE "AccessPointStats" ADD CONSTRAINT "AccessPointStats_accessPointId_fkey" FOREIGN KEY ("accessPointId") REFERENCES "AccessPoint"("id") ON DELETE CASCADE ON UPDATE CASCADE;
diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma
index b22089a..765d840 100644
--- a/server/prisma/schema.prisma
+++ b/server/prisma/schema.prisma
@@ -105,7 +105,7 @@ model WifiDevice {
identity String? // The user informed by the controller
accessPointId Int?
- accessPoint AccessPoint? @relation("wifidevice_to_ap", fields: [accessPointId], references: [id])
+ accessPoint AccessPoint? @relation("wifidevice_to_ap", fields: [accessPointId], references: [id], onDelete: SetNull)
userId Int? // The connected User
user User? @relation("wifidevice_to_user", fields: [userId], references: [id])
@@ -199,7 +199,7 @@ model AccessPointStats {
sumUsage BigInt?
accessPointId Int
- accessPoint AccessPoint @relation("accesspointstats_to_ap", fields: [accessPointId], references: [id])
+ accessPoint AccessPoint @relation("accesspointstats_to_ap", fields: [accessPointId], references: [id], onDelete: Cascade)
}
model Network {
diff --git a/server/src/resolvers/Mutation/deleteAccessPoint.js b/server/src/resolvers/Mutation/deleteAccessPoint.js
new file mode 100644
index 0000000..79acb2f
--- /dev/null
+++ b/server/src/resolvers/Mutation/deleteAccessPoint.js
@@ -0,0 +1,54 @@
+import prisma from '../../prisma'
+import { ACCESS_POINTS_UPDATED, pubsub } from '../../pubsub'
+import { logError, logInfo } from '../../lib/logger'
+import { getSubnetInfo } from '../../lib/subnetInfo'
+
+export async function deleteAccessPoint(_, { id }, { 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 deletar o
+ 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 deletar APs da rede do seu campus.`
+ )
+ }
+
+ const updatedAccessPoint = await prisma.accessPoint.delete({
+ where: { id: parseInt(id) }
+ })
+
+ logInfo({
+ tags: ['accessPointDeleted', 'accessPoints'],
+ message: `O usuário ${auth.displayName} (${
+ auth.sAMAccountName
+ }) deletou o AP ${updatedAccessPoint.name || updatedAccessPoint.hostname}`,
+ data: updatedAccessPoint
+ })
+
+ const accessPoints = await prisma.accessPoint.findMany({
+ include: { wifiDevices: true }
+ })
+
+ pubsub.publish(ACCESS_POINTS_UPDATED, {
+ accessPointsUpdated: accessPoints
+ })
+
+ return updatedAccessPoint
+}
diff --git a/server/src/resolvers/Mutation/index.js b/server/src/resolvers/Mutation/index.js
index 2804d29..ee4fe15 100644
--- a/server/src/resolvers/Mutation/index.js
+++ b/server/src/resolvers/Mutation/index.js
@@ -8,6 +8,7 @@ import { deleteExpiredTokens } from './deleteExpiredTokens'
import { importUsers } from './importUsers'
import { addPAHost } from './addPAHost'
import { delPAHost } from './delPAHost'
+import { deleteAccessPoint } from './deleteAccessPoint'
import { updateAccessPoint } from './updateAccessPoint'
const Mutation = {
@@ -21,6 +22,7 @@ const Mutation = {
importUsers,
addPAHost,
delPAHost,
+ deleteAccessPoint,
updateAccessPoint
}
diff --git a/server/src/schemaDirectives/AuthDirective.js b/server/src/schemaDirectives/AuthDirective.js
index 26a7f9c..d20b837 100755
--- a/server/src/schemaDirectives/AuthDirective.js
+++ b/server/src/schemaDirectives/AuthDirective.js
@@ -25,11 +25,6 @@ class AuthDirective extends SchemaDirectiveVisitor {
context.auth = user
- console.log({
- user: user.updatePassword,
- context: context.auth.updatePassword
- })
-
if (user.pwdLastSet.toISOString() === pwdLastSet) {
if (
expectedRoles.length === 0 ||
diff --git a/server/src/typeDefs.js b/server/src/typeDefs.js
index 9397a48..71e7606 100644
--- a/server/src/typeDefs.js
+++ b/server/src/typeDefs.js
@@ -102,6 +102,9 @@ const typeDefs = gql`
"Update an Access Point"
updateAccessPoint(data: UpdateAccessPointInput): AccessPoint!
@auth(roles: ["superAdmin"])
+
+ "Delete an Access Point"
+ deleteAccessPoint(id: ID!): AccessPoint! @auth(roles: ["superAdmin"])
}
type Subscription {
diff --git a/web/src/views/AccessPoints/edit.vue b/web/src/views/AccessPoints/edit.vue
index 619231f..c4c8a98 100644
--- a/web/src/views/AccessPoints/edit.vue
+++ b/web/src/views/AccessPoints/edit.vue
@@ -31,6 +31,9 @@
/>
+
+ mdi-delete
+
mdi-check
@@ -96,6 +99,47 @@ export default {
}
})
+ this.$router.push({ name: 'access-points' })
+ } catch (e) {
+ this.errors = e.graphQLErrors.map(error => error.message)
+ } finally {
+ this.loading = false
+ }
+ },
+
+ async onDeleteAccessPoint() {
+ this.errors = []
+ this.loading = true
+
+ try {
+ if (
+ !confirm('Deletar este Access Point?') ||
+ !confirm(
+ `ATENÇÃO!
+
+Esta ação desassociará todos os dispositivos que
+já se conectaram à este AP. Além disso, se o AP
+ainda estiver registrado na controladora, ele
+será incluído novamente automaticamente.
+
+Continuar?`
+ )
+ )
+ return
+
+ await this.$apollo.mutate({
+ mutation: gql`
+ mutation ($id: ID!) {
+ deleteAccessPoint(id: $id) {
+ id
+ }
+ }
+ `,
+ variables: {
+ id: this.$route.params.id
+ }
+ })
+
this.$router.push({ name: 'access-points' })
} catch (e) {
this.errors = e.graphQLErrors.map(error => error.message)
diff --git a/web/src/views/AccessPoints/index.vue b/web/src/views/AccessPoints/index.vue
index 1b5cc84..734cf56 100644
--- a/web/src/views/AccessPoints/index.vue
+++ b/web/src/views/AccessPoints/index.vue
@@ -117,6 +117,7 @@
mdi-pencil
+
{{ item.name }}