From a2c9cfc55be686f1e650d9150ae5a06268a23690 Mon Sep 17 00:00:00 2001 From: Mechiel Lukkien Date: Thu, 9 May 2024 15:58:14 +0200 Subject: [PATCH] webadmin: don't show runtime typecheck error for invalid values in dmarc and tls reports several fields in dmarc and tls reports have known string values. we have a Go string type for them. sherpats (through sherpadoc) turns those strings into typescript enums, and sherpats generates runtime-typechecking code (to enforce correct types for incoming json, to prevent failing deeper in the code when we get invalid data (much harder to debug)). the Go not-really-enum types allow other values, and real-world reports have unknown/unspecified/invalid values. this uses the sherpadoc -rename flag to turn those enums into regular untyped strings, so sherpats doesn't generate enum-enforcing runtime type checking code. this required an update to sherpadoc, to properly handling renaming a type to a basic type instead of another named type. for issue #161 by RobSlgm, thanks for reporting! --- Makefile | 6 +- go.mod | 2 +- go.sum | 4 +- vendor/github.com/mjl-/sherpadoc/check.go | 20 +- .../mjl-/sherpadoc/cmd/sherpadoc/main.go | 37 +- .../mjl-/sherpadoc/cmd/sherpadoc/parse.go | 3 + vendor/modules.txt | 2 +- webadmin/admin.js | 129 +------ webadmin/admin.ts | 14 +- webadmin/api.json | 332 +----------------- webadmin/api.ts | 151 ++------ 11 files changed, 117 insertions(+), 583 deletions(-) diff --git a/Makefile b/Makefile index 09cff30..16077ad 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,11 @@ build0: CGO_ENABLED=0 go build CGO_ENABLED=0 go vet ./... ./gendoc.sh - (cd webadmin && CGO_ENABLED=0 go run ../vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/*.go -adjust-function-names none -rename 'config Domain ConfigDomain,dmarc Policy DMARCPolicy,mtasts MX STSMX,tlsrptdb Record TLSReportRecord,tlsrptdb SuppressAddress TLSRPTSuppressAddress' Admin) >webadmin/api.json + # we rewrite some dmarcprt and tlsrpt enums into untyped strings: real-world + # reports have invalid values, and our loose Go typed strings accept all values, + # but we don't want the typescript runtime checker to fail on those unrecognized + # values. + (cd webadmin && CGO_ENABLED=0 go run ../vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/*.go -adjust-function-names none -rename 'config Domain ConfigDomain,dmarc Policy DMARCPolicy,mtasts MX STSMX,tlsrptdb Record TLSReportRecord,tlsrptdb SuppressAddress TLSRPTSuppressAddress,dmarcrpt DKIMResult string,dmarcrpt SPFResult string,dmarcrpt SPFDomainScope string,dmarcrpt DMARCResult string,dmarcrpt PolicyOverride string,dmarcrpt Alignment string,dmarcrpt Disposition string,tlsrpt PolicyType string,tlsrpt ResultType string' Admin) >webadmin/api.json (cd webaccount && CGO_ENABLED=0 go run ../vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/*.go -adjust-function-names none Account) >webaccount/api.json (cd webmail && CGO_ENABLED=0 go run ../vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/*.go -adjust-function-names none Webmail) >webmail/api.json ./gents.sh webadmin/api.json webadmin/api.ts diff --git a/go.mod b/go.mod index 940dca5..7a71dd9 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/mjl-/bstore v0.0.5 github.com/mjl-/sconf v0.0.6 github.com/mjl-/sherpa v0.6.7 - github.com/mjl-/sherpadoc v0.0.14 + github.com/mjl-/sherpadoc v0.0.16 github.com/mjl-/sherpaprom v0.0.2 github.com/mjl-/sherpats v0.0.6 github.com/prometheus/client_golang v1.18.0 diff --git a/go.sum b/go.sum index 6bc1ee7..3fccb33 100644 --- a/go.sum +++ b/go.sum @@ -35,8 +35,8 @@ github.com/mjl-/sconf v0.0.6/go.mod h1:uF8OdWtLT8La3i4ln176i1pB0ps9pXGCaABEU55Zk github.com/mjl-/sherpa v0.6.7 h1:C5F8XQdV5nCuS4fvB+ye/ziUQrajEhOoj/t2w5T14BY= github.com/mjl-/sherpa v0.6.7/go.mod h1:dSpAOdgpwdqQZ72O4n3EHo/tR68eKyan8tYYraUMPNc= github.com/mjl-/sherpadoc v0.0.0-20190505200843-c0a7f43f5f1d/go.mod h1:5khTKxoKKNXcB8bkVUO6GlzC7PFtMmkHq578lPbmnok= -github.com/mjl-/sherpadoc v0.0.14 h1:Xrdg8RhAmTDQXlEU+qDSlige4zfhMHr+VKBJNpPeWe4= -github.com/mjl-/sherpadoc v0.0.14/go.mod h1:vh5zcsk3j/Tvm725EY+unTZb3EZcZcpiEQzrODSa6+I= +github.com/mjl-/sherpadoc v0.0.16 h1:BdlFNXfnTaA7qO54kof4xpNFJxYBTY0cIObRk7QAP6M= +github.com/mjl-/sherpadoc v0.0.16/go.mod h1:vh5zcsk3j/Tvm725EY+unTZb3EZcZcpiEQzrODSa6+I= github.com/mjl-/sherpaprom v0.0.2 h1:1dlbkScsNafM5jURI44uiWrZMSwfZtcOFEEq7vx2C1Y= github.com/mjl-/sherpaprom v0.0.2/go.mod h1:cl5nMNOvqhzMiQJ2FzccQ9ReivjHXe53JhOVkPfSvw4= github.com/mjl-/sherpats v0.0.6 h1:2lSoJbb+jkjLOdlvoMxItq0QQrrnkH+rnm3PMRfpbmA= diff --git a/vendor/github.com/mjl-/sherpadoc/check.go b/vendor/github.com/mjl-/sherpadoc/check.go index 40b1141..5f9df3a 100644 --- a/vendor/github.com/mjl-/sherpadoc/check.go +++ b/vendor/github.com/mjl-/sherpadoc/check.go @@ -4,6 +4,15 @@ import ( "fmt" ) +// IsBasicType returns whether name is a basic type, like int32, string, any, timestamp, etc. +func IsBasicType(name string) bool { + switch name { + case "any", "bool", "int8", "uint8", "int16", "uint16", "int32", "uint32", "int64", "uint64", "int64s", "uint64s", "float32", "float64", "string", "timestamp": + return true + } + return false +} + type genError struct{ error } func parseError(path string, format string, args ...interface{}) { @@ -88,6 +97,13 @@ func (c checker) checkTypewords(path string, tokens []string, okNullable bool) { } t := tokens[0] tokens = tokens[1:] + if IsBasicType(t) { + if len(tokens) != 0 { + parseError(path, "leftover typewords %v", tokens) + } + return + } + switch t { case "nullable": if !okNullable { @@ -97,10 +113,6 @@ func (c checker) checkTypewords(path string, tokens []string, okNullable bool) { parseError(path, "missing typeword after %#v", t) } c.checkTypewords(path, tokens, false) - case "any", "bool", "int8", "uint8", "int16", "uint16", "int32", "uint32", "int64", "uint64", "int64s", "uint64s", "float32", "float64", "string", "timestamp": - if len(tokens) != 0 { - parseError(path, "leftover typewords %v", tokens) - } case "[]", "{}": if len(tokens) == 0 { parseError(path, "missing typeword after %#v", t) diff --git a/vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/main.go b/vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/main.go index 1d8bb01..a7610c6 100644 --- a/vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/main.go +++ b/vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/main.go @@ -46,6 +46,7 @@ import ( "log" "os" "path/filepath" + "sort" "strings" "github.com/mjl-/sherpadoc" @@ -59,6 +60,8 @@ var ( rename = flag.String("rename", "", "comma-separated list of type renames as used with a package selector, e.g. \"somepkg SomeName OtherName\"") title = flag.String("title", "", "title of the API, default is the name of the type of the main API") adjustFunctionNames = flag.String("adjust-function-names", "", `by default, the first character of function names is turned into lower case; with "lowerWord" the first string of upper case characters is lower cased, with "none" the name is left as is`) + sortfuncs = flag.Bool("sort-funcs", false, "sort functions within section by name") + sorttypes = flag.Bool("sort-types", false, "sort types within section by name") ) // If there is a "vendor" directory, we'll load packages from there (instead of @@ -176,11 +179,13 @@ func main() { log.Printf("duplicate rename %q", elem) usage() } - if to[l[2]] { - log.Printf("duplicate rename type %q", l[2]) - usage() + if !sherpadoc.IsBasicType(l[2]) { + if to[l[2]] { + log.Printf("duplicate rename type %q", l[2]) + usage() + } + to[l[2]] = true } - to[l[2]] = true renames[src] = l[2] } } @@ -223,9 +228,33 @@ func main() { err := sherpadoc.Check(doc) check(err, "checking sherpadoc output before writing") + sortFuncs(doc) + writeJSON(doc) } +func sortFuncs(s *sherpadoc.Section) { + if *sortfuncs { + sort.Slice(s.Functions, func(i, j int) bool { + return s.Functions[i].Name < s.Functions[j].Name + }) + } + if *sorttypes { + sort.Slice(s.Structs, func(i, j int) bool { + return s.Structs[i].Name < s.Structs[j].Name + }) + sort.Slice(s.Ints, func(i, j int) bool { + return s.Ints[i].Name < s.Ints[j].Name + }) + sort.Slice(s.Strings, func(i, j int) bool { + return s.Strings[i].Name < s.Strings[j].Name + }) + } + for _, ss := range s.Sections { + sortFuncs(ss) + } +} + func writeJSON(v interface{}) { buf, err := json.MarshalIndent(v, "", "\t") check(err, "marshal to json") diff --git a/vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/parse.go b/vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/parse.go index 181e0e7..6c63db1 100644 --- a/vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/parse.go +++ b/vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/parse.go @@ -186,6 +186,9 @@ func parseSection(t *doc.Type, pp *parsedPackage) *section { func ensureNamedType(t *doc.Type, sec *section, pp *parsedPackage) (name string) { if s, ok := renames[renameSrc{pp.Pkg.Name, t.Name}]; ok { name = s + if sherpadoc.IsBasicType(s) { + return + } } else { name = t.Name } diff --git a/vendor/modules.txt b/vendor/modules.txt index 0a85c4d..8575b16 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -25,7 +25,7 @@ github.com/mjl-/sconf # github.com/mjl-/sherpa v0.6.7 ## explicit; go 1.12 github.com/mjl-/sherpa -# github.com/mjl-/sherpadoc v0.0.14 +# github.com/mjl-/sherpadoc v0.0.16 ## explicit; go 1.16 github.com/mjl-/sherpadoc github.com/mjl-/sherpadoc/cmd/sherpadoc diff --git a/webadmin/admin.js b/webadmin/admin.js index ae1008a..147bffa 100644 --- a/webadmin/admin.js +++ b/webadmin/admin.js @@ -250,95 +250,8 @@ var api; Mode["ModeTesting"] = "testing"; Mode["ModeNone"] = "none"; })(Mode = api.Mode || (api.Mode = {})); - // PolicyType indicates the policy success/failure results are for. - let PolicyType; - (function (PolicyType) { - PolicyType["TLSA"] = "tlsa"; - PolicyType["STS"] = "sts"; - // Recipient domain did not have MTA-STS policy, or mail host (TSLA base domain) - // did not have DANE TLSA records. - PolicyType["NoPolicyFound"] = "no-policy-found"; - })(PolicyType = api.PolicyType || (api.PolicyType = {})); - // ResultType represents a TLS error. - let ResultType; - (function (ResultType) { - ResultType["ResultSTARTTLSNotSupported"] = "starttls-not-supported"; - ResultType["ResultCertificateHostMismatch"] = "certificate-host-mismatch"; - ResultType["ResultCertificateExpired"] = "certificate-expired"; - ResultType["ResultTLSAInvalid"] = "tlsa-invalid"; - ResultType["ResultDNSSECInvalid"] = "dnssec-invalid"; - ResultType["ResultDANERequired"] = "dane-required"; - ResultType["ResultCertificateNotTrusted"] = "certificate-not-trusted"; - ResultType["ResultSTSPolicyInvalid"] = "sts-policy-invalid"; - ResultType["ResultSTSWebPKIInvalid"] = "sts-webpki-invalid"; - ResultType["ResultValidationFailure"] = "validation-failure"; - ResultType["ResultSTSPolicyFetch"] = "sts-policy-fetch-error"; - })(ResultType = api.ResultType || (api.ResultType = {})); - // Alignment is the identifier alignment. - let Alignment; - (function (Alignment) { - Alignment["AlignmentAbsent"] = ""; - Alignment["AlignmentRelaxed"] = "r"; - Alignment["AlignmentStrict"] = "s"; - })(Alignment = api.Alignment || (api.Alignment = {})); - // Disposition is the requested action for a DMARC fail as specified in the - // DMARC policy in DNS. - let Disposition; - (function (Disposition) { - Disposition["DispositionAbsent"] = ""; - Disposition["DispositionNone"] = "none"; - Disposition["DispositionQuarantine"] = "quarantine"; - Disposition["DispositionReject"] = "reject"; - })(Disposition = api.Disposition || (api.Disposition = {})); - // DMARCResult is the final validation and alignment verdict for SPF and DKIM. - let DMARCResult; - (function (DMARCResult) { - DMARCResult["DMARCAbsent"] = ""; - DMARCResult["DMARCPass"] = "pass"; - DMARCResult["DMARCFail"] = "fail"; - })(DMARCResult = api.DMARCResult || (api.DMARCResult = {})); - // PolicyOverride is a reason the requested DMARC policy from the DNS record - // was not applied. - let PolicyOverride; - (function (PolicyOverride) { - PolicyOverride["PolicyOverrideAbsent"] = ""; - PolicyOverride["PolicyOverrideForwarded"] = "forwarded"; - PolicyOverride["PolicyOverrideSampledOut"] = "sampled_out"; - PolicyOverride["PolicyOverrideTrustedForwarder"] = "trusted_forwarder"; - PolicyOverride["PolicyOverrideMailingList"] = "mailing_list"; - PolicyOverride["PolicyOverrideLocalPolicy"] = "local_policy"; - PolicyOverride["PolicyOverrideOther"] = "other"; - })(PolicyOverride = api.PolicyOverride || (api.PolicyOverride = {})); - let DKIMResult; - (function (DKIMResult) { - DKIMResult["DKIMAbsent"] = ""; - DKIMResult["DKIMNone"] = "none"; - DKIMResult["DKIMPass"] = "pass"; - DKIMResult["DKIMFail"] = "fail"; - DKIMResult["DKIMPolicy"] = "policy"; - DKIMResult["DKIMNeutral"] = "neutral"; - DKIMResult["DKIMTemperror"] = "temperror"; - DKIMResult["DKIMPermerror"] = "permerror"; - })(DKIMResult = api.DKIMResult || (api.DKIMResult = {})); - let SPFDomainScope; - (function (SPFDomainScope) { - SPFDomainScope["SPFDomainScopeAbsent"] = ""; - SPFDomainScope["SPFDomainScopeHelo"] = "helo"; - SPFDomainScope["SPFDomainScopeMailFrom"] = "mfrom"; - })(SPFDomainScope = api.SPFDomainScope || (api.SPFDomainScope = {})); - let SPFResult; - (function (SPFResult) { - SPFResult["SPFAbsent"] = ""; - SPFResult["SPFNone"] = "none"; - SPFResult["SPFNeutral"] = "neutral"; - SPFResult["SPFPass"] = "pass"; - SPFResult["SPFFail"] = "fail"; - SPFResult["SPFSoftfail"] = "softfail"; - SPFResult["SPFTemperror"] = "temperror"; - SPFResult["SPFPermerror"] = "permerror"; - })(SPFResult = api.SPFResult || (api.SPFResult = {})); api.structTypes = { "Account": true, "Address": true, "AddressAlias": true, "Alias": true, "AliasAddress": true, "AuthResults": true, "AutoconfCheckResult": true, "AutodiscoverCheckResult": true, "AutodiscoverSRV": true, "AutomaticJunkFlags": true, "Canonicalization": true, "CheckResult": true, "ClientConfigs": true, "ClientConfigsEntry": true, "ConfigDomain": true, "DANECheckResult": true, "DKIM": true, "DKIMAuthResult": true, "DKIMCheckResult": true, "DKIMRecord": true, "DMARC": true, "DMARCCheckResult": true, "DMARCRecord": true, "DMARCSummary": true, "DNSSECResult": true, "DateRange": true, "Destination": true, "Directive": true, "Domain": true, "DomainFeedback": true, "Dynamic": true, "Evaluation": true, "EvaluationStat": true, "Extension": true, "FailureDetails": true, "Filter": true, "HoldRule": true, "Hook": true, "HookFilter": true, "HookResult": true, "HookRetired": true, "HookRetiredFilter": true, "HookRetiredSort": true, "HookSort": true, "IPDomain": true, "IPRevCheckResult": true, "Identifiers": true, "IncomingWebhook": true, "JunkFilter": true, "MTASTS": true, "MTASTSCheckResult": true, "MTASTSRecord": true, "MX": true, "MXCheckResult": true, "Modifier": true, "Msg": true, "MsgResult": true, "MsgRetired": true, "OutgoingWebhook": true, "Pair": true, "Policy": true, "PolicyEvaluated": true, "PolicyOverrideReason": true, "PolicyPublished": true, "PolicyRecord": true, "Record": true, "Report": true, "ReportMetadata": true, "ReportRecord": true, "Result": true, "ResultPolicy": true, "RetiredFilter": true, "RetiredSort": true, "Reverse": true, "Route": true, "Row": true, "Ruleset": true, "SMTPAuth": true, "SPFAuthResult": true, "SPFCheckResult": true, "SPFRecord": true, "SRV": true, "SRVConfCheckResult": true, "STSMX": true, "Selector": true, "Sort": true, "SubjectPass": true, "Summary": true, "SuppressAddress": true, "TLSCheckResult": true, "TLSRPT": true, "TLSRPTCheckResult": true, "TLSRPTDateRange": true, "TLSRPTRecord": true, "TLSRPTSummary": true, "TLSRPTSuppressAddress": true, "TLSReportRecord": true, "TLSResult": true, "Transport": true, "TransportDirect": true, "TransportSMTP": true, "TransportSocks": true, "URI": true, "WebForward": true, "WebHandler": true, "WebRedirect": true, "WebStatic": true, "WebserverConfig": true }; - api.stringsTypes = { "Align": true, "Alignment": true, "CSRFToken": true, "DKIMResult": true, "DMARCPolicy": true, "DMARCResult": true, "Disposition": true, "IP": true, "Localpart": true, "Mode": true, "PolicyOverride": true, "PolicyType": true, "RUA": true, "ResultType": true, "SPFDomainScope": true, "SPFResult": true }; + api.stringsTypes = { "Align": true, "CSRFToken": true, "DMARCPolicy": true, "IP": true, "Localpart": true, "Mode": true, "RUA": true }; api.intsTypes = {}; api.types = { "CheckResult": { "Name": "CheckResult", "Docs": "", "Fields": [{ "Name": "Domain", "Docs": "", "Typewords": ["string"] }, { "Name": "DNSSEC", "Docs": "", "Typewords": ["DNSSECResult"] }, { "Name": "IPRev", "Docs": "", "Typewords": ["IPRevCheckResult"] }, { "Name": "MX", "Docs": "", "Typewords": ["MXCheckResult"] }, { "Name": "TLS", "Docs": "", "Typewords": ["TLSCheckResult"] }, { "Name": "DANE", "Docs": "", "Typewords": ["DANECheckResult"] }, { "Name": "SPF", "Docs": "", "Typewords": ["SPFCheckResult"] }, { "Name": "DKIM", "Docs": "", "Typewords": ["DKIMCheckResult"] }, { "Name": "DMARC", "Docs": "", "Typewords": ["DMARCCheckResult"] }, { "Name": "HostTLSRPT", "Docs": "", "Typewords": ["TLSRPTCheckResult"] }, { "Name": "DomainTLSRPT", "Docs": "", "Typewords": ["TLSRPTCheckResult"] }, { "Name": "MTASTS", "Docs": "", "Typewords": ["MTASTSCheckResult"] }, { "Name": "SRVConf", "Docs": "", "Typewords": ["SRVConfCheckResult"] }, { "Name": "Autoconf", "Docs": "", "Typewords": ["AutoconfCheckResult"] }, { "Name": "Autodiscover", "Docs": "", "Typewords": ["AutodiscoverCheckResult"] }] }, @@ -397,22 +310,22 @@ var api; "Report": { "Name": "Report", "Docs": "", "Fields": [{ "Name": "OrganizationName", "Docs": "", "Typewords": ["string"] }, { "Name": "DateRange", "Docs": "", "Typewords": ["TLSRPTDateRange"] }, { "Name": "ContactInfo", "Docs": "", "Typewords": ["string"] }, { "Name": "ReportID", "Docs": "", "Typewords": ["string"] }, { "Name": "Policies", "Docs": "", "Typewords": ["[]", "Result"] }] }, "TLSRPTDateRange": { "Name": "TLSRPTDateRange", "Docs": "", "Fields": [{ "Name": "Start", "Docs": "", "Typewords": ["timestamp"] }, { "Name": "End", "Docs": "", "Typewords": ["timestamp"] }] }, "Result": { "Name": "Result", "Docs": "", "Fields": [{ "Name": "Policy", "Docs": "", "Typewords": ["ResultPolicy"] }, { "Name": "Summary", "Docs": "", "Typewords": ["Summary"] }, { "Name": "FailureDetails", "Docs": "", "Typewords": ["[]", "FailureDetails"] }] }, - "ResultPolicy": { "Name": "ResultPolicy", "Docs": "", "Fields": [{ "Name": "Type", "Docs": "", "Typewords": ["PolicyType"] }, { "Name": "String", "Docs": "", "Typewords": ["[]", "string"] }, { "Name": "Domain", "Docs": "", "Typewords": ["string"] }, { "Name": "MXHost", "Docs": "", "Typewords": ["[]", "string"] }] }, + "ResultPolicy": { "Name": "ResultPolicy", "Docs": "", "Fields": [{ "Name": "Type", "Docs": "", "Typewords": ["string"] }, { "Name": "String", "Docs": "", "Typewords": ["[]", "string"] }, { "Name": "Domain", "Docs": "", "Typewords": ["string"] }, { "Name": "MXHost", "Docs": "", "Typewords": ["[]", "string"] }] }, "Summary": { "Name": "Summary", "Docs": "", "Fields": [{ "Name": "TotalSuccessfulSessionCount", "Docs": "", "Typewords": ["int64"] }, { "Name": "TotalFailureSessionCount", "Docs": "", "Typewords": ["int64"] }] }, - "FailureDetails": { "Name": "FailureDetails", "Docs": "", "Fields": [{ "Name": "ResultType", "Docs": "", "Typewords": ["ResultType"] }, { "Name": "SendingMTAIP", "Docs": "", "Typewords": ["string"] }, { "Name": "ReceivingMXHostname", "Docs": "", "Typewords": ["string"] }, { "Name": "ReceivingMXHelo", "Docs": "", "Typewords": ["string"] }, { "Name": "ReceivingIP", "Docs": "", "Typewords": ["string"] }, { "Name": "FailedSessionCount", "Docs": "", "Typewords": ["int64"] }, { "Name": "AdditionalInformation", "Docs": "", "Typewords": ["string"] }, { "Name": "FailureReasonCode", "Docs": "", "Typewords": ["string"] }] }, + "FailureDetails": { "Name": "FailureDetails", "Docs": "", "Fields": [{ "Name": "ResultType", "Docs": "", "Typewords": ["string"] }, { "Name": "SendingMTAIP", "Docs": "", "Typewords": ["string"] }, { "Name": "ReceivingMXHostname", "Docs": "", "Typewords": ["string"] }, { "Name": "ReceivingMXHelo", "Docs": "", "Typewords": ["string"] }, { "Name": "ReceivingIP", "Docs": "", "Typewords": ["string"] }, { "Name": "FailedSessionCount", "Docs": "", "Typewords": ["int64"] }, { "Name": "AdditionalInformation", "Docs": "", "Typewords": ["string"] }, { "Name": "FailureReasonCode", "Docs": "", "Typewords": ["string"] }] }, "TLSRPTSummary": { "Name": "TLSRPTSummary", "Docs": "", "Fields": [{ "Name": "PolicyDomain", "Docs": "", "Typewords": ["Domain"] }, { "Name": "Success", "Docs": "", "Typewords": ["int64"] }, { "Name": "Failure", "Docs": "", "Typewords": ["int64"] }, { "Name": "ResultTypeCounts", "Docs": "", "Typewords": ["{}", "int64"] }] }, "DomainFeedback": { "Name": "DomainFeedback", "Docs": "", "Fields": [{ "Name": "ID", "Docs": "", "Typewords": ["int64"] }, { "Name": "Domain", "Docs": "", "Typewords": ["string"] }, { "Name": "FromDomain", "Docs": "", "Typewords": ["string"] }, { "Name": "Version", "Docs": "", "Typewords": ["string"] }, { "Name": "ReportMetadata", "Docs": "", "Typewords": ["ReportMetadata"] }, { "Name": "PolicyPublished", "Docs": "", "Typewords": ["PolicyPublished"] }, { "Name": "Records", "Docs": "", "Typewords": ["[]", "ReportRecord"] }] }, "ReportMetadata": { "Name": "ReportMetadata", "Docs": "", "Fields": [{ "Name": "OrgName", "Docs": "", "Typewords": ["string"] }, { "Name": "Email", "Docs": "", "Typewords": ["string"] }, { "Name": "ExtraContactInfo", "Docs": "", "Typewords": ["string"] }, { "Name": "ReportID", "Docs": "", "Typewords": ["string"] }, { "Name": "DateRange", "Docs": "", "Typewords": ["DateRange"] }, { "Name": "Errors", "Docs": "", "Typewords": ["[]", "string"] }] }, "DateRange": { "Name": "DateRange", "Docs": "", "Fields": [{ "Name": "Begin", "Docs": "", "Typewords": ["int64"] }, { "Name": "End", "Docs": "", "Typewords": ["int64"] }] }, - "PolicyPublished": { "Name": "PolicyPublished", "Docs": "", "Fields": [{ "Name": "Domain", "Docs": "", "Typewords": ["string"] }, { "Name": "ADKIM", "Docs": "", "Typewords": ["Alignment"] }, { "Name": "ASPF", "Docs": "", "Typewords": ["Alignment"] }, { "Name": "Policy", "Docs": "", "Typewords": ["Disposition"] }, { "Name": "SubdomainPolicy", "Docs": "", "Typewords": ["Disposition"] }, { "Name": "Percentage", "Docs": "", "Typewords": ["int32"] }, { "Name": "ReportingOptions", "Docs": "", "Typewords": ["string"] }] }, + "PolicyPublished": { "Name": "PolicyPublished", "Docs": "", "Fields": [{ "Name": "Domain", "Docs": "", "Typewords": ["string"] }, { "Name": "ADKIM", "Docs": "", "Typewords": ["string"] }, { "Name": "ASPF", "Docs": "", "Typewords": ["string"] }, { "Name": "Policy", "Docs": "", "Typewords": ["string"] }, { "Name": "SubdomainPolicy", "Docs": "", "Typewords": ["string"] }, { "Name": "Percentage", "Docs": "", "Typewords": ["int32"] }, { "Name": "ReportingOptions", "Docs": "", "Typewords": ["string"] }] }, "ReportRecord": { "Name": "ReportRecord", "Docs": "", "Fields": [{ "Name": "Row", "Docs": "", "Typewords": ["Row"] }, { "Name": "Identifiers", "Docs": "", "Typewords": ["Identifiers"] }, { "Name": "AuthResults", "Docs": "", "Typewords": ["AuthResults"] }] }, "Row": { "Name": "Row", "Docs": "", "Fields": [{ "Name": "SourceIP", "Docs": "", "Typewords": ["string"] }, { "Name": "Count", "Docs": "", "Typewords": ["int32"] }, { "Name": "PolicyEvaluated", "Docs": "", "Typewords": ["PolicyEvaluated"] }] }, - "PolicyEvaluated": { "Name": "PolicyEvaluated", "Docs": "", "Fields": [{ "Name": "Disposition", "Docs": "", "Typewords": ["Disposition"] }, { "Name": "DKIM", "Docs": "", "Typewords": ["DMARCResult"] }, { "Name": "SPF", "Docs": "", "Typewords": ["DMARCResult"] }, { "Name": "Reasons", "Docs": "", "Typewords": ["[]", "PolicyOverrideReason"] }] }, - "PolicyOverrideReason": { "Name": "PolicyOverrideReason", "Docs": "", "Fields": [{ "Name": "Type", "Docs": "", "Typewords": ["PolicyOverride"] }, { "Name": "Comment", "Docs": "", "Typewords": ["string"] }] }, + "PolicyEvaluated": { "Name": "PolicyEvaluated", "Docs": "", "Fields": [{ "Name": "Disposition", "Docs": "", "Typewords": ["string"] }, { "Name": "DKIM", "Docs": "", "Typewords": ["string"] }, { "Name": "SPF", "Docs": "", "Typewords": ["string"] }, { "Name": "Reasons", "Docs": "", "Typewords": ["[]", "PolicyOverrideReason"] }] }, + "PolicyOverrideReason": { "Name": "PolicyOverrideReason", "Docs": "", "Fields": [{ "Name": "Type", "Docs": "", "Typewords": ["string"] }, { "Name": "Comment", "Docs": "", "Typewords": ["string"] }] }, "Identifiers": { "Name": "Identifiers", "Docs": "", "Fields": [{ "Name": "EnvelopeTo", "Docs": "", "Typewords": ["string"] }, { "Name": "EnvelopeFrom", "Docs": "", "Typewords": ["string"] }, { "Name": "HeaderFrom", "Docs": "", "Typewords": ["string"] }] }, "AuthResults": { "Name": "AuthResults", "Docs": "", "Fields": [{ "Name": "DKIM", "Docs": "", "Typewords": ["[]", "DKIMAuthResult"] }, { "Name": "SPF", "Docs": "", "Typewords": ["[]", "SPFAuthResult"] }] }, - "DKIMAuthResult": { "Name": "DKIMAuthResult", "Docs": "", "Fields": [{ "Name": "Domain", "Docs": "", "Typewords": ["string"] }, { "Name": "Selector", "Docs": "", "Typewords": ["string"] }, { "Name": "Result", "Docs": "", "Typewords": ["DKIMResult"] }, { "Name": "HumanResult", "Docs": "", "Typewords": ["string"] }] }, - "SPFAuthResult": { "Name": "SPFAuthResult", "Docs": "", "Fields": [{ "Name": "Domain", "Docs": "", "Typewords": ["string"] }, { "Name": "Scope", "Docs": "", "Typewords": ["SPFDomainScope"] }, { "Name": "Result", "Docs": "", "Typewords": ["SPFResult"] }] }, + "DKIMAuthResult": { "Name": "DKIMAuthResult", "Docs": "", "Fields": [{ "Name": "Domain", "Docs": "", "Typewords": ["string"] }, { "Name": "Selector", "Docs": "", "Typewords": ["string"] }, { "Name": "Result", "Docs": "", "Typewords": ["string"] }, { "Name": "HumanResult", "Docs": "", "Typewords": ["string"] }] }, + "SPFAuthResult": { "Name": "SPFAuthResult", "Docs": "", "Fields": [{ "Name": "Domain", "Docs": "", "Typewords": ["string"] }, { "Name": "Scope", "Docs": "", "Typewords": ["string"] }, { "Name": "Result", "Docs": "", "Typewords": ["string"] }] }, "DMARCSummary": { "Name": "DMARCSummary", "Docs": "", "Fields": [{ "Name": "Domain", "Docs": "", "Typewords": ["string"] }, { "Name": "Total", "Docs": "", "Typewords": ["int32"] }, { "Name": "DispositionNone", "Docs": "", "Typewords": ["int32"] }, { "Name": "DispositionQuarantine", "Docs": "", "Typewords": ["int32"] }, { "Name": "DispositionReject", "Docs": "", "Typewords": ["int32"] }, { "Name": "DKIMFail", "Docs": "", "Typewords": ["int32"] }, { "Name": "SPFFail", "Docs": "", "Typewords": ["int32"] }, { "Name": "PolicyOverrides", "Docs": "", "Typewords": ["{}", "int32"] }] }, "Reverse": { "Name": "Reverse", "Docs": "", "Fields": [{ "Name": "Hostnames", "Docs": "", "Typewords": ["[]", "string"] }] }, "ClientConfigs": { "Name": "ClientConfigs", "Docs": "", "Fields": [{ "Name": "Entries", "Docs": "", "Typewords": ["[]", "ClientConfigsEntry"] }] }, @@ -444,7 +357,7 @@ var api; "TransportSocks": { "Name": "TransportSocks", "Docs": "", "Fields": [{ "Name": "Address", "Docs": "", "Typewords": ["string"] }, { "Name": "RemoteIPs", "Docs": "", "Typewords": ["[]", "string"] }, { "Name": "RemoteHostname", "Docs": "", "Typewords": ["string"] }] }, "TransportDirect": { "Name": "TransportDirect", "Docs": "", "Fields": [{ "Name": "DisableIPv4", "Docs": "", "Typewords": ["bool"] }, { "Name": "DisableIPv6", "Docs": "", "Typewords": ["bool"] }] }, "EvaluationStat": { "Name": "EvaluationStat", "Docs": "", "Fields": [{ "Name": "Domain", "Docs": "", "Typewords": ["Domain"] }, { "Name": "Dispositions", "Docs": "", "Typewords": ["[]", "string"] }, { "Name": "Count", "Docs": "", "Typewords": ["int32"] }, { "Name": "SendReport", "Docs": "", "Typewords": ["bool"] }] }, - "Evaluation": { "Name": "Evaluation", "Docs": "", "Fields": [{ "Name": "ID", "Docs": "", "Typewords": ["int64"] }, { "Name": "PolicyDomain", "Docs": "", "Typewords": ["string"] }, { "Name": "Evaluated", "Docs": "", "Typewords": ["timestamp"] }, { "Name": "Optional", "Docs": "", "Typewords": ["bool"] }, { "Name": "IntervalHours", "Docs": "", "Typewords": ["int32"] }, { "Name": "Addresses", "Docs": "", "Typewords": ["[]", "string"] }, { "Name": "PolicyPublished", "Docs": "", "Typewords": ["PolicyPublished"] }, { "Name": "SourceIP", "Docs": "", "Typewords": ["string"] }, { "Name": "Disposition", "Docs": "", "Typewords": ["Disposition"] }, { "Name": "AlignedDKIMPass", "Docs": "", "Typewords": ["bool"] }, { "Name": "AlignedSPFPass", "Docs": "", "Typewords": ["bool"] }, { "Name": "OverrideReasons", "Docs": "", "Typewords": ["[]", "PolicyOverrideReason"] }, { "Name": "EnvelopeTo", "Docs": "", "Typewords": ["string"] }, { "Name": "EnvelopeFrom", "Docs": "", "Typewords": ["string"] }, { "Name": "HeaderFrom", "Docs": "", "Typewords": ["string"] }, { "Name": "DKIMResults", "Docs": "", "Typewords": ["[]", "DKIMAuthResult"] }, { "Name": "SPFResults", "Docs": "", "Typewords": ["[]", "SPFAuthResult"] }] }, + "Evaluation": { "Name": "Evaluation", "Docs": "", "Fields": [{ "Name": "ID", "Docs": "", "Typewords": ["int64"] }, { "Name": "PolicyDomain", "Docs": "", "Typewords": ["string"] }, { "Name": "Evaluated", "Docs": "", "Typewords": ["timestamp"] }, { "Name": "Optional", "Docs": "", "Typewords": ["bool"] }, { "Name": "IntervalHours", "Docs": "", "Typewords": ["int32"] }, { "Name": "Addresses", "Docs": "", "Typewords": ["[]", "string"] }, { "Name": "PolicyPublished", "Docs": "", "Typewords": ["PolicyPublished"] }, { "Name": "SourceIP", "Docs": "", "Typewords": ["string"] }, { "Name": "Disposition", "Docs": "", "Typewords": ["string"] }, { "Name": "AlignedDKIMPass", "Docs": "", "Typewords": ["bool"] }, { "Name": "AlignedSPFPass", "Docs": "", "Typewords": ["bool"] }, { "Name": "OverrideReasons", "Docs": "", "Typewords": ["[]", "PolicyOverrideReason"] }, { "Name": "EnvelopeTo", "Docs": "", "Typewords": ["string"] }, { "Name": "EnvelopeFrom", "Docs": "", "Typewords": ["string"] }, { "Name": "HeaderFrom", "Docs": "", "Typewords": ["string"] }, { "Name": "DKIMResults", "Docs": "", "Typewords": ["[]", "DKIMAuthResult"] }, { "Name": "SPFResults", "Docs": "", "Typewords": ["[]", "SPFAuthResult"] }] }, "SuppressAddress": { "Name": "SuppressAddress", "Docs": "", "Fields": [{ "Name": "ID", "Docs": "", "Typewords": ["int64"] }, { "Name": "Inserted", "Docs": "", "Typewords": ["timestamp"] }, { "Name": "ReportingAddress", "Docs": "", "Typewords": ["string"] }, { "Name": "Until", "Docs": "", "Typewords": ["timestamp"] }, { "Name": "Comment", "Docs": "", "Typewords": ["string"] }] }, "TLSResult": { "Name": "TLSResult", "Docs": "", "Fields": [{ "Name": "ID", "Docs": "", "Typewords": ["int64"] }, { "Name": "PolicyDomain", "Docs": "", "Typewords": ["string"] }, { "Name": "DayUTC", "Docs": "", "Typewords": ["string"] }, { "Name": "RecipientDomain", "Docs": "", "Typewords": ["string"] }, { "Name": "Created", "Docs": "", "Typewords": ["timestamp"] }, { "Name": "Updated", "Docs": "", "Typewords": ["timestamp"] }, { "Name": "IsHost", "Docs": "", "Typewords": ["bool"] }, { "Name": "SendReport", "Docs": "", "Typewords": ["bool"] }, { "Name": "SentToRecipientDomain", "Docs": "", "Typewords": ["bool"] }, { "Name": "RecipientDomainReportingAddresses", "Docs": "", "Typewords": ["[]", "string"] }, { "Name": "SentToPolicyDomain", "Docs": "", "Typewords": ["bool"] }, { "Name": "Results", "Docs": "", "Typewords": ["[]", "Result"] }] }, "TLSRPTSuppressAddress": { "Name": "TLSRPTSuppressAddress", "Docs": "", "Fields": [{ "Name": "ID", "Docs": "", "Typewords": ["int64"] }, { "Name": "Inserted", "Docs": "", "Typewords": ["timestamp"] }, { "Name": "ReportingAddress", "Docs": "", "Typewords": ["string"] }, { "Name": "Until", "Docs": "", "Typewords": ["timestamp"] }, { "Name": "Comment", "Docs": "", "Typewords": ["string"] }] }, @@ -455,15 +368,6 @@ var api; "RUA": { "Name": "RUA", "Docs": "", "Values": null }, "Mode": { "Name": "Mode", "Docs": "", "Values": [{ "Name": "ModeEnforce", "Value": "enforce", "Docs": "" }, { "Name": "ModeTesting", "Value": "testing", "Docs": "" }, { "Name": "ModeNone", "Value": "none", "Docs": "" }] }, "Localpart": { "Name": "Localpart", "Docs": "", "Values": null }, - "PolicyType": { "Name": "PolicyType", "Docs": "", "Values": [{ "Name": "TLSA", "Value": "tlsa", "Docs": "" }, { "Name": "STS", "Value": "sts", "Docs": "" }, { "Name": "NoPolicyFound", "Value": "no-policy-found", "Docs": "" }] }, - "ResultType": { "Name": "ResultType", "Docs": "", "Values": [{ "Name": "ResultSTARTTLSNotSupported", "Value": "starttls-not-supported", "Docs": "" }, { "Name": "ResultCertificateHostMismatch", "Value": "certificate-host-mismatch", "Docs": "" }, { "Name": "ResultCertificateExpired", "Value": "certificate-expired", "Docs": "" }, { "Name": "ResultTLSAInvalid", "Value": "tlsa-invalid", "Docs": "" }, { "Name": "ResultDNSSECInvalid", "Value": "dnssec-invalid", "Docs": "" }, { "Name": "ResultDANERequired", "Value": "dane-required", "Docs": "" }, { "Name": "ResultCertificateNotTrusted", "Value": "certificate-not-trusted", "Docs": "" }, { "Name": "ResultSTSPolicyInvalid", "Value": "sts-policy-invalid", "Docs": "" }, { "Name": "ResultSTSWebPKIInvalid", "Value": "sts-webpki-invalid", "Docs": "" }, { "Name": "ResultValidationFailure", "Value": "validation-failure", "Docs": "" }, { "Name": "ResultSTSPolicyFetch", "Value": "sts-policy-fetch-error", "Docs": "" }] }, - "Alignment": { "Name": "Alignment", "Docs": "", "Values": [{ "Name": "AlignmentAbsent", "Value": "", "Docs": "" }, { "Name": "AlignmentRelaxed", "Value": "r", "Docs": "" }, { "Name": "AlignmentStrict", "Value": "s", "Docs": "" }] }, - "Disposition": { "Name": "Disposition", "Docs": "", "Values": [{ "Name": "DispositionAbsent", "Value": "", "Docs": "" }, { "Name": "DispositionNone", "Value": "none", "Docs": "" }, { "Name": "DispositionQuarantine", "Value": "quarantine", "Docs": "" }, { "Name": "DispositionReject", "Value": "reject", "Docs": "" }] }, - "DMARCResult": { "Name": "DMARCResult", "Docs": "", "Values": [{ "Name": "DMARCAbsent", "Value": "", "Docs": "" }, { "Name": "DMARCPass", "Value": "pass", "Docs": "" }, { "Name": "DMARCFail", "Value": "fail", "Docs": "" }] }, - "PolicyOverride": { "Name": "PolicyOverride", "Docs": "", "Values": [{ "Name": "PolicyOverrideAbsent", "Value": "", "Docs": "" }, { "Name": "PolicyOverrideForwarded", "Value": "forwarded", "Docs": "" }, { "Name": "PolicyOverrideSampledOut", "Value": "sampled_out", "Docs": "" }, { "Name": "PolicyOverrideTrustedForwarder", "Value": "trusted_forwarder", "Docs": "" }, { "Name": "PolicyOverrideMailingList", "Value": "mailing_list", "Docs": "" }, { "Name": "PolicyOverrideLocalPolicy", "Value": "local_policy", "Docs": "" }, { "Name": "PolicyOverrideOther", "Value": "other", "Docs": "" }] }, - "DKIMResult": { "Name": "DKIMResult", "Docs": "", "Values": [{ "Name": "DKIMAbsent", "Value": "", "Docs": "" }, { "Name": "DKIMNone", "Value": "none", "Docs": "" }, { "Name": "DKIMPass", "Value": "pass", "Docs": "" }, { "Name": "DKIMFail", "Value": "fail", "Docs": "" }, { "Name": "DKIMPolicy", "Value": "policy", "Docs": "" }, { "Name": "DKIMNeutral", "Value": "neutral", "Docs": "" }, { "Name": "DKIMTemperror", "Value": "temperror", "Docs": "" }, { "Name": "DKIMPermerror", "Value": "permerror", "Docs": "" }] }, - "SPFDomainScope": { "Name": "SPFDomainScope", "Docs": "", "Values": [{ "Name": "SPFDomainScopeAbsent", "Value": "", "Docs": "" }, { "Name": "SPFDomainScopeHelo", "Value": "helo", "Docs": "" }, { "Name": "SPFDomainScopeMailFrom", "Value": "mfrom", "Docs": "" }] }, - "SPFResult": { "Name": "SPFResult", "Docs": "", "Values": [{ "Name": "SPFAbsent", "Value": "", "Docs": "" }, { "Name": "SPFNone", "Value": "none", "Docs": "" }, { "Name": "SPFNeutral", "Value": "neutral", "Docs": "" }, { "Name": "SPFPass", "Value": "pass", "Docs": "" }, { "Name": "SPFFail", "Value": "fail", "Docs": "" }, { "Name": "SPFSoftfail", "Value": "softfail", "Docs": "" }, { "Name": "SPFTemperror", "Value": "temperror", "Docs": "" }, { "Name": "SPFPermerror", "Value": "permerror", "Docs": "" }] }, "IP": { "Name": "IP", "Docs": "", "Values": [] }, }; api.parser = { @@ -581,15 +485,6 @@ var api; RUA: (v) => api.parse("RUA", v), Mode: (v) => api.parse("Mode", v), Localpart: (v) => api.parse("Localpart", v), - PolicyType: (v) => api.parse("PolicyType", v), - ResultType: (v) => api.parse("ResultType", v), - Alignment: (v) => api.parse("Alignment", v), - Disposition: (v) => api.parse("Disposition", v), - DMARCResult: (v) => api.parse("DMARCResult", v), - PolicyOverride: (v) => api.parse("PolicyOverride", v), - DKIMResult: (v) => api.parse("DKIMResult", v), - SPFDomainScope: (v) => api.parse("SPFDomainScope", v), - SPFResult: (v) => api.parse("SPFResult", v), IP: (v) => api.parse("IP", v), }; // Admin exports web API functions for the admin web interface. All its methods are @@ -2911,10 +2806,10 @@ const domainDMARC = async (d) => { } const alignments = { '': '', 'r': 'relaxed', 's': 'strict' }; if (r.PolicyPublished.ADKIM !== '') { - policy.push('dkim ' + (alignments[r.PolicyPublished.ADKIM] || r.PolicyPublished.ADKIM)); + policy.push('dkim ' + (alignments[r.PolicyPublished.ADKIM] || ('invalid dkim alignment: ' + (r.PolicyPublished.ADKIM || '(missing)')))); } if (r.PolicyPublished.ASPF !== '') { - policy.push('spf ' + (alignments[r.PolicyPublished.ASPF] || r.PolicyPublished.ASPF)); + policy.push('spf ' + (alignments[r.PolicyPublished.ASPF] || ('invalid spf alignment: ' + (r.PolicyPublished.ASPF || '(missing)')))); } if (r.PolicyPublished.Policy !== '') { policy.push('policy ' + r.PolicyPublished.Policy); @@ -2968,7 +2863,7 @@ const domainDMARC = async (d) => { ], rows.length > 0 ? [] : [ dom.td(recordRowspan, valignTop, sourceIP(row.SourceIP)), dom.td(recordRowspan, valignTop, '' + row.Count), - dom.td(recordRowspan, valignTop, dom.span(pol.Disposition === 'none' ? 'none' : box(red, pol.Disposition), attr.title(pol.Disposition + ': ' + dmarcStatuses[pol.Disposition])), (pol.Reasons || []).map(reason => [dom.br(), dom.span(reason.Type + (reason.Comment ? ' (' + reason.Comment + ')' : ''), attr.title('Policy was overridden by remote mail server for this reasons.'))])), + dom.td(recordRowspan, valignTop, dom.span(pol.Disposition === 'none' ? 'none' : box(red, pol.Disposition), attr.title(pol.Disposition + ': ' + (dmarcStatuses[pol.Disposition] || '(invalid disposition)'))), (pol.Reasons || []).map(reason => [dom.br(), dom.span(reason.Type + (reason.Comment ? ' (' + reason.Comment + ')' : ''), attr.title('Policy was overridden by remote mail server for this reasons.'))])), dom.td(recordRowspan, valignTop, pol.DKIM === 'pass' ? 'pass' : box(yellow, dom.span(pol.DKIM, attr.title('No or no valid DKIM-signature is present that is "aligned" with the domain name.')))), dom.td(recordRowspan, valignTop, pol.SPF === 'pass' ? 'pass' : box(yellow, dom.span(pol.SPF, attr.title('No SPF policy was found, or IP is not allowed by policy, or domain name is not "aligned" with the domain name.')))), dom.td(recordRowspan, valignTop, ids.EnvelopeTo), diff --git a/webadmin/admin.ts b/webadmin/admin.ts index 58f9492..8e62c26 100644 --- a/webadmin/admin.ts +++ b/webadmin/admin.ts @@ -2444,12 +2444,12 @@ const domainDMARC = async (d: string) => { if (r.PolicyPublished.Domain !== d) { policy.push(r.PolicyPublished.Domain) } - const alignments = {'': '', 'r': 'relaxed', 's': 'strict'} + const alignments: {[k: string]: string} = {'': '', 'r': 'relaxed', 's': 'strict'} if (r.PolicyPublished.ADKIM as string !== '') { - policy.push('dkim '+(alignments[r.PolicyPublished.ADKIM] || r.PolicyPublished.ADKIM)) + policy.push('dkim '+(alignments[r.PolicyPublished.ADKIM] || ('invalid dkim alignment: '+(r.PolicyPublished.ADKIM || '(missing)')))) } if (r.PolicyPublished.ASPF as string !== '') { - policy.push('spf '+(alignments[r.PolicyPublished.ASPF] || r.PolicyPublished.ASPF)) + policy.push('spf '+(alignments[r.PolicyPublished.ASPF] || ('invalid spf alignment: '+(r.PolicyPublished.ASPF || '(missing)')))) } if (r.PolicyPublished.Policy as string !== '') { policy.push('policy '+r.PolicyPublished.Policy) @@ -2490,7 +2490,7 @@ const domainDMARC = async (d: string) => { const recordRowspan = attr.rowspan('' + (dkims.length+spfs.length)) const valignTop = style({verticalAlign: 'top'}) - const dmarcStatuses = { + const dmarcStatuses: {[k: string]: string} = { '': '(missing)', none: 'DMARC checks or were not applied. This does not mean these messages are definitely not spam though, and they may have been rejected based on other checks, such as reputation or content-based filters.', quarantine: 'DMARC policy is to mark message as spam.', @@ -2509,7 +2509,7 @@ const domainDMARC = async (d: string) => { dom.td(recordRowspan, valignTop, sourceIP(row.SourceIP)), dom.td(recordRowspan, valignTop, '' + row.Count), dom.td(recordRowspan, valignTop, - dom.span(pol.Disposition === 'none' ? 'none' : box(red, pol.Disposition), attr.title(pol.Disposition + ': ' + dmarcStatuses[pol.Disposition])), + dom.span(pol.Disposition === 'none' ? 'none' : box(red, pol.Disposition), attr.title(pol.Disposition + ': ' + (dmarcStatuses[pol.Disposition] || '(invalid disposition)'))), (pol.Reasons || []).map(reason => [dom.br(), dom.span(reason.Type + (reason.Comment ? ' (' + reason.Comment + ')' : ''), attr.title('Policy was overridden by remote mail server for this reasons.'))]), ), dom.td(recordRowspan, valignTop, pol.DKIM === 'pass' ? 'pass' : box(yellow, dom.span(pol.DKIM, attr.title('No or no valid DKIM-signature is present that is "aligned" with the domain name.')))), @@ -2523,7 +2523,7 @@ const domainDMARC = async (d: string) => { rows.push(tr) } for (const dkim of dkims) { - const statuses = { + const statuses: {[k: string]: string} = { '': '(missing)', none: 'Message was not signed', pass: 'Message was signed and signature was verified.', @@ -2543,7 +2543,7 @@ const domainDMARC = async (d: string) => { ) } for (const spf of spfs) { - const statuses = { + const statuses: {[k: string]: string} = { '': '(missing)', none: 'No SPF policy found.', neutral: 'Policy states nothing about IP, typically due to "?" qualifier in SPF record.', diff --git a/webadmin/api.json b/webadmin/api.json index de95e35..a848d85 100644 --- a/webadmin/api.json +++ b/webadmin/api.json @@ -4494,7 +4494,7 @@ "Name": "Type", "Docs": "", "Typewords": [ - "PolicyType" + "string" ] }, { @@ -4550,7 +4550,7 @@ "Name": "ResultType", "Docs": "", "Typewords": [ - "ResultType" + "string" ] }, { @@ -4779,28 +4779,28 @@ "Name": "ADKIM", "Docs": "", "Typewords": [ - "Alignment" + "string" ] }, { "Name": "ASPF", "Docs": "", "Typewords": [ - "Alignment" + "string" ] }, { "Name": "Policy", "Docs": "", "Typewords": [ - "Disposition" + "string" ] }, { "Name": "SubdomainPolicy", "Docs": "", "Typewords": [ - "Disposition" + "string" ] }, { @@ -4881,21 +4881,21 @@ "Name": "Disposition", "Docs": "", "Typewords": [ - "Disposition" + "string" ] }, { "Name": "DKIM", "Docs": "", "Typewords": [ - "DMARCResult" + "string" ] }, { "Name": "SPF", "Docs": "", "Typewords": [ - "DMARCResult" + "string" ] }, { @@ -4916,7 +4916,7 @@ "Name": "Type", "Docs": "", "Typewords": [ - "PolicyOverride" + "string" ] }, { @@ -4999,7 +4999,7 @@ "Name": "Result", "Docs": "", "Typewords": [ - "DKIMResult" + "string" ] }, { @@ -5026,14 +5026,14 @@ "Name": "Scope", "Docs": "", "Typewords": [ - "SPFDomainScope" + "string" ] }, { "Name": "Result", "Docs": "", "Typewords": [ - "SPFResult" + "string" ] } ] @@ -6912,7 +6912,7 @@ "Name": "Disposition", "Docs": "", "Typewords": [ - "Disposition" + "string" ] }, { @@ -7293,310 +7293,6 @@ "Docs": "Localpart is a decoded local part of an email address, before the \"@\".\nFor quoted strings, values do not hold the double quote or escaping backslashes.\nAn empty string can be a valid localpart.\nLocalparts are in Unicode NFC.", "Values": null }, - { - "Name": "PolicyType", - "Docs": "PolicyType indicates the policy success/failure results are for.", - "Values": [ - { - "Name": "TLSA", - "Value": "tlsa", - "Docs": "For DANE, against a mail host (not recipient domain)." - }, - { - "Name": "STS", - "Value": "sts", - "Docs": "For MTA-STS, against a recipient domain (not a mail host)." - }, - { - "Name": "NoPolicyFound", - "Value": "no-policy-found", - "Docs": "Recipient domain did not have MTA-STS policy, or mail host (TSLA base domain)\ndid not have DANE TLSA records." - } - ] - }, - { - "Name": "ResultType", - "Docs": "ResultType represents a TLS error.", - "Values": [ - { - "Name": "ResultSTARTTLSNotSupported", - "Value": "starttls-not-supported", - "Docs": "" - }, - { - "Name": "ResultCertificateHostMismatch", - "Value": "certificate-host-mismatch", - "Docs": "" - }, - { - "Name": "ResultCertificateExpired", - "Value": "certificate-expired", - "Docs": "" - }, - { - "Name": "ResultTLSAInvalid", - "Value": "tlsa-invalid", - "Docs": "" - }, - { - "Name": "ResultDNSSECInvalid", - "Value": "dnssec-invalid", - "Docs": "" - }, - { - "Name": "ResultDANERequired", - "Value": "dane-required", - "Docs": "" - }, - { - "Name": "ResultCertificateNotTrusted", - "Value": "certificate-not-trusted", - "Docs": "" - }, - { - "Name": "ResultSTSPolicyInvalid", - "Value": "sts-policy-invalid", - "Docs": "" - }, - { - "Name": "ResultSTSWebPKIInvalid", - "Value": "sts-webpki-invalid", - "Docs": "" - }, - { - "Name": "ResultValidationFailure", - "Value": "validation-failure", - "Docs": "Other error." - }, - { - "Name": "ResultSTSPolicyFetch", - "Value": "sts-policy-fetch-error", - "Docs": "" - } - ] - }, - { - "Name": "Alignment", - "Docs": "Alignment is the identifier alignment.", - "Values": [ - { - "Name": "AlignmentAbsent", - "Value": "", - "Docs": "" - }, - { - "Name": "AlignmentRelaxed", - "Value": "r", - "Docs": "Subdomains match the DMARC from-domain." - }, - { - "Name": "AlignmentStrict", - "Value": "s", - "Docs": "Only exact from-domain match." - } - ] - }, - { - "Name": "Disposition", - "Docs": "Disposition is the requested action for a DMARC fail as specified in the\nDMARC policy in DNS.", - "Values": [ - { - "Name": "DispositionAbsent", - "Value": "", - "Docs": "" - }, - { - "Name": "DispositionNone", - "Value": "none", - "Docs": "" - }, - { - "Name": "DispositionQuarantine", - "Value": "quarantine", - "Docs": "" - }, - { - "Name": "DispositionReject", - "Value": "reject", - "Docs": "" - } - ] - }, - { - "Name": "DMARCResult", - "Docs": "DMARCResult is the final validation and alignment verdict for SPF and DKIM.", - "Values": [ - { - "Name": "DMARCAbsent", - "Value": "", - "Docs": "" - }, - { - "Name": "DMARCPass", - "Value": "pass", - "Docs": "" - }, - { - "Name": "DMARCFail", - "Value": "fail", - "Docs": "" - } - ] - }, - { - "Name": "PolicyOverride", - "Docs": "PolicyOverride is a reason the requested DMARC policy from the DNS record\nwas not applied.", - "Values": [ - { - "Name": "PolicyOverrideAbsent", - "Value": "", - "Docs": "" - }, - { - "Name": "PolicyOverrideForwarded", - "Value": "forwarded", - "Docs": "" - }, - { - "Name": "PolicyOverrideSampledOut", - "Value": "sampled_out", - "Docs": "" - }, - { - "Name": "PolicyOverrideTrustedForwarder", - "Value": "trusted_forwarder", - "Docs": "" - }, - { - "Name": "PolicyOverrideMailingList", - "Value": "mailing_list", - "Docs": "" - }, - { - "Name": "PolicyOverrideLocalPolicy", - "Value": "local_policy", - "Docs": "" - }, - { - "Name": "PolicyOverrideOther", - "Value": "other", - "Docs": "" - } - ] - }, - { - "Name": "DKIMResult", - "Docs": "", - "Values": [ - { - "Name": "DKIMAbsent", - "Value": "", - "Docs": "" - }, - { - "Name": "DKIMNone", - "Value": "none", - "Docs": "" - }, - { - "Name": "DKIMPass", - "Value": "pass", - "Docs": "" - }, - { - "Name": "DKIMFail", - "Value": "fail", - "Docs": "" - }, - { - "Name": "DKIMPolicy", - "Value": "policy", - "Docs": "" - }, - { - "Name": "DKIMNeutral", - "Value": "neutral", - "Docs": "" - }, - { - "Name": "DKIMTemperror", - "Value": "temperror", - "Docs": "" - }, - { - "Name": "DKIMPermerror", - "Value": "permerror", - "Docs": "" - } - ] - }, - { - "Name": "SPFDomainScope", - "Docs": "", - "Values": [ - { - "Name": "SPFDomainScopeAbsent", - "Value": "", - "Docs": "" - }, - { - "Name": "SPFDomainScopeHelo", - "Value": "helo", - "Docs": "SMTP EHLO" - }, - { - "Name": "SPFDomainScopeMailFrom", - "Value": "mfrom", - "Docs": "SMTP \"MAIL FROM\"." - } - ] - }, - { - "Name": "SPFResult", - "Docs": "", - "Values": [ - { - "Name": "SPFAbsent", - "Value": "", - "Docs": "" - }, - { - "Name": "SPFNone", - "Value": "none", - "Docs": "" - }, - { - "Name": "SPFNeutral", - "Value": "neutral", - "Docs": "" - }, - { - "Name": "SPFPass", - "Value": "pass", - "Docs": "" - }, - { - "Name": "SPFFail", - "Value": "fail", - "Docs": "" - }, - { - "Name": "SPFSoftfail", - "Value": "softfail", - "Docs": "" - }, - { - "Name": "SPFTemperror", - "Value": "temperror", - "Docs": "" - }, - { - "Name": "SPFPermerror", - "Value": "permerror", - "Docs": "" - } - ] - }, { "Name": "IP", "Docs": "An IP is a single IP address, a slice of bytes.\nFunctions in this package accept either 4-byte (IPv4)\nor 16-byte (IPv6) slices as input.\n\nNote that in this documentation, referring to an\nIP address as an IPv4 address or an IPv6 address\nis a semantic property of the address, not just the\nlength of the byte slice: a 16-byte slice can still\nbe an IPv4 address.", diff --git a/webadmin/api.ts b/webadmin/api.ts index 2113bda..d200f43 100644 --- a/webadmin/api.ts +++ b/webadmin/api.ts @@ -490,7 +490,7 @@ export interface Result { } export interface ResultPolicy { - Type: PolicyType + Type: string String?: string[] | null Domain: string // ASCII/A-labels, ../rfc/8460:704 MXHost?: string[] | null @@ -502,7 +502,7 @@ export interface Summary { } export interface FailureDetails { - ResultType: ResultType + ResultType: string SendingMTAIP: string ReceivingMXHostname: string ReceivingMXHelo: string @@ -549,10 +549,10 @@ export interface DateRange { // PolicyPublished is the policy as found in DNS for the domain. export interface PolicyPublished { Domain: string // Domain is where DMARC record was found, not necessarily message From. Reports we generate use unicode names, incoming reports may have either ASCII-only or Unicode domains. - ADKIM: Alignment - ASPF: Alignment - Policy: Disposition - SubdomainPolicy: Disposition + ADKIM: string + ASPF: string + Policy: string + SubdomainPolicy: string Percentage: number ReportingOptions: string } @@ -570,14 +570,14 @@ export interface Row { } export interface PolicyEvaluated { - Disposition: Disposition - DKIM: DMARCResult - SPF: DMARCResult + Disposition: string + DKIM: string + SPF: string Reasons?: PolicyOverrideReason[] | null } export interface PolicyOverrideReason { - Type: PolicyOverride + Type: string Comment: string } @@ -595,14 +595,14 @@ export interface AuthResults { export interface DKIMAuthResult { Domain: string Selector: string - Result: DKIMResult + Result: string HumanResult: string } export interface SPFAuthResult { Domain: string - Scope: SPFDomainScope - Result: SPFResult + Scope: string + Result: string } // DMARCSummary presents DMARC aggregate reporting statistics for a single domain @@ -987,7 +987,7 @@ export interface Evaluation { Addresses?: string[] | null // "rua" in DMARC record, we only store evaluations for records with aggregate reporting addresses, so always non-empty. PolicyPublished: PolicyPublished // Policy used for evaluation. We don't store the "fo" field for failure reporting options, since we don't send failure reports for individual messages. SourceIP: string // For "row" in a report record. - Disposition: Disposition + Disposition: string AlignedDKIMPass: boolean AlignedSPFPass: boolean OverrideReasons?: PolicyOverrideReason[] | null @@ -1079,93 +1079,6 @@ export enum Mode { // Localparts are in Unicode NFC. export type Localpart = string -// PolicyType indicates the policy success/failure results are for. -export enum PolicyType { - TLSA = "tlsa", // For DANE, against a mail host (not recipient domain). - STS = "sts", // For MTA-STS, against a recipient domain (not a mail host). - // Recipient domain did not have MTA-STS policy, or mail host (TSLA base domain) - // did not have DANE TLSA records. - NoPolicyFound = "no-policy-found", -} - -// ResultType represents a TLS error. -export enum ResultType { - ResultSTARTTLSNotSupported = "starttls-not-supported", - ResultCertificateHostMismatch = "certificate-host-mismatch", - ResultCertificateExpired = "certificate-expired", - ResultTLSAInvalid = "tlsa-invalid", - ResultDNSSECInvalid = "dnssec-invalid", - ResultDANERequired = "dane-required", - ResultCertificateNotTrusted = "certificate-not-trusted", - ResultSTSPolicyInvalid = "sts-policy-invalid", - ResultSTSWebPKIInvalid = "sts-webpki-invalid", - ResultValidationFailure = "validation-failure", // Other error. - ResultSTSPolicyFetch = "sts-policy-fetch-error", -} - -// Alignment is the identifier alignment. -export enum Alignment { - AlignmentAbsent = "", - AlignmentRelaxed = "r", // Subdomains match the DMARC from-domain. - AlignmentStrict = "s", // Only exact from-domain match. -} - -// Disposition is the requested action for a DMARC fail as specified in the -// DMARC policy in DNS. -export enum Disposition { - DispositionAbsent = "", - DispositionNone = "none", - DispositionQuarantine = "quarantine", - DispositionReject = "reject", -} - -// DMARCResult is the final validation and alignment verdict for SPF and DKIM. -export enum DMARCResult { - DMARCAbsent = "", - DMARCPass = "pass", - DMARCFail = "fail", -} - -// PolicyOverride is a reason the requested DMARC policy from the DNS record -// was not applied. -export enum PolicyOverride { - PolicyOverrideAbsent = "", - PolicyOverrideForwarded = "forwarded", - PolicyOverrideSampledOut = "sampled_out", - PolicyOverrideTrustedForwarder = "trusted_forwarder", - PolicyOverrideMailingList = "mailing_list", - PolicyOverrideLocalPolicy = "local_policy", - PolicyOverrideOther = "other", -} - -export enum DKIMResult { - DKIMAbsent = "", - DKIMNone = "none", - DKIMPass = "pass", - DKIMFail = "fail", - DKIMPolicy = "policy", - DKIMNeutral = "neutral", - DKIMTemperror = "temperror", - DKIMPermerror = "permerror", -} - -export enum SPFDomainScope { - SPFDomainScopeAbsent = "", - SPFDomainScopeHelo = "helo", // SMTP EHLO - SPFDomainScopeMailFrom = "mfrom", // SMTP "MAIL FROM". -} - -export enum SPFResult { - SPFAbsent = "", - SPFNone = "none", - SPFNeutral = "neutral", - SPFPass = "pass", - SPFFail = "fail", - SPFSoftfail = "softfail", - SPFTemperror = "temperror", - SPFPermerror = "permerror", -} - // An IP is a single IP address, a slice of bytes. // Functions in this package accept either 4-byte (IPv4) // or 16-byte (IPv6) slices as input. @@ -1178,7 +1091,7 @@ export enum SPFResult { export type IP = string export const structTypes: {[typename: string]: boolean} = {"Account":true,"Address":true,"AddressAlias":true,"Alias":true,"AliasAddress":true,"AuthResults":true,"AutoconfCheckResult":true,"AutodiscoverCheckResult":true,"AutodiscoverSRV":true,"AutomaticJunkFlags":true,"Canonicalization":true,"CheckResult":true,"ClientConfigs":true,"ClientConfigsEntry":true,"ConfigDomain":true,"DANECheckResult":true,"DKIM":true,"DKIMAuthResult":true,"DKIMCheckResult":true,"DKIMRecord":true,"DMARC":true,"DMARCCheckResult":true,"DMARCRecord":true,"DMARCSummary":true,"DNSSECResult":true,"DateRange":true,"Destination":true,"Directive":true,"Domain":true,"DomainFeedback":true,"Dynamic":true,"Evaluation":true,"EvaluationStat":true,"Extension":true,"FailureDetails":true,"Filter":true,"HoldRule":true,"Hook":true,"HookFilter":true,"HookResult":true,"HookRetired":true,"HookRetiredFilter":true,"HookRetiredSort":true,"HookSort":true,"IPDomain":true,"IPRevCheckResult":true,"Identifiers":true,"IncomingWebhook":true,"JunkFilter":true,"MTASTS":true,"MTASTSCheckResult":true,"MTASTSRecord":true,"MX":true,"MXCheckResult":true,"Modifier":true,"Msg":true,"MsgResult":true,"MsgRetired":true,"OutgoingWebhook":true,"Pair":true,"Policy":true,"PolicyEvaluated":true,"PolicyOverrideReason":true,"PolicyPublished":true,"PolicyRecord":true,"Record":true,"Report":true,"ReportMetadata":true,"ReportRecord":true,"Result":true,"ResultPolicy":true,"RetiredFilter":true,"RetiredSort":true,"Reverse":true,"Route":true,"Row":true,"Ruleset":true,"SMTPAuth":true,"SPFAuthResult":true,"SPFCheckResult":true,"SPFRecord":true,"SRV":true,"SRVConfCheckResult":true,"STSMX":true,"Selector":true,"Sort":true,"SubjectPass":true,"Summary":true,"SuppressAddress":true,"TLSCheckResult":true,"TLSRPT":true,"TLSRPTCheckResult":true,"TLSRPTDateRange":true,"TLSRPTRecord":true,"TLSRPTSummary":true,"TLSRPTSuppressAddress":true,"TLSReportRecord":true,"TLSResult":true,"Transport":true,"TransportDirect":true,"TransportSMTP":true,"TransportSocks":true,"URI":true,"WebForward":true,"WebHandler":true,"WebRedirect":true,"WebStatic":true,"WebserverConfig":true} -export const stringsTypes: {[typename: string]: boolean} = {"Align":true,"Alignment":true,"CSRFToken":true,"DKIMResult":true,"DMARCPolicy":true,"DMARCResult":true,"Disposition":true,"IP":true,"Localpart":true,"Mode":true,"PolicyOverride":true,"PolicyType":true,"RUA":true,"ResultType":true,"SPFDomainScope":true,"SPFResult":true} +export const stringsTypes: {[typename: string]: boolean} = {"Align":true,"CSRFToken":true,"DMARCPolicy":true,"IP":true,"Localpart":true,"Mode":true,"RUA":true} export const intsTypes: {[typename: string]: boolean} = {} export const types: TypenameMap = { "CheckResult": {"Name":"CheckResult","Docs":"","Fields":[{"Name":"Domain","Docs":"","Typewords":["string"]},{"Name":"DNSSEC","Docs":"","Typewords":["DNSSECResult"]},{"Name":"IPRev","Docs":"","Typewords":["IPRevCheckResult"]},{"Name":"MX","Docs":"","Typewords":["MXCheckResult"]},{"Name":"TLS","Docs":"","Typewords":["TLSCheckResult"]},{"Name":"DANE","Docs":"","Typewords":["DANECheckResult"]},{"Name":"SPF","Docs":"","Typewords":["SPFCheckResult"]},{"Name":"DKIM","Docs":"","Typewords":["DKIMCheckResult"]},{"Name":"DMARC","Docs":"","Typewords":["DMARCCheckResult"]},{"Name":"HostTLSRPT","Docs":"","Typewords":["TLSRPTCheckResult"]},{"Name":"DomainTLSRPT","Docs":"","Typewords":["TLSRPTCheckResult"]},{"Name":"MTASTS","Docs":"","Typewords":["MTASTSCheckResult"]},{"Name":"SRVConf","Docs":"","Typewords":["SRVConfCheckResult"]},{"Name":"Autoconf","Docs":"","Typewords":["AutoconfCheckResult"]},{"Name":"Autodiscover","Docs":"","Typewords":["AutodiscoverCheckResult"]}]}, @@ -1237,22 +1150,22 @@ export const types: TypenameMap = { "Report": {"Name":"Report","Docs":"","Fields":[{"Name":"OrganizationName","Docs":"","Typewords":["string"]},{"Name":"DateRange","Docs":"","Typewords":["TLSRPTDateRange"]},{"Name":"ContactInfo","Docs":"","Typewords":["string"]},{"Name":"ReportID","Docs":"","Typewords":["string"]},{"Name":"Policies","Docs":"","Typewords":["[]","Result"]}]}, "TLSRPTDateRange": {"Name":"TLSRPTDateRange","Docs":"","Fields":[{"Name":"Start","Docs":"","Typewords":["timestamp"]},{"Name":"End","Docs":"","Typewords":["timestamp"]}]}, "Result": {"Name":"Result","Docs":"","Fields":[{"Name":"Policy","Docs":"","Typewords":["ResultPolicy"]},{"Name":"Summary","Docs":"","Typewords":["Summary"]},{"Name":"FailureDetails","Docs":"","Typewords":["[]","FailureDetails"]}]}, - "ResultPolicy": {"Name":"ResultPolicy","Docs":"","Fields":[{"Name":"Type","Docs":"","Typewords":["PolicyType"]},{"Name":"String","Docs":"","Typewords":["[]","string"]},{"Name":"Domain","Docs":"","Typewords":["string"]},{"Name":"MXHost","Docs":"","Typewords":["[]","string"]}]}, + "ResultPolicy": {"Name":"ResultPolicy","Docs":"","Fields":[{"Name":"Type","Docs":"","Typewords":["string"]},{"Name":"String","Docs":"","Typewords":["[]","string"]},{"Name":"Domain","Docs":"","Typewords":["string"]},{"Name":"MXHost","Docs":"","Typewords":["[]","string"]}]}, "Summary": {"Name":"Summary","Docs":"","Fields":[{"Name":"TotalSuccessfulSessionCount","Docs":"","Typewords":["int64"]},{"Name":"TotalFailureSessionCount","Docs":"","Typewords":["int64"]}]}, - "FailureDetails": {"Name":"FailureDetails","Docs":"","Fields":[{"Name":"ResultType","Docs":"","Typewords":["ResultType"]},{"Name":"SendingMTAIP","Docs":"","Typewords":["string"]},{"Name":"ReceivingMXHostname","Docs":"","Typewords":["string"]},{"Name":"ReceivingMXHelo","Docs":"","Typewords":["string"]},{"Name":"ReceivingIP","Docs":"","Typewords":["string"]},{"Name":"FailedSessionCount","Docs":"","Typewords":["int64"]},{"Name":"AdditionalInformation","Docs":"","Typewords":["string"]},{"Name":"FailureReasonCode","Docs":"","Typewords":["string"]}]}, + "FailureDetails": {"Name":"FailureDetails","Docs":"","Fields":[{"Name":"ResultType","Docs":"","Typewords":["string"]},{"Name":"SendingMTAIP","Docs":"","Typewords":["string"]},{"Name":"ReceivingMXHostname","Docs":"","Typewords":["string"]},{"Name":"ReceivingMXHelo","Docs":"","Typewords":["string"]},{"Name":"ReceivingIP","Docs":"","Typewords":["string"]},{"Name":"FailedSessionCount","Docs":"","Typewords":["int64"]},{"Name":"AdditionalInformation","Docs":"","Typewords":["string"]},{"Name":"FailureReasonCode","Docs":"","Typewords":["string"]}]}, "TLSRPTSummary": {"Name":"TLSRPTSummary","Docs":"","Fields":[{"Name":"PolicyDomain","Docs":"","Typewords":["Domain"]},{"Name":"Success","Docs":"","Typewords":["int64"]},{"Name":"Failure","Docs":"","Typewords":["int64"]},{"Name":"ResultTypeCounts","Docs":"","Typewords":["{}","int64"]}]}, "DomainFeedback": {"Name":"DomainFeedback","Docs":"","Fields":[{"Name":"ID","Docs":"","Typewords":["int64"]},{"Name":"Domain","Docs":"","Typewords":["string"]},{"Name":"FromDomain","Docs":"","Typewords":["string"]},{"Name":"Version","Docs":"","Typewords":["string"]},{"Name":"ReportMetadata","Docs":"","Typewords":["ReportMetadata"]},{"Name":"PolicyPublished","Docs":"","Typewords":["PolicyPublished"]},{"Name":"Records","Docs":"","Typewords":["[]","ReportRecord"]}]}, "ReportMetadata": {"Name":"ReportMetadata","Docs":"","Fields":[{"Name":"OrgName","Docs":"","Typewords":["string"]},{"Name":"Email","Docs":"","Typewords":["string"]},{"Name":"ExtraContactInfo","Docs":"","Typewords":["string"]},{"Name":"ReportID","Docs":"","Typewords":["string"]},{"Name":"DateRange","Docs":"","Typewords":["DateRange"]},{"Name":"Errors","Docs":"","Typewords":["[]","string"]}]}, "DateRange": {"Name":"DateRange","Docs":"","Fields":[{"Name":"Begin","Docs":"","Typewords":["int64"]},{"Name":"End","Docs":"","Typewords":["int64"]}]}, - "PolicyPublished": {"Name":"PolicyPublished","Docs":"","Fields":[{"Name":"Domain","Docs":"","Typewords":["string"]},{"Name":"ADKIM","Docs":"","Typewords":["Alignment"]},{"Name":"ASPF","Docs":"","Typewords":["Alignment"]},{"Name":"Policy","Docs":"","Typewords":["Disposition"]},{"Name":"SubdomainPolicy","Docs":"","Typewords":["Disposition"]},{"Name":"Percentage","Docs":"","Typewords":["int32"]},{"Name":"ReportingOptions","Docs":"","Typewords":["string"]}]}, + "PolicyPublished": {"Name":"PolicyPublished","Docs":"","Fields":[{"Name":"Domain","Docs":"","Typewords":["string"]},{"Name":"ADKIM","Docs":"","Typewords":["string"]},{"Name":"ASPF","Docs":"","Typewords":["string"]},{"Name":"Policy","Docs":"","Typewords":["string"]},{"Name":"SubdomainPolicy","Docs":"","Typewords":["string"]},{"Name":"Percentage","Docs":"","Typewords":["int32"]},{"Name":"ReportingOptions","Docs":"","Typewords":["string"]}]}, "ReportRecord": {"Name":"ReportRecord","Docs":"","Fields":[{"Name":"Row","Docs":"","Typewords":["Row"]},{"Name":"Identifiers","Docs":"","Typewords":["Identifiers"]},{"Name":"AuthResults","Docs":"","Typewords":["AuthResults"]}]}, "Row": {"Name":"Row","Docs":"","Fields":[{"Name":"SourceIP","Docs":"","Typewords":["string"]},{"Name":"Count","Docs":"","Typewords":["int32"]},{"Name":"PolicyEvaluated","Docs":"","Typewords":["PolicyEvaluated"]}]}, - "PolicyEvaluated": {"Name":"PolicyEvaluated","Docs":"","Fields":[{"Name":"Disposition","Docs":"","Typewords":["Disposition"]},{"Name":"DKIM","Docs":"","Typewords":["DMARCResult"]},{"Name":"SPF","Docs":"","Typewords":["DMARCResult"]},{"Name":"Reasons","Docs":"","Typewords":["[]","PolicyOverrideReason"]}]}, - "PolicyOverrideReason": {"Name":"PolicyOverrideReason","Docs":"","Fields":[{"Name":"Type","Docs":"","Typewords":["PolicyOverride"]},{"Name":"Comment","Docs":"","Typewords":["string"]}]}, + "PolicyEvaluated": {"Name":"PolicyEvaluated","Docs":"","Fields":[{"Name":"Disposition","Docs":"","Typewords":["string"]},{"Name":"DKIM","Docs":"","Typewords":["string"]},{"Name":"SPF","Docs":"","Typewords":["string"]},{"Name":"Reasons","Docs":"","Typewords":["[]","PolicyOverrideReason"]}]}, + "PolicyOverrideReason": {"Name":"PolicyOverrideReason","Docs":"","Fields":[{"Name":"Type","Docs":"","Typewords":["string"]},{"Name":"Comment","Docs":"","Typewords":["string"]}]}, "Identifiers": {"Name":"Identifiers","Docs":"","Fields":[{"Name":"EnvelopeTo","Docs":"","Typewords":["string"]},{"Name":"EnvelopeFrom","Docs":"","Typewords":["string"]},{"Name":"HeaderFrom","Docs":"","Typewords":["string"]}]}, "AuthResults": {"Name":"AuthResults","Docs":"","Fields":[{"Name":"DKIM","Docs":"","Typewords":["[]","DKIMAuthResult"]},{"Name":"SPF","Docs":"","Typewords":["[]","SPFAuthResult"]}]}, - "DKIMAuthResult": {"Name":"DKIMAuthResult","Docs":"","Fields":[{"Name":"Domain","Docs":"","Typewords":["string"]},{"Name":"Selector","Docs":"","Typewords":["string"]},{"Name":"Result","Docs":"","Typewords":["DKIMResult"]},{"Name":"HumanResult","Docs":"","Typewords":["string"]}]}, - "SPFAuthResult": {"Name":"SPFAuthResult","Docs":"","Fields":[{"Name":"Domain","Docs":"","Typewords":["string"]},{"Name":"Scope","Docs":"","Typewords":["SPFDomainScope"]},{"Name":"Result","Docs":"","Typewords":["SPFResult"]}]}, + "DKIMAuthResult": {"Name":"DKIMAuthResult","Docs":"","Fields":[{"Name":"Domain","Docs":"","Typewords":["string"]},{"Name":"Selector","Docs":"","Typewords":["string"]},{"Name":"Result","Docs":"","Typewords":["string"]},{"Name":"HumanResult","Docs":"","Typewords":["string"]}]}, + "SPFAuthResult": {"Name":"SPFAuthResult","Docs":"","Fields":[{"Name":"Domain","Docs":"","Typewords":["string"]},{"Name":"Scope","Docs":"","Typewords":["string"]},{"Name":"Result","Docs":"","Typewords":["string"]}]}, "DMARCSummary": {"Name":"DMARCSummary","Docs":"","Fields":[{"Name":"Domain","Docs":"","Typewords":["string"]},{"Name":"Total","Docs":"","Typewords":["int32"]},{"Name":"DispositionNone","Docs":"","Typewords":["int32"]},{"Name":"DispositionQuarantine","Docs":"","Typewords":["int32"]},{"Name":"DispositionReject","Docs":"","Typewords":["int32"]},{"Name":"DKIMFail","Docs":"","Typewords":["int32"]},{"Name":"SPFFail","Docs":"","Typewords":["int32"]},{"Name":"PolicyOverrides","Docs":"","Typewords":["{}","int32"]}]}, "Reverse": {"Name":"Reverse","Docs":"","Fields":[{"Name":"Hostnames","Docs":"","Typewords":["[]","string"]}]}, "ClientConfigs": {"Name":"ClientConfigs","Docs":"","Fields":[{"Name":"Entries","Docs":"","Typewords":["[]","ClientConfigsEntry"]}]}, @@ -1284,7 +1197,7 @@ export const types: TypenameMap = { "TransportSocks": {"Name":"TransportSocks","Docs":"","Fields":[{"Name":"Address","Docs":"","Typewords":["string"]},{"Name":"RemoteIPs","Docs":"","Typewords":["[]","string"]},{"Name":"RemoteHostname","Docs":"","Typewords":["string"]}]}, "TransportDirect": {"Name":"TransportDirect","Docs":"","Fields":[{"Name":"DisableIPv4","Docs":"","Typewords":["bool"]},{"Name":"DisableIPv6","Docs":"","Typewords":["bool"]}]}, "EvaluationStat": {"Name":"EvaluationStat","Docs":"","Fields":[{"Name":"Domain","Docs":"","Typewords":["Domain"]},{"Name":"Dispositions","Docs":"","Typewords":["[]","string"]},{"Name":"Count","Docs":"","Typewords":["int32"]},{"Name":"SendReport","Docs":"","Typewords":["bool"]}]}, - "Evaluation": {"Name":"Evaluation","Docs":"","Fields":[{"Name":"ID","Docs":"","Typewords":["int64"]},{"Name":"PolicyDomain","Docs":"","Typewords":["string"]},{"Name":"Evaluated","Docs":"","Typewords":["timestamp"]},{"Name":"Optional","Docs":"","Typewords":["bool"]},{"Name":"IntervalHours","Docs":"","Typewords":["int32"]},{"Name":"Addresses","Docs":"","Typewords":["[]","string"]},{"Name":"PolicyPublished","Docs":"","Typewords":["PolicyPublished"]},{"Name":"SourceIP","Docs":"","Typewords":["string"]},{"Name":"Disposition","Docs":"","Typewords":["Disposition"]},{"Name":"AlignedDKIMPass","Docs":"","Typewords":["bool"]},{"Name":"AlignedSPFPass","Docs":"","Typewords":["bool"]},{"Name":"OverrideReasons","Docs":"","Typewords":["[]","PolicyOverrideReason"]},{"Name":"EnvelopeTo","Docs":"","Typewords":["string"]},{"Name":"EnvelopeFrom","Docs":"","Typewords":["string"]},{"Name":"HeaderFrom","Docs":"","Typewords":["string"]},{"Name":"DKIMResults","Docs":"","Typewords":["[]","DKIMAuthResult"]},{"Name":"SPFResults","Docs":"","Typewords":["[]","SPFAuthResult"]}]}, + "Evaluation": {"Name":"Evaluation","Docs":"","Fields":[{"Name":"ID","Docs":"","Typewords":["int64"]},{"Name":"PolicyDomain","Docs":"","Typewords":["string"]},{"Name":"Evaluated","Docs":"","Typewords":["timestamp"]},{"Name":"Optional","Docs":"","Typewords":["bool"]},{"Name":"IntervalHours","Docs":"","Typewords":["int32"]},{"Name":"Addresses","Docs":"","Typewords":["[]","string"]},{"Name":"PolicyPublished","Docs":"","Typewords":["PolicyPublished"]},{"Name":"SourceIP","Docs":"","Typewords":["string"]},{"Name":"Disposition","Docs":"","Typewords":["string"]},{"Name":"AlignedDKIMPass","Docs":"","Typewords":["bool"]},{"Name":"AlignedSPFPass","Docs":"","Typewords":["bool"]},{"Name":"OverrideReasons","Docs":"","Typewords":["[]","PolicyOverrideReason"]},{"Name":"EnvelopeTo","Docs":"","Typewords":["string"]},{"Name":"EnvelopeFrom","Docs":"","Typewords":["string"]},{"Name":"HeaderFrom","Docs":"","Typewords":["string"]},{"Name":"DKIMResults","Docs":"","Typewords":["[]","DKIMAuthResult"]},{"Name":"SPFResults","Docs":"","Typewords":["[]","SPFAuthResult"]}]}, "SuppressAddress": {"Name":"SuppressAddress","Docs":"","Fields":[{"Name":"ID","Docs":"","Typewords":["int64"]},{"Name":"Inserted","Docs":"","Typewords":["timestamp"]},{"Name":"ReportingAddress","Docs":"","Typewords":["string"]},{"Name":"Until","Docs":"","Typewords":["timestamp"]},{"Name":"Comment","Docs":"","Typewords":["string"]}]}, "TLSResult": {"Name":"TLSResult","Docs":"","Fields":[{"Name":"ID","Docs":"","Typewords":["int64"]},{"Name":"PolicyDomain","Docs":"","Typewords":["string"]},{"Name":"DayUTC","Docs":"","Typewords":["string"]},{"Name":"RecipientDomain","Docs":"","Typewords":["string"]},{"Name":"Created","Docs":"","Typewords":["timestamp"]},{"Name":"Updated","Docs":"","Typewords":["timestamp"]},{"Name":"IsHost","Docs":"","Typewords":["bool"]},{"Name":"SendReport","Docs":"","Typewords":["bool"]},{"Name":"SentToRecipientDomain","Docs":"","Typewords":["bool"]},{"Name":"RecipientDomainReportingAddresses","Docs":"","Typewords":["[]","string"]},{"Name":"SentToPolicyDomain","Docs":"","Typewords":["bool"]},{"Name":"Results","Docs":"","Typewords":["[]","Result"]}]}, "TLSRPTSuppressAddress": {"Name":"TLSRPTSuppressAddress","Docs":"","Fields":[{"Name":"ID","Docs":"","Typewords":["int64"]},{"Name":"Inserted","Docs":"","Typewords":["timestamp"]},{"Name":"ReportingAddress","Docs":"","Typewords":["string"]},{"Name":"Until","Docs":"","Typewords":["timestamp"]},{"Name":"Comment","Docs":"","Typewords":["string"]}]}, @@ -1295,15 +1208,6 @@ export const types: TypenameMap = { "RUA": {"Name":"RUA","Docs":"","Values":null}, "Mode": {"Name":"Mode","Docs":"","Values":[{"Name":"ModeEnforce","Value":"enforce","Docs":""},{"Name":"ModeTesting","Value":"testing","Docs":""},{"Name":"ModeNone","Value":"none","Docs":""}]}, "Localpart": {"Name":"Localpart","Docs":"","Values":null}, - "PolicyType": {"Name":"PolicyType","Docs":"","Values":[{"Name":"TLSA","Value":"tlsa","Docs":""},{"Name":"STS","Value":"sts","Docs":""},{"Name":"NoPolicyFound","Value":"no-policy-found","Docs":""}]}, - "ResultType": {"Name":"ResultType","Docs":"","Values":[{"Name":"ResultSTARTTLSNotSupported","Value":"starttls-not-supported","Docs":""},{"Name":"ResultCertificateHostMismatch","Value":"certificate-host-mismatch","Docs":""},{"Name":"ResultCertificateExpired","Value":"certificate-expired","Docs":""},{"Name":"ResultTLSAInvalid","Value":"tlsa-invalid","Docs":""},{"Name":"ResultDNSSECInvalid","Value":"dnssec-invalid","Docs":""},{"Name":"ResultDANERequired","Value":"dane-required","Docs":""},{"Name":"ResultCertificateNotTrusted","Value":"certificate-not-trusted","Docs":""},{"Name":"ResultSTSPolicyInvalid","Value":"sts-policy-invalid","Docs":""},{"Name":"ResultSTSWebPKIInvalid","Value":"sts-webpki-invalid","Docs":""},{"Name":"ResultValidationFailure","Value":"validation-failure","Docs":""},{"Name":"ResultSTSPolicyFetch","Value":"sts-policy-fetch-error","Docs":""}]}, - "Alignment": {"Name":"Alignment","Docs":"","Values":[{"Name":"AlignmentAbsent","Value":"","Docs":""},{"Name":"AlignmentRelaxed","Value":"r","Docs":""},{"Name":"AlignmentStrict","Value":"s","Docs":""}]}, - "Disposition": {"Name":"Disposition","Docs":"","Values":[{"Name":"DispositionAbsent","Value":"","Docs":""},{"Name":"DispositionNone","Value":"none","Docs":""},{"Name":"DispositionQuarantine","Value":"quarantine","Docs":""},{"Name":"DispositionReject","Value":"reject","Docs":""}]}, - "DMARCResult": {"Name":"DMARCResult","Docs":"","Values":[{"Name":"DMARCAbsent","Value":"","Docs":""},{"Name":"DMARCPass","Value":"pass","Docs":""},{"Name":"DMARCFail","Value":"fail","Docs":""}]}, - "PolicyOverride": {"Name":"PolicyOverride","Docs":"","Values":[{"Name":"PolicyOverrideAbsent","Value":"","Docs":""},{"Name":"PolicyOverrideForwarded","Value":"forwarded","Docs":""},{"Name":"PolicyOverrideSampledOut","Value":"sampled_out","Docs":""},{"Name":"PolicyOverrideTrustedForwarder","Value":"trusted_forwarder","Docs":""},{"Name":"PolicyOverrideMailingList","Value":"mailing_list","Docs":""},{"Name":"PolicyOverrideLocalPolicy","Value":"local_policy","Docs":""},{"Name":"PolicyOverrideOther","Value":"other","Docs":""}]}, - "DKIMResult": {"Name":"DKIMResult","Docs":"","Values":[{"Name":"DKIMAbsent","Value":"","Docs":""},{"Name":"DKIMNone","Value":"none","Docs":""},{"Name":"DKIMPass","Value":"pass","Docs":""},{"Name":"DKIMFail","Value":"fail","Docs":""},{"Name":"DKIMPolicy","Value":"policy","Docs":""},{"Name":"DKIMNeutral","Value":"neutral","Docs":""},{"Name":"DKIMTemperror","Value":"temperror","Docs":""},{"Name":"DKIMPermerror","Value":"permerror","Docs":""}]}, - "SPFDomainScope": {"Name":"SPFDomainScope","Docs":"","Values":[{"Name":"SPFDomainScopeAbsent","Value":"","Docs":""},{"Name":"SPFDomainScopeHelo","Value":"helo","Docs":""},{"Name":"SPFDomainScopeMailFrom","Value":"mfrom","Docs":""}]}, - "SPFResult": {"Name":"SPFResult","Docs":"","Values":[{"Name":"SPFAbsent","Value":"","Docs":""},{"Name":"SPFNone","Value":"none","Docs":""},{"Name":"SPFNeutral","Value":"neutral","Docs":""},{"Name":"SPFPass","Value":"pass","Docs":""},{"Name":"SPFFail","Value":"fail","Docs":""},{"Name":"SPFSoftfail","Value":"softfail","Docs":""},{"Name":"SPFTemperror","Value":"temperror","Docs":""},{"Name":"SPFPermerror","Value":"permerror","Docs":""}]}, "IP": {"Name":"IP","Docs":"","Values":[]}, } @@ -1422,15 +1326,6 @@ export const parser = { RUA: (v: any) => parse("RUA", v) as RUA, Mode: (v: any) => parse("Mode", v) as Mode, Localpart: (v: any) => parse("Localpart", v) as Localpart, - PolicyType: (v: any) => parse("PolicyType", v) as PolicyType, - ResultType: (v: any) => parse("ResultType", v) as ResultType, - Alignment: (v: any) => parse("Alignment", v) as Alignment, - Disposition: (v: any) => parse("Disposition", v) as Disposition, - DMARCResult: (v: any) => parse("DMARCResult", v) as DMARCResult, - PolicyOverride: (v: any) => parse("PolicyOverride", v) as PolicyOverride, - DKIMResult: (v: any) => parse("DKIMResult", v) as DKIMResult, - SPFDomainScope: (v: any) => parse("SPFDomainScope", v) as SPFDomainScope, - SPFResult: (v: any) => parse("SPFResult", v) as SPFResult, IP: (v: any) => parse("IP", v) as IP, }