{"id":27007435,"url":"https://github.com/hackermondev/lapti-pow-captcha","last_synced_at":"2026-01-19T03:07:35.805Z","repository":{"id":106078014,"uuid":"519373518","full_name":"hackermondev/lapti-pow-captcha","owner":"hackermondev","description":"Proof-of-Work captcha without external service calls","archived":false,"fork":false,"pushed_at":"2022-06-30T10:11:54.000Z","size":396,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-04T08:48:49.918Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hackermondev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-07-29T23:31:04.000Z","updated_at":"2024-02-12T19:33:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"c5b946f7-4418-4c3f-b427-4955fd4a05ad","html_url":"https://github.com/hackermondev/lapti-pow-captcha","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hackermondev/lapti-pow-captcha","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackermondev%2Flapti-pow-captcha","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackermondev%2Flapti-pow-captcha/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackermondev%2Flapti-pow-captcha/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackermondev%2Flapti-pow-captcha/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hackermondev","download_url":"https://codeload.github.com/hackermondev/lapti-pow-captcha/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackermondev%2Flapti-pow-captcha/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28559382,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T00:46:33.223Z","status":"online","status_checked_at":"2026-01-19T02:00:08.049Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-04-04T08:46:49.441Z","updated_at":"2026-01-19T03:07:35.800Z","avatar_url":"https://github.com/hackermondev.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Lapti Proof-of-Work Captcha [![npm version](https://badge.fury.io/js/lapti-pow-captcha.svg)](https://www.npmjs.com/package/lapti-pow-captcha)\n\nProtect heavy API methods with the force of Proof-of-Work algorithms hosted locally.\n\n## Idea\n\nIf there are some methods in the API which take much time to serve, you may want to guard them against DDoS attacks. A way of doing that is described below.\n\nThe server keeps some secret data `SECRET` which is unknown to anyone. The client sends a bit of arbitrary data `data` to the API method `/handshake/{data}`. In response to the call the server returns a token `token` which is `SHA3(data + SECRET)`, and also a number `complexity` which sets the complexity level.\n\nThe client then takes `token` and tries to find such a value `nonce` that the first n characters of `SHA3(token + nonce)` are `0` characters, where n equals `complexity`.\n\nWhen the needed `nonce` is found the client sends a request to the protected API method and attach two values to it: the initial `data` and the found `nonce`.\n\nThe server then calculates the `token` from `data` and `SECRET` one more time (or gets it from a storage of some kind) and checks if `SHA3(token + nonce)` really matches the given `complexity`. If it does indeed, the protected method can be called.\n\n## Alternatives\n\nYou can freely modify the captcha so its `handshake` method does not require any data and a session is created for every request with `token` entries stored somewhere in a database bound each to a correlating session. After that, all you will need to do is to check the validity of `SHA3(token, nonce)` against the given `complexity`.\n\n## Usage\n\nThere are two principal ways to use this captcha.\n\nThe first one is to initialize it with the `container` field and optional `onComplete` callback:\n\n```\nLaptiCaptcha.create({\n    apiUrl: 'https://api.root.url',\n    data: 'data-to-be-passed-in-handshake',\n    container: 'containerId',\n    onComplete: function (data, proof) {\n        fetch(API_ROOT + '/action/' + dataOne + '/' + proof).then(function (res) {\n            res.json().then(function (data) {\n                console.log(data);\n            });\n        });\n    }\n});\n```\n\nThe second one is to create an instance of the captcha and interact with it through the API:\n\n```\nvar captcha = LaptiCaptcha.create({\n    apiUrl: 'https://api.root.url',\n    data: 'data-to-be-passed-in-handshake'\n});\n\n// You can run it from wherever you want\nsecond.run().then(function (proof) {\n    console.log(proof);\n    fetch('https://api.root.url/action/' + captcha.data + '/' + proof).then(function (res) {\n        res.json().then(function (data) {\n            console.log(data);\n        });\n    });\n});\n```\n\n## Test setup\n\nStart the server file with Node JS and run Gulp:\n\n```\nnode server/main.js \u0026\ngulp\n```\n\nWhen finished, open [http://localhost:8080](http://localhost:8080).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhackermondev%2Flapti-pow-captcha","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhackermondev%2Flapti-pow-captcha","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhackermondev%2Flapti-pow-captcha/lists"}