aetherisyl
v0.2.0
Published
Aetherisyl browser SDK
Readme
Aetherisyl browser SDK
The official browser SDK for embedding an Aetherisyl verification widget.
Aetherisyl issues a short-lived, single-use token after the user completes the configured verification flow. Your application must send that token to its own backend, which then consumes it through the Aetherisyl API before allowing the protected operation.
Installation
pnpm add aetherisylThe package is a modern ESM package with bundled TypeScript declarations and no runtime dependencies.
Browser integration
Add a mount point to the page:
<div id="aetherisyl-verification"></div>Create one client for the environment and render a widget for each verification point:
import { createAetherisyl } from "aetherisyl";
const mountPoint = document.querySelector<HTMLElement>(
"#aetherisyl-verification",
);
if (!mountPoint) {
throw new Error("Aetherisyl mount point is missing.");
}
const client = createAetherisyl({
apiBaseUrl: "https://api.example.com",
widgetBaseUrl: "https://widget.example.com",
debug: false,
});
const widget = client.render(mountPoint, {
verificationPointId: "vp_...",
async onSuccess(token) {
// Send the token to your own backend with the protected business request.
const response = await fetch("/api/register", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ token }),
});
if (!response.ok) {
widget.reset();
}
},
onExpired() {
// The token can no longer be consumed. Ask the user to verify again.
widget.reset();
},
onError(error) {
console.error("Aetherisyl verification failed", error.code);
},
});onSuccess means that the browser challenge completed. It does not authorize
the business operation by itself. Never trust a token without consuming it from
your backend.
For an SPA, keep the returned widget handle and call destroy() when the
component unmounts:
widget.destroy();Server-side token consumption
Keep the verification-point secret on your backend. Never include an avs_...
secret in browser code or public configuration.
Your backend must consume the token before completing the protected operation:
POST /v1/verifications/consume
Authorization: Bearer avs_...
Content-Type: application/json
{
"token": "avt_...",
"verificationPointId": "vp_...",
"idempotencyKey": "your-stable-business-request-id"
}Proceed only when the API returns a successful HTTP response with
"success": true.
The idempotency key must be generated by your backend and remain stable across
retries of the same business operation. Invalid, expired, already-consumed, or
scope-mismatched tokens, as well as all other 4xx responses, must reject the
operation. Only network failures, timeouts, and 5xx responses may use a
deliberately configured fail-open policy.
API
createAetherisyl(options)
Creates a client and starts collecting privacy-reduced browser signals.
interface AetherisylOptions {
apiBaseUrl: string;
widgetBaseUrl: string;
debug?: boolean;
}Service URLs must be absolute HTTPS URLs. HTTP is accepted only for
localhost, 127.0.0.1, and [::1] during local development.
client.render(element, options)
Mounts an isolated widget iframe into element.
interface RenderOptions {
verificationPointId: string;
evaluationBatchToken?: string;
onSuccess(token: string): void;
onExpired?(): void;
onError?(error: AetherisylError): void;
}verificationPointId belongs to each widget instance, not to the global client.
Multiple independent widgets can be rendered on the same page.
evaluationBatchToken is reserved for Aetherisyl evaluation tooling. Normal
production integrations should omit it.
Widget handle
interface AetherisylWidget {
getToken(): string | null;
reset(): void;
destroy(): void;
}getToken()returns the current unexpired token, ornull.reset()discards the current token and starts a new verification session.destroy()closes the message channel and removes the widget iframe.
The SDK does not create hidden form fields or submit forms automatically.
Errors
onError receives an AetherisylError with a stable machine-readable code
and a human-readable message. Configuration errors are thrown synchronously
with the code invalid_configuration.
Content Security Policy
Allow the configured widget origin in frame-src. The SDK does not require
blob:, unsafe-eval, or a cross-origin Worker:
Content-Security-Policy: default-src 'self'; script-src 'self'; frame-src https://widget.example.com; connect-src 'self'All Aetherisyl network requests are made by the cross-origin widget. The host page SDK handles collection, mounting, and authenticated message passing.
Browser support
Aetherisyl targets the current and previous major versions of Chrome, Edge, Firefox, and Safari, including their corresponding iOS and Android browsers.
License
Apache-2.0
