Class: Www::WarrantyRegistrationsController
- Inherits:
-
BasePortalController
- Object
- ActionController::Base
- ApplicationController
- BasePortalController
- Www::WarrantyRegistrationsController
- Defined in:
- app/controllers/www/warranty_registrations_controller.rb
Overview
Public warranty registration (Warranty Registration v2, Phase 2). Replaces
the eleven per-product MailForm::Warranty* contact forms with an
order-aware flow:
new— order lookup (order number + email/ZIP verifier), or the
registration form when a verified order token / manual
mode is present.lookup— runs Warranty::OrderLookup; success redirects back to
newcarrying a short-lived signed order token, so the
order id itself never round-trips tamperable.create— Turnstile + SpamCheck gated; Warranty::PublicRegistration
resolves the end-consumer customer, saves the warranty,
claims uploads, and emails staff.thank_you— confirmation + (Phase 3) review prompt for matched orders.
The lookup endpoint is rate-limited in config/initializers/380_rack_attack.rb.
Constant Summary collapse
- ORDER_TOKEN_PURPOSE =
Signing purpose for fully verified order tokens (email/ZIP verifier matched).
:warranty_registration- LIMITED_ORDER_TOKEN_PURPOSE =
Issued when the lookup had no matching email/ZIP verifier: the form
shows the order's products but never prefills the customer's contact
details. Two distinct signing purposes keep the "verified" bit
tamper-proof. :warranty_registration_products_only- ORDER_TOKEN_TTL =
Lifetime of issued order tokens before they expire.
2.hours
Constants included from Controllers::MasqueradeGuarded
Controllers::MasqueradeGuarded::DEFAULT_BLOCK_MESSAGE
Constants included from Controllers::AnalyticsEvents
Controllers::AnalyticsEvents::MAX_QUEUED_EVENTS, Controllers::AnalyticsEvents::SESSION_KEY
Constants included from Controllers::ErrorRendering
Controllers::ErrorRendering::NON_CONTENT_PATH_PREFIXES
Instance Method Summary collapse
-
#create ⇒ Object
POST — persist the registration.
-
#lookup ⇒ Object
POST — order lookup with verifier.
-
#new ⇒ Object
Step 1 (lookup form), or step 2 (registration form) when a verified order token or explicit manual mode is present.
-
#sku_lookup ⇒ Object
GET (JSON) — manual-flow product lookup: resolves a typed SKU, SKU alias, Amazon ASIN, UPC, or EAN to the catalog item so the form can prefill the product line and name.
-
#thank_you ⇒ void
Confirmation page after registration: shows the registered warranty's coverage (the whole order's displayable line items for matched orders) and a review prompt.
Methods inherited from BasePortalController
#current_ability, #portal_party, #set_catalog, #set_webpack
Methods included from Controllers::MasqueradeGuarded
block_while_masquerading, #masquerade_blocks?
Methods inherited from ApplicationController
#account_impersonated?, #add_to_flash, #after_sign_in_path_for, #bypass_forgery_protection?, #chat_enabled?, #cloudflare_cleared?, #default_catalog, #default_url_options, #enable_turbo_frames, #find_publication, #fix_invalid_accept_header, #init_js_utils, #is_globals_call?, #layout_by_resource, #locale_store, #redirect_to, #require_employee_for_crm, #set_base_host, #set_real_ip, #set_report_errors_for, #should_render_layout?, #skip_layout_for_turbo_frame?, #stamp_impersonation_context, #tab_frame_breakout_request?, #warmlyyours_canada_ip?, #warmlyyours_ip?, #y
Methods included from Controllers::ReturnPathHandling
#check_for_return_path, #redirect_to_return_path_or_default
Methods included from Controllers::AnalyticsEvents
#consume_queued_analytics_events, #registration_lead_type, #track_event
Methods included from Controllers::DeviceDetection
Methods included from Controllers::SubdomainDetection
#is_crm_request?, #is_www_request?, #json_request?
Methods included from Controllers::TurboSafeRedirect
Methods included from Controllers::TrackingDetection
#bot_request?, #gdpr_country?, #gdpr_country_data, #prevent_bots, #set_tracking_cookie, #track_visitor?
Methods included from Controllers::AcceleratedFileSending
#send_file_accelerated, #send_upload_accelerated
Methods included from Controllers::ErrorRendering
#excp_string, #mail_to_for_error_reporting, #render_400, #render_404, #render_406, #render_410, #render_500, #render_invalid_authenticity_token, #render_ip_spoof_error, #render_unpermitted_parameters, #safe_referer_or_fallback
Methods included from Controllers::TurnstileVerification
#load_turnstile_script_tag, #turnstile_lazy_widget, #turnstile_script_tag, #turnstile_widget, #validate_turnstile!
Methods included from Controllers::CloudflareCaching
edge_cached, #edge_cached_action?, #reset_cloudflare_cache, #set_cloudflare_cache, #skip_edge_cache!, #skip_session
Methods included from Controllers::Webpackable
#preload_webpack_fonts, #webpack_css_include, #webpack_css_url, #webpack_js_include, #wpd_is_running?
Methods included from Controllers::Localizable
#cloudflare_country_locale, #determine_request_locale, #geocoder_locale, #guest_user_locale_check, #locale_optional_www_auth_path?, #param_locale, #set_locale, #set_request_locale, #skip_localization?, #warmlyyours_ip_locale
Methods included from Controllers::Authenticable
#access_denied, #authenticate_account, #authenticate_account!, #authenticate_account_from_login_token!, #check_is_a_manager, #check_is_a_sales_manager, #check_is_an_admin, #check_is_an_employee, #check_party, #clear_mismatched_guest_user, #create_guest_user, #credentials?, #current_or_guest_user, #current_or_guest_user_id_read_only, #current_user, #devise_mapping, #fully_logged_in?, #generate_bot_id, #guest_user, #identifiable?, #init_current_user, #initialize_guest, #load_context_user, #logging_in, #resource, #resource_name, #restrict_access_for_non_employees, #scrubbed_request_path, #user_object, #warn_on_session_guest_id_leak
Methods included from UrlsHelper
#catalog_breadcrumb_links, #catalog_link, #catalog_link_for_product_line, #catalog_link_for_sku, #cms_link, #delocalized_path, #path_to_sales_product_sku, #path_to_sales_product_sku_for_product_line, #path_to_sales_product_sku_for_product_line_slug, #product_line_from_catalog_link, #protocol_neutral_url, #sanitize_external_url, #valid_external_url?
Instance Method Details
#create ⇒ Object
POST — persist the registration.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'app/controllers/www/warranty_registrations_controller.rb', line 87 def create @order = order_from_token # One-shot per order: a second submission (stale tab, double-click, # replay) bounces to the status page instead of creating duplicates. if @order && Warranty.where(order_id: @order.id).exists? redirect_to new_warranty_registration_path(order_token: params[:order_token].presence) return end if spam_check_failed? flash[:error] = 'There was an error submitting your request. Please call us at (800) 875-5285.' redirect_to new_warranty_registration_path return end submission = Warranty::RegistrationParams.new(params, order: @order) result = Warranty::PublicRegistration.call( order: @order, registrant: submission.registrant_attributes, warranties_attributes: submission.warranties_attributes, warranty_attributes: submission.shared_warranty_attributes, upload_ids: submission.upload_ids, # Claims are restricted to files this browser session uploaded # (tracked by Www::UploadsController) — a guessed id attaches nothing. allowed_upload_ids: Array(session[:public_upload_ids]) ) if result.success session[:warranty_registration_ids] = [result.warranty.id] redirect_to thank_you_warranty_registrations_path elsif result.already_registered # Concurrent double-submit caught under the order lock — same # treatment as the pre-check: show the coverage-status page. redirect_to new_warranty_registration_path(order_token: params[:order_token].presence) else # Log the rejection reason — the flash renders client-side only, and # "customer couldn't register" reports are undebuggable without it. Rails.logger.warn "[WarrantyRegistration] create rejected: #{result.error.inspect} " \ "(order=#{@order&.id}, manual=#{@order.nil?})" flash.now[:error] = result.error.presence || 'There was a problem submitting your registration. Please try again.' @manual = @order.nil? # Re-render with everything the customer typed — the views read the # per-row/repeater values back from @submission. @submission = submission @warranty = Warranty.new(submission.shared_warranty_attributes .except('installers', *Warranty::PublicRegistration::PRODUCT_ATTR_KEYS)) load_product_line_groups render :register, status: :unprocessable_content end end |
#lookup ⇒ Object
POST — order lookup with verifier. Never discloses whether the order
number exists without a matching verifier (see Warranty::OrderLookup).
73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'app/controllers/www/warranty_registrations_controller.rb', line 73 def lookup result = Warranty::OrderLookup.call(lookup_params.to_h.symbolize_keys) if result.success purpose = result.verified ? ORDER_TOKEN_PURPOSE : LIMITED_ORDER_TOKEN_PURPOSE token = result.order.signed_id(purpose: purpose, expires_in: ORDER_TOKEN_TTL) redirect_to new_warranty_registration_path(order_token: token) else flash[:error] = result.error redirect_to new_warranty_registration_path(q: lookup_params[:query]) end end |
#new ⇒ Object
Step 1 (lookup form), or step 2 (registration form) when a verified
order token or explicit manual mode is present.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'app/controllers/www/warranty_registrations_controller.rb', line 37 def new @order = order_from_token # Optional query flag — `expect` would 400 when it's absent. @manual = params[:manual].to_b # rubocop:disable Rails/StrongParametersExpect @warranty = Warranty.new(product_line: params[:product_line].presence) # A failed lookup carries the typed order number via ?q= — keep it so # the manual registration stores what the customer actually has. @warranty.external_order_number = params[:q].presence if @manual && @order.nil? # An already-registered order lands on a status page with the coverage # summary — the registration is one-shot; changes go through support/CRM. @order_warranty = @order && Warranty.find_by(order_id: @order.id) @order_products = @order_warranty&.products&.order(:id).to_a load_product_line_groups return render :already_registered if @order_warranty render(@order || @manual ? :register : :new) end |
#sku_lookup ⇒ Object
GET (JSON) — manual-flow product lookup: resolves a typed SKU, SKU
alias, Amazon ASIN, UPC, or EAN to the catalog item so the form can
prefill the product line and name. Catalog data is public (the
storefront lists it), so no verifier is needed; rack-attack keeps
scraping in check. product_line is null for items that aren't
registrable on their own (thermostats, accessories).
61 62 63 64 65 66 67 68 69 |
# File 'app/controllers/www/warranty_registrations_controller.rb', line 61 def sku_lookup item = find_item_by_code(params[:sku].to_s.strip) return render json: { found: false } unless item product_line = Warranty.product_line_for_item(item) render json: { found: true, name: item.name, sku: item.sku, product_line: product_line, product_line_label: product_line && Warranty::PRODUCT_LINE_LABELS[product_line] } end |
#thank_you ⇒ void
This method returns an undefined value.
Confirmation page after registration: shows the registered warranty's coverage
(the whole order's displayable line items for matched orders) and a review prompt.
Redirects to the registration form when no completed registration is in the session.
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'app/controllers/www/warranty_registrations_controller.rb', line 143 def thank_you @warranty = Warranty.where(id: Array(session.delete(:warranty_registration_ids))).order(:id).first @products = @warranty&.products&.order(:id).to_a if @warranty.nil? redirect_to new_warranty_registration_path return end # Matched orders show the WHOLE order's coverage — including the # accessories/controls that are covered automatically — not just the # rows that were registered. @order = @warranty.order if @order @order_products = @products @displayable_line_items = Warranty.displayable_line_items(@order) end @review_prompt_url = Warranty::ReviewPrompt.call(warranty: @warranty) end |