Skip to content

Commit

Permalink
Fix SPF parsing and IP evaluation (#203)
Browse files Browse the repository at this point in the history
  • Loading branch information
MattIPv4 committed Jan 3, 2024
1 parent c8b0d4a commit a050b42
Show file tree
Hide file tree
Showing 10 changed files with 257 additions and 132 deletions.
132 changes: 132 additions & 0 deletions package-lock.json

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

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@
"dependencies": {
"abortcontroller-polyfill": "^1.7.5",
"babel-polyfill": "^6.26.0",
"cidr-matcher": "^2.1.1",
"do-bulma": "github:do-community/do-bulma",
"do-vue": "github:do-community/do-vue",
"vue": "^3.3.4",
"vue-tippy": "^6.2.0",
"web-whois": "0.0.6"
},
"devDependencies": {
"@types/cidr-matcher": "^2.1.2",
"@typescript-eslint/eslint-plugin": "^6.2.1",
"@typescript-eslint/parser": "^6.2.1",
"@vue/component-compiler-utils": "^3.3.0",
Expand Down
65 changes: 28 additions & 37 deletions src/spf-explainer/templates/app.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!--
Copyright 2022 DigitalOcean
Copyright 2024 DigitalOcean
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -46,7 +46,7 @@ limitations under the License.
<EvalNotif ref="EvalNotif" :ip="ipEval"></EvalNotif>
</template>
<template #buttons>
<form v-if="!SPFSandbox.empty()" autocomplete="on" @submit.prevent="">
<form v-if="showEvalForm" autocomplete="on" @submit.prevent="">
<div class="input-container">
<label for="EvaluateInput" class="hidden">Evaluate</label>
<input
Expand Down Expand Up @@ -87,11 +87,11 @@ limitations under the License.

<script>
import i18n from "../i18n"
import cfDNS from "../../shared/utils/cfDNS"
import SPFBase from "./spf_base"
import { spawnLine } from "../utils/line_spawn"
import NoSPFRecords from "./no_spf_records"
import SPFSandbox from "../utils/spf_sandbox"
import getSPFRecords from "../utils/spf_records"
import EvalNotif from "./eval_notif"
import AllPartExplanations from "./all_part_explanations"
import ErrorModal from "../../shared/templates/error_modal"
Expand Down Expand Up @@ -130,6 +130,7 @@ limitations under the License.
loading: false,
records: [],
ipEval: "",
showEvalForm: false,
errorMessage: "",
spfTop,
spfBottom,
Expand All @@ -156,44 +157,28 @@ limitations under the License.
this.$data.errorMessage = `<p>${message}</p>`
this.$refs.ErrorModal.open()
},
async cfPart(input) {
async lookup(input) {
const [domain, result] = await validateDomain(input)
if (result !== null) return this.error(result)
const res = await cfDNS(domain, "TXT")
if (!res.ok) return this.error(i18n.templates.app.fetchError)
let json
try {
json = await res.json()
} catch {
// Sometimes Cloudflare's DNS sends invalid JSON in the event that it is invalid.
// That has happened here.
return this.error(i18n.templates.app.fetchError)
if (result !== null) {
this.error(result)
return
}
if (!json.Answer) {
this.$refs.NoSPFRecords.toggle()
return false
}
SPFSandbox.wipe()
SPFSandbox.listen(() => this.$data.showEvalForm = !SPFSandbox.empty())
remakeController()
return json
},
async lookup(domain, json) {
if (this.$data.lastDomain === domain) this.$data.records = []
this.$data.records = await getSPFRecords(domain)
window.history.pushState({}, "", `?domain=${domain}`)
const records = []
for (const answer of json.Answer) {
answer.data = answer.data.substr(1).slice(0, -1)
if (answer.data.startsWith("v=spf1")) records.push(answer)
}
if (records.length === 0) {
return this.$refs.NoSPFRecords.toggle()
if (this.$data.records.length === 0) {
this.$refs.NoSPFRecords.open()
return
} else {
this.$refs.NoSPFRecords.close()
}
this.$data.records = records
window.history.pushState({}, "", `?domain=${domain}`)
SPFSandbox.wipe()
remakeController()
this.$data.firstSearch = false
this.$data.lastDomain = domain
},
Expand All @@ -202,12 +187,18 @@ limitations under the License.
try {
el.classList.add("is-loading")
const domain = this.$data.domain.toLowerCase().replace(/^https*:\/\//, "").replace(/\/+$/, "")
const j = await this.cfPart(domain)
if (!j) return
this.$data.loading = true
try {
const domain = this.$data.domain.toLowerCase().replace(/^https*:\/\//, "").replace(/\/+$/, "")
await this.lookup(domain)
} catch {
// Sometimes Cloudflare's DNS sends invalid JSON in the event that it is invalid.
this.error(i18n.templates.app.fetchError)
return
}
spawnLine(undefined)
await this.lookup(domain, j)
} catch(e) {
console.error(e)
} finally {
Expand Down
Loading

1 comment on commit a050b42

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit has been deployed to DigitalOcean Spaces for easy reviewing.

dns-lookup (Build Analysis Report) spf-explainer (Build Analysis Report)

Please sign in to comment.