Add DKIM record creator
This commit is contained in:
parent
7183b21d24
commit
0d41b2b813
@ -10,6 +10,7 @@ export class Field {
|
||||
categoryName = null;
|
||||
isHidden = false;
|
||||
isDisabled = false;
|
||||
isRequired = false;
|
||||
allowMultiple = false;
|
||||
|
||||
constructor(key) {
|
||||
@ -32,6 +33,11 @@ export class Field {
|
||||
|
||||
// Builder methods
|
||||
|
||||
required() {
|
||||
this.isRequired = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
label(label) {
|
||||
this.displayName = label;
|
||||
return this;
|
||||
|
||||
@ -12,8 +12,7 @@ export class FieldInputItem {
|
||||
|
||||
appendHtml(parent) {
|
||||
const container = document.createElement("div");
|
||||
container.style.display = "flex";
|
||||
container.style.gap = "0.5rem";
|
||||
container.className = "input-container";
|
||||
|
||||
if (this.field.allowMultiple) {
|
||||
const wrapper = document.createElement("div");
|
||||
|
||||
55
assets/scripts/records/DkimRecord.js
Normal file
55
assets/scripts/records/DkimRecord.js
Normal file
@ -0,0 +1,55 @@
|
||||
import { TagListRecord } from "./TagListRecord.js";
|
||||
import { ConstantTag } from "../tags/ConstantTag.js";
|
||||
import { EnumTag } from "../tags/EnumTag.js";
|
||||
import { TextTag } from "../tags/TextTag.js";
|
||||
import { FlagsTag } from "../tags/FlagsTag.js";
|
||||
|
||||
export class DkimRecord extends TagListRecord {
|
||||
static fields = [
|
||||
new ConstantTag("v", "DKIM1")
|
||||
.required()
|
||||
.hidden()
|
||||
.pos(0),
|
||||
|
||||
new TextTag("p")
|
||||
.label("Public key")
|
||||
.desc("Base64-encoded public key data")
|
||||
.required()
|
||||
.pos(1),
|
||||
|
||||
new FlagsTag("t", ["y", "s"])
|
||||
.label("Flags")
|
||||
.desc("Optional extra options that can be enabled")
|
||||
.options(["Test mode", "Require identical domain in i= and d= tags of DKIM signature (Recommended)"])
|
||||
.default("")
|
||||
.pos(1),
|
||||
|
||||
new EnumTag("h", ["sha1", "sha256"])
|
||||
.label("Hash algorithms")
|
||||
.desc("Which hash algorithms are allowed to be used. If not set, all are allowed")
|
||||
.options(["SHA-1", "SHA-256"])
|
||||
.category("advanced")
|
||||
.pos(1),
|
||||
|
||||
new TextTag("n")
|
||||
.label("Note")
|
||||
.desc("Any extra comments for humans. Not parsed by machines")
|
||||
.category("advanced")
|
||||
.default("")
|
||||
.pos(1),
|
||||
|
||||
new EnumTag("k", ["rsa"])
|
||||
.disabled()
|
||||
.default("rsa")
|
||||
.pos(1),
|
||||
|
||||
new EnumTag("s", ["*", "email"])
|
||||
.disabled()
|
||||
.default("*")
|
||||
.pos(1),
|
||||
];
|
||||
|
||||
static categories = {
|
||||
"advanced": "Advanced",
|
||||
};
|
||||
}
|
||||
@ -78,9 +78,10 @@ export class DmarcRecord extends TagListRecord {
|
||||
.default(86400)
|
||||
.pos(2),
|
||||
|
||||
new Tag("rf")
|
||||
new EnumTag("rf", ["afrf"])
|
||||
.disabled()
|
||||
.default("afrf"), // Other values not supported
|
||||
.default("afrf")
|
||||
.pos(2),
|
||||
];
|
||||
|
||||
static categories = {
|
||||
|
||||
@ -11,7 +11,7 @@ export class TagListRecord {
|
||||
static createFromFieldInputItems(items) {
|
||||
const tokens = items
|
||||
.filter(item => !item.field.isDisabled && item.isValid())
|
||||
.filter(item => !item.field.defaultValue || item.getValue() !== item.field.defaultValue)
|
||||
.filter(item => item.field.defaultValue === null || item.getValue() !== item.field.defaultValue)
|
||||
.map(input => input.toString());
|
||||
|
||||
const text = tokens.join("; ");
|
||||
|
||||
@ -3,7 +3,6 @@ import { Field } from "../Field.js";
|
||||
|
||||
export class Term extends Field {
|
||||
separator = null;
|
||||
isRequired = false;
|
||||
position = null;
|
||||
valueRequirement = ValueRequirement.REQUIRED;
|
||||
|
||||
@ -41,11 +40,6 @@ export class Term extends Field {
|
||||
|
||||
// Builder methods
|
||||
|
||||
required() {
|
||||
this.isRequired = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
pos(i) {
|
||||
this.position = i;
|
||||
return this;
|
||||
|
||||
@ -17,9 +17,9 @@ export class EnumTag extends Tag {
|
||||
|
||||
getInputHtml(id) {
|
||||
return `<select id="${id}" name="${this.key}" ${this.isRequired ? "required" : ""}>` +
|
||||
(this.isRequired || this.defaultValue ? "" : `<option value="" selected><not set></option>`) +
|
||||
(this.isRequired || this.initialValue ? "" : `<option value="" selected><not set></option>`) +
|
||||
this.values.map((value, i) =>
|
||||
`<option value="${value}" ${this.defaultValue === value ? "selected" : ""}>
|
||||
`<option value="${value}" ${this.initialValue === value ? "selected" : ""}>
|
||||
${this.optionLabels[i] + (this.defaultValue === value ? " (Default)" : "")}
|
||||
</option>`
|
||||
) +
|
||||
|
||||
28
assets/scripts/tags/FlagsTag.js
Normal file
28
assets/scripts/tags/FlagsTag.js
Normal file
@ -0,0 +1,28 @@
|
||||
import { Tag } from "./Tag.js";
|
||||
|
||||
export class FlagsTag extends Tag {
|
||||
constructor(key, flags) {
|
||||
super(key);
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
options(labels) {
|
||||
this.flagLabels = labels;
|
||||
return this;
|
||||
}
|
||||
|
||||
getInputHtml() {
|
||||
return `
|
||||
<div style="display: flex; flex-direction: column; gap: 0.5rem">` +
|
||||
this.flags.map((flag, i) => `
|
||||
<label><input id="${this.id + "-" + flag}" type="checkbox"> ${this.flagLabels[i]}</label>
|
||||
`).join("") +
|
||||
"</div>";
|
||||
}
|
||||
|
||||
getInputValue() {
|
||||
return this.flags.map(flag => document.getElementById(this.id + "-" + flag).checked ? flag : "")
|
||||
.filter(val => val)
|
||||
.join(":");
|
||||
}
|
||||
}
|
||||
@ -23,7 +23,7 @@ export class IntTag extends Tag {
|
||||
}
|
||||
|
||||
getInputHtml(id) {
|
||||
return `<input id="${id}" type="number" name="${this.key}" min="${this.min}" max="${this.max}" ${this.isRequired ? "required" : ""} placeholder="${this.defaultValue ?? ""}">`;
|
||||
return `<input id="${id}" type="number" name="${this.key}" min="${this.min}" max="${this.max}" ${this.isRequired ? "required" : ""} placeholder="${this.initialValue ?? ""}">`;
|
||||
}
|
||||
|
||||
getInputValue(id) {
|
||||
|
||||
@ -2,8 +2,8 @@ import { Field } from "../Field.js";
|
||||
|
||||
/** A tag within a DMARC/DKIM record */
|
||||
export class Tag extends Field {
|
||||
isRequired = false;
|
||||
defaultValue = null;
|
||||
initialValue = null;
|
||||
position = null;
|
||||
|
||||
constructor(key) {
|
||||
@ -34,13 +34,14 @@ export class Tag extends Field {
|
||||
|
||||
// Builder methods
|
||||
|
||||
required() {
|
||||
this.isRequired = true;
|
||||
default(value) {
|
||||
this.defaultValue = value;
|
||||
this.initialValue = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
default(value) {
|
||||
this.defaultValue = value;
|
||||
initial(value) {
|
||||
this.initialValue = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
19
assets/scripts/tags/TextTag.js
Normal file
19
assets/scripts/tags/TextTag.js
Normal file
@ -0,0 +1,19 @@
|
||||
import { Tag } from "./Tag.js";
|
||||
|
||||
export class TextTag extends Tag {
|
||||
constructor(key) {
|
||||
super(key);
|
||||
}
|
||||
|
||||
validate(value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
getInputHtml(id) {
|
||||
return `<input id="${id}" type="text" name="${this.key}" value="${this.initialValue ?? ""}" style="width: 100%">`;
|
||||
}
|
||||
|
||||
getInputValue(id) {
|
||||
return document.getElementById(id).value;
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,9 @@
|
||||
import { DkimRecord } from "../records/DkimRecord.js";
|
||||
import { DmarcRecord } from "../records/DmarcRecord.js";
|
||||
import { SpfRecord } from "../records/SpfRecord.js";
|
||||
|
||||
const records = {
|
||||
"/dkim-creator": DkimRecord,
|
||||
"/dmarc-creator": DmarcRecord,
|
||||
"/spf-creator": SpfRecord,
|
||||
};
|
||||
|
||||
@ -31,7 +31,7 @@ h1, h2 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
label {
|
||||
body > label {
|
||||
color: #757575;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
@ -122,7 +122,7 @@ li:not(:first-of-type) {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
form label {
|
||||
form > label, details > label {
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
@ -134,6 +134,7 @@ form input {
|
||||
border: 1px solid #BDBDBD;
|
||||
padding: 0.5rem 1rem;
|
||||
transition: border 200ms;
|
||||
accent-color: black;
|
||||
}
|
||||
|
||||
form input:focus {
|
||||
@ -173,6 +174,12 @@ summary:hover {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.input-container {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.text-button {
|
||||
background: none;
|
||||
border: none;
|
||||
|
||||
57
dkim-creator/index.html
Normal file
57
dkim-creator/index.html
Normal file
@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>DKIM Record Creator - Generate DKIM DNS Records</title>
|
||||
<link rel="stylesheet" href="/assets/styles/main.css">
|
||||
<script type="module" src="/assets/scripts/ui/creator.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>DKIM Record Creator</h1>
|
||||
|
||||
<label for="record">DNS Record</label><br>
|
||||
<input id="record" type="text" readonly>
|
||||
|
||||
<main>
|
||||
<h2>Create a DKIM DNS Record</h2>
|
||||
|
||||
<p>Customize the options below to generate a DKIM record, which will be shown in the input field above.</p>
|
||||
|
||||
<form id="form"></form>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
This tool can be used to create DKIM DNS records, which together with a signature header can be used
|
||||
for authorizing emails.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When setting up DKIM, you must first generate a public/private key pair. The private key is signed with
|
||||
the email message and should be automatically included in the DKIM-signature email header, while the
|
||||
public key should be pasted here in the DKIM DNS record, so that other email servers can verify the
|
||||
signature.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Using DKIM prevents your emails from ending up in the receiver's spam folder. It is recommended to also
|
||||
set up <a href="/spf-creator">SPF</a> (to authorize certain IP addresses to send mail) and
|
||||
<a href="/dmarc-creator">DMARC</a> (to specify how to handle failed validation), to minimize the risk of
|
||||
getting your emails flagged as spam.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This tool only helps with setting up the DNS record. The DKIM-signature email header should be
|
||||
automatically set by your email provider when sending mails.
|
||||
</p>
|
||||
|
||||
<center>
|
||||
<h3>More tools:</h3>
|
||||
<a href="/dkim-validator">DKIM Validator Tool</a> •
|
||||
<a href="/dmarc-creator">DMARC Creator Tool</a> •
|
||||
<a href="/spf-creator">SPF Creator Tool</a>
|
||||
</center>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@ -23,7 +23,7 @@
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
This tool allows you to create DMARC DNS records, which can be used when you are hosting an email-server
|
||||
This tool allows you to create DMARC DNS records, which can be used when you are hosting an email server
|
||||
and want to provide an extra layer of security, so other email providers will trust your emails.
|
||||
</p>
|
||||
|
||||
@ -32,9 +32,16 @@
|
||||
subdomain (e.g. _dmarc.example.com) with the content being the text above.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Using DMARC prevents your emails from ending up in the receiver's spam folder by telling email servers
|
||||
how strictly to handle validation with <a href="/dkim-creator">DKIM</a> and
|
||||
<a href="/spf-creator">SPF</a>. It is highly recommended to set up both of these before using DMARC.
|
||||
</p>
|
||||
|
||||
<center>
|
||||
<h3>More tools:</h3>
|
||||
<a href="/dmarc-validator">DMARC Validator Tool</a> •
|
||||
<a href="/DKIM-creator">DKIM Creator Tool</a> •
|
||||
<a href="/spf-creator">SPF Creator Tool</a>
|
||||
</center>
|
||||
</main>
|
||||
|
||||
@ -49,9 +49,17 @@
|
||||
current IP address. See the <a href="/spf-macro-guide">Macro Guide</a> for a list of all macros.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Using SPF prevents your emails from ending up in the receiver's spam folder. It is recommended to also
|
||||
set up <a href="/dkim-creator">DKIM</a> (to authorize emails by signing them cryptographically) and
|
||||
<a href="/dmarc-creator">DMARC</a> (to specify how to handle failed validation), to minimize the risk of
|
||||
getting your emails flagged as spam.
|
||||
</p>
|
||||
|
||||
<center>
|
||||
<h3>More tools:</h3>
|
||||
<a href="/spf-validator">SPF Validator Tool</a> •
|
||||
<a href="/dkim-creator">DKIM Creator Tool</a> •
|
||||
<a href="/dmarc-creator">DMARC Creator Tool</a>
|
||||
</center>
|
||||
</main>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user