Skip to content

omnishield/altcha API reference

Floor
Provider · Omnishield
Version
1.x
Conformance suite
runs, no CI read
Verified for real
Verified for real
Licence
MIT
composer require omnishield/altcha:1.x-dev

Read from the package's own PHP files at the commit 667269062ed9: its namespaces, classes, interfaces and enums, their public constants, properties and methods with their PHPDoc, and the options its factories take. Nothing of it is run.

Omnishield\Altcha

  • AltchaGateway class

    An ALTCHA challenge issued, solved by the visitor's browser, checked here: its signature (the site's key), its expiry, the solution, the action it was issued for - and, since ALTCHA itself cannot tell a solution it saw before, that it was not posted already (the replay store).

    10 methods · 1 constant

  • AltchaGatewayFactory class

    ALTCHA: a proof of work the site issues and checks itself - the visitor's browser derives keys until one starts as the challenge asks, the site checks the one it found. Nobody else is involved: no third party, no cookie.

    13 options · 2 methods · 5 constants

Omnishield\Altcha

AltchaGateway class

final class AltchaGateway implements ChallengeIssuerInterface, LocalizableInterface AltchaGateway.php:27

An ALTCHA challenge issued, solved by the visitor's browser, checked here: its signature (the site's key), its expiry, the solution, the action it was issued for - and, since ALTCHA itself cannot tell a solution it saw before, that it was not posted already (the replay store).

The action is signed into the challenge's data with the time it was issued: {"action": "contact", "issued": 1791363600}.

const TEXTS = ['label', 'verifying', 'verified', 'verificationRequired', 'waitAlert', 'error', 'expired', 'footer', 'ariaLinkLabel', 'loading', 'reload', 'verify', 'cancel…

The texts the widget shows (altcha 3.3.0's i18n keys).

AltchaGateway::__construct()

public function __construct(string $hmacKey, readonly DeriveKeyInterface $algorithm, readonly ReplayStoreInterface $replays, readonly int $cost = 5000, readonly string $keyPrefix = '00', readonly int $expires = 600, readonly ?string $challengeUrl = null, readonly string $field = 'altcha', readonly ?string $script = AltchaGatewayFactory::SCRIPT, readonly ?string $integrity = AltchaGatewayFactory::INTEGRITY, readonly array $attributes = [], readonly array $configuration = [], ?string $language = null, array $strings = [])
$strings

the widget's texts, by name (TEXTS)

AltchaGateway::texts()

public function texts(): array

AltchaGateway::language()

public function language(): ?string

AltchaGateway::localized()

public function localized(string $language, array $strings = []): static

AltchaGateway::getName()

public function getName(): string

AltchaGateway::getTitle()

public function getTitle(): string

AltchaGateway::capabilities()

public function capabilities(): Capabilities

AltchaGateway::issue()

public function issue(?string $action = null): array

AltchaGateway::widget()

public function widget(?string $action = null): Widget

AltchaGateway::verify()

public function verify(Attempt $attempt): Verdict

AltchaGatewayFactory class

final class AltchaGatewayFactory extends GatewayFactory AltchaGatewayFactory.php:42

ALTCHA: a proof of work the site issues and checks itself - the visitor's browser derives keys until one starts as the challenge asks, the site checks the one it found. Nobody else is involved: no third party, no cookie.

options: hmac_key: '%env(ALTCHA_HMAC_KEY)%' # required: signs the challenges - long, random, secret algorithm: PBKDF2/SHA-256 # or PBKDF2/SHA-384, PBKDF2/SHA-512, SHA-256, SHA-384, SHA-512 cost: 5000 # the key derivation's iterations: the work of one try key_prefix: '00' # what the derived key must start with: each hex pair, 256 times the tries expires: 600 # seconds a challenge may be solved and posted in challenge_url: ~ # where the widget fetches a challenge (the bridge's route); none: inline in the page field: altcha # the posted field script: https://cdn.jsdelivr.net/npm/altcha@3.3.0/dist/main/altcha.min.js # in PHP alone; the Symfony bridge serves the package's own copy (SCRIPT_PATH) integrity: sha256-... # the script's Subresource Integrity, set for the default address attributes: { auto: onsubmit, display: standard, language: fr } # <altcha-widget>'s own attributes configuration: { hideFooter: true } # its configuration attribute (JSON) language: fr # the widget's language (its language attribute) strings: { label: "Je ne suis pas un robot" } # its texts, by name (AltchaGateway::TEXTS); they win over the bridge's translations

Spent solutions are remembered in the ReplayStoreInterface given to the factory - the application's, shared by every request. Without one, this process's memory: right in a test or a worker, not behind PHP-FPM.

Options

OptionDefault
algorithm'PBKDF2/SHA-256'
cost5000
key_prefix'00'
expires600
challenge_urlnull
field'altcha'
scriptself::SCRIPT
integritynull
attributes[]
configuration[]
languagenull
strings[]
hmac_keyrequired
const SCRIPT = 'https://cdn.jsdelivr.net/npm/altcha@3.3.0/dist/main/altcha.min.js'

The widget, as published on npm (altcha 3.3.0, MIT) and served by jsDelivr.

const INTEGRITY = 'sha256-/CeoPc2Yo9is9tcPvkZD3L7lEqv7mIhu3Y7QRTUK2Ck='
const SCRIPT_VERSION = '3.3.0'
const SCRIPT_FILE = __DIR__ . '/public/altcha.min.js'

The same file, shipped in this package (public/, MIT): for the site to serve it itself.

const SCRIPT_PATH = '/omnishield/altcha/' . self::SCRIPT_VERSION . '/altcha.min.js'

Where omnishield's Symfony bridge serves that file, and the address its gateways use by default.

AltchaGatewayFactory::__construct()

public function __construct(readonly ?ReplayStoreInterface $replays = null)

AltchaGatewayFactory::algorithm()

public static function algorithm(string $name): DeriveKeyInterface