npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. > telegram-task-earning@0.20.1 check > node scripts/run-quality-checks.js [phase-20-check] Running lint npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. > telegram-task-earning@0.20.1 lint > eslint . --max-warnings=0 [phase-20-check] Running format:check npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. > telegram-task-earning@0.20.1 format:check > prettier . --check Checking formatting... All matched files use Prettier code style! [phase-20-check] Running test npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. > telegram-task-earning@0.20.1 test > node --test ✔ Admin auth routes are composed behind validation, session, and CSRF gates (89.945914ms) ✔ configured Admin IP policy rejects disallowed networks before authentication (14.926185ms) ✔ Express foundation serves service, liveness, readiness, and safe 404 responses (120.384571ms) ✔ readiness returns 503 without disclosing database errors (26.992487ms) ✔ web bootstrap verifies MySQL, configures HTTP, becomes ready, and shuts down (61.183288ms) ✔ web bootstrap fails closed and releases resources for an unsupported database (4.053274ms) ✔ web bootstrap connects Redis for distributed protection and closes it on shutdown (27.032281ms) ✔ Spaceship web bootstrap selects the database limiter without starting Redis (28.560634ms) ✔ migration dry run validates all files without secrets or a live database (314.346031ms) ✔ seed and rollback dry runs are offline and deterministic (677.885507ms) ✔ unknown database command options fail closed (281.659393ms) ✔ example verification succeeds and redacts sensitive placeholders (343.970326ms) ✔ using the example as a runtime environment fails closed without leaking secrets (276.936893ms) ✔ runtime verification succeeds from deployment environment values (260.285048ms) ✔ wallet and history endpoints require a verified Telegram session (114.777022ms) ✔ wallet API returns string amounts and cursor pagination metadata (23.198406ms) ✔ wallet history rejects excessive limits and unknown query input (23.902355ms) ✔ task APIs require a server-verified Telegram user session (151.393445ms) ✔ task start requires CSRF, an empty body, and an Idempotency-Key (62.92433ms) ✔ claim validates ownership-shaped IDs and returns server reward data (32.261363ms) ✔ Admin task lifecycle routes enforce their exact permission (32.605853ms) ✔ public referral endpoints require a verified Telegram session (127.397711ms) ✔ Admin referral routes enforce distinct view, review, and settings permissions (61.954777ms) ✔ Admin review requires CSRF, review permission, reason, and resource version (24.587243ms) ✔ public Mystery Box endpoints require a verified Telegram session (114.77351ms) ✔ free claim requires CSRF, an empty body, and an Idempotency-Key (91.553849ms) ✔ Admin reads, claims, management, and lifecycle use distinct permissions (100.970066ms) ✔ public method, quote, and withdrawal history endpoints require verified Telegram identity (155.56951ms) ✔ quote and create use strict schemas, CSRF, and a required idempotency key (85.291678ms) ✔ Admin withdrawal reads and decrypted destination details use distinct permissions (14.552402ms) ✔ Admin review checks the submitted decision permission and payout confirmation is separate (22.431705ms) ✔ content endpoints require verified Telegram identity (91.417222ms) ✔ announcement read evidence requires CSRF and an empty strict body (49.798768ms) ✔ Admin banner reading, editing, and publishing use separate permissions (29.670876ms) ✔ Admin settings and feature flags enforce exact permissions and strict versions (32.367026ms) ✔ Notification inbox requires Telegram identity and read mutation requires CSRF (122.518513ms) ✔ Template reads and broadcast approval require their exact Admin permissions (38.299975ms) ✔ Reminder creation validates timezone-shaped schedule inputs before service execution (22.597637ms) ✔ earning history and leaderboard require a Telegram-authenticated user (217.626364ms) ✔ financial analytics require their exact high-sensitivity permission (71.646735ms) ✔ report range and leaderboard pagination are rejected before service execution (46.371803ms) ✔ Mini App shell renders EJS with a narrowly scoped official Telegram SDK CSP (98.658245ms) ✔ Mini App module assets revalidate and private paths remain inaccessible (43.219427ms) ✔ Maintenance allows only the public shell/assets while protected API stays closed (15.800979ms) ✔ Banned sessions can load the shell for an error screen but cannot access API data (11.6486ms) ✔ admin shell and assets are public but contain no account data and deny framing (168.865667ms) ✔ every operational route fails closed without its exact read permission (111.198934ms) ✔ authorized reads validate pagination, return string amounts, and record audit context (36.533442ms) ✔ catalog exposes only allowed screens and hides payment account details from reviewers (16.907408ms) ✔ maintenance preserves shell access and follows configured admin access policy (32.609519ms) ✔ upload size exception requires permission and CSRF and does not enlarge other routes (76.299631ms) ✔ all Phase 19 operations reject anonymous callers even with a valid anonymous CSRF token (271.427764ms) ✔ all Phase 19 operations enforce their exact permissions before invoking the service (73.365081ms) ✔ every authorized operation routes a strict validated body and trusted actor context (68.923536ms) ✔ CSRF, malformed money, stale-body fields and oversized input are rejected without a write (37.008562ms) ✔ public enrollment keeps CSRF protection and strict one-time-token validation (16.39831ms) ✔ Phase 9 user endpoints require a server-attached session (147.508846ms) ✔ profile mutation requires CSRF and rejects unapproved fields (67.389426ms) ✔ admin user inspection requires both admin authentication and users.view (23.615511ms) ✔ maintenance keeps bootstrap, authenticated admins, and configured webhook reachable (29.364644ms) ✔ Telegram auth and webhook routes are composed behind their security gates (157.529233ms) ✔ Admin authentication and RBAC trust only server-attached identity and permissions (1.767545ms) ✔ Admin IP allowlist supports exact addresses and bounded CIDR ranges (7.436576ms) ✔ database schema enforces the current security and money contract (66.865635ms) ✔ unexpected async errors disclose neither stack traces nor embedded Telegram tokens (110.779043ms) ✔ invalid incoming request IDs are replaced with server-generated identifiers (20.635185ms) ✔ security headers allow Telegram framing only through CSP (77.123527ms) ✔ production responses enable HSTS and HTTPS upgrade policy (37.232571ms) ✔ strict CORS rejects unknown origins and handles approved preflights (17.99703ms) ✔ signed double-submit CSRF flow protects unsafe JSON requests (54.501236ms) ✔ body parsing rejects unsupported, malformed, and oversized payloads safely (46.424573ms) ✔ rate limiting emits standard controls and fails closed when its store fails (26.019981ms) ✔ maintenance gates application traffic but preserve liveness (16.977642ms) ✔ readiness fails safely when the distributed security dependency is unavailable (9.288254ms) ✔ Phase 10 migration makes ledger entries append-only and excludes pending balances (7.81916ms) ✔ ledger repository locks account rows in deterministic database order (1.295385ms) ✔ wallet history keeps cursor values parameterized (0.780022ms) ✔ runtime ledger repository contains no entry update or delete operation (5.54666ms) ✔ Phase 11 migration snapshots attempts and blocks duplicate active attempts and claims (12.859841ms) ✔ public task mapping never exposes destination or internal database identifiers (5.335193ms) ✔ Admin task filters keep hostile input parameterized (0.872219ms) ✔ task completion uses the existing transaction for ledger settlement (10.396565ms) ✔ task routes declare separate permissions for viewing, editing, publishing, and review (1.298821ms) ✔ Phase 12 migration preserves referral evidence and optimistic state transitions (9.599053ms) ✔ Admin referral search keeps hostile input in query parameters (1.151936ms) ✔ Referral reward settings require string minor units and matching versions (10.741834ms) ✔ Task completion invokes referral activation inside its existing transaction (4.295532ms) ✔ Referral API exposes reads only while Admin mutations require exact permissions (4.571723ms) ✔ Referral activation amount comes only from validated server settings (2.015372ms) ✔ Phase 13 migration enforces single-active, free-only, immutable claim evidence (10.790582ms) ✔ claim flow locks user and reward state before atomic ledger settlement (1.89125ms) ✔ client cannot select the box, reward, amount, ticket, or paid access fields (7.65513ms) ✔ Admin claim search keeps hostile values parameterized (1.172531ms) ✔ repository hardcodes zero cost and no purchase on every box insert (1.427616ms) ✔ route permissions separate claim evidence from lifecycle and configuration (5.061563ms) ✔ Phase 14 migration protects immutable quotes, requests, approvals, history, and payouts (23.874018ms) ✔ withdrawal creation locks user, quote, and method before holding funds and consuming the quote (9.693671ms) ✔ client payloads cannot choose fees, net totals, status, approvals, or payout evidence (5.31843ms) ✔ Admin search values remain parameterized and LIKE metacharacters are escaped (0.814947ms) ✔ destination details use authenticated encryption context and a separate hash (3.876702ms) ✔ manual provider is the only enabled payout implementation and rejects automatic mode (1.328983ms) ✔ route permissions separate reads, sensitive details, decisions, payout, methods, and settings (9.118814ms) ✔ Phase 15 migration versions content and protects lifecycle evidence (16.368266ms) ✔ public banner query requires active time window and verified public media (0.692916ms) ✔ public announcement query binds user reads and server-owned visibility windows (1.270458ms) ✔ public tutorial queries expose published rows only with safe cover media (0.558646ms) ✔ content routes separate management, viewing, and publishing permissions (3.415356ms) ✔ configuration routes enforce exact settings, flag, theme, currency, and maintenance permissions (1.778865ms) ✔ raw Admin text is converted to safe HTML and never passed through as body_html (4.289692ms) ✔ public media serving uses verified metadata, containment, size, and hash controls (1.984195ms) ✔ Phase 16 migration protects immutable template and delivery evidence (10.250818ms) ✔ Outbox claim query uses row locks, leases, bounded attempts, and SKIP LOCKED (3.656711ms) ✔ Message routes separate view, edit, approval, cancellation, and reminder permissions (3.947173ms) ✔ Telegram worker has one allowlisted method and never stores raw provider response (8.759606ms) ✔ Broadcast audience excludes deleted and non-writable Telegram accounts (5.586431ms) ✔ Phase 17 migration protects immutable leaderboard and rollup evidence (14.943604ms) ✔ leaderboard materialization snapshots privacy-safe display data (12.016281ms) ✔ earning history is sourced from posted ledger evidence and uses keyset pagination (10.164656ms) ✔ financial totals and operational reports use distinct permissions (2.572456ms) ✔ Telegram re-sync merges profile data instead of erasing privacy preferences (6.095099ms) ✔ Mini App modules use local resolvable imports and do not persist authentication material (93.304017ms) ✔ Mini App shell permits zoom, has safe-area viewport and loads no inline code (1.81155ms) ✔ Mini App CSS retains mobile clearance, keyboard focus and reduced effects (2.460929ms) ✔ media processor decodes pixels, removes appended data and strips metadata (30.690512ms) ✔ media processor rejects disguised SVG, mismatched MIME, truncated data and excess pixels (24.294297ms) ✔ upload accepts only strict filenames, bounded base64 and explicit supported media types (13.799118ms) ✔ upload writes only generated paths and stores a digest matching the served pixels (18.384554ms) ✔ operational searches bind escaped wildcards and reject unknown query models (1.408401ms) ✔ console projections exclude password, session, payload and raw security evidence columns (0.673932ms) ✔ admin user filters keep hostile search and status values out of SQL text (1.55195ms) ✔ admin user repository parameterizes pagination and search values (1.622811ms) ✔ profile writes update only allowlisted preference columns (0.515445ms) ✔ Telegram webhook requires the exact secret header without reflecting it (1.406924ms) ✔ approved project directories exist (21.567804ms) ✔ package metadata is private, ESM, exact-pinned, and script-complete (10.469335ms) ✔ runtime policy accepts supported LTS lines and rejects unsupported lines (1.256995ms) ✔ web entry point fails closed when deployment configuration is missing (863.316621ms) ✔ repository does not contain a real environment file (8.420845ms) ✔ password success creates only a staged two-factor challenge (4.062434ms) ✔ unknown and incorrect Admin credentials return the same public failure (1.892426ms) ✔ valid TOTP atomically advances replay state and promotes the challenge (1.133195ms) ✔ invalid TOTP revokes its challenge and commits lockout evidence (1.687627ms) ✔ one-time bootstrap creates an active 2FA Super Admin under a database lock (2.258832ms) ✔ bootstrap command refuses missing one-time inputs before opening MySQL (0.81438ms) ✔ native Argon2id hashes verify correctly and reject malformed resource parameters (236.006554ms) ✔ AES-256-GCM encrypts TOTP secrets with admin-bound authenticated context (11.937648ms) ✔ TOTP matches RFC 6238 vectors and blocks accepted-step replay (3.715671ms) ✔ recovery codes are one-time-hashable, bounded, and never store plaintext (2.62682ms) ✔ admin challenge is opaque, hashed at rest, short-lived, and cookie-separated (2.850784ms) ✔ authenticated admin session loads server-side permissions and rolls idle expiry (1.560366ms) ✔ operational error classes expose stable codes and HTTP statuses (1.358942ms) ✔ AppError rejects invalid status codes and unstable error codes (0.84052ms) ✔ unknown errors normalize to a non-exposed internal failure (0.213755ms) ✔ malformed JSON normalizes to a safe client error (0.313477ms) ✔ configuration modules map validated values and preserve bigint-safe database options (23.032313ms) ✔ complete configuration is deeply frozen (1.669391ms) ✔ diagnostic projection does not expose configuration secrets (5.59765ms) ✔ MySQL version policy accepts supported Oracle MySQL and rejects alternatives (1.656975ms) ✔ acquired MySQL connections are initialized with UTC and strict SQL mode (0.356114ms) ✔ query helpers keep values parameterized and identifiers allowlisted (1.024765ms) ✔ pagination helpers clamp limits and calculate stable metadata (0.287052ms) ✔ transaction helper commits success and rolls back failure (0.629159ms) ✔ transaction helper retries only deadlock-class errors (0.351328ms) ✔ example template contains every declared key and validates in template mode (32.792944ms) ✔ valid production values are parsed into typed and frozen environment data (4.128146ms) ✔ runtime parsing rejects placeholders without exposing their values (3.299845ms) ✔ production validation rejects insecure transport, proxy, cache, logging, and cookie choices (1.571698ms) ✔ cross-field validation rejects unsafe TTL and upload directory relationships (1.567927ms) ✔ cross-field validation keeps route limits within the global request budget (1.655787ms) ✔ database configuration requires UTC and TLS for remote production servers (1.489901ms) ✔ path traversal and unknown template keys are rejected (4.206889ms) ✔ duplicate environment keys fail before parsing (0.688743ms) ✔ file loading rejects file typos while ignoring unrelated process variables (23.254413ms) ✔ unrelated process variables are ignored when strict file mode is not requested (1.299638ms) ✔ environment and nested diagnostic redaction hide all sensitive values (0.993929ms) ✔ health-check CLI parses bounded options and rejects unknown input (2.966248ms) ✔ health-check URL defaults locally and rejects embedded credentials (0.797935ms) ✔ health-check client validates the response contract (5.002219ms) ✔ application lifecycle moves through starting, ready, draining, and stopped (1.439746ms) ✔ application lifecycle rejects impossible transitions (0.42457ms) ✔ graceful shutdown stops HTTP before closing the database and is idempotent (11.743471ms) ✔ shutdown deadline force-closes connections and still closes the pool (12.404937ms) ✔ secret redaction handles nested keys, tokens, URL credentials, bigint, and cycles (4.1829ms) ✔ JSON logger applies thresholds, child bindings, and stderr separation (1.349309ms) ✔ ledger validation rejects unbalanced, duplicate-account, and unsafe amount inputs (2.456497ms) ✔ balanced reward posts atomically and rebuilds the user projection (18.247272ms) ✔ a repeated ledger idempotency key returns the committed result without new entries (3.95638ms) ✔ reusing a ledger idempotency key for different data is rejected (1.826926ms) ✔ a debit cannot make a user available account negative (0.870126ms) ✔ reversal appends opposite entries and restores reward and lifetime projections (2.819942ms) ✔ wallet cursor is signed, round-trips, and rejects tampering (5.712999ms) ✔ wallet history validation bounds limit and rejects unknown query fields (3.505907ms) ✔ wallet returns authoritative integer strings and projection health (1.23182ms) ✔ history preserves available and held deltas and emits a signed next cursor (1.140513ms) ✔ projection comparison identifies exact mismatched fields (0.58844ms) ✔ reconciliation repair locks user accounts before replacing the snapshot (0.706001ms) ✔ Admin-created task always uses the server settlement currency and starts as draft (6.879097ms) ✔ publishing a future timer task uses optimistic versioning and scheduled state (2.640909ms) ✔ unsupported verification integrations and stale Admin versions fail closed (1.276664ms) ✔ an early task claim rolls back without creating a ledger reward (24.513121ms) ✔ verified task claim posts ledger and completion in one transaction (3.329801ms) ✔ manual verification claim becomes pending without issuing a reward (3.562367ms) ✔ claim idempotency replay returns the committed completion before task mutation (3.193897ms) ✔ task validation accepts only server-governed task fields and integer minor units (9.655105ms) ✔ eligibility rules fail closed when stored configuration is malformed (1.68619ms) ✔ eligibility evaluates username, geography, progress, and account age server-side (2.187377ms) ✔ completion policy enforces active, global, one-time, daily, and cooldown limits (0.461523ms) ✔ task configuration uses deployment URL policy and rejects unavailable callbacks (1.706024ms) ✔ start and claim idempotency hashes are scoped and compared safely (1.44056ms) ✔ completion period keys make one-time, daily, and repeatable awards deterministic (0.78974ms) ✔ scheduled task activates safely and snapshots all reward-critical fields on start (26.654505ms) ✔ an existing active attempt blocks a second start before any insert (1.774588ms) ✔ start idempotency replay returns the immutable destination snapshot (1.575222ms) ✔ referral policy uses safe defaults for invalid database settings (3.843448ms) ✔ referral activation waits for the server-counted task threshold (2.160222ms) ✔ eligible referral activation posts both server-controlled rewards atomically (4.544651ms) ✔ shared-device risk holds a referral and never posts a reward (0.882636ms) ✔ account restriction is evaluated before age and task progress (0.202792ms) ✔ Admin referral setting update versions history and commits optimistic write (6.874869ms) ✔ stale Admin referral setting version rolls back without writing (0.893999ms) ✔ Admin approval records review then re-runs activation in the same transaction (2.374227ms) ✔ Admin-created boxes persist only server-enforced free access fields (3.714542ms) ✔ stale Admin box updates roll back before a database mutation (1.912761ms) ✔ publish validates the reward pool and performs one optimistic transition (2.468872ms) ✔ reward inventory cannot be reduced below its immutable awarded count (0.800666ms) ✔ daily eligibility uses server task count and timezone period boundaries (29.755339ms) ✔ task requirements are evaluated from authoritative integer counts (0.630118ms) ✔ cooldown eligibility is anchored to the last committed claim (0.784449ms) ✔ weighted selection uses an injected cryptographic ticket boundary (0.61654ms) ✔ exhausted rewards are excluded and fixed mode requires exactly one reward (1.710717ms) ✔ publishing enforces free-only configuration and a valid reward pool (1.545438ms) ✔ Admin payloads cannot introduce payment fields or unsafe money numbers (6.150442ms) ✔ eligible free claim reserves inventory, posts ledger, and stores evidence atomically (41.710023ms) ✔ insufficient verified task progress rolls back before reward or ledger mutation (1.719662ms) ✔ a committed idempotency key returns the original claim without a new transaction (2.942076ms) ✔ earning-restricted users cannot reserve inventory or receive a reward (0.859352ms) ✔ reject atomically refunds the full held gross amount, never only the net amount (3.761506ms) ✔ the first high-value approval remains under review and does not move money (0.399139ms) ✔ the required final approval transitions to approved with immutable approval evidence (0.515782ms) ✔ manual paid confirmation settles held gross into exact net payout and fee credits (1.049081ms) ✔ decrypted destination details are released only after stored hash verification (1.076116ms) ✔ payout confirmation rejects stale versions and non-approved states before settlement (0.439228ms) ✔ global and method rules combine using the stricter financial limits (4.560419ms) ✔ percentage fees round upward and all amounts stay decimal strings (1.293277ms) ✔ eligibility is derived from server account, task, referral, wallet, day, and cooldown state (1.786632ms) ✔ restricted and too-new accounts fail closed (0.35653ms) ✔ dynamic destination fields reject unknown values and produce a safe display mask (1.976068ms) ✔ dual approval is required only at or above the configured high-value threshold (0.303332ms) ✔ withdrawal payload schemas reject client-controlled totals and unsafe numeric amounts (5.123157ms) ✔ Admin method and setting schemas enforce consistent fees and optimistic versions (12.64905ms) ✔ invalid stored setting values fall back to conservative defaults (0.546345ms) ✔ quote derives fee and expiry on the server without posting ledger entries (34.704843ms) ✔ request atomically encrypts details, holds the gross amount, consumes quote, and records history (6.995677ms) ✔ a concurrent quote-consumption conflict rolls back the complete request transaction (5.483843ms) ✔ idempotent request replays must match the original canonical input fingerprint (4.283555ms) ✔ managed setting policy preserves the free-only Mystery Box boundary (1.867173ms) ✔ managed setting policy bounds pagination and normalizes allowlisted URLs (0.301519ms) ✔ theme payload accepts the closed token contract and rejects CSS injection (6.999832ms) ✔ feature flag mutation permits rollout only and rejects targeting objects (2.285457ms) ✔ currency input canonicalizes ISO-style codes and caps decimal precision (2.695329ms) ✔ maintenance windows require strictly ordered timestamps (2.698905ms) ✔ setting updates write an immutable next-version record in one transaction (3.272846ms) ✔ setting updates reject null when it violates the stored value type (1.254086ms) ✔ settlement currency precision cannot change after ledger setup (0.869618ms) ✔ publishing a theme retires the former active theme inside the transaction (1.168291ms) ✔ plain content is encoded into inert server-generated HTML (1.66617ms) ✔ banner validation requires verified-media identity and paired actions (4.448716ms) ✔ announcement targeting schema is strict and date ordered (3.434207ms) ✔ tutorial validation rejects client lifecycle and malformed slugs (3.610028ms) ✔ announcement targeting fails closed for missing or mismatched user attributes (0.35847ms) ✔ disabled banner feature avoids every content database read (1.514218ms) ✔ banner creation rejects media that is not verified and public (1.659433ms) ✔ future announcement publishing selects scheduled state on the server clock (7.276098ms) ✔ tutorial creation rejects a URL outside the deployment allowlist (1.306281ms) ✔ media resolution blocks storage paths that escape the public root (0.822994ms) ✔ Telegram templates preserve allowlisted markup and escape every variable (2.507619ms) ✔ Template buttons are HTTPS-only and expose one closed Telegram keyboard shape (1.296476ms) ✔ Internal Telegram payload contract rejects arbitrary methods, chats, and oversized text (4.406843ms) ✔ Outbox claims use leases and exponential retry is bounded and honors Telegram retry-after (0.997512ms) ✔ Outbox worker completes successes and records failures without logging payloads (0.594952ms) ✔ Telegram job rejects malformed success responses instead of recording a false delivery (0.881726ms) ✔ Reminder next-run calculation follows IANA local time and ISO weekdays (53.013035ms) ✔ Broadcast creator cannot approve their own draft (1.112988ms) ✔ Transactional amount placeholders format integer minor units without floating point (0.263504ms) ✔ analytics periods use closed UTC dates and ISO calendar boundaries (4.090313ms) ✔ earning-history cursors are scoped, signed, and reject tampering (2.343986ms) ✔ earning history emits only signed server ledger deltas and an opaque next cursor (1.276609ms) ✔ earning summary keeps integer minor units and reports reversals separately (1.148815ms) ✔ public leaderboard uses snapshots and never requests Telegram identifiers (0.930396ms) ✔ rollup is idempotent per closed date and builds every allowlisted snapshot (2.074451ms) ✔ Admin financial reports keep monetary values behind a separate service method (0.797832ms) ✔ profile contract accepts explicit leaderboard privacy without accepting identity fields (4.4261ms) ✔ miniapp money formatting preserves every BIGINT minor unit including negative fractions (23.789859ms) ✔ miniapp amount entry never uses floating point or accepts exponent notation (0.474111ms) ✔ miniapp navigation normalizes hashes and rejects malformed or traversal routes (2.091754ms) ✔ miniapp rejects credential-bearing and executable URLs (0.35125ms) ✔ withdrawal field validation mirrors allowed format and option contracts (2.027093ms) ✔ miniapp API rejects non-local paths before sending credentials (1.21429ms) ✔ miniapp shares CSRF retrieval and coalesces concurrent identical mutations (8.396438ms) ✔ failed CSRF requests can be retried and do not send a mutation (1.435357ms) ✔ uncertain financial mutations reuse the same key on deliberate retry (6.389328ms) ✔ API failures retain safe request references and distinguish timeout (4.925674ms) ✔ authentication never invents a development identity outside Telegram (0.487857ms) ✔ theme tokens reject CSS injection and reset stale per-theme overrides (1.960682ms) ✔ admin client rejects external and traversal destinations before sending credentials (3.13792ms) ✔ admin mutations coalesce and use the admin CSRF token without persisting credentials (8.372848ms) ✔ failed mutations are never automatically retried and preserve error context (4.796012ms) ✔ session invalidation discards late responses and does not send an awaiting mutation (0.928784ms) ✔ 401 invalidates authentication while 403 keeps an actionable permission error (4.690948ms) ✔ catalog hides ungranted resources and exact withdrawal decision controls (0.460291ms) ✔ minor units remain decimal strings and numeric configuration rejects unsafe integers (0.544259ms) ✔ forms preserve optional omission, explicit null, booleans and nested reward values (389.84315ms) ✔ create task form submits only supported server fields and keeps rewards precise (48.533503ms) ✔ editing plain content round-trips server HTML without double encoding (27.887213ms) ✔ reminder form reconstructs template keys and keeps nested audience rules (24.083412ms) ✔ template editor sends all strict fields and represents nullable button config (25.556086ms) ✔ settings editor fixes free-only protection and preserves server versions (30.048501ms) ✔ resource query only includes route-supported fields and identities are encoded (0.554129ms) ✔ login completes password challenge and TOTP without persisting a password (56.693624ms) ✔ withdrawal confirmation requires review and duplicate clicks share one request (48.389191ms) ✔ conflict keeps the draft visible and prevents immediate resubmission (33.039196ms) ✔ resource UI renders hostile text inert and ignores a disposed response (30.033433ms) ✔ dashboard renders daily chart and table from real response values and isolates financial reports (41.242534ms) ✔ search phrases with spaces and encoded URL punctuation stay on the local admin endpoint (1.564732ms) ✔ admin entry restores an authenticated shell and logout clears its private data (36.478753ms) ✔ administrator form loads named roles, reviews the request and displays a one-time invitation safely (269.147478ms) ✔ wallet correction editor creates a stable hidden idempotency key per draft (12.260015ms) ✔ resolved fraud records offer no further review action (30.336448ms) ✔ enrollment accepts own password then verifies TOTP without retaining invitation or password fields (31.421552ms) ✔ closing enrollment while a response is pending cannot restore its secret (13.700558ms) ✔ enrollment API obtains anonymous admin CSRF and never exempts its mutations (1.540856ms) ✔ mobile authenticator app switching hides the setup key but permits returning with a code (16.639309ms) ✔ retry risk acknowledgement requires a deliberate checked choice (11.969897ms) ✔ administrative changes recheck active session and fresh permission before writing (6.337667ms) ✔ identity management cannot be delegated by assigning only a manage permission (1.401783ms) ✔ invitation stores only a token digest and does not provision active credentials (2.644676ms) ✔ self access changes and stale administrator versions cannot revoke the last operator (1.381593ms) ✔ administrator role/status change and session revocation commit together (6.716587ms) ✔ a cancelled, unenrolled administrator cannot be enabled through access editing (7.182061ms) ✔ built-in roles cannot be edited, while custom grants revoke assigned sessions (1.637806ms) ✔ account ban revokes sessions without leaving a permanent banned status after expiry (1.33006ms) ✔ unban removes only the selected scope and requires its separate permission (1.136547ms) ✔ competing fraud decisions have one winner and persist the review reason (1.694893ms) ✔ wallet correction preparation is idempotent and cannot change money (1.591729ms) ✔ wallet adjustment rejects self approval and posts exactly once under competing reviews (9.884592ms) ✔ insufficient debit rolls back review and ledger; rejection never changes money (1.03112ms) ✔ money and control inputs reject floats, forged actor fields and missing risk acknowledgement (2.027011ms) ✔ manual retry refuses sent, cancelled, unlinked, stale and permanent recipient failures (0.525252ms) ✔ manual retry retains attempt number/payload and only schedules one additional attempt (1.611514ms) ✔ retry rechecks delivery consent and cannot revive an ineligible campaign (0.316453ms) ✔ invitation enrollment consumes both tokens, encrypts TOTP, and returns recovery codes only once (5.527376ms) ✔ failed enrollment attempts commit their counter and stop verification after five codes (3.272152ms) ✔ outbox terminal failure records its linked job in the same executor and never writes for a lost lease (0.646032ms) ✔ administrative repositories bind arbitrary text and refuse arbitrary table names (0.376835ms) ✔ fraud evidence reveal redacts nested credentials and sensitive identity evidence (0.859623ms) ✔ release schema check is read-only and verifies the complete release (31.144238ms) ✔ release refuses missing schema history (10.754362ms) ✔ release refuses changed schema history (12.8015ms) ✔ release refuses missingSeed schema history (24.431424ms) ✔ release refuses partial schema history (26.276966ms) ✔ Redis fails immediately while offline and bounds queued commands (0.381627ms) ✔ production rejects unsafe DATABASE_QUEUE_LIMIT=0 (19.323477ms) ✔ production rejects unsafe REDIS_URL=redis://default:valid-pass@remote.internal:6379 (4.345575ms) ✔ production rejects unsafe REDIS_URL=redis://127.0.0.1:6379 (2.733647ms) ✔ live acceptance cannot select a production database or an unconfirmed target (1.514584ms) ✔ backup roundtrip preserves binary bytes and private output permissions (132.818577ms) ✔ backup rejects wrong-key and removes unauthenticated plaintext (15.140309ms) ✔ backup rejects ciphertext and removes unauthenticated plaintext (9.13749ms) ✔ backup rejects tag and removes unauthenticated plaintext (6.907437ms) ✔ backup rejects header and removes unauthenticated plaintext (196.408393ms) ✔ backup rejects truncated and removes unauthenticated plaintext (23.746484ms) ✔ backup rejects size-limit and removes unauthenticated plaintext (15.888519ms) ✔ backup and restore never overwrite an existing output (18.842739ms) ✔ backup key rejects malformed, ambiguous or short key material (0.954702ms) ✔ completed polling intervals release abort listeners over repeated cycles (87.832912ms) ✔ readiness times out even when the database connection queue never resolves (19.652885ms) ✔ mysql backup CLI publishes only a successful dump (failure=false) (520.213543ms) ✔ mysql backup CLI publishes only a successful dump (failure=true) (798.587724ms) ✔ mariadb backup CLI publishes only a successful dump (failure=false) (96.439413ms) ✔ mariadb backup CLI publishes only a successful dump (failure=true) (107.110831ms) ✔ admin user list schema caps page sizes and rejects deleted pseudo-filter (7.746691ms) ✔ admin user mappings preserve large numeric values as strings (1.313039ms) ✔ admin user list uses normalized pagination and parallel repository reads (0.645608ms) ✔ admin user detail combines profile, restrictions, wallets, and metrics (1.073727ms) ✔ cache returns a valid hit without invoking the loader (3.741193ms) ✔ cache fails open on malformed reads and write failures (0.664384ms) ✔ cache does not persist oversized responses (0.993119ms) ✔ local day and week boundaries are converted to UTC for Dhaka (29.650134ms) ✔ day boundaries respect daylight-saving transitions (1.153204ms) ✔ database and offset datetimes normalize to the same UTC representation (0.676988ms) ✔ theme tokens accept a closed safe schema and reject CSS injection (1.14025ms) ✔ setting guards accept only usable locale lists and IANA timezones (23.728199ms) ✔ bootstrap combines safe public configuration with user-scoped state (1.623229ms) ✔ dashboard returns decimal-safe strings and never exposes task destination URLs (5.301953ms) ✔ feature gates prevent disabled task and free-reward database reads (1.558671ms) ✔ database numeric guards reject unsafe representations (0.591942ms) ✔ free reward eligibility is display-only and honors frequency boundaries (0.359532ms) ✔ profile schema rejects Telegram-owned and financial fields (3.071257ms) ✔ profile reads expose Telegram IDs as strings and only public fields (1.028265ms) ✔ profile update validates flags/settings before opening a transaction (17.516067ms) ✔ disabled profile editing fails before a database transaction begins (1.573176ms) ✔ unsupported language and invalid timezone are rejected server-side (0.602257ms) ✔ memory rate-limit store increments and resets fixed windows (3.109728ms) ✔ Redis rate-limit store uses one atomic script and namespaced keys (1.048583ms) ✔ Redis client factory applies TLS verification and bounded reconnects (0.611569ms) ✔ Redis connection, readiness cache, and close lifecycle are bounded (1.236658ms) ✔ database readiness is cached and concurrent checks share one query (2.048787ms) ✔ database readiness fails closed without throwing dependency details (1.478003ms) ✔ migration runner applies each immutable migration once under a schema lock (3.854857ms) ✔ migration runner resumes after a partial DDL failure without replaying recorded statements (1.844177ms) ✔ migration runner rejects a changed file after it has been applied (1.081017ms) ✔ seeds require all migrations, run once, and rollback invalidates seed history (4.344367ms) ✔ validation middleware stores only schema-approved data and returns safe issues (10.739033ms) ✔ maintenance and ban gates use trusted server-side providers (0.99344ms) ✔ idempotency middleware hashes accepted keys and rejects duplicates (1.684154ms) ✔ audit middleware records completed mutations without delaying responses (6.824189ms) ✔ HMAC signatures are deterministic and reject modified input (1.405805ms) ✔ CSRF tokens are signed, session-bound, and time-limited (20.870655ms) ✔ secure random and idempotency helpers enforce bounded keys (0.436972ms) ✔ managed URL allowlist requires approved schemes, domains, and credential-free URLs (3.616115ms) ✔ HTML and plain-text helpers encode markup and remove unsafe controls (1.69059ms) ✔ Spaceship accepts the supplied MariaDB release and rejects other engine/version families (2.404229ms) ✔ Spaceship production configuration keeps database rate limiting without Redis (24.174102ms) ✔ Spaceship refuses unsafe profile override RATE_LIMIT_STORE=memory (1.271749ms) ✔ Spaceship refuses unsafe profile override DATABASE_DIALECT=mysql (1.275454ms) ✔ Spaceship refuses unsafe profile override REDIS_ENABLED=true (1.237925ms) ✔ Spaceship refuses unsafe profile override QUEUE_BATCH_SIZE=20 (1.205491ms) ✔ Spaceship refuses unsafe profile override DATABASE_CONNECTION_LIMIT=1 (5.094739ms) ✔ Spaceship refuses unsafe profile override DATABASE_CONNECTION_LIMIT=10 (3.906078ms) ✔ Spaceship refuses unsafe profile override DATABASE_QUEUE_LIMIT=0 (8.134031ms) ✔ the Spaceship template includes and validates every environment key (26.890861ms) ✔ MariaDB requires the configured engine, its collation alias and enabled CHECK constraints (1.297803ms) ✔ MariaDB preserves original business DDL and refuses MySQL migration history (426.519561ms) ✔ persistent workers are rejected before opening any connection on Spaceship (3.890136ms) ✔ database rate limit uses a transaction and database clock without storing the client key (0.965321ms) ✔ database limiter outage denies the request with 503 (0.591951ms) ✔ cron already_running does not execute work (0.719659ms) ✔ cron interval_not_elapsed does not execute work (0.116041ms) ✔ cron reports failures without private payloads and releases its connection lock (0.321663ms) ✔ cron defers further batches when its work budget expires (0.293108ms) ✔ cron stops work when the owning database lock is lost (0.332202ms) ✔ SQL splitter preserves quoted semicolons and removes comments (1.739428ms) ✔ migration parser requires both sections and rejects session control (1.813111ms) ✔ seed parser accepts one section and checksum is deterministic (0.933863ms) ✔ all migration and seed files load in contiguous order (91.174091ms) ✔ Telegram exchange creates one user, first-touch referral, and opaque session atomically (3.175889ms) ✔ existing Telegram users retain their internal database ID during profile sync (0.636654ms) ✔ simultaneous first login recovers from a unique-user insert race (1.27457ms) ✔ Telegram API client sends JSON webhook settings and exposes no token on failure (2.793189ms) ✔ bot command routing is private-chat only and preserves a bounded referral payload (1.03389ms) ✔ Mini App keyboards require HTTPS and Telegram HTML is escaped (0.320936ms) ✔ webhook service acknowledges duplicates and retries failed processing safely (0.627549ms) ✔ failed webhook retries cannot replace the payload for an existing update ID (0.737332ms) ✔ Telegram initData validates HMAC, freshness, and bigint-safe identity strings (6.855517ms) ✔ Telegram initData rejects tampering, expiry, future dates, and duplicate protected fields (4.918986ms) ✔ Telegram initData rejects bot users and unsafe numeric identities (2.066729ms) ✔ user sessions store only a hash and emit an HttpOnly secure cookie (2.871428ms) ✔ cookie and IP parsing fail safely on malformed values (5.927261ms) ✔ session authentication maps public identity and rolls idle expiry server-side (0.64937ms) ✔ public IDs are 26-character sortable Crockford identifiers (0.772006ms) ℹ tests 460 ℹ suites 0 ℹ pass 460 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0 ℹ duration_ms 6943.763078 [phase-20-check] Running verify:environment:example npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. > telegram-task-earning@0.20.1 verify:environment:example > node bin/verify-environment.js --example Telegram Task Earning — Phase 20 environment verification Mode: example-template Source: .env.example (found) Node.js: v24.19.0 (supported) Keys: 89/89 recognized Placeholders: 13 Environment verification passed. [phase-20-check] Running verify:database-schema npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. > telegram-task-earning@0.20.1 verify:database-schema > node scripts/verify-database-schema.js Database schema verified: 23 migrations, 6 seeds, 77 tables, 259 named constraints, 202 up statements, 178 down statements, 19 seed statements. [phase-20-check] Running verify:spaceship npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. > telegram-task-earning@0.20.1 verify:spaceship > node scripts/verify-spaceship.js {"passed":true,"scope":"static-only","migrations":24,"seeds":6,"liveMariaDb":"pending"} [phase-20-check] Running build:css npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. > telegram-task-earning@0.20.1 build:css > node scripts/build-css.js npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. > telegram-task-earning@0.20.1 build:css:miniapp > postcss resources/css/miniapp.css --output public/miniapp/css/app.min.css --env production npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. > telegram-task-earning@0.20.1 build:css:admin > postcss resources/css/admin.css --output public/admin/css/admin.min.css --env production CSS bundles built successfully. [phase-20-check] Running verify:project npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. > telegram-task-earning@0.20.1 verify:project > node scripts/verify-project.js Phase 20 project verification passed: 81 directories, 521 required files, and 40 npm scripts. Phase 20 quality gate passed.