{"id":13552060,"url":"https://github.com/librecaptcha/lc-core","last_synced_at":"2025-04-03T02:32:59.011Z","repository":{"id":34253354,"uuid":"115977971","full_name":"librecaptcha/lc-core","owner":"librecaptcha","description":"The LibreCaptcha framework, for self-hosted, privacy respecting CAPTCHAs","archived":false,"fork":false,"pushed_at":"2025-04-02T04:02:12.000Z","size":13093,"stargazers_count":417,"open_issues_count":21,"forks_count":20,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-02T04:31:38.034Z","etag":null,"topics":["captcha","captcha-framework","privacy"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/librecaptcha.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2018-01-02T05:27:00.000Z","updated_at":"2025-04-02T04:02:15.000Z","dependencies_parsed_at":"2023-11-19T03:24:44.855Z","dependency_job_id":"10a397e2-c23d-43b9-a536-5e7c2ba59c7d","html_url":"https://github.com/librecaptcha/lc-core","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librecaptcha%2Flc-core","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librecaptcha%2Flc-core/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librecaptcha%2Flc-core/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librecaptcha%2Flc-core/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/librecaptcha","download_url":"https://codeload.github.com/librecaptcha/lc-core/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246925560,"owners_count":20855903,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["captcha","captcha-framework","privacy"],"created_at":"2024-08-01T12:01:58.391Z","updated_at":"2025-04-03T02:32:55.663Z","avatar_url":"https://github.com/librecaptcha.png","language":"Scala","funding_links":[],"categories":["Scala"],"sub_categories":[],"readme":"# LibreCaptcha\nLibreCaptcha is a framework that allows developers to create their own [CAPTCHA](https://en.wikipedia.org/wiki/CAPTCHA)s.\nThe framework defines the API for a CAPTCHA generator and takes care of mundane details\nsuch as:\n* An HTTP interface for serving CAPTCHAs\n* Background workers to pre-compute CAPTCHAs and to store them in a database\n* Managing secrets for the CAPTCHAs (tokens, expected answers, etc)\n* Safe re-impressions of CAPTCHA images (by creating unique tokens for every impression)\n* Garbage collection of stale CAPTCHAs\n* Sandboxed plugin architecture (TBD)\n\nSome sample CAPTCHA generators are included in the distribution (see below). We will continue adding more samples to the list. For quick\ndeployments the samples themselves might be sufficient. Projects with more resources might want create their own CAPTCHAs\nand use the samples as inspiration. See the [CAPTCHA creation guide](https://github.com/librecaptcha/lc-core/wiki/Creating-your-own-CAPTCHA-provider).\n\n## Current Status\nThe framework is stable, but since it is our first public release, we recommend using it only on small to medium scale\nweb apps.\n\nThe sample CAPTCHAs are also just that, samples. They have not been tested against bots or CAPTCHA crackers yet.\n\n## Quick start with Java\n\n1. Download the `jar` file from the latest release\n2. Type `mkdir data/`.\n   (The data directory is used to store a config file that you can tweak, and for storing the Database)\n3. Type `java -jar LibreCaptcha.jar`\n4. Open [localhost:8888/demo/index.html](http://localhost:8888/demo/index.html) in browser\n\nWe recommend a Java 11+ runtime as that's what we compile the code with.\n\nAlternatively,\n1. Install [sbt](https://www.scala-sbt.org/)\n2. Clone this repository\n3. Type `sbt run` within the repository\n4. Open [localhost:8888/demo/index.html](http://localhost:8888/demo/index.html) in browser\n\n\n## Quick start with Docker\nUsing `docker-compose`:\n\n```\ngit clone https://github.com/librecaptcha/lc-core.git\ndocker-compose up\n```\n\nUsing `docker`:\n\n```\ndocker run -p=8888:8888 -v ./lcdata:/lc-core/data librecaptcha/lc-core:2.0\n```\n\nA default `config.json` is automatically created in the mounted volume.\n\nThe above commands should work with `podman` as well, if docker.io registry is pre-configured. Otherwise,\nyou can manually specify the repository like so:\n\n```\npodman run -p=8888:8888 -v ./lcdata:/lc-core/data docker.io/librecaptcha/lc-core:2.0\n```\n\n## Quick test\nOpen [localhost:8888/demo/index.html](http://localhost:8888/demo/index.html) in browser.\n\nAlternatively, on the command line, try:\n\n```\n\u003e $ curl -d '{\"media\":\"image/png\",\"level\":\"easy\",\"input_type\":\"text\",\"size\":\"350x100\"}' localhost:8888/v2/captcha\n{\"id\":\"3bf928ce-a1e7-4616-b34f-8252d777855d\"}\n\n\u003e $ curl \"localhost:8888/v1/media?id=3bf928ce-a1e7-4616-b34f-8252d777855d\" -o sample.png\n\n\u003e $ file sample.png\nsample.png: PNG image data, 350 x 100, 8-bit/color RGB, non-interlaced\n```\n\nThe API endpoints are described at the end of this file.\n\n## Configuration\nIf a `config.json` file is not present in the `data/` folder, the app creates one, and this can be modified\nto customize the app features, such as which CAPTCHAs are enabled and their difficulty settings.\n\nMore details can be found [in the wiki](https://github.com/librecaptcha/lc-core/wiki/Configuration)\n\n## Why LibreCaptcha?\n\n### Eliminate dependency on a third-party\nAn open-source CAPTCHA framework will allow anyone to host their own CAPTCHA service and thus avoid dependencies on\nthird-parties.\n\n### Respecting user privacy\nA self-hosted service prevents user information from leaking to other parties.\n\n### More variety of CAPTCHAs\nAin't it boring to identify photos of buses, store-fronts and traffic signals? With LibreCaptcha, developers can\ncreate CAPTCHAs that suit their application and audience, with matching themes and looks.\n\nAnd, the more the variety of CAPTCHAS, the harder it is for bots to crack CAPTCHAs.\n\n## Sample CAPTCHAs\nThese are included in this server.\n\n### ShadowText\n![ShadowText Sample](./samples/shadowText.png)\n\n\n### FilterCaptcha\n\n![FilterCaptcha Sample](./samples/FilterChallenge.png)\n\nAn image of a random string of alphabets is created. Then a series of image filters that add effects such as Smear, Diffuse, and Ripple are applied to the image to make it less readable.\n\n### RainDropsCaptcha\n![RaindDrops Sample](./samples/RainDropsCaptcha.gif)\n\n### PoppingCharactersCaptcha\n![PoppingCharacters Sample](./samples/popping.gif)\n\n### LabelCaptcha\nThis CAPTCHA provider takes in two sets of images. One with known labels, and the other unknown.\nThe created image has a pair of words one from each set.\nThe user is tested on the known word, and their answer to the unknown word is recorded.\nIf a sufficient number of users agree on their answer to the unknown word, it is transferred to the list of known words.\n\n(There is a known issue with this provider; see issue #68 )\n\n***\n\n## HTTP API\n\nThe service can be accessed using a simple HTTP API.\n\n### - `/v1/captcha`: `POST`\n- Parameters:\n    - `level`: `String` -\n      The difficulty level of a captcha\n        - easy\n        - medium\n        - hard\n    - `input_type`: `String` -\n      The type of input option for a captcha\n        - text\n        - (More to come)\n    - `media`: `String` -\n      The type of media of a captcha\n        - image/png\n        - image/gif\n        - (More to come)\n    - `size`: String -\n      The dimensions of a captcha. It needs to be a string in the format `\"widthxheight\"` in pixels, and will be matched\n      with the `allowedSizes` config setting. Example: `size: \"450x200\"` which requests an image of width 450 and height\n      200 pixels.\n\n- Returns:\n    - `id`: `String` - The uuid of the captcha generated\n\n\n### - `/v1/media`: `GET`\n- Parameters:\n    - `id`: `String` - The uuid of the captcha\n\n- Returns:\n    - `image`: `Array[Byte]` - The requested media as bytes\n\n\n### - `/v1/answer`: `POST`\n- Parameter:\n    - `id`: `String` - The uuid of the captcha that needs to be solved\n    - `answer`: `String` - The answer to the captcha that needs to be validated\n\n- Returns:\n    - `result`: `String` - The result after validation/checking of the answer\n        - True - If the answer is correct\n        - False - If the answer is incorrect\n        - Expired - If the time limit to solve the captcha exceeds\n\n\n## Example usage\n\nIn javascript:\n\n```js\nconst resp = await fetch(\"/v2/captcha\", {\n    method: 'POST',\n    body: JSON.stringify({level: \"easy\", media: \"image/png\", \"input_type\" : \"text\", size: \"350x100\"})\n})\n\nconst respJson = await resp.json();\n\nlet captchaId = null;\n\nif (resp.ok) {\n    // The CAPTCHA can be displayed using the data in respJson.\n    console.log(respJson);\n    // Store the id somewhere so that it can be used later for answer verification\n    captchaId = respJson.id;\n} else {\n    console.err(respJson);\n}\n\n\n// When user submits an answer it can be sent to the server for verification thusly:\nconst resp = await fetch(\"/v2/answer\", {\n    method: 'POST',\n    body: JSON.stringify({id: captchaId, answer: \"user input\"})\n});\nconst respJson = await resp.json();\nconsole.log(respJson.result);\n```\n\n***\n\n## Roadmap\n\nThings to do in the future:\n* Sandboxed plugin architecture\n* Audio CAPTCHA samples\n* Interactive CAPTCHA samples\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibrecaptcha%2Flc-core","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flibrecaptcha%2Flc-core","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibrecaptcha%2Flc-core/lists"}