diff --git a/app/controllers/domains_controller.rb b/app/controllers/domains_controller.rb index c9d6cc92..925ea168 100644 --- a/app/controllers/domains_controller.rb +++ b/app/controllers/domains_controller.rb @@ -104,6 +104,15 @@ def regenerate_transfer_code redirect_to domain_path(domain_name: @response.domain[:name]) end + def cancel_pending_update + conn = ApiConnector::Domains::PendingUpdateCanceller.new(**auth_info) + result = conn.call_action(payload: { name: params[:domain_name] }) + handle_response(result); return if performed? + + flash.notice = @message + redirect_to domain_path(domain_name: @response.domain[:name]) + end + def delete authorize! :delete, 'Epp::Domain' end diff --git a/app/services/api_connector/domains/pending_update_canceller.rb b/app/services/api_connector/domains/pending_update_canceller.rb new file mode 100644 index 00000000..b28954dd --- /dev/null +++ b/app/services/api_connector/domains/pending_update_canceller.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +class ApiConnector + module Domains + class PendingUpdateCanceller < ApiConnector + ACTION = 'cancel_pending_update' + ENDPOINT = { + method: 'delete', + endpoint: '/domains', + }.freeze + + def cancel_pending_update(payload: nil) + request(url: url_with_id(CGI.escape(payload[:name])), method: method) + end + + private + + def url_with_id(domain_name) + "#{endpoint_url}/#{domain_name}/pending_update" + end + end + end +end diff --git a/app/views/domains/show.html.erb b/app/views/domains/show.html.erb index f772ef7b..fdb82a36 100644 --- a/app/views/domains/show.html.erb +++ b/app/views/domains/show.html.erb @@ -20,6 +20,15 @@ <%= link_to t(:delete), delete_domain_path(domain_name: @domain[:name]), class: 'button button--danger' %> <% end %> + <% if @domain[:statuses].key?('pendingUpdate') %> +
+ <%= link_to t('.cancel_pending_update'), + domain_cancel_pending_update_path(domain_name: @domain[:name]), + class: 'button button--danger', + data: { 'turbo-method': 'delete', + turbo_confirm: t('.cancel_pending_update_confirm') } %> +
+ <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 7a969f68..92a9c48b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -231,7 +231,9 @@ en: flag: "Flag" public_key: "Public key" regenerate: "Regenerate transfer code" - + cancel_pending_update: "Cancel registrant change" + cancel_pending_update_confirm: "Cancel the pending registrant change of this domain?" + edit: title: "Edit domain" diff --git a/config/locales/et.yml b/config/locales/et.yml index ba2c2863..cc880241 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -238,7 +238,9 @@ et: flag: "Lipp" public_key: "Avalik võti" regenerate: "Regenerate transfer code" - + cancel_pending_update: "Tühista registreerija vahetus" + cancel_pending_update_confirm: "Kas tühistada selle domeeni ootel registreerija vahetus?" + edit: title: "Muuda domeeni" diff --git a/config/locales/statuses.en.yml b/config/locales/statuses.en.yml index 5181f7d7..fd3c2ca9 100644 --- a/config/locales/statuses.en.yml +++ b/config/locales/statuses.en.yml @@ -32,7 +32,7 @@ et: pendingRenew_text: "Renew command has been processed for the domain registration, but the action has not been completed by the server." pendingTransfer: "pendingTransfer" pendingTransfer_text: "Transfer command has been processed for the domain registration, but the action has not been completed by the server." - pendingUpdate": "pendingUpdate" + pendingUpdate: "pendingUpdate" pendingUpdate_text: "Update command has been processed for the domain registration, but the action has not been completed by the server." serverAdminChangeProhibited: "serverAdminChangeProhibited" serverAdminChangeProhibited_text: "Requests to replace admin contacts are rejected." diff --git a/config/locales/statuses.et.yml b/config/locales/statuses.et.yml index bbd30ec5..260a2ca0 100644 --- a/config/locales/statuses.et.yml +++ b/config/locales/statuses.et.yml @@ -32,7 +32,7 @@ et: pendingRenew_text: "Domeeni registreeringu pikendamine on ootel." pendingTransfer: "Registripidaja vahetus ootel" pendingTransfer_text: "Registripidaja vahetus on ootel." - pendingUpdate": "Andmete muutmine ootel" + pendingUpdate: "Andmete muutmine ootel" pendingUpdate_text: "Oodatakse registreerija kinnitust registreerija vahetuse päringule" serverAdminChangeProhibited: "Halduskontakti vahetus keelatud" serverAdminChangeProhibited_text: "Domeeni halduskontakti(de) muutmine on keelatud" diff --git a/config/routes.rb b/config/routes.rb index 59b162ff..4fecd41c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -31,6 +31,8 @@ post 'domains/transfer', to: 'domains#transfer', as: :domain_transfer post 'domains/renew', to: 'domains#renew', as: :domain_renew delete 'domains/destroy', to: 'domains#destroy', as: :destroy_domain + delete 'domain/cancel_pending_update', to: 'domains#cancel_pending_update', + as: :domain_cancel_pending_update resources :domains, except: %i[destroy update show edit] resources :bulk_change, only: %i[show update], controller: 'steps_controllers/bulk_change' diff --git a/spec/controllers/domains_controller_spec.rb b/spec/controllers/domains_controller_spec.rb index 6b95ff36..a7c779c6 100644 --- a/spec/controllers/domains_controller_spec.rb +++ b/spec/controllers/domains_controller_spec.rb @@ -129,6 +129,13 @@ params: { domain_name: domain, }, + }, + { + method: :cancel_pending_update, + http_method: :delete, + params: { + domain_name: domain, + }, } ] diff --git a/spec/fixtures/vcr_cassettes/controllers/domains_controller/cancel_pending_update-auth-fail.yml b/spec/fixtures/vcr_cassettes/controllers/domains_controller/cancel_pending_update-auth-fail.yml new file mode 100644 index 00000000..30510890 --- /dev/null +++ b/spec/fixtures/vcr_cassettes/controllers/domains_controller/cancel_pending_update-auth-fail.yml @@ -0,0 +1,53 @@ +--- +http_interactions: +- request: + method: delete + uri: http://registry:3000/repp/v1/domains/example092022.ee/pending_update + body: + encoding: UTF-8 + string: '' + headers: + Authorization: + - "" + User-Agent: + - Faraday v2.3.0 + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 401 + message: Unauthorized + headers: + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Permitted-Cross-Domain-Policies: + - none + Referrer-Policy: + - strict-origin-when-cross-origin + Content-Type: + - application/json; charset=utf-8 + Vary: + - Accept + Cache-Control: + - no-cache + X-Request-Id: + - 3c9d5b81-7a44-4e02-8f6d-95ab2c0e13da + X-Runtime: + - '0.012884' + Transfer-Encoding: + - chunked + body: + encoding: UTF-8 + string: '{"code":2202,"message":"Invalid authorization information","data":{"username":"ullam","password":"HcH9cT6k7O79","active":null}}' + recorded_at: Mon, 10 Aug 2026 08:30:00 GMT +recorded_with: VCR 6.1.0 diff --git a/spec/fixtures/vcr_cassettes/controllers/domains_controller/cancel_pending_update.yml b/spec/fixtures/vcr_cassettes/controllers/domains_controller/cancel_pending_update.yml new file mode 100644 index 00000000..5db3519c --- /dev/null +++ b/spec/fixtures/vcr_cassettes/controllers/domains_controller/cancel_pending_update.yml @@ -0,0 +1,53 @@ +--- +http_interactions: +- request: + method: delete + uri: http://registry:3000/repp/v1/domains/example092022.ee/pending_update + body: + encoding: UTF-8 + string: '' + headers: + Authorization: + - "" + User-Agent: + - Faraday v2.3.0 + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Permitted-Cross-Domain-Policies: + - none + Referrer-Policy: + - strict-origin-when-cross-origin + Content-Type: + - application/json; charset=utf-8 + Vary: + - Accept + Cache-Control: + - no-cache + X-Request-Id: + - 8f2a1c47-2d5e-4f19-9c3b-1b6e0d7a5f42 + X-Runtime: + - '0.041207' + Transfer-Encoding: + - chunked + body: + encoding: UTF-8 + string: '{"code":1000,"message":"Command completed successfully","data":{"domain":{"name":"example092022.ee"}}}' + recorded_at: Mon, 10 Aug 2026 08:30:00 GMT +recorded_with: VCR 6.1.0