{"id":14990171,"url":"https://github.com/altcha-org/altcha","last_synced_at":"2025-05-14T09:09:10.272Z","repository":{"id":207907591,"uuid":"720381676","full_name":"altcha-org/altcha","owner":"altcha-org","description":"GDPR, WCAG 2.2 AA, and EAA compliant, self-hosted CAPTCHA alternative with PoW mechanism and advanced anti-spam filter.","archived":false,"fork":false,"pushed_at":"2025-04-28T10:07:18.000Z","size":1759,"stargazers_count":815,"open_issues_count":3,"forks_count":34,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-05-03T12:36:32.174Z","etag":null,"topics":["antispam","captcha","captcha-alternative","ddos-mitigation","ddos-protection","hcaptcha","proof-of-work","recaptcha","spam-api","spam-detection","spam-filtering","spam-prevention","spam-protection","svelte","wcag","webcomponent"],"latest_commit_sha":null,"homepage":"https://altcha.org","language":"JavaScript","has_issues":true,"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/altcha-org.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-11-18T10:05:44.000Z","updated_at":"2025-05-02T16:18:06.000Z","dependencies_parsed_at":"2023-12-05T05:25:16.597Z","dependency_job_id":"dca6d7ea-31d0-47ea-bd90-84e5066cc67d","html_url":"https://github.com/altcha-org/altcha","commit_stats":{"total_commits":75,"total_committers":3,"mean_commits":25.0,"dds":"0.040000000000000036","last_synced_commit":"dc10c7262e102eda85e018ea63796d7b1c9c351e"},"previous_names":["altcha-org/altcha","altcha-org/altchajs"],"tags_count":50,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altcha-org%2Faltcha","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altcha-org%2Faltcha/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altcha-org%2Faltcha/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altcha-org%2Faltcha/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/altcha-org","download_url":"https://codeload.github.com/altcha-org/altcha/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253890452,"owners_count":21979833,"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":["antispam","captcha","captcha-alternative","ddos-mitigation","ddos-protection","hcaptcha","proof-of-work","recaptcha","spam-api","spam-detection","spam-filtering","spam-prevention","spam-protection","svelte","wcag","webcomponent"],"created_at":"2024-09-24T14:19:39.157Z","updated_at":"2025-05-14T09:09:05.256Z","avatar_url":"https://github.com/altcha-org.png","language":"JavaScript","readme":"# ALTCHA\n\nALTCHA leverages a proof-of-work mechanism to safeguard your website, APIs, and online services from spam and abuse. Unlike traditional solutions, ALTCHA is self-hosted, does not rely on cookies or fingerprinting, and ensures complete user privacy. It is fully compliant with [GDPR](https://altcha.org/docs/gdpr/), [WCAG 2.2 AA-level](https://altcha.org/docs/wcag/), and the [European Accessibility Act](https://altcha.org/docs/european-accessibility-act-2025/).\n\nFor more details, visit [ALTCHA](https://altcha.org).\n\n## Features\n\n- **Frictionless Experience**: Utilizes proof-of-work (PoW) instead of visual puzzles, ensuring a seamless user experience.\n- **Cookie-Free Design**: Built to be GDPR-compliant by default, with no cookies or tracking.\n- **Fully Accessible**: Meets WCAG 2.2 AA-level standards and complies with the European Accessibility Act (EAA).\n- **Lightweight**: Minimal bundle size for fast page loads and optimal performance.\n- **Self-Hosted**: Operates independently without depending on third-party services.\n- **SaaS Option Available**: Get started quickly with the SaaS API at [altcha.org](https://altcha.org/).\n\n## Examples\n\n- [React](https://github.com/altcha-org/altcha-starter-react-ts)\n- [Vue](https://github.com/altcha-org/altcha-starter-vue-ts)\n- [Svelte](https://github.com/altcha-org/altcha-starter-svelte-ts)\n- [Solid](https://github.com/altcha-org/altcha-starter-solid-ts)\n- [Lit](https://github.com/altcha-org/altcha-starter-lit-ts)\n- [Angular](https://github.com/altcha-org/altcha-starter-angular)\n\n## Server Integrations\n\n- [TypeScript](https://github.com/altcha-org/altcha-lib)\n- [PHP](https://github.com/altcha-org/altcha-lib-php)\n- [Go](https://github.com/altcha-org/altcha-lib-go)\n- [Python](https://github.com/altcha-org/altcha-lib-py)\n- [Java](https://github.com/altcha-org/altcha-lib-java)\n- [Ruby](https://github.com/altcha-org/altcha-lib-rb)\n- [Elixir](https://github.com/altcha-org/altcha-lib-ex)\n\n## CMS\n\n- [WordPress plugin](https://github.com/altcha-org/wordpress-plugin)\n- [Other libraries and plugins](https://altcha.org/docs/integrations/)\n\n## More anti-spam solutions\n\n- [Spam Filter](https://altcha.org/anti-spam) - stop sophisticated attacks and human-generated spam by classifying data.\n\n## Usage\n\nALTCHA widget is distributed as a \"Web Component\" and [supports all modern browsers](https://developer.mozilla.org/en-US/docs/Web/API/Web_components#browser_compatibility).\n\n### 1. Install ALTCHA\n\n```sh\nnpm install altcha\n```\n\nimport `altcha` in your main file:\n\n```js\nimport 'altcha';\n```\n\nor insert `\u003cscript\u003e` tag to your website:\n\n```html\n\u003cscript async defer src=\"/altcha.js\" type=\"module\"\u003e\u003c/script\u003e\n```\n\nCDN: https://cdn.jsdelivr.net/gh/altcha-org/altcha@main/dist/altcha.min.js\n\n### 2. Use `\u003caltcha-widget\u003e` tag in your forms\n\n```html\n\u003cform\u003e\n  \u003caltcha-widget\n    challengeurl=\"https://...\"\n  \u003e\u003c/altcha-widget\u003e  \n\u003c/form\u003e\n```\n\nSee the [configuration](#configuration) below or visit the [website integration documentation](https://altcha.org/docs/website-integration).\n\n### 3. Integrate ALTCHA with your server\n\nSee [server documentation](https://altcha.org/docs/server-integration) for more details.\n\n## Bundle Size\n\nALTCHA's default bundle is lightweight, combining all assets, including CSS and the JavaScript Web Worker, into a single file. When GZIPped, it totals only 17 kB, making ALTCHA’s widget 94% smaller than reCAPTCHA.\n\n|Distribution|Size (GZIPped)|\n|---|---|\n|ALTCHA (v1.x)|17 kB|\n|hCaptcha|48+ kB|\n|reCAPTCHA|270+ kB|\n\n## Content Security Policy (CSP)\n\nThe default distribution bundle of the WebComponent includes styles and the worker in a single file. This might cause issues with strict CSP rules. If you require strict CSP compliance, consider using the scripts located in the `/dist_external` directory. For more details, please refer to the [documentation](https://altcha.org/docs/website-integration).\n\n## Configuration\n\nRequired options (at least one is required):\n\n- **challengeurl**: URL of your server to fetch the challenge from. Refer to [server integration](https://altcha.org/docs/server-integration).\n- **challengejson**: JSON-encoded challenge data. If avoiding an HTTP request to `challengeurl`, provide the data here.\n\nAdditional options:\n\n- **auto**: Automatically verify without user interaction (possible values: `off`, `onfocus`, `onload`, `onsubmit`).\n- **customfetch**: A custom `fetch` function for retrieving the challenge.  \n  Accepts `url: string` and `init: RequestInit` as arguments and must return a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response).  \n- **delay**: Artificial delay in milliseconds before verification (defaults to 0).\n- **expire**: Challenge expiration duration in milliseconds.\n- **floating**: Enable floating UI (possible values: `auto`, `top`, `bottom`).\n- **floatinganchor**: CSS selector of the \"anchor\" to which the floating UI will be attached (defaults to the `button[type=\"submit\"]` in the related form).\n- **floatingoffset**: Y offset from the anchor element for the floating UI in pixels (defaults to `12`).\n- **floatingpersist**: Whether to \"persist\" (keep visible) the floating widget after verification (possible values: `true` | `false` | `focus`; defaults to `false`, meaning the widget will hide).\n- **hidefooter**: Hide the footer (ALTCHA link).\n- **hidelogo**: Hide the ALTCHA logo.\n- **id**: The checkbox `id` attribute. Useful for multiple instances of the widget on the same page.\n- **maxnumber**: Max number to iterate to (defaults to 1,000,000).\n- **name**: Name of the hidden field containing the payload (defaults to \"altcha\").\n- **strings**: JSON-encoded translation strings. Refer to [customization](https://altcha.org/docs/widget-customization).\n- **refetchonexpire**: Automatically re-fetch and re-validate when the challenge expires (defaults to true).\n- **workers**: Number of workers to utilize for PoW (defaults to `navigator.hardwareConcurrency || 8`, max value `16`).\n- **workerurl**: URL of the Worker script (defaults to `./worker.js`, only works with `external` build).\n\nSpam Filter-related options:\n\n- **blockspam**: Only used with the `spamfilter` option. If enabled, it will block form submission and fail verification if the Spam Filter returns a negative classification. This prevents form submission.\n- **spamfilter**: Enable [Spam Filter](#spam-filter).\n- **verifyurl**: URL for server-side verification requests. This option is automatically configured when the `spamfilter` option is used. Override this setting only if using a custom server implementation.\n\nData Obfuscation options:\n\n- **obfuscated**: The [obfuscated data](https://altcha.org/docs/obfuscation) provided as a base64-encoded string (requires `altcha/obfuscation` plugin). Use only without `challengeurl`/`challengejson`.\n\nDevelopment / Testing options:\n\n- **debug**: Print log messages in the console.\n- **mockerror**: Causes verification to always fail with a \"mock\" error.\n- **test**: Generates a \"mock\" challenge within the widget, bypassing the request to `challengeurl`.\n\n## Plugins\n\nVersion 0.9.x introduced _plugins_ that can be enabled by importing individual plugin scripts:\n\n```js\nimport 'altcha/obfuscation';\nimport 'altcha';\n```\n\nIt is recommended to import plugins _before_ the main `altcha` package to ensure proper registration before any widget instance is created.\n\nAvailable plugins built-in to the `altcha` package:\n\n- `altcha/analytics`: Enable analytics with [ALTCHA Forms](https://altcha.org/forms/). See [HTML submissions documentation](https://altcha.org/docs/forms/features/html-submissions).\n- `altcha/obfuscation`: Enable [obfuscation](https://altcha.org/docs/obfuscation) for sensitive data such as email addresses or phone numbers.\n- `altcha/upload`: Enable file upload from `type=file` fields to [ALTCHA Forms](https://altcha.org/forms/). See [HTML submissions documentation](https://altcha.org/docs/forms/features/html-submissions).\n\nTo enable specific plugins for a particular instance of the widget, use the `plugins` attribute in the widget tag. List the names of the plugins you want to enable, separated by commas, such as `plugins=\"analytics,obfuscation\"`. Plugins still need to be imported as described above. The `plugins` attribute only specifies which plugins should be active for that instance, even if other plugins are already imported.\n\n## Programmatic Configuration\n\nTo configure the widget programmatically, use the `configure()` method:\n\n```ts\ndocument.querySelector('#altcha').configure({\n  challenge: {\n    algorithm: 'SHA-256',\n    challenge: '...',\n    salt: '...',\n    signature: '...',\n  },\n  strings: {\n    label: 'Verify',\n  },\n});\n```\n\nAvailable configuration options: \n\n```ts\nexport interface Configure {\n  auto?: 'off' | 'onfocus' | 'onload' | 'onsubmit';\n  challenge?: {\n    algorithm: string;\n    challenge: string;\n    maxnumber?: number;\n    salt: string;\n    signature: string;\n  };\n  challengeurl?: string;\n  customfetch?: string | ((url: string, init?: RequestInit) =\u003e Promise\u003cResponse\u003e);\n  debug?: boolean;\n  delay?: number;\n  expire?: number;\n  floating?: 'auto' | 'top' | 'bottom';\n  floatinganchor?: string;\n  floatingoffset?: number;\n  floatingpersist?: boolean | 'focus';\n  hidefooter?: boolean;\n  hidelogo?: boolean;\n  maxnumber?: number;\n  mockerror?: boolean;\n  name?: string;\n  obfuscated?: string;\n  refetchonexpire?: boolean;\n  spamfilter?: boolean | 'ipAddress' | SpamFilter;\n  strings?: {\n    error: string;\n    expired: string;\n    footer: string;\n    label: string;\n    verified: string;\n    verifying: string;\n    waitAlert: string;\n  }\n  test?: boolean | number | 'delay';\n  verifyurl?: string;\n  workers?: number;\n  workerurl?: string;\n}\n```\n\n## Custom `fetch` Function  \n\nThe widget does not send cookies (i.e., it does not use `credentials: 'include'`) when requesting the challenge from the server. To modify this behavior or add custom request headers, use the `customfetch` configuration option. This option lets you define a custom request function.  \n\nThe custom function must return a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) object.  \n\n### Sending Cookies  \n\nTo include cookies in the request, use `credentials: 'include'`:  \n\n```ts\nfunction altchaCustomFetch(url: string, init: RequestInit) {\n  return fetch(url, {\n    ...init,\n    credentials: 'include', // Include cookies with the request\n  });\n}\n```  \n\nFor more details on possible request options, refer to the [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) documentation.  \n\n### Using `customfetch`  \n\nThe `customfetch` option can accept either:  \n- A `string` (the name of a globally accessible function defined in the global context, such as `window`), or  \n- A function itself.  \n\n### Example Usage  \n\n```html\n\u003caltcha-widget\n  challengeurl=\"https://example.com/challenge\"\n  customfetch=\"altchaCustomFetch\"\n\u003e\u003c/altcha-widget\u003e\n```  \n\n## Events\n\n- **load** - Triggers when the widget loads. The exported methods become available after this event.\n- **serververification** - Triggers upon a server verification (only in conjunction with `spamfilter`).\n- **statechange** - Triggers whenever an internal `state` changes.\n- **verified** - Triggers when the challenge is verified.\n\n```ts\nenum State {\n  ERROR = 'error',\n  VERIFIED = 'verified',\n  VERIFYING = 'verifying',\n  UNVERIFIED = 'unverified',\n  EXPIRED = 'expired',\n};\n```\n\nUsing events:\n\n```js\ndocument.querySelector('#altcha').addEventListener('statechange', (ev) =\u003e {\n  // See enum State above\n  console.log('state:', ev.detail.state);\n});\n```\n\n\u003e [!IMPORTANT]  \n\u003e Both programmatic configuration and event listeners have to called/attached after the ALTCHA script loads, such as within `window.addEventListener('load', ...)`.\n\n## Spam Filter\n\nThe widget integrates with ALTCHA's [Anti-Spam solution](https://altcha.org/anti-spam) to allow checking submitted form data for potential spam.\n\nThe Spam Filter API analyzes various signals in the submitted data to determine if it exhibits characteristics of spam. This non-invasive filtering helps reduce spam submissions without frustrating legitimate users.\n\n### Spam Filter Configuration\n\nThe Spam Filter can be enabled with default configuration by setting the `spamfilter` option to `true`, or `ipAddress` to verify only the IP address and the time zone, or it can be customized using the following configuration schema:\n\n```ts\ninterface SpamFilter {\n  blockedCountries?: string[];\n  classifier?: string;\n  disableRules?: string[];\n  email?: string | false;\n  expectedCountries?: string[];\n  expectedLanguages?: string[];\n  fields?: string[] | false;\n  ipAddress?: string | false;\n  text?: string | string[];\n  timeZone?: string | false;\n}\n```\n\nSpamFilter configuration options:\n\n- **blockedCountries** - An array of country codes (ISO 3166 alpha-2) that you want to block.\n- **classifier** - Enforce a specific classifier.\n- **disableRules** - An array of rules to disable.\n- **email** - The name of the input field for the user's email. Disable email checking with `false`.\n- **expectedCountries** - An array of expected countries as 2-letter codes (ISO 3166-1 alpha-2).\n- **expectedLanguages** - An array of expected languages as 2-letter codes (ISO 639 alpha-2).\n- **fields** - An array of input names to send to the spam filter.\n- **ipAddress** - The user's IP is detected automatically but can be overridden or disabled with `false`.\n- **text** - The text to classify. An array of strings can also be submitted.\n- **timeZone** - The user's timezone is detected automatically but can be overridden or disabled with `false`.\n\nTo include the email field into `fields` (for easier server-side verification), configure the list of input names using the `spamfilter.fields: string[]` option.\n\n### Exclude Inputs from Spam Checking\n\nBy default, all text inputs and textareas within the parent form are spam-checked. To exclude a specific input, add the `data-no-spamfilter` attribute. Alternatively, explicitly list the checked fields using the `fields` config option.\n\n## Contributing\nSee [Contributing Guide](https://github.com/altcha-org/altcha/blob/main/CONTRIBUTING.md) and please follow our [Code of Conduct](https://github.com/altcha-org/altcha/blob/main/CODE_OF_CONDUCT.md).\n\n## Sponsorship  \n\nThis project is sponsored by [BAUSW.com - Digital Construction Site Diary](https://bausw.com/digital-construction-diary/), promoting transparency and trust in construction projects with real-time documentation.\n\n## License\n\nMIT\n\n","funding_links":[],"categories":["Third Party Components","JavaScript"],"sub_categories":["Captcha"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faltcha-org%2Faltcha","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faltcha-org%2Faltcha","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faltcha-org%2Faltcha/lists"}