mirror of
https://github.com/postalserver/postal.git
synced 2026-10-18 18:26:06 +00:00
feat(dkim): make key size configurable and allow keys to be rotated
This commit is contained in:
@@ -4,31 +4,33 @@
|
||||
#
|
||||
# Table name: domains
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# server_id :integer
|
||||
# uuid :string(255)
|
||||
# name :string(255)
|
||||
# verification_token :string(255)
|
||||
# verification_method :string(255)
|
||||
# verified_at :datetime
|
||||
# dkim_private_key :text(65535)
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# dns_checked_at :datetime
|
||||
# spf_status :string(255)
|
||||
# spf_error :string(255)
|
||||
# dkim_status :string(255)
|
||||
# dkim_error :string(255)
|
||||
# mx_status :string(255)
|
||||
# mx_error :string(255)
|
||||
# return_path_status :string(255)
|
||||
# return_path_error :string(255)
|
||||
# outgoing :boolean default(TRUE)
|
||||
# incoming :boolean default(TRUE)
|
||||
# owner_type :string(255)
|
||||
# owner_id :integer
|
||||
# dkim_identifier_string :string(255)
|
||||
# use_for_any :boolean
|
||||
# id :integer not null, primary key
|
||||
# dkim_error :string(255)
|
||||
# dkim_identifier_string :string(255)
|
||||
# dkim_private_key :text(65535)
|
||||
# dkim_status :string(255)
|
||||
# dns_checked_at :datetime
|
||||
# incoming :boolean default(TRUE)
|
||||
# mx_error :string(255)
|
||||
# mx_status :string(255)
|
||||
# name :string(255)
|
||||
# outgoing :boolean default(TRUE)
|
||||
# owner_type :string(255)
|
||||
# pending_dkim_identifier_string :string(255)
|
||||
# pending_dkim_private_key :text(65535)
|
||||
# return_path_error :string(255)
|
||||
# return_path_status :string(255)
|
||||
# spf_error :string(255)
|
||||
# spf_status :string(255)
|
||||
# use_for_any :boolean
|
||||
# uuid :string(255)
|
||||
# verification_method :string(255)
|
||||
# verification_token :string(255)
|
||||
# verified_at :datetime
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# owner_id :integer
|
||||
# server_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
||||
+300
-25
@@ -4,31 +4,33 @@
|
||||
#
|
||||
# Table name: domains
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# dkim_error :string(255)
|
||||
# dkim_identifier_string :string(255)
|
||||
# dkim_private_key :text(65535)
|
||||
# dkim_status :string(255)
|
||||
# dns_checked_at :datetime
|
||||
# incoming :boolean default(TRUE)
|
||||
# mx_error :string(255)
|
||||
# mx_status :string(255)
|
||||
# name :string(255)
|
||||
# outgoing :boolean default(TRUE)
|
||||
# owner_type :string(255)
|
||||
# return_path_error :string(255)
|
||||
# return_path_status :string(255)
|
||||
# spf_error :string(255)
|
||||
# spf_status :string(255)
|
||||
# use_for_any :boolean
|
||||
# uuid :string(255)
|
||||
# verification_method :string(255)
|
||||
# verification_token :string(255)
|
||||
# verified_at :datetime
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# owner_id :integer
|
||||
# server_id :integer
|
||||
# id :integer not null, primary key
|
||||
# dkim_error :string(255)
|
||||
# dkim_identifier_string :string(255)
|
||||
# dkim_private_key :text(65535)
|
||||
# dkim_status :string(255)
|
||||
# dns_checked_at :datetime
|
||||
# incoming :boolean default(TRUE)
|
||||
# mx_error :string(255)
|
||||
# mx_status :string(255)
|
||||
# name :string(255)
|
||||
# outgoing :boolean default(TRUE)
|
||||
# owner_type :string(255)
|
||||
# pending_dkim_identifier_string :string(255)
|
||||
# pending_dkim_private_key :text(65535)
|
||||
# return_path_error :string(255)
|
||||
# return_path_status :string(255)
|
||||
# spf_error :string(255)
|
||||
# spf_status :string(255)
|
||||
# use_for_any :boolean
|
||||
# uuid :string(255)
|
||||
# verification_method :string(255)
|
||||
# verification_token :string(255)
|
||||
# verified_at :datetime
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# owner_id :integer
|
||||
# server_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
@@ -162,6 +164,22 @@ describe Domain do
|
||||
it "generates a new dkim key" do
|
||||
expect { domain.generate_dkim_key }.to change { domain.dkim_private_key }.from(nil).to(match(/\A-+BEGIN RSA PRIVATE KEY-+/))
|
||||
end
|
||||
|
||||
it "generates a key of the configured size" do
|
||||
domain.generate_dkim_key
|
||||
expect(OpenSSL::PKey::RSA.new(domain.dkim_private_key).n.num_bits).to eq Postal::Config.dns.dkim_key_size
|
||||
end
|
||||
|
||||
context "when a different key size is configured" do
|
||||
before do
|
||||
allow(Postal::Config.dns).to receive(:dkim_key_size).and_return(1024)
|
||||
end
|
||||
|
||||
it "generates a key of that size" do
|
||||
domain.generate_dkim_key
|
||||
expect(OpenSSL::PKey::RSA.new(domain.dkim_private_key).n.num_bits).to eq 1024
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#dkim_key" do
|
||||
@@ -183,6 +201,138 @@ describe Domain do
|
||||
end
|
||||
end
|
||||
|
||||
describe "#pending_dkim_key" do
|
||||
context "when the domain has a pending DKIM key" do
|
||||
let(:domain) { create(:domain, dkim_status: "OK") }
|
||||
|
||||
before do
|
||||
domain.regenerate_dkim_key!
|
||||
end
|
||||
|
||||
it "returns the pending dkim key as a OpenSSL::PKey::RSA" do
|
||||
expect(domain.pending_dkim_key).to be_a OpenSSL::PKey::RSA
|
||||
expect(domain.pending_dkim_key.to_s).to eq domain.pending_dkim_private_key
|
||||
end
|
||||
end
|
||||
|
||||
context "when the domain has no pending DKIM key" do
|
||||
let(:domain) { create(:domain) }
|
||||
|
||||
it "returns nil" do
|
||||
expect(domain.pending_dkim_key).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#regenerate_dkim_key!" do
|
||||
context "when the current DKIM record is verified" do
|
||||
let(:domain) { create(:domain, dkim_status: "OK") }
|
||||
|
||||
it "stores the new key as a pending key with a new identifier" do
|
||||
domain.regenerate_dkim_key!
|
||||
expect(domain.pending_dkim_private_key).to match(/\A-+BEGIN RSA PRIVATE KEY-+/)
|
||||
expect(domain.pending_dkim_identifier_string).to be_present
|
||||
expect(domain.pending_dkim_identifier_string).to_not eq domain.dkim_identifier_string
|
||||
end
|
||||
|
||||
it "does not change the active key or status" do
|
||||
expect { domain.regenerate_dkim_key! }.to_not(change { domain.reload.dkim_private_key })
|
||||
expect(domain.dkim_status).to eq "OK"
|
||||
end
|
||||
end
|
||||
|
||||
context "when the current DKIM record is not verified" do
|
||||
let(:domain) { create(:domain, dkim_status: "Missing", dkim_error: "No TXT records") }
|
||||
|
||||
it "replaces the active key immediately without creating a pending key" do
|
||||
original_key = domain.dkim_key.to_s
|
||||
domain.regenerate_dkim_key!
|
||||
expect(domain.reload.dkim_private_key).to_not eq original_key
|
||||
expect(domain.pending_dkim_private_key).to be_nil
|
||||
expect(domain.dkim_key.to_s).to eq domain.dkim_private_key
|
||||
end
|
||||
|
||||
it "resets the DKIM status" do
|
||||
domain.regenerate_dkim_key!
|
||||
expect(domain.dkim_status).to be_nil
|
||||
expect(domain.dkim_error).to be_nil
|
||||
end
|
||||
|
||||
context "when a key change was already in progress" do
|
||||
# This happens when the active record breaks (so the status is no longer
|
||||
# "OK") while a pending key is waiting to be activated. The immediate
|
||||
# replacement supersedes the in-flight change, so the stale pending key
|
||||
# must not be left behind to be activated later.
|
||||
let(:domain) { create(:domain, dkim_status: "OK") }
|
||||
|
||||
before do
|
||||
domain.regenerate_dkim_key!
|
||||
domain.update!(dkim_status: "Missing", dkim_error: "No TXT records")
|
||||
end
|
||||
|
||||
it "abandons the pending key" do
|
||||
expect(domain.pending_dkim_private_key).to_not be_nil
|
||||
domain.regenerate_dkim_key!
|
||||
expect(domain.reload.pending_dkim_private_key).to be_nil
|
||||
expect(domain.pending_dkim_identifier_string).to be_nil
|
||||
expect(domain.pending_dkim_key).to be_nil
|
||||
end
|
||||
|
||||
it "replaces the active key rather than promoting the pending one" do
|
||||
stale_pending_key = domain.pending_dkim_private_key
|
||||
original_key = domain.dkim_private_key
|
||||
domain.regenerate_dkim_key!
|
||||
expect(domain.reload.dkim_private_key).to_not eq original_key
|
||||
expect(domain.dkim_private_key).to_not eq stale_pending_key
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#activate_pending_dkim_key" do
|
||||
context "when there is no pending key" do
|
||||
let(:domain) { create(:domain) }
|
||||
|
||||
it "does nothing" do
|
||||
expect { domain.activate_pending_dkim_key }.to_not(change { domain.dkim_private_key })
|
||||
end
|
||||
end
|
||||
|
||||
context "when there is a pending key" do
|
||||
let(:domain) { create(:domain, dkim_status: "OK") }
|
||||
|
||||
before do
|
||||
domain.regenerate_dkim_key!
|
||||
end
|
||||
|
||||
it "promotes the pending key and identifier and clears the pending values" do
|
||||
pending_key = domain.pending_dkim_private_key
|
||||
pending_identifier = domain.pending_dkim_identifier_string
|
||||
domain.activate_pending_dkim_key
|
||||
expect(domain.dkim_private_key).to eq pending_key
|
||||
expect(domain.dkim_identifier_string).to eq pending_identifier
|
||||
expect(domain.pending_dkim_private_key).to be_nil
|
||||
expect(domain.pending_dkim_identifier_string).to be_nil
|
||||
expect(domain.dkim_key.to_s).to eq pending_key
|
||||
expect(domain.pending_dkim_key).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#cancel_pending_dkim_key!" do
|
||||
let(:domain) { create(:domain, dkim_status: "OK") }
|
||||
|
||||
before do
|
||||
domain.regenerate_dkim_key!
|
||||
end
|
||||
|
||||
it "discards the pending key without changing the active key" do
|
||||
expect { domain.cancel_pending_dkim_key! }.to_not(change { domain.reload.dkim_private_key })
|
||||
expect(domain.pending_dkim_private_key).to be_nil
|
||||
expect(domain.pending_dkim_identifier_string).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to_param" do
|
||||
context "when the domain has not been saved" do
|
||||
it "returns nil" do
|
||||
@@ -274,6 +424,131 @@ describe Domain do
|
||||
end
|
||||
end
|
||||
|
||||
describe "#pending_dkim_record" do
|
||||
context "when the domain has no pending DKIM key" do
|
||||
it "returns nil" do
|
||||
expect(domain.pending_dkim_record).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when the domain has a pending DKIM key" do
|
||||
let(:domain) { create(:domain, dkim_status: "OK") }
|
||||
|
||||
before do
|
||||
domain.regenerate_dkim_key!
|
||||
end
|
||||
|
||||
it "returns the DKIM record for the pending key" do
|
||||
expect(domain.pending_dkim_record).to match(/\Av=DKIM1; t=s; h=sha256; p=.*;\z/)
|
||||
expect(domain.pending_dkim_record).to_not eq domain.dkim_record
|
||||
end
|
||||
|
||||
it "returns a record name using the pending identifier" do
|
||||
expect(domain.pending_dkim_record_name).to eq "#{Postal::Config.dns.dkim_identifier}-#{domain.pending_dkim_identifier_string}._domainkey"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#check_dkim_record" do
|
||||
let(:domain) { create(:domain, dkim_status: "OK") }
|
||||
let(:resolver) { instance_double(DNSResolver) }
|
||||
|
||||
before do
|
||||
allow(domain).to receive(:resolver).and_return(resolver)
|
||||
end
|
||||
|
||||
context "when there is a pending DKIM key" do
|
||||
before do
|
||||
domain.regenerate_dkim_key!
|
||||
end
|
||||
|
||||
context "when the pending record has been published" do
|
||||
it "activates and verifies the pending key from a single DNS response" do
|
||||
responses = [[domain.pending_dkim_record], []]
|
||||
allow(resolver).to receive(:txt).with("#{domain.pending_dkim_record_name}.#{domain.name}") { responses.shift }
|
||||
|
||||
pending_key = domain.pending_dkim_private_key
|
||||
domain.check_dkim_record
|
||||
expect(domain.dkim_private_key).to eq pending_key
|
||||
expect(domain.pending_dkim_private_key).to be_nil
|
||||
expect(domain.dkim_status).to eq "OK"
|
||||
expect(domain.dkim_error).to be_nil
|
||||
expect(responses).to eq([[]])
|
||||
end
|
||||
end
|
||||
|
||||
context "when multiple pending records have been published" do
|
||||
before do
|
||||
allow(resolver).to receive(:txt).with("#{domain.pending_dkim_record_name}.#{domain.name}").and_return([domain.pending_dkim_record, domain.pending_dkim_record])
|
||||
allow(resolver).to receive(:txt).with("#{domain.dkim_record_name}.#{domain.name}").and_return([domain.dkim_record])
|
||||
end
|
||||
|
||||
it "keeps the current key active and retains the pending key" do
|
||||
original_key = domain.dkim_private_key
|
||||
domain.check_dkim_record
|
||||
expect(domain.dkim_private_key).to eq original_key
|
||||
expect(domain.pending_dkim_private_key).to_not be_nil
|
||||
expect(domain.dkim_status).to eq "OK"
|
||||
end
|
||||
end
|
||||
|
||||
context "when the pending record has not been published" do
|
||||
before do
|
||||
allow(resolver).to receive(:txt).with("#{domain.pending_dkim_record_name}.#{domain.name}").and_return([])
|
||||
allow(resolver).to receive(:txt).with("#{domain.dkim_record_name}.#{domain.name}").and_return([domain.dkim_record])
|
||||
end
|
||||
|
||||
it "keeps the current key active and retains the pending key" do
|
||||
original_key = domain.dkim_private_key
|
||||
domain.check_dkim_record
|
||||
expect(domain.dkim_private_key).to eq original_key
|
||||
expect(domain.pending_dkim_private_key).to_not be_nil
|
||||
expect(domain.dkim_status).to eq "OK"
|
||||
end
|
||||
end
|
||||
|
||||
context "when the pending record does not match" do
|
||||
before do
|
||||
allow(resolver).to receive(:txt).with("#{domain.pending_dkim_record_name}.#{domain.name}").and_return(["v=DKIM1; t=s; h=sha256; p=something;"])
|
||||
allow(resolver).to receive(:txt).with("#{domain.dkim_record_name}.#{domain.name}").and_return([domain.dkim_record])
|
||||
end
|
||||
|
||||
it "keeps the current key active and retains the pending key" do
|
||||
original_key = domain.dkim_private_key
|
||||
domain.check_dkim_record
|
||||
expect(domain.dkim_private_key).to eq original_key
|
||||
expect(domain.pending_dkim_private_key).to_not be_nil
|
||||
expect(domain.dkim_status).to eq "OK"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when there is no pending DKIM key" do
|
||||
context "when the record is published" do
|
||||
before do
|
||||
allow(resolver).to receive(:txt).with("#{domain.dkim_record_name}.#{domain.name}").and_return([domain.dkim_record])
|
||||
end
|
||||
|
||||
it "marks the record as OK" do
|
||||
domain.check_dkim_record
|
||||
expect(domain.dkim_status).to eq "OK"
|
||||
expect(domain.dkim_error).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when the record is missing" do
|
||||
before do
|
||||
allow(resolver).to receive(:txt).with("#{domain.dkim_record_name}.#{domain.name}").and_return([])
|
||||
end
|
||||
|
||||
it "marks the record as missing" do
|
||||
domain.check_dkim_record
|
||||
expect(domain.dkim_status).to eq "Missing"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#return_path_domain" do
|
||||
it "returns the return path domain" do
|
||||
expect(domain.return_path_domain).to eq "#{Postal::Config.dns.custom_return_path_prefix}.#{domain.name}"
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe "DomainsController", type: :request do
|
||||
let(:user) { create(:user, admin: true) }
|
||||
let(:organization) { create(:organization, owner: user) }
|
||||
let(:server) { create(:server, organization: organization) }
|
||||
|
||||
before do
|
||||
post "/login", params: { email_address: user.email_address, password: "passw0rd" }
|
||||
end
|
||||
|
||||
describe "POST /org/:org/servers/:server/domains/:domain/regenerate_dkim" do
|
||||
context "when the domain's DKIM record is verified" do
|
||||
let(:domain) { create(:domain, owner: server, dkim_status: "OK") }
|
||||
|
||||
it "generates a pending DKIM key without changing the active key" do
|
||||
original_key = domain.dkim_private_key
|
||||
post "/org/#{organization.permalink}/servers/#{server.permalink}/domains/#{domain.uuid}/regenerate_dkim"
|
||||
expect(response).to redirect_to(setup_organization_server_domain_path(organization, server, domain))
|
||||
expect(flash[:notice]).to include("Keep the old DNS record published afterward")
|
||||
expect(flash[:notice]).to include("queued, held, or available for redelivery")
|
||||
expect(flash[:notice]).to_not include("you can remove the old record")
|
||||
domain.reload
|
||||
expect(domain.dkim_private_key).to eq original_key
|
||||
expect(domain.pending_dkim_private_key).to_not be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when the domain's DKIM record is not verified" do
|
||||
let(:domain) { create(:domain, owner: server, dkim_status: "Missing") }
|
||||
|
||||
it "replaces the active key immediately" do
|
||||
original_key = domain.dkim_private_key
|
||||
post "/org/#{organization.permalink}/servers/#{server.permalink}/domains/#{domain.uuid}/regenerate_dkim"
|
||||
expect(response).to redirect_to(setup_organization_server_domain_path(organization, server, domain))
|
||||
domain.reload
|
||||
expect(domain.dkim_private_key).to_not eq original_key
|
||||
expect(domain.pending_dkim_private_key).to be_nil
|
||||
expect(domain.dkim_status).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when a key change is already in progress" do
|
||||
let(:domain) { create(:domain, owner: server, dkim_status: "OK") }
|
||||
|
||||
before do
|
||||
domain.regenerate_dkim_key!
|
||||
end
|
||||
|
||||
it "refuses and leaves the pending key untouched" do
|
||||
existing_pending_key = domain.pending_dkim_private_key
|
||||
existing_pending_identifier = domain.pending_dkim_identifier_string
|
||||
post "/org/#{organization.permalink}/servers/#{server.permalink}/domains/#{domain.uuid}/regenerate_dkim"
|
||||
expect(response).to redirect_to(setup_organization_server_domain_path(organization, server, domain))
|
||||
expect(flash[:alert]).to include("already in progress")
|
||||
domain.reload
|
||||
expect(domain.pending_dkim_private_key).to eq existing_pending_key
|
||||
expect(domain.pending_dkim_identifier_string).to eq existing_pending_identifier
|
||||
end
|
||||
|
||||
it "does not change the active key" do
|
||||
expect do
|
||||
post "/org/#{organization.permalink}/servers/#{server.permalink}/domains/#{domain.uuid}/regenerate_dkim"
|
||||
end.to_not(change { domain.reload.dkim_private_key })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /org/:org/domains/:domain/regenerate_dkim" do
|
||||
let(:domain) { create(:domain, owner: organization, dkim_status: "OK") }
|
||||
|
||||
it "generates a pending DKIM key for an organization-owned domain" do
|
||||
post "/org/#{organization.permalink}/domains/#{domain.uuid}/regenerate_dkim"
|
||||
expect(response).to redirect_to(setup_organization_domain_path(organization, domain))
|
||||
expect(domain.reload.pending_dkim_private_key).to_not be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /org/:org/servers/:server/domains/:domain/check with a pending DKIM key" do
|
||||
let(:domain) { create(:domain, owner: server, dkim_status: "OK") }
|
||||
let(:resolver) { instance_double(DNSResolver) }
|
||||
|
||||
before do
|
||||
domain.regenerate_dkim_key!
|
||||
allow(DNSResolver).to receive(:for_domain).and_return(resolver)
|
||||
allow(resolver).to receive(:txt).with(domain.name).and_return([domain.spf_record])
|
||||
allow(resolver).to receive(:mx).with(domain.name).and_return([])
|
||||
allow(resolver).to receive(:cname).and_return([])
|
||||
end
|
||||
|
||||
context "when the pending DKIM record has been published" do
|
||||
before do
|
||||
allow(resolver).to receive(:txt).with("#{domain.pending_dkim_record_name}.#{domain.name}").and_return([domain.pending_dkim_record])
|
||||
end
|
||||
|
||||
it "activates the pending key and tells the user to retain the old record" do
|
||||
old_record_name = domain.dkim_record_name
|
||||
new_key = domain.pending_dkim_private_key
|
||||
post "/org/#{organization.permalink}/servers/#{server.permalink}/domains/#{domain.uuid}/check"
|
||||
expect(response).to redirect_to(setup_organization_server_domain_path(organization, server, domain))
|
||||
expect(flash[:notice]).to include("new DKIM key is now active")
|
||||
expect(flash[:notice]).to include(old_record_name)
|
||||
expect(flash[:notice]).to include("queued, held, or available for redelivery")
|
||||
expect(flash[:notice]).to_not include("can remove")
|
||||
domain.reload
|
||||
expect(domain.dkim_private_key).to eq new_key
|
||||
expect(domain.pending_dkim_private_key).to be_nil
|
||||
expect(domain.dkim_status).to eq "OK"
|
||||
end
|
||||
end
|
||||
|
||||
context "when the pending DKIM record has not been published" do
|
||||
before do
|
||||
allow(resolver).to receive(:txt).with("#{domain.pending_dkim_record_name}.#{domain.name}").and_return([])
|
||||
allow(resolver).to receive(:txt).with("#{domain.dkim_record_name}.#{domain.name}").and_return([domain.dkim_record])
|
||||
end
|
||||
|
||||
it "keeps the current key active and tells the user the new record wasn't verified" do
|
||||
post "/org/#{organization.permalink}/servers/#{server.permalink}/domains/#{domain.uuid}/check"
|
||||
expect(response).to redirect_to(setup_organization_server_domain_path(organization, server, domain))
|
||||
expect(flash[:alert]).to include("couldn't verify the record for your new DKIM key")
|
||||
domain.reload
|
||||
expect(domain.pending_dkim_private_key).to_not be_nil
|
||||
expect(domain.dkim_status).to eq "OK"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /org/:org/servers/:server/domains/:domain/cancel_dkim_regeneration" do
|
||||
let(:domain) { create(:domain, owner: server, dkim_status: "OK") }
|
||||
|
||||
before do
|
||||
domain.regenerate_dkim_key!
|
||||
end
|
||||
|
||||
it "discards the pending DKIM key" do
|
||||
post "/org/#{organization.permalink}/servers/#{server.permalink}/domains/#{domain.uuid}/cancel_dkim_regeneration"
|
||||
expect(response).to redirect_to(setup_organization_server_domain_path(organization, server, domain))
|
||||
expect(domain.reload.pending_dkim_private_key).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,48 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe "domains/index", type: :view do
|
||||
let(:user) { create(:user, admin: true) }
|
||||
let(:organization) { create(:organization, owner: user) }
|
||||
let(:domain) { create(:domain, owner: organization, dkim_status: "OK") }
|
||||
|
||||
before do
|
||||
assign(:organization, organization)
|
||||
assign(:domains, [domain])
|
||||
assign(:server, nil)
|
||||
without_partial_double_verification do
|
||||
allow(view).to receive(:organization).and_return(organization)
|
||||
allow(view).to receive(:current_user).and_return(user)
|
||||
allow(view).to receive(:page_title).and_return(["Postal"])
|
||||
end
|
||||
end
|
||||
|
||||
context "when no key change is in progress" do
|
||||
it "does not flag a pending DKIM key" do
|
||||
render
|
||||
expect(rendered).to_not include("New DKIM key pending")
|
||||
end
|
||||
end
|
||||
|
||||
context "when a key change is in progress" do
|
||||
before do
|
||||
domain.regenerate_dkim_key!
|
||||
end
|
||||
|
||||
it "flags the domain as having a pending DKIM key" do
|
||||
render
|
||||
expect(rendered).to include("New DKIM key pending")
|
||||
end
|
||||
|
||||
it "links the flag to the DNS setup page" do
|
||||
render
|
||||
expect(rendered).to include(setup_organization_domain_path(organization, domain))
|
||||
end
|
||||
|
||||
it "still shows DKIM as OK because the active key is unaffected" do
|
||||
render
|
||||
expect(rendered).to include("domainList__check--ok")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,73 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe "domains/setup", type: :view do
|
||||
let(:user) { create(:user, admin: true) }
|
||||
let(:organization) { create(:organization, owner: user) }
|
||||
let(:domain) { create(:domain, owner: organization, dkim_status: "OK") }
|
||||
|
||||
before do
|
||||
assign(:organization, organization)
|
||||
assign(:domain, domain)
|
||||
assign(:server, nil)
|
||||
without_partial_double_verification do
|
||||
allow(view).to receive(:organization).and_return(organization)
|
||||
allow(view).to receive(:current_user).and_return(user)
|
||||
allow(view).to receive(:page_title).and_return(["Postal"])
|
||||
end
|
||||
end
|
||||
|
||||
context "when no key change is in progress" do
|
||||
it "shows the active record and offers regeneration" do
|
||||
render
|
||||
expect(rendered).to include(domain.dkim_record_name)
|
||||
expect(rendered).to include(domain.dkim_record)
|
||||
expect(rendered).to include("Regenerate DKIM key")
|
||||
expect(rendered).to_not include("Key change in progress")
|
||||
expect(rendered).to_not include("Cancel new DKIM key")
|
||||
end
|
||||
end
|
||||
|
||||
context "when a key change is in progress" do
|
||||
before do
|
||||
domain.regenerate_dkim_key!
|
||||
end
|
||||
|
||||
it "shows both the current and the new record" do
|
||||
render
|
||||
expect(rendered).to include(domain.dkim_record_name)
|
||||
expect(rendered).to include(domain.dkim_record)
|
||||
expect(rendered).to include(domain.pending_dkim_record_name)
|
||||
expect(rendered).to include(domain.pending_dkim_record)
|
||||
end
|
||||
|
||||
it "labels which record is active and which must be added" do
|
||||
render
|
||||
expect(rendered).to include("Key change in progress")
|
||||
expect(rendered).to include("Keep this record exactly as it is")
|
||||
expect(rendered).to include("Add this record as well")
|
||||
end
|
||||
|
||||
it "tells the user to add the new record rather than replace the old one" do
|
||||
render
|
||||
expect(rendered).to include("alongside the record above rather than replacing it")
|
||||
end
|
||||
|
||||
it "does not describe the active record as one which needs adding" do
|
||||
render
|
||||
expect(rendered).to_not include("You need to add a new TXT record")
|
||||
end
|
||||
|
||||
it "offers cancellation instead of another regeneration" do
|
||||
render
|
||||
expect(rendered).to include("Cancel new DKIM key")
|
||||
expect(rendered).to_not include("Regenerate DKIM key")
|
||||
end
|
||||
|
||||
it "does not claim the DKIM record is fully good" do
|
||||
render
|
||||
expect(rendered).to_not include("Your DKIM record looks good!")
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user