322 lines
23 KiB
Plaintext
322 lines
23 KiB
Plaintext
component Captcha {
|
|
props {
|
|
provider = "self-hosted"
|
|
siteKey = ""
|
|
type = "alphanumeric"
|
|
action = "form-submit"
|
|
presentation = "visual"
|
|
difficulty = "normal"
|
|
disturbance = 50
|
|
imageStyle = "random"
|
|
allowedStyles = ""
|
|
excludedStyles = ""
|
|
randomizeStyle = false
|
|
locale = "en"
|
|
size = "normal"
|
|
color = "primary"
|
|
class = ""
|
|
|
|
id = ""
|
|
name = "wrn-captcha-response"
|
|
endpoint = "/__wrnexus/captcha/challenge"
|
|
verifyEndpoint = "/__wrnexus/captcha/verify"
|
|
responseField = "wrn-captcha-response"
|
|
|
|
label = "Security verification"
|
|
description = "Complete the challenge to continue."
|
|
helpText = ""
|
|
requiredMessage = "Please complete the security check."
|
|
incorrectMessage = "That answer was not correct. Try again."
|
|
expiredMessage = "This challenge expired. Load a new one."
|
|
networkMessage = "The verification service is unavailable. Try again."
|
|
|
|
autoLoad = true
|
|
autoVerify = false
|
|
showVerify = true
|
|
showRefresh = true
|
|
showAudio = true
|
|
showListen = true
|
|
showStatus = true
|
|
disabled = false
|
|
required = true
|
|
resetOnError = true
|
|
compact = false
|
|
layout = "vertical"
|
|
|
|
@event ready = function
|
|
@event challenge = function
|
|
@event input = function
|
|
@event verify = function
|
|
@event success = function
|
|
@event failure = function
|
|
@event expired = function
|
|
@event refresh = function
|
|
@event audioStart = function
|
|
@event audioEnd = function
|
|
@event error = function
|
|
}
|
|
|
|
view {
|
|
<section
|
|
{...attrs}
|
|
id='{id}'
|
|
data-wrn-captcha
|
|
data-wrnexus-runtime="captcha"
|
|
data-captcha-provider='{provider}'
|
|
data-captcha-site-key='{siteKey}'
|
|
data-captcha-type='{type}'
|
|
data-captcha-action='{action}'
|
|
data-captcha-presentation='{presentation}'
|
|
data-captcha-difficulty='{difficulty}'
|
|
data-captcha-disturbance='{disturbance}'
|
|
data-captcha-image-style='{imageStyle}'
|
|
data-captcha-allowed-styles='{allowedStyles}'
|
|
data-captcha-excluded-styles='{excludedStyles}'
|
|
data-captcha-randomize-style='{randomizeStyle}'
|
|
data-captcha-locale='{locale}'
|
|
data-captcha-size='{size}'
|
|
data-captcha-color='{color}'
|
|
data-captcha-endpoint='{endpoint}'
|
|
data-captcha-verify-endpoint='{verifyEndpoint}'
|
|
data-captcha-response-field='{responseField}'
|
|
data-captcha-name='{name}'
|
|
data-captcha-auto-load='{autoLoad}'
|
|
data-captcha-auto-verify='{autoVerify}'
|
|
data-captcha-show-verify='{showVerify}'
|
|
data-captcha-show-refresh='{showRefresh}'
|
|
data-captcha-show-audio='{showAudio}'
|
|
data-captcha-show-listen='{showListen}'
|
|
data-captcha-show-status='{showStatus}'
|
|
data-captcha-disabled='{disabled}'
|
|
data-captcha-required='{required}'
|
|
data-captcha-reset-on-error='{resetOnError}'
|
|
data-captcha-compact='{compact}'
|
|
data-captcha-layout='{layout}'
|
|
data-captcha-required-message='{requiredMessage}'
|
|
data-captcha-incorrect-message='{incorrectMessage}'
|
|
data-captcha-expired-message='{expiredMessage}'
|
|
data-captcha-network-message='{networkMessage}'
|
|
data-captcha-status="idle"
|
|
data-server-verification-required="true"
|
|
aria-busy="false"
|
|
class='group/captcha relative flex w-full max-w-lg flex-col gap-3 rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface)] p-4 text-[var(--wire-color-text)] shadow-[var(--wire-shadow-1)] [--captcha-accent:var(--wire-color-primary)] data-[captcha-color=secondary]:[--captcha-accent:var(--wire-color-secondary)] data-[captcha-color=success]:[--captcha-accent:var(--wire-color-success)] data-[captcha-color=warning]:[--captcha-accent:var(--wire-color-warning)] data-[captcha-color=danger]:[--captcha-accent:var(--wire-color-danger)] data-[captcha-color=info]:[--captcha-accent:var(--wire-color-info)] data-[captcha-size=compact]:max-w-xs data-[captcha-size=compact]:gap-1.5 data-[captcha-size=compact]:p-2 data-[captcha-size=big]:max-w-2xl data-[captcha-size=big]:gap-4 data-[captcha-size=big]:p-5 data-[captcha-compact=true]:max-w-xs data-[captcha-compact=true]:gap-1.5 data-[captcha-compact=true]:p-2 data-[captcha-layout=horizontal]:max-w-2xl data-[captcha-layout=horizontal]:grid data-[captcha-layout=horizontal]:grid-cols-1 sm:data-[captcha-layout=horizontal]:grid-cols-[minmax(0,1fr)_minmax(12rem,0.8fr)] sm:data-[captcha-layout=horizontal]:items-start data-[captcha-type=not-robot]:max-w-sm data-[captcha-type=not-robot]:gap-0 data-[captcha-type=not-robot]:p-0 data-[captcha-disabled=true]:pointer-events-none data-[captcha-disabled=true]:opacity-60 data-[captcha-status=verified]:border-[var(--wire-color-success)] data-[captcha-status=incorrect]:border-[var(--wire-color-danger)] data-[captcha-status=expired]:border-[var(--wire-color-danger)] data-[captcha-status=network-error]:border-[var(--wire-color-danger)] data-[captcha-status=provider-error]:border-[var(--wire-color-danger)] {class}'
|
|
>
|
|
<header data-captcha-header class='flex items-start justify-between gap-3 group-data-[captcha-size=compact]/captcha:gap-1.5 group-data-[captcha-layout=horizontal]/captcha:col-span-full group-data-[captcha-type=not-robot]/captcha:hidden'>
|
|
<div class='min-w-0'>
|
|
<div class='flex items-center gap-2 group-data-[captcha-size=compact]/captcha:gap-1.5'>
|
|
<span
|
|
aria-hidden="true"
|
|
class='icon-[lucide--shield-check] size-5 shrink-0 text-[var(--captcha-accent)] group-data-[captcha-size=compact]/captcha:size-4'
|
|
></span>
|
|
<h3 class='m-0 text-sm font-semibold leading-5 text-[var(--wire-color-text)] group-data-[captcha-size=compact]/captcha:text-[11px] group-data-[captcha-size=compact]/captcha:leading-4 group-data-[captcha-size=big]/captcha:text-base'>
|
|
{label}
|
|
</h3>
|
|
</div>
|
|
<p class='m-0 mt-1 text-xs leading-5 text-[var(--wire-color-muted)] group-data-[captcha-size=compact]/captcha:hidden group-data-[captcha-size=big]/captcha:text-sm'>
|
|
{description}
|
|
</p>
|
|
</div>
|
|
|
|
<span
|
|
data-captcha-verified-badge
|
|
hidden
|
|
class='shrink-0 items-center gap-1 rounded-full bg-[color-mix(in_srgb,var(--wire-color-success)_12%,transparent)] px-2 py-1 text-xs font-semibold text-[var(--wire-color-success)] group-data-[captcha-size=compact]/captcha:gap-0.5 group-data-[captcha-size=compact]/captcha:px-1.5 group-data-[captcha-size=compact]/captcha:py-0.5 group-data-[captcha-size=compact]/captcha:text-[10px]'
|
|
>
|
|
<span aria-hidden="true" class='icon-[lucide--circle-check] size-3.5 group-data-[captcha-size=compact]/captcha:size-3'></span>
|
|
Verified
|
|
</span>
|
|
</header>
|
|
|
|
<div
|
|
data-captcha-provider-mount
|
|
hidden
|
|
class='flex min-h-16 w-full items-center justify-center overflow-hidden rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-surface-2)] p-2 group-data-[captcha-size=compact]/captcha:min-h-12 group-data-[captcha-size=compact]/captcha:p-1.5'
|
|
></div>
|
|
|
|
<div
|
|
data-captcha-loading
|
|
hidden
|
|
class='flex min-h-28 items-center justify-center gap-2 rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-surface-2)] text-sm text-[var(--wire-color-muted)] group-data-[captcha-size=compact]/captcha:min-h-14 group-data-[captcha-size=compact]/captcha:gap-1.5 group-data-[captcha-size=compact]/captcha:text-[11px] group-data-[captcha-size=compact]/captcha:leading-4 group-data-[captcha-size=big]/captcha:min-h-36 group-data-[captcha-type=not-robot]/captcha:m-3 group-data-[captcha-type=not-robot]/captcha:min-h-16'
|
|
>
|
|
<span aria-hidden="true" class='icon-[lucide--loader-circle] size-5 animate-spin group-data-[captcha-size=compact]/captcha:size-4'></span>
|
|
Loading challenge…
|
|
</div>
|
|
|
|
<div data-captcha-challenge hidden class='flex min-w-0 flex-col gap-3 group-data-[captcha-size=compact]/captcha:gap-1.5 group-data-[captcha-size=big]/captcha:gap-4 group-data-[captcha-type=not-robot]/captcha:p-3'>
|
|
<div data-captcha-prompt-row class='flex items-start justify-between gap-3 group-data-[captcha-size=compact]/captcha:gap-2'>
|
|
<p data-captcha-prompt class='m-0 text-sm font-medium text-[var(--wire-color-text)] group-data-[captcha-size=compact]/captcha:text-[11px] group-data-[captcha-size=compact]/captcha:leading-4'></p>
|
|
<span data-captcha-countdown hidden class='shrink-0 text-xs tabular-nums text-[var(--wire-color-muted)] group-data-[captcha-size=compact]/captcha:text-[10px]'></span>
|
|
</div>
|
|
|
|
<div data-captcha-not-robot hidden class='w-full'>
|
|
<button
|
|
data-captcha-not-robot-button
|
|
type="button"
|
|
aria-pressed="false"
|
|
class='flex min-h-20 w-full items-center gap-3 rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-4 py-3 text-left transition-[border-color,box-shadow,background-color] hover:border-[var(--captcha-accent)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--captcha-accent)] disabled:cursor-wait disabled:opacity-80 group-data-[captcha-size=compact]/captcha:min-h-16 group-data-[captcha-size=compact]/captcha:gap-2.5 group-data-[captcha-size=compact]/captcha:px-3 group-data-[captcha-size=compact]/captcha:py-2.5 group-data-[captcha-size=big]/captcha:min-h-24 group-data-[captcha-size=big]/captcha:px-5 group-data-[captcha-size=big]/captcha:py-4'
|
|
>
|
|
<span
|
|
data-captcha-not-robot-control
|
|
aria-hidden="true"
|
|
class='inline-flex size-7 shrink-0 items-center justify-center rounded-md border-2 border-[var(--wire-color-border)] bg-[var(--wire-color-surface)] text-white transition-colors data-[verified=true]:border-[var(--wire-color-success)] data-[verified=true]:bg-[var(--wire-color-success)] group-data-[captcha-size=compact]/captcha:size-6 group-data-[captcha-size=big]/captcha:size-8'
|
|
>
|
|
<span data-captcha-not-robot-empty class='size-full'></span>
|
|
<span data-captcha-not-robot-spinner hidden class='icon-[lucide--loader-circle] size-4 animate-spin text-[var(--captcha-accent)]'></span>
|
|
<span data-captcha-not-robot-check hidden class='icon-[lucide--check] size-5'></span>
|
|
</span>
|
|
|
|
<span data-captcha-not-robot-label class='min-w-0 flex-1 text-sm font-semibold text-[var(--wire-color-text)] group-data-[captcha-size=compact]/captcha:text-[11px] group-data-[captcha-size=compact]/captcha:leading-4 group-data-[captcha-size=big]/captcha:text-base'>
|
|
I'm not a robot
|
|
</span>
|
|
|
|
<span class='flex shrink-0 flex-col items-center gap-0.5 text-[10px] leading-none text-[var(--wire-color-muted)]'>
|
|
<span aria-hidden="true" class='icon-[lucide--shield-check] size-6 text-[var(--captcha-accent)] group-data-[captcha-size=compact]/captcha:size-5 group-data-[captcha-size=big]/captcha:size-7'></span>
|
|
<span>WRNexus</span>
|
|
</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div
|
|
data-captcha-image-wrap
|
|
hidden
|
|
class='overflow-hidden rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-white'
|
|
>
|
|
<img
|
|
data-captcha-image
|
|
src=""
|
|
alt="CAPTCHA challenge"
|
|
draggable="false"
|
|
class='block h-auto min-h-20 w-full select-none object-contain group-data-[captcha-size=compact]/captcha:max-h-24 group-data-[captcha-size=compact]/captcha:min-h-12 group-data-[captcha-size=big]/captcha:min-h-28'
|
|
/>
|
|
</div>
|
|
|
|
<div
|
|
data-captcha-items
|
|
hidden
|
|
role="group"
|
|
class='grid grid-cols-2 gap-2 group-data-[captcha-size=compact]/captcha:gap-1 sm:grid-cols-3 group-data-[captcha-size=big]/captcha:gap-3'
|
|
></div>
|
|
|
|
<template data-captcha-item-template>
|
|
<button
|
|
type="button"
|
|
aria-pressed="false"
|
|
class='group relative overflow-hidden rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-white p-1 group-data-[captcha-size=compact]/captcha:p-0.5 transition-[border-color,box-shadow,transform] duration-[var(--wire-motion-fast)] hover:border-[var(--captcha-accent)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--captcha-accent)] aria-[pressed=true]:border-[var(--captcha-accent)] aria-[pressed=true]:ring-2 aria-[pressed=true]:ring-[var(--captcha-accent)]'
|
|
>
|
|
<img
|
|
data-captcha-item-image
|
|
src=""
|
|
alt=""
|
|
draggable="false"
|
|
class='aspect-[4/3] w-full select-none object-cover'
|
|
/>
|
|
<span
|
|
data-captcha-item-check
|
|
hidden
|
|
aria-hidden="true"
|
|
class='absolute right-1.5 top-1.5 inline-flex size-5 group-data-[captcha-size=compact]/captcha:right-1 group-data-[captcha-size=compact]/captcha:top-1 group-data-[captcha-size=compact]/captcha:size-4 items-center justify-center rounded-full bg-[var(--captcha-accent)] text-white shadow-sm'
|
|
>
|
|
<span class='icon-[lucide--check] size-3.5'></span>
|
|
</span>
|
|
</button>
|
|
</template>
|
|
|
|
<input
|
|
data-captcha-honeypot
|
|
type="text"
|
|
name=""
|
|
value=""
|
|
tabindex="-1"
|
|
autocomplete="off"
|
|
aria-hidden="true"
|
|
class='pointer-events-none absolute -left-[10000px] top-auto h-px w-px overflow-hidden opacity-0'
|
|
/>
|
|
</div>
|
|
|
|
<div data-captcha-response-panel class='flex min-w-0 flex-col gap-2 group-data-[captcha-layout=horizontal]/captcha:self-stretch'>
|
|
<label data-captcha-answer-wrap hidden class='flex min-w-0 flex-col gap-1.5 group-data-[captcha-size=compact]/captcha:gap-1'>
|
|
<span class='text-xs font-semibold text-[var(--wire-color-text)] group-data-[captcha-size=compact]/captcha:text-[10px]'>Your answer</span>
|
|
<input
|
|
data-captcha-answer
|
|
type="text"
|
|
inputmode="text"
|
|
autocomplete="off"
|
|
autocapitalize="characters"
|
|
spellcheck="false"
|
|
class='h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface)] px-3 text-base font-semibold tracking-[0.18em] text-[var(--wire-color-text)] outline-none transition-[border-color,box-shadow] placeholder:tracking-normal focus:border-[var(--captcha-accent)] focus:ring-2 focus:ring-[var(--captcha-accent)] disabled:cursor-not-allowed disabled:bg-[var(--wire-color-surface-2)] aria-[invalid=true]:border-[var(--wire-color-danger)] aria-[invalid=true]:ring-2 aria-[invalid=true]:ring-[var(--wire-color-danger)] group-data-[captcha-size=compact]/captcha:h-8 group-data-[captcha-size=compact]/captcha:px-2 group-data-[captcha-size=compact]/captcha:text-xs group-data-[captcha-size=compact]/captcha:tracking-[0.12em] group-data-[captcha-size=big]/captcha:h-12 group-data-[captcha-size=big]/captcha:px-4 group-data-[captcha-size=big]/captcha:text-lg'
|
|
placeholder="Enter the answer"
|
|
/>
|
|
</label>
|
|
|
|
<div data-captcha-success hidden role="status" aria-live="polite" class='flex items-start gap-1.5 text-xs leading-5 text-[var(--wire-color-success)] group-data-[captcha-size=compact]/captcha:gap-1 group-data-[captcha-size=compact]/captcha:text-[10px] group-data-[captcha-size=compact]/captcha:leading-4 group-data-[captcha-type=not-robot]/captcha:hidden'>
|
|
<span aria-hidden="true" class='icon-[lucide--circle-check] mt-0.5 size-3.5 shrink-0'></span>
|
|
<span data-captcha-success-message>Verification completed.</span>
|
|
</div>
|
|
|
|
<div data-captcha-error hidden role="alert" aria-live="polite" class='flex items-start gap-1.5 text-xs leading-5 text-[var(--wire-color-danger)] group-data-[captcha-size=compact]/captcha:gap-1 group-data-[captcha-size=compact]/captcha:text-[10px] group-data-[captcha-size=compact]/captcha:leading-4 group-data-[captcha-type=not-robot]/captcha:mx-3 group-data-[captcha-type=not-robot]/captcha:mb-3'>
|
|
<span aria-hidden="true" class='icon-[lucide--circle-alert] mt-0.5 size-3.5 shrink-0'></span>
|
|
<span data-captcha-error-message></span>
|
|
</div>
|
|
|
|
<p data-captcha-help class='m-0 text-xs leading-5 text-[var(--wire-color-muted)] group-data-[captcha-size=compact]/captcha:text-[10px] group-data-[captcha-size=compact]/captcha:leading-4 group-data-[captcha-type=not-robot]/captcha:hidden'>
|
|
{helpText}
|
|
</p>
|
|
|
|
<footer data-captcha-footer class='flex flex-wrap items-center justify-between gap-2 group-data-[captcha-size=compact]/captcha:flex-nowrap group-data-[captcha-size=compact]/captcha:gap-1 group-data-[captcha-type=not-robot]/captcha:hidden'>
|
|
<div class='flex flex-wrap items-center gap-1.5 group-data-[captcha-size=compact]/captcha:flex-nowrap group-data-[captcha-size=compact]/captcha:gap-0.5'>
|
|
<button
|
|
data-captcha-audio
|
|
hidden
|
|
type="button"
|
|
class='inline-flex h-9 items-center justify-center gap-1.5 rounded-[var(--wire-radius-sm)] px-2.5 text-xs group-data-[captcha-size=compact]/captcha:h-8 group-data-[captcha-size=compact]/captcha:gap-1 group-data-[captcha-size=compact]/captcha:px-1.5 group-data-[captcha-size=compact]/captcha:text-[10px] font-semibold text-[var(--wire-color-muted)] transition-colors hover:bg-[var(--wire-color-surface-2)] hover:text-[var(--captcha-accent)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--captcha-accent)] disabled:cursor-not-allowed disabled:opacity-50'
|
|
>
|
|
<span aria-hidden="true" class='icon-[lucide--volume-2] size-4 group-data-[captcha-size=compact]/captcha:size-3.5'></span>
|
|
Listen
|
|
</button>
|
|
|
|
<button
|
|
data-captcha-audio-alternative
|
|
hidden
|
|
type="button"
|
|
class='inline-flex h-9 items-center justify-center gap-1.5 rounded-[var(--wire-radius-sm)] px-2.5 text-xs group-data-[captcha-size=compact]/captcha:h-8 group-data-[captcha-size=compact]/captcha:gap-1 group-data-[captcha-size=compact]/captcha:px-1.5 group-data-[captcha-size=compact]/captcha:text-[10px] font-semibold text-[var(--wire-color-muted)] transition-colors hover:bg-[var(--wire-color-surface-2)] hover:text-[var(--captcha-accent)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--captcha-accent)] disabled:cursor-not-allowed disabled:opacity-50'
|
|
>
|
|
<span aria-hidden="true" class='icon-[lucide--ear] size-4 group-data-[captcha-size=compact]/captcha:size-3.5'></span>
|
|
Use audio
|
|
</button>
|
|
|
|
<button
|
|
data-captcha-refresh
|
|
type="button"
|
|
class='inline-flex h-9 items-center justify-center gap-1.5 rounded-[var(--wire-radius-sm)] px-2.5 text-xs group-data-[captcha-size=compact]/captcha:h-8 group-data-[captcha-size=compact]/captcha:gap-1 group-data-[captcha-size=compact]/captcha:px-1.5 group-data-[captcha-size=compact]/captcha:text-[10px] font-semibold text-[var(--wire-color-muted)] transition-colors hover:bg-[var(--wire-color-surface-2)] hover:text-[var(--captcha-accent)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--captcha-accent)] disabled:cursor-not-allowed disabled:opacity-50'
|
|
>
|
|
<span aria-hidden="true" class='icon-[lucide--refresh-cw] size-4 group-data-[captcha-size=compact]/captcha:size-3.5'></span>
|
|
New challenge
|
|
</button>
|
|
</div>
|
|
|
|
<button
|
|
data-captcha-verify
|
|
type="button"
|
|
class='inline-flex h-9 items-center justify-center gap-1.5 rounded-[var(--wire-radius-sm)] bg-[var(--captcha-accent)] px-3 text-xs group-data-[captcha-size=compact]/captcha:h-8 group-data-[captcha-size=compact]/captcha:gap-1 group-data-[captcha-size=compact]/captcha:px-2.5 group-data-[captcha-size=compact]/captcha:text-[10px] font-semibold text-white shadow-sm transition-[filter,transform] hover:brightness-95 active:translate-y-px focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--captcha-accent)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--wire-color-surface)] disabled:cursor-not-allowed disabled:opacity-50'
|
|
>
|
|
<span data-captcha-verify-icon aria-hidden="true" class='icon-[lucide--shield-check] size-4 group-data-[captcha-size=compact]/captcha:size-3.5'></span>
|
|
<span data-captcha-verify-spinner hidden aria-hidden="true" class='icon-[lucide--loader-circle] size-4 animate-spin group-data-[captcha-size=compact]/captcha:size-3.5'></span>
|
|
<span data-captcha-verify-label>Verify</span>
|
|
</button>
|
|
</footer>
|
|
|
|
<input
|
|
data-captcha-response
|
|
type="hidden"
|
|
name='{responseField}'
|
|
value=""
|
|
/>
|
|
|
|
<p data-captcha-credit class='m-0 text-[11px] leading-4 text-[var(--wire-color-muted)] group-data-[captcha-size=compact]/captcha:hidden group-data-[captcha-type=not-robot]/captcha:hidden'>
|
|
Protected by WRNexus CAPTCHA. Server-side verification is required.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
}
|
|
}
|