 #  How a Bug Report Made HashCash Smarter 

 

  ![How a Bug Report Made HashCash Smarter](https://cdn.richeyweb.com/images/how-a-bug-report-made-hashcash-smarter/double-lock.webp)    A few weeks ago, a user named Roger filed a [bug report](/blog/development/the-humbling-art-of-free-software "The Humbling Art of Free Software"). Not the kind that makes you cringe - the kind that makes you think. He'd placed two forms on the same page, both protected by [Captcha](/joomla-techniques/building-a-better-joomla "Building a better Joomla") - [HashCash](/blog/development/did-i-just-solve-joomla-bot-spam-with-hashcash "Did I Just Solve Joomla Bot Spam With HashCash?"), and neither submit button would enable until *both* forms had their required fields filled in. Worse, the button decoration logic was cross-wiring between forms. Fill out the second form completely? HashCash was still waiting on the first one.

He was right. It was broken. And fixing it properly led to something better than just a bug fix.

## Roger's Two-Form Page Bug Report

Roger's page had a Joomla Contact Form component and a newsletter subscription module sitting side by side. Both were running HashCash. The expected behavior: each form manages its own state, its own hash calculation, its own submit button - independently. The actual behavior: they were tangled. The plugin was treating the page as a single form context, not two separate ones.

To reproduce it reliably, I needed a real third-party newsletter form to test against. That's where Christopher Mavros and his Newsletter Subscriber module came in.

Christopher's module is exactly what it sounds like - a clean, lightweight Joomla newsletter subscription module, free, available on the JED. When I reached out to explain the situation and ask if I could use it as a test case, he was immediately generous about it. That kind of open collaboration is what makes the [Joomla ecosystem](/joomla-techniques/load-feedback-in-joomla-without-an-extension "Load Feedback in Joomla Without an Extension") worth building for. The module gave me a realistic two-form environment to work in, and it's what drove the solution from "technically fixed" to "actually works well in the wild."

## What Was Broken and Why

The root cause was straightforward once I could see it clearly: the button decoration logic - the code responsible for disabling the submit button while the hash calculates and re-enabling it when done - wasn't scoped per form instance. It was written assuming one HashCash instance per page. When a second instance loaded, both were reaching for the same DOM context, stepping on each other's state.

The fix required scoping each instance to its own form, so each one tracks its own calculation state, manages its own button, and completes entirely independently of anything else on the page.

That's **version 5.6.0** - and it came with a bonus.

## The Bonus: The Generic Decorator

While working through the fix with Christopher's module as my test bed, something became obvious. Roger had noted a secondary quirk: the Newsletter Subscriber form's submit button wasn't being decorated - no spinner, no "Loading..." state - because HashCash didn't have a registered decorator for that form context. The form worked, the hash calculated, the spam was blocked - but the [UX](/blog/development/seo-tabs-with-details-summary "SEO Friendly Tabs with details/summary") was rougher than it should be.

Previously, the solution would have been to write a custom decorator - a small JavaScript file, correctly named and placed, telling HashCash how to find and manage the submit button for that specific form. That's documented, it works, and it's not hard for a developer. But it *is* friction, and it means every third-party form is a potential "does HashCash know about this one?" question for site builders.

So I built a generic decorator into 5.6.0.

It activates automatically for any form HashCash doesn't have a specific decorator for, using reasonable assumptions about form structure that hold true for the vast majority of Joomla-compatible forms in the wild - including Newsletter Subscriber. Drop HashCash onto a page with a third-party form today and it will almost certainly just work. Full decoration, correct button behavior, proper UX - out of the box, no custom code required.

Christopher's module was the proving ground. It works beautifully.

## If You Have an Existing Custom Decorator

Good news: **your custom decorator still works.** You don't need to do anything for your forms to remain protected and functional.

The one reason to update is to get the full multi-form benefits. If your page only ever has one HashCash-protected form, there's no urgency. If you have - or plan to have - multiple forms on the same page, a small update to your decorator will bring it in line with the new per-form scoping.

I've made that update as easy as I could: the original decorator code is left commented inside the new scripts, so you can see exactly what changed at a glance. The diff is minimal. Check the updated `com_contact.contact.js` in `/media/plg_captcha_hashcash/js/` as your reference - the old code is right there alongside the new.

## When You'd Still Write a Custom Decorator

The generic decorator handles typical form structures well. There are edge cases where a custom decorator remains the right call:

- **Non-standard submit elements** - if the button isn't a `<button>` or `<input type="submit">`, or is positioned outside the form element in the DOM
- **Multi-step or conditional forms** where the loading state needs to interact with your own step logic
- **Forms with their own loading UI** that would conflict with the generic decorator's spinner
- **Strict design system requirements** where you need precise control over the loading treatment
 
For everything else, 5.6.0 has you covered.

## Bug Report: Closed

A genuine thank-you to **Roger** for the detailed bug report - the kind that includes reproduction steps, follow-up testing, and patience while the fix baked. And to **Christopher Mavros** at [mavxr.com](https://mavxr.com) for his generosity in letting [Newsletter Subscriber](https://mavxr.com/joomla-extensions/free/newsletter-subscriber) serve as the real-world test case that shaped this release. If you're looking for a clean, no-fuss Joomla newsletter subscription module, his work is worth your time.

*[Captcha - HashCash](/software/joomla/plugins/captcha-hashcash) is free, [self-hosted](/blog/development/ad-block-detection-for-joomla-updated "Ad Block Detection for Joomla Updated"), and listed on the Joomla Extension Directory with 5-star reviews. No paid tier, no third-party dependencies, no tracking. If it's useful to you, a review on the JED is all I ask.*



- [      email ](mailto:?subject=How+a+Bug+Report+Made+HashCash+Smarter&body=https%3A%2F%2Fwww.richeyweb.com%2Fblog%2Fdevelopment%2Fhow-a-bug-report-made-hashcash-smarter)
- [      facebook ](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fwww.richeyweb.com%2Fblog%2Fdevelopment%2Fhow-a-bug-report-made-hashcash-smarter)
- [      x-twitter ](https://twitter.com/intent/tweet?text=How+a+Bug+Report+Made+HashCash+Smarter%3A+https%3A%2F%2Fwww.richeyweb.com%2Fblog%2Fdevelopment%2Fhow-a-bug-report-made-hashcash-smarter)
- [      linkedin ](http://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fwww.richeyweb.com%2Fblog%2Fdevelopment%2Fhow-a-bug-report-made-hashcash-smarter&title=How+a+Bug+Report+Made+HashCash+Smarter&summary=A+few+weeks+ago%2C+a+user+named+Roger+filed+a+bug+re...)
- [      pinterest ](http://pinterest.com/pin/create/button/?url=https%3A%2F%2Fwww.richeyweb.com%2Fblog%2Fdevelopment%2Fhow-a-bug-report-made-hashcash-smarter&media=https%3A%2F%2Fcdn.joomla.org%2Fimages%2Fjoomla-org-og.jpg&description=How+a+Bug+Report+Made+HashCash+Smarter)
 


 

   [  Next article: I Built This on February 3rd. Cloudflare Announced It on February 12th  I Built This on February 3rd. Cloudflare Announced It on February 12th  ](/blog/development/i-built-this-on-february-3rd-cloudflare-announced-it-on-february-12th)  

##### We Value Your Privacy

 

We use cookies to enhance your experience and for traffic analysis. By continuing to visit this site you agree to our use of cookies.

[Privacy Policy](/privacy-policy)

 Details 

###### Google Tag Manager Items

- Ad Storage
- Ad User Data
- Ad Personalization
- Analytics Storage
- Functionality Storage
- Personalization Storage
- Security Storage
 
 

 

 

 

 

 Decline Accept
```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://www.richeyweb.com/#organization","name":"RicheyWeb","url":"https://www.richeyweb.com/","logo":{"@type":"ImageObject","url":"https://www.richeyweb.com/images/logo/richeyweb.svg","contentUrl":"https://www.richeyweb.com/images/logo/richeyweb.svg","width":{"@type":"QuantitativeValue","value":38,"unitCode":"PX"},"height":{"@type":"QuantitativeValue","value":38,"unitCode":"PX"},"@id":"https://www.richeyweb.com/#logo"},"image":{"@id":"https://www.richeyweb.com/#logo"},"sameAs":["https://x.com/ComRicheyweb","https://www.facebook.com/RicheyWebDev/","https://www.youtube.com/channel/UCxnVG8BwOvQRO7hVqNX7T2g","https://community.joomla.org/service-providers-directory/listings/115:richeyweb.html"],"description":"RicheyWeb is a custom software developer specializing in Joomla extensions.","ContactPoint":[{"@type":"ContactPoint","url":"https://www.richeyweb.com/contact-us","telephone":"903-873-8460","contactType":"Owner/Administrator","areaServed":["United States",{"@type":"Country","name":"United States","sameAs":["https://en.wikipedia.org/wiki/United_States","https://www.wikidata.org/wiki/Q30","https://g.co/kg/m/09c7w0"]},"European Union",{"@type":"AdministrativeArea","name":"European Union","sameAs":["https://en.wikipedia.org/wiki/European_Union","https://www.wikidata.org/wiki/Q458","https://g.co/kg/m/0_6t_z8"]},"United Kingdom",{"@type":"Country","name":"United Kingdom","sameAs":["https://en.wikipedia.org/wiki/United_Kingdom","https://www.wikidata.org/wiki/Q145","https://g.co/kg/m/07ssc"]},"Australia",{"@type":"Country","name":"Australia","sameAs":["https://en.wikipedia.org/wiki/Australia","https://www.wikidata.org/wiki/Q408","https://g.co/kg/m/0chghy"]},"Canada",{"@type":"Country","name":"Canada","sameAs":["https://en.wikipedia.org/wiki/Canada","https://www.wikidata.org/wiki/Q16","https://g.co/kg/m/0d060g"]},"Russia",{"@type":"Country","name":"Russia","sameAs":["https://en.wikipedia.org/wiki/Russia","https://www.wikidata.org/wiki/Q159","https://g.co/kg/m/06bnz"]},"China",{"@type":"Country","name":"China","sameAs":["https://en.wikipedia.org/wiki/China","https://www.wikidata.org/wiki/Q148","https://g.co/kg/m/0d05w3"]}],"availableLanguage":"en"},{"@type":"ContactPoint","url":"https://www.richeyweb.com/bugs","telephone":"903-873-8460","contactType":"Technical Support","areaServed":["United States",{"@type":"Country","name":"United States","sameAs":["https://en.wikipedia.org/wiki/United_States","https://www.wikidata.org/wiki/Q30","https://g.co/kg/m/09c7w0"]},"European Union",{"@type":"AdministrativeArea","name":"European Union","sameAs":["https://en.wikipedia.org/wiki/European_Union","https://www.wikidata.org/wiki/Q458","https://g.co/kg/m/0_6t_z8"]},"United Kingdom",{"@type":"Country","name":"United Kingdom","sameAs":["https://en.wikipedia.org/wiki/United_Kingdom","https://www.wikidata.org/wiki/Q145","https://g.co/kg/m/07ssc"]},"Australia",{"@type":"Country","name":"Australia","sameAs":["https://en.wikipedia.org/wiki/Australia","https://www.wikidata.org/wiki/Q408","https://g.co/kg/m/0chghy"]},"Canada",{"@type":"Country","name":"Canada","sameAs":["https://en.wikipedia.org/wiki/Canada","https://www.wikidata.org/wiki/Q16","https://g.co/kg/m/0d060g"]},"Russia",{"@type":"Country","name":"Russia","sameAs":["https://en.wikipedia.org/wiki/Russia","https://www.wikidata.org/wiki/Q159","https://g.co/kg/m/06bnz"]},"China",{"@type":"Country","name":"China","sameAs":["https://en.wikipedia.org/wiki/China","https://www.wikidata.org/wiki/Q148","https://g.co/kg/m/0d05w3"]}],"availableLanguage":"en"}],"knowsAbout":["Computer programming",{"@type":"Thing","name":"Computer programming","sameAs":["https://en.wikipedia.org/wiki/Computer_programming","https://www.wikidata.org/wiki/Q80006","https://g.co/kg/m/01mf_"]},"PHP",{"@type":"Thing","name":"PHP","sameAs":["https://en.wikipedia.org/wiki/PHP","https://www.wikidata.org/wiki/Q59","https://g.co/kg/m/060kv"]},"JavaScript",{"@type":"Thing","name":"JavaScript","sameAs":["https://en.wikipedia.org/wiki/JavaScript","https://www.wikidata.org/wiki/Q2005","https://g.co/kg/m/02p97"]},"arduino","Computer forensics",{"@type":"Thing","name":"Computer forensics","sameAs":["https://en.wikipedia.org/wiki/Computer_forensics","https://www.wikidata.org/wiki/Q878553","https://g.co/kg/m/02wxbd"]},"White hat",{"@type":"Thing","name":"White hat","sameAs":["https://en.wikipedia.org/wiki/White_hat_(computer_security)","https://www.wikidata.org/wiki/Q7995625","https://g.co/kg/m/03ns_5"]},"Search engine optimization",{"@type":"Thing","name":"Search engine optimization","sameAs":["https://en.wikipedia.org/wiki/Search_engine_optimization","https://www.wikidata.org/wiki/Q180711","https://g.co/kg/m/019qb_"]},"Search engine marketing",{"@type":"Thing","name":"Search engine marketing","sameAs":["https://en.wikipedia.org/wiki/Search_engine_marketing","https://www.wikidata.org/wiki/Q846132","https://g.co/kg/m/06mw8r"]},"Digital marketing",{"@type":"Thing","name":"Digital marketing","sameAs":["https://en.wikipedia.org/wiki/Digital_marketing","https://www.wikidata.org/wiki/Q1323528","https://g.co/kg/g/122hcnps"]},"Web hosting service",{"@type":"Thing","name":"Web hosting service","sameAs":["https://en.wikipedia.org/wiki/Web_hosting_service","https://www.wikidata.org/wiki/Q5892272","https://g.co/kg/m/014pz4"]},"Email hosting service",{"@type":"Thing","name":"Email hosting service","sameAs":["https://en.wikipedia.org/wiki/Email_hosting_service","https://www.wikidata.org/wiki/Q5368818","https://g.co/kg/m/09w60m"]},"Internet hosting service",{"@type":"Thing","name":"Internet hosting service","sameAs":["https://en.wikipedia.org/wiki/Internet_hosting_service","https://www.wikidata.org/wiki/Q1210425","https://g.co/kg/m/09w5yw"]},"Virtual hosting",{"@type":"Thing","name":"Virtual hosting","sameAs":["https://en.wikipedia.org/wiki/Virtual_hosting","https://www.wikidata.org/wiki/Q588365","https://g.co/kg/m/024mvh"]},"Web performance",{"@type":"Thing","name":"Web performance","sameAs":["https://en.wikipedia.org/wiki/Web_performance","https://www.wikidata.org/wiki/Q7978612","https://g.co/kg/m/0gfj3f1"]},"Web content management system",{"@type":"Thing","name":"Web content management system","sameAs":["https://en.wikipedia.org/wiki/Web_content_management_system","https://www.wikidata.org/wiki/Q45211","https://g.co/kg/m/0615s2"]},"Content management system",{"@type":"Thing","name":"Content management system","sameAs":["https://en.wikipedia.org/wiki/Content_management_system","https://www.wikidata.org/wiki/Q131093","https://g.co/kg/m/0k23c"]},"General Data Protection Regulation",{"@type":"Thing","name":"General Data Protection Regulation","sameAs":["https://en.wikipedia.org/wiki/General_Data_Protection_Regulation","https://www.wikidata.org/wiki/Q1172506","https://g.co/kg/m/0pk_7xs"]},"SERP",{"@type":"Thing","name":"SERP","sameAs":["https://en.wikipedia.org/wiki/SERP","https://www.wikidata.org/wiki/Q2205811","https://g.co/kg/g/11c5szp7kc"]},"Artificial intelligence",{"@type":"Thing","name":"Artificial intelligence","sameAs":["https://en.wikipedia.org/wiki/Artificial_intelligence","https://www.wikidata.org/wiki/Q11660","https://g.co/kg/m/0mkz"]},"Prompt engineering",{"@type":"Thing","name":"Prompt engineering","sameAs":["https://en.wikipedia.org/wiki/Prompt_engineering","https://www.wikidata.org/wiki/Q108941486","https://g.co/kg/g/11p6kpgt_n"]},"E-learning",{"@type":"Thing","name":"E-learning","sameAs":["https://en.wikipedia.org/wiki/E-learning_(theory)","https://www.wikidata.org/wiki/Q182250","https://g.co/kg/g/122czm1f"]},"Sharable Content Object Reference Model",{"@type":"Thing","name":"Sharable Content Object Reference Model","sameAs":["https://en.wikipedia.org/wiki/Sharable_Content_Object_Reference_Model","https://www.wikidata.org/wiki/Q827811","https://g.co/kg/m/06_40"]},"Experience API",{"@type":"Thing","name":"Experience API","sameAs":["https://en.wikipedia.org/wiki/Experience_API","https://www.wikidata.org/wiki/Q7807728","https://g.co/kg/g/1yw9ktxr8"]},"Joomla",{"@type":"Thing","name":"Joomla","sameAs":["https://en.wikipedia.org/wiki/Joomla","https://www.wikidata.org/wiki/Q13167","https://g.co/kg/m/07qb81"]},"Nginx",{"@type":"Thing","name":"Nginx","sameAs":["https://en.wikipedia.org/wiki/Nginx","https://www.wikidata.org/wiki/Q306144","https://g.co/kg/m/02qft91"]},"MySQL",{"@type":"Thing","name":"MySQL","sameAs":["https://en.wikipedia.org/wiki/MySQL","https://www.wikidata.org/wiki/Q850","https://g.co/kg/m/04y3k"]}],"areaServed":["United States",{"@type":"Country","name":"United States","sameAs":["https://en.wikipedia.org/wiki/United_States","https://www.wikidata.org/wiki/Q30","https://g.co/kg/m/09c7w0"]},"European Union",{"@type":"AdministrativeArea","name":"European Union","sameAs":["https://en.wikipedia.org/wiki/European_Union","https://www.wikidata.org/wiki/Q458","https://g.co/kg/m/0_6t_z8"]},"United Kingdom",{"@type":"Country","name":"United Kingdom","sameAs":["https://en.wikipedia.org/wiki/United_Kingdom","https://www.wikidata.org/wiki/Q145","https://g.co/kg/m/07ssc"]},"Australia",{"@type":"Country","name":"Australia","sameAs":["https://en.wikipedia.org/wiki/Australia","https://www.wikidata.org/wiki/Q408","https://g.co/kg/m/0chghy"]},"Canada",{"@type":"Country","name":"Canada","sameAs":["https://en.wikipedia.org/wiki/Canada","https://www.wikidata.org/wiki/Q16","https://g.co/kg/m/0d060g"]},"Russia",{"@type":"Country","name":"Russia","sameAs":["https://en.wikipedia.org/wiki/Russia","https://www.wikidata.org/wiki/Q159","https://g.co/kg/m/06bnz"]},"China",{"@type":"Country","name":"China","sameAs":["https://en.wikipedia.org/wiki/China","https://www.wikidata.org/wiki/Q148","https://g.co/kg/m/0d05w3"]}],"memberOf":["Mensa International",{"@type":"Organization","name":"Mensa International","sameAs":["https://en.wikipedia.org/wiki/Mensa_International","https://www.wikidata.org/wiki/Q184194","https://g.co/kg/m/0140pf"]},"National Rifle Association",{"@type":"Organization","name":"National Rifle Association","sameAs":["https://en.wikipedia.org/wiki/National_Rifle_Association","https://www.wikidata.org/wiki/Q863259","https://g.co/kg/m/0j6f9"]},"CompTIA",{"@type":"Organization","name":"CompTIA","sameAs":["https://en.wikipedia.org/wiki/CompTIA","https://www.wikidata.org/wiki/Q597534","https://g.co/kg/m/040shq"]},"ISFCE LLC",{"@type":"Organization","name":"ISFCE LLC","sameAs":["https://isfce.com","https://g.co/kg/g/11wxm5r0rg"]}],"hasCredential":[{"@type":"EducationalOccupationalCredential","name":"Joomla 3 Certified Administrator","credentialCategory":"Certification","description":"Administrator Exam is the first available Joomla! certification exam","recognizedBy":{"@type":"Organization","name":"Open Source Matters, Inc.","sameAs":["https://en.wikipedia.org/wiki/Open_Source_Matters,_Inc.","https://g.co/kg/g/11f00wvjhz"]},"url":"https://certification.joomla.org/certified-user-directory/michael-richey","about":["Content management system",{"@type":"Thing","name":"Content management system","sameAs":["https://en.wikipedia.org/wiki/Content_management_system","https://www.wikidata.org/wiki/Q131093","https://g.co/kg/m/0k23c"]},"Web content management system",{"@type":"Thing","name":"Web content management system","sameAs":["https://en.wikipedia.org/wiki/Web_content_management_system","https://www.wikidata.org/wiki/Q45211","https://g.co/kg/m/0615s2"]},"Joomla",{"@type":"Thing","name":"Joomla","sameAs":["https://en.wikipedia.org/wiki/Joomla","https://www.wikidata.org/wiki/Q13167","https://g.co/kg/m/07qb81"]}],"educationalLevel":"expert","image":{"@type":"ImageObject","url":"https://www.richeyweb.com/images/contact/badge.webp","contentUrl":"https://www.richeyweb.com/images/contact/badge.webp","width":{"@type":"QuantitativeValue","value":300,"unitCode":"PX"},"height":{"@type":"QuantitativeValue","value":86,"unitCode":"PX"},"caption":"Joomla 3 Certified Administrator"}},{"@type":"EducationalOccupationalCredential","name":"Certified Computer Examiner","credentialCategory":"Certification","description":"Internationally recognized computer forensics certifiecation","recognizedBy":{"@type":"Organization","name":"ISFCE LLC","sameAs":["https://en.wikipedia.org/wiki/ISFCE_LLC","https://g.co/kg/g/11wxm5r0rg"]},"url":"https://isfce.com/","about":["Digital forensics",{"@type":"Thing","name":"Digital forensics","sameAs":["https://en.wikipedia.org/wiki/Digital_forensics","https://www.wikidata.org/wiki/Q3246940","https://g.co/kg/m/0cnxzfx"]},"Computer forensics",{"@type":"Thing","name":"Computer forensics","sameAs":["https://en.wikipedia.org/wiki/Computer_forensics","https://www.wikidata.org/wiki/Q878553","https://g.co/kg/m/02wxbd"]},"Mobile device forensics",{"@type":"Thing","name":"Mobile device forensics","sameAs":["https://en.wikipedia.org/wiki/Mobile_device_forensics","https://www.wikidata.org/wiki/Q6887097","https://g.co/kg/m/06zp3tp"]},"Network forensics",{"@type":"Thing","name":"Network forensics","sameAs":["https://en.wikipedia.org/wiki/Network_forensics","https://www.wikidata.org/wiki/Q7001032","https://g.co/kg/m/05pb280"]},"Database forensics",{"@type":"Thing","name":"Database forensics","sameAs":["https://en.wikipedia.org/wiki/Database_forensics","https://www.wikidata.org/wiki/Q5227405","https://g.co/kg/m/0cgqsy"]}],"educationalLevel":"expert","image":{"@type":"ImageObject","url":"https://www.richeyweb.com/images/contact/isfce-cce.webp","contentUrl":"https://www.richeyweb.com/images/contact/isfce-cce.webp","width":{"@type":"QuantitativeValue","value":150,"unitCode":"PX"},"height":{"@type":"QuantitativeValue","value":150,"unitCode":"PX"},"caption":"Certified Computer Examiner"}}],"hasOfferCatalog":{"@type":"OfferCatalog","name":"Web Services","itemListElement":[{"@type":"Offer","itemOffered":{"@type":"Service","name":"Hosting"}},{"@type":"Offer","itemOffered":{"@type":"Service","name":"Development"}},{"@type":"Offer","itemOffered":{"@type":"Service","name":"Search Engine Optimization"}}]}},{"@type":"WebSite","@id":"https://www.richeyweb.com/#website","url":"https://www.richeyweb.com/","name":"RicheyWeb","publisher":{"@id":"https://www.richeyweb.com/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://www.richeyweb.com/search?q={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string","valueMaxLength":256,"valueMinLength":2,"valuePattern":"^[A-Za-z0-9\\s]+$"}},"creator":{"@id":"https://www.richeyweb.com/#organization"},"copyrightHolder":{"@id":"https://www.richeyweb.com/#organization"}},{"@type":"WebPage","@id":"https://www.richeyweb.com/blog/development/how-a-bug-report-made-hashcash-smarter#webpage","url":"https://www.richeyweb.com/blog/development/how-a-bug-report-made-hashcash-smarter","name":"How a Bug Report Made HashCash Smarter","description":"Discover how a bug report improved HashCash, fixing multi-form issues and enhancing UX with a generic decorator in Joomla.","isPartOf":{"@id":"https://www.richeyweb.com/#website"},"about":{"@id":"https://www.richeyweb.com/#organization"},"inLanguage":"en-GB"},{"@type":"Article","image":{"@type":"ImageObject","url":"https://www.richeyweb.com/images/how-a-bug-report-made-hashcash-smarter/double-lock.webp","contentUrl":"https://www.richeyweb.com/images/how-a-bug-report-made-hashcash-smarter/double-lock.webp","width":{"@type":"QuantitativeValue","value":1280,"unitCode":"PX"},"height":{"@type":"QuantitativeValue","value":720,"unitCode":"PX"},"caption":"How a Bug Report Made HashCash Smarter","representativeOfPage":true},"headline":"How a Bug Report Made HashCash Smarter","description":"Discover how a bug report improved HashCash, fixing multi-form issues and enhancing UX with a generic decorator in Joomla.","author":{"@type":"Person","name":"Michael Richey","url":"https://www.richeyweb.com/contact-us","@id":"https://www.richeyweb.com/contact-us#person"},"datePublished":"2026-03-24T00:00:00+00:00","dateModified":"2026-03-30T00:00:00+00:00","about":["Joomla",{"@type":"SoftwareApplication","name":"Joomla","sameAs":["https://en.wikipedia.org/wiki/Joomla","https://www.wikidata.org/wiki/Q13167","https://g.co/kg/m/07qb81"]},"CAPTCHA",{"@type":"Thing","name":"CAPTCHA","sameAs":["https://en.wikipedia.org/wiki/CAPTCHA","https://www.wikidata.org/wiki/Q484598","https://grokipedia.com/page/CAPTCHA","https://g.co/kg/m/01hl4j"]},"Anti-spam techniques",{"@type":"Thing","name":"Anti-spam techniques","sameAs":["https://en.wikipedia.org/wiki/Anti-spam_techniques","https://www.wikidata.org/wiki/Q2392270","https://grokipedia.com/page/Anti-spam_techniques","https://g.co/kg/m/01tk85"]},"Hashcash",{"@type":"Thing","name":"Hashcash","sameAs":["https://en.wikipedia.org/wiki/Hashcash","https://www.wikidata.org/wiki/Q357569","https://grokipedia.com/page/Hashcash","https://g.co/kg/m/02qsnf"]},"Captcha - HashCash",{"@type":"SoftwareApplication","@id":"https://www.richeyweb.com/software/joomla/plugins/captcha-hashcash/#softwareapplication","name":"Captcha - HashCash","sameAs":["https://extensions.joomla.org/extension/access-a-security/site-security/hashcash/","https://en.wikipedia.org/wiki/Captcha_-_HashCash"]},"Proof of work",{"@type":"Thing","name":"Proof of work","sameAs":["https://en.wikipedia.org/wiki/Proof_of_work","https://www.wikidata.org/wiki/Q7249984","https://g.co/kg/m/05bdrw"]}],"mentions":["HTML form",{"@type":"Thing","name":"HTML form","sameAs":["https://en.wikipedia.org/wiki/HTML_form","https://www.wikidata.org/wiki/Q287539","https://g.co/kg/m/09bpb0"]},"Software bug",{"@type":"Thing","name":"Software bug","sameAs":["https://en.wikipedia.org/wiki/Software_bug","https://www.wikidata.org/wiki/Q179550","https://g.co/kg/m/0274l59"]},"Debugging",{"@type":"Thing","name":"Debugging","sameAs":["https://en.wikipedia.org/wiki/Debugging","https://www.wikidata.org/wiki/Q845566","https://g.co/kg/m/01vtxk"]}],"@id":"https://www.richeyweb.com/blog/development/how-a-bug-report-made-hashcash-smarter#article","isPartOf":{"@id":"https://www.richeyweb.com/blog/development/how-a-bug-report-made-hashcash-smarter#webpage"},"publisher":{"@id":"https://www.richeyweb.com/#organization"},"keywords":"bug report, HashCash, Captcha, submit button, button decoration logic, Joomla Contact Form component, newsletter subscription module, hash calculation, DOM context, third-party newsletter form, Joomla ecosystem, open collaboration, test case, generic decorator, custom decorator, multi-form environment, per-form scoping, loading state, UX, multi-step forms, conditional forms, design system requirements, reproduction steps, Joomla Extension Directory, 5-star reviews, self-hosted","articleSection":"Development","url":"https://www.richeyweb.com/blog/development/how-a-bug-report-made-hashcash-smarter"}]}
```
