npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. > telegram-task-earning@0.20.0 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.0 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.0 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.0 test > node --test ✔ Admin auth routes are composed behind validation, session, and CSRF gates (78.117395ms) ✔ configured Admin IP policy rejects disallowed networks before authentication (10.46141ms) ✔ Express foundation serves service, liveness, readiness, and safe 404 responses (71.020159ms) ✔ readiness returns 503 without disclosing database errors (21.530777ms) ✔ web bootstrap verifies MySQL, configures HTTP, becomes ready, and shuts down (27.098629ms) ✔ web bootstrap fails closed and releases resources for an unsupported database (2.490999ms) ✔ web bootstrap connects Redis for distributed protection and closes it on shutdown (6.304083ms) ✔ migration dry run validates all files without secrets or a live database (266.462356ms) ✔ seed and rollback dry runs are offline and deterministic (421.580602ms) ✔ unknown database command options fail closed (164.513147ms) ✔ example verification succeeds and redacts sensitive placeholders (174.89036ms) ✔ using the example as a runtime environment fails closed without leaking secrets (141.637214ms) ✔ runtime verification succeeds from deployment environment values (121.68718ms) ✔ wallet and history endpoints require a verified Telegram session (58.510992ms) ✔ wallet API returns string amounts and cursor pagination metadata (20.351523ms) ✔ wallet history rejects excessive limits and unknown query input (17.877621ms) ✔ task APIs require a server-verified Telegram user session (107.754565ms) ✔ task start requires CSRF, an empty body, and an Idempotency-Key (36.066323ms) ✔ claim validates ownership-shaped IDs and returns server reward data (15.184466ms) ✔ Admin task lifecycle routes enforce their exact permission (16.531178ms) ✔ public referral endpoints require a verified Telegram session (63.527251ms) ✔ Admin referral routes enforce distinct view, review, and settings permissions (36.297463ms) ✔ Admin review requires CSRF, review permission, reason, and resource version (14.887425ms) ✔ public Mystery Box endpoints require a verified Telegram session (63.76349ms) ✔ free claim requires CSRF, an empty body, and an Idempotency-Key (53.678951ms) ✔ Admin reads, claims, management, and lifecycle use distinct permissions (35.435306ms) ✔ public method, quote, and withdrawal history endpoints require verified Telegram identity (105.558673ms) ✔ quote and create use strict schemas, CSRF, and a required idempotency key (58.129072ms) ✔ Admin withdrawal reads and decrypted destination details use distinct permissions (19.798694ms) ✔ Admin review checks the submitted decision permission and payout confirmation is separate (15.19432ms) ✔ content endpoints require verified Telegram identity (65.927783ms) ✔ announcement read evidence requires CSRF and an empty strict body (39.361671ms) ✔ Admin banner reading, editing, and publishing use separate permissions (12.217484ms) ✔ Admin settings and feature flags enforce exact permissions and strict versions (14.413405ms) ✔ Notification inbox requires Telegram identity and read mutation requires CSRF (90.009714ms) ✔ Template reads and broadcast approval require their exact Admin permissions (27.682025ms) ✔ Reminder creation validates timezone-shaped schedule inputs before service execution (18.946114ms) ✔ earning history and leaderboard require a Telegram-authenticated user (57.755365ms) ✔ financial analytics require their exact high-sensitivity permission (17.355376ms) ✔ report range and leaderboard pagination are rejected before service execution (11.679069ms) ✔ Mini App shell renders EJS with a narrowly scoped official Telegram SDK CSP (120.191873ms) ✔ Mini App module assets revalidate and private paths remain inaccessible (48.021871ms) ✔ Maintenance allows only the public shell/assets while protected API stays closed (16.693748ms) ✔ Banned sessions can load the shell for an error screen but cannot access API data (9.446046ms) ✔ admin shell and assets are public but contain no account data and deny framing (88.585626ms) ✔ every operational route fails closed without its exact read permission (50.59869ms) ✔ authorized reads validate pagination, return string amounts, and record audit context (15.962656ms) ✔ catalog exposes only allowed screens and hides payment account details from reviewers (8.225801ms) ✔ maintenance preserves shell access and follows configured admin access policy (14.997771ms) ✔ upload size exception requires permission and CSRF and does not enlarge other routes (40.691068ms) ✔ all Phase 19 operations reject anonymous callers even with a valid anonymous CSRF token (120.467443ms) ✔ all Phase 19 operations enforce their exact permissions before invoking the service (51.482578ms) ✔ every authorized operation routes a strict validated body and trusted actor context (46.811315ms) ✔ CSRF, malformed money, stale-body fields and oversized input are rejected without a write (18.219299ms) ✔ public enrollment keeps CSRF protection and strict one-time-token validation (16.183139ms) ✔ Phase 9 user endpoints require a server-attached session (96.778738ms) ✔ profile mutation requires CSRF and rejects unapproved fields (41.414469ms) ✔ admin user inspection requires both admin authentication and users.view (14.209152ms) ✔ maintenance keeps bootstrap, authenticated admins, and configured webhook reachable (11.281259ms) ✔ Telegram auth and webhook routes are composed behind their security gates (92.862855ms) ✔ Admin authentication and RBAC trust only server-attached identity and permissions (1.064555ms) ✔ Admin IP allowlist supports exact addresses and bounded CIDR ranges (3.510623ms) ✔ database schema enforces the current security and money contract (51.453674ms) ✔ unexpected async errors disclose neither stack traces nor embedded Telegram tokens (57.551432ms) ✔ invalid incoming request IDs are replaced with server-generated identifiers (10.992152ms) ✔ security headers allow Telegram framing only through CSP (41.719578ms) ✔ production responses enable HSTS and HTTPS upgrade policy (20.886971ms) ✔ strict CORS rejects unknown origins and handles approved preflights (10.600832ms) ✔ signed double-submit CSRF flow protects unsafe JSON requests (18.49553ms) ✔ body parsing rejects unsupported, malformed, and oversized payloads safely (20.302619ms) ✔ rate limiting emits standard controls and fails closed when its store fails (16.656102ms) ✔ maintenance gates application traffic but preserve liveness (12.322438ms) ✔ readiness fails safely when the distributed security dependency is unavailable (6.231585ms) ✔ Phase 10 migration makes ledger entries append-only and excludes pending balances (3.930556ms) ✔ ledger repository locks account rows in deterministic database order (1.014669ms) ✔ wallet history keeps cursor values parameterized (0.310027ms) ✔ runtime ledger repository contains no entry update or delete operation (2.479959ms) ✔ Phase 11 migration snapshots attempts and blocks duplicate active attempts and claims (12.738656ms) ✔ public task mapping never exposes destination or internal database identifiers (0.644622ms) ✔ Admin task filters keep hostile input parameterized (0.484ms) ✔ task completion uses the existing transaction for ledger settlement (1.77036ms) ✔ task routes declare separate permissions for viewing, editing, publishing, and review (7.103309ms) ✔ Phase 12 migration preserves referral evidence and optimistic state transitions (14.324537ms) ✔ Admin referral search keeps hostile input in query parameters (0.561316ms) ✔ Referral reward settings require string minor units and matching versions (9.402095ms) ✔ Task completion invokes referral activation inside its existing transaction (1.943681ms) ✔ Referral API exposes reads only while Admin mutations require exact permissions (9.055382ms) ✔ Referral activation amount comes only from validated server settings (0.667466ms) ✔ Phase 13 migration enforces single-active, free-only, immutable claim evidence (7.453808ms) ✔ claim flow locks user and reward state before atomic ledger settlement (2.038894ms) ✔ client cannot select the box, reward, amount, ticket, or paid access fields (2.756756ms) ✔ Admin claim search keeps hostile values parameterized (0.466183ms) ✔ repository hardcodes zero cost and no purchase on every box insert (0.295576ms) ✔ route permissions separate claim evidence from lifecycle and configuration (4.297339ms) ✔ Phase 14 migration protects immutable quotes, requests, approvals, history, and payouts (14.18743ms) ✔ withdrawal creation locks user, quote, and method before holding funds and consuming the quote (1.965733ms) ✔ client payloads cannot choose fees, net totals, status, approvals, or payout evidence (8.368356ms) ✔ Admin search values remain parameterized and LIKE metacharacters are escaped (0.493724ms) ✔ destination details use authenticated encryption context and a separate hash (4.463018ms) ✔ manual provider is the only enabled payout implementation and rejects automatic mode (0.673626ms) ✔ route permissions separate reads, sensitive details, decisions, payout, methods, and settings (0.86911ms) ✔ Phase 15 migration versions content and protects lifecycle evidence (7.257192ms) ✔ public banner query requires active time window and verified public media (0.532493ms) ✔ public announcement query binds user reads and server-owned visibility windows (1.052938ms) ✔ public tutorial queries expose published rows only with safe cover media (0.221854ms) ✔ content routes separate management, viewing, and publishing permissions (2.849636ms) ✔ configuration routes enforce exact settings, flag, theme, currency, and maintenance permissions (0.667026ms) ✔ raw Admin text is converted to safe HTML and never passed through as body_html (1.015792ms) ✔ public media serving uses verified metadata, containment, size, and hash controls (1.58518ms) ✔ Phase 16 migration protects immutable template and delivery evidence (10.579771ms) ✔ Outbox claim query uses row locks, leases, bounded attempts, and SKIP LOCKED (1.08719ms) ✔ Message routes separate view, edit, approval, cancellation, and reminder permissions (1.876629ms) ✔ Telegram worker has one allowlisted method and never stores raw provider response (1.382294ms) ✔ Broadcast audience excludes deleted and non-writable Telegram accounts (0.64988ms) ✔ Phase 17 migration protects immutable leaderboard and rollup evidence (11.496253ms) ✔ leaderboard materialization snapshots privacy-safe display data (1.207481ms) ✔ earning history is sourced from posted ledger evidence and uses keyset pagination (3.283591ms) ✔ financial totals and operational reports use distinct permissions (2.597416ms) ✔ Telegram re-sync merges profile data instead of erasing privacy preferences (1.80396ms) ✔ Mini App modules use local resolvable imports and do not persist authentication material (37.545416ms) ✔ Mini App shell permits zoom, has safe-area viewport and loads no inline code (1.195182ms) ✔ Mini App CSS retains mobile clearance, keyboard focus and reduced effects (0.938615ms) ✔ media processor decodes pixels, removes appended data and strips metadata (20.092713ms) ✔ media processor rejects disguised SVG, mismatched MIME, truncated data and excess pixels (15.973923ms) ✔ upload accepts only strict filenames, bounded base64 and explicit supported media types (6.621844ms) ✔ upload writes only generated paths and stores a digest matching the served pixels (9.473954ms) ✔ operational searches bind escaped wildcards and reject unknown query models (0.712484ms) ✔ console projections exclude password, session, payload and raw security evidence columns (0.296397ms) ✔ admin user filters keep hostile search and status values out of SQL text (0.769961ms) ✔ admin user repository parameterizes pagination and search values (0.866376ms) ✔ profile writes update only allowlisted preference columns (0.249196ms) ✔ Telegram webhook requires the exact secret header without reflecting it (1.346921ms) ✔ approved project directories exist (9.923782ms) ✔ package metadata is private, ESM, exact-pinned, and script-complete (2.446358ms) ✔ runtime policy accepts supported LTS lines and rejects unsupported lines (0.355656ms) ✔ web entry point fails closed when deployment configuration is missing (526.056731ms) ✔ repository does not contain a real environment file (4.145815ms) ✔ password success creates only a staged two-factor challenge (1.897351ms) ✔ unknown and incorrect Admin credentials return the same public failure (1.475575ms) ✔ valid TOTP atomically advances replay state and promotes the challenge (0.780857ms) ✔ invalid TOTP revokes its challenge and commits lockout evidence (0.84248ms) ✔ one-time bootstrap creates an active 2FA Super Admin under a database lock (1.872453ms) ✔ bootstrap command refuses missing one-time inputs before opening MySQL (0.567125ms) ✔ native Argon2id hashes verify correctly and reject malformed resource parameters (111.094592ms) ✔ AES-256-GCM encrypts TOTP secrets with admin-bound authenticated context (2.800663ms) ✔ TOTP matches RFC 6238 vectors and blocks accepted-step replay (5.938803ms) ✔ recovery codes are one-time-hashable, bounded, and never store plaintext (1.095081ms) ✔ admin challenge is opaque, hashed at rest, short-lived, and cookie-separated (1.920595ms) ✔ authenticated admin session loads server-side permissions and rolls idle expiry (0.92854ms) ✔ operational error classes expose stable codes and HTTP statuses (1.043093ms) ✔ AppError rejects invalid status codes and unstable error codes (0.404069ms) ✔ unknown errors normalize to a non-exposed internal failure (0.27848ms) ✔ malformed JSON normalizes to a safe client error (0.144427ms) ✔ configuration modules map validated values and preserve bigint-safe database options (8.040402ms) ✔ complete configuration is deeply frozen (1.051155ms) ✔ diagnostic projection does not expose configuration secrets (1.22041ms) ✔ MySQL version policy accepts supported Oracle MySQL and rejects alternatives (1.640453ms) ✔ acquired MySQL connections are initialized with UTC and strict SQL mode (0.286943ms) ✔ query helpers keep values parameterized and identifiers allowlisted (0.790592ms) ✔ pagination helpers clamp limits and calculate stable metadata (0.270047ms) ✔ transaction helper commits success and rolls back failure (0.515027ms) ✔ transaction helper retries only deadlock-class errors (0.866066ms) ✔ example template contains every declared key and validates in template mode (26.099199ms) ✔ valid production values are parsed into typed and frozen environment data (1.696067ms) ✔ runtime parsing rejects placeholders without exposing their values (1.361383ms) ✔ production validation rejects insecure transport, proxy, cache, logging, and cookie choices (0.594987ms) ✔ cross-field validation rejects unsafe TTL and upload directory relationships (1.409475ms) ✔ cross-field validation keeps route limits within the global request budget (10.160043ms) ✔ database configuration requires UTC and TLS for remote production servers (0.921018ms) ✔ path traversal and unknown template keys are rejected (1.663978ms) ✔ duplicate environment keys fail before parsing (0.332131ms) ✔ file loading rejects file typos while ignoring unrelated process variables (7.208097ms) ✔ unrelated process variables are ignored when strict file mode is not requested (0.740066ms) ✔ environment and nested diagnostic redaction hide all sensitive values (0.497971ms) ✔ health-check CLI parses bounded options and rejects unknown input (1.448404ms) ✔ health-check URL defaults locally and rejects embedded credentials (3.24342ms) ✔ health-check client validates the response contract (2.406017ms) ✔ application lifecycle moves through starting, ready, draining, and stopped (1.154691ms) ✔ application lifecycle rejects impossible transitions (0.342797ms) ✔ graceful shutdown stops HTTP before closing the database and is idempotent (6.231114ms) ✔ shutdown deadline force-closes connections and still closes the pool (13.505892ms) ✔ secret redaction handles nested keys, tokens, URL credentials, bigint, and cycles (3.215217ms) ✔ JSON logger applies thresholds, child bindings, and stderr separation (0.828379ms) ✔ ledger validation rejects unbalanced, duplicate-account, and unsafe amount inputs (1.271917ms) ✔ balanced reward posts atomically and rebuilds the user projection (9.072218ms) ✔ a repeated ledger idempotency key returns the committed result without new entries (4.405902ms) ✔ reusing a ledger idempotency key for different data is rejected (1.242944ms) ✔ a debit cannot make a user available account negative (0.486233ms) ✔ reversal appends opposite entries and restores reward and lifetime projections (1.338337ms) ✔ wallet cursor is signed, round-trips, and rejects tampering (2.65965ms) ✔ wallet history validation bounds limit and rejects unknown query fields (1.792943ms) ✔ wallet returns authoritative integer strings and projection health (0.600145ms) ✔ history preserves available and held deltas and emits a signed next cursor (0.654607ms) ✔ projection comparison identifies exact mismatched fields (0.209405ms) ✔ reconciliation repair locks user accounts before replacing the snapshot (0.577961ms) ✔ Admin-created task always uses the server settlement currency and starts as draft (3.51584ms) ✔ publishing a future timer task uses optimistic versioning and scheduled state (1.084696ms) ✔ unsupported verification integrations and stale Admin versions fail closed (0.838564ms) ✔ an early task claim rolls back without creating a ledger reward (16.680348ms) ✔ verified task claim posts ledger and completion in one transaction (1.722727ms) ✔ manual verification claim becomes pending without issuing a reward (0.650361ms) ✔ claim idempotency replay returns the committed completion before task mutation (1.161631ms) ✔ task validation accepts only server-governed task fields and integer minor units (10.364966ms) ✔ eligibility rules fail closed when stored configuration is malformed (0.929561ms) ✔ eligibility evaluates username, geography, progress, and account age server-side (1.309544ms) ✔ completion policy enforces active, global, one-time, daily, and cooldown limits (0.256166ms) ✔ task configuration uses deployment URL policy and rejects unavailable callbacks (0.568848ms) ✔ start and claim idempotency hashes are scoped and compared safely (0.768539ms) ✔ completion period keys make one-time, daily, and repeatable awards deterministic (0.257078ms) ✔ scheduled task activates safely and snapshots all reward-critical fields on start (15.948174ms) ✔ an existing active attempt blocks a second start before any insert (1.075401ms) ✔ start idempotency replay returns the immutable destination snapshot (1.087019ms) ✔ referral policy uses safe defaults for invalid database settings (1.04108ms) ✔ referral activation waits for the server-counted task threshold (1.272869ms) ✔ eligible referral activation posts both server-controlled rewards atomically (1.420642ms) ✔ shared-device risk holds a referral and never posts a reward (0.326502ms) ✔ account restriction is evaluated before age and task progress (0.162084ms) ✔ Admin referral setting update versions history and commits optimistic write (2.083501ms) ✔ stale Admin referral setting version rolls back without writing (0.620365ms) ✔ Admin approval records review then re-runs activation in the same transaction (1.191056ms) ✔ Admin-created boxes persist only server-enforced free access fields (1.686663ms) ✔ stale Admin box updates roll back before a database mutation (0.772655ms) ✔ publish validates the reward pool and performs one optimistic transition (0.686755ms) ✔ reward inventory cannot be reduced below its immutable awarded count (0.395556ms) ✔ daily eligibility uses server task count and timezone period boundaries (13.893577ms) ✔ task requirements are evaluated from authoritative integer counts (0.149275ms) ✔ cooldown eligibility is anchored to the last committed claim (0.302106ms) ✔ weighted selection uses an injected cryptographic ticket boundary (0.286752ms) ✔ exhausted rewards are excluded and fixed mode requires exactly one reward (0.788598ms) ✔ publishing enforces free-only configuration and a valid reward pool (0.764783ms) ✔ Admin payloads cannot introduce payment fields or unsafe money numbers (3.160425ms) ✔ eligible free claim reserves inventory, posts ledger, and stores evidence atomically (15.345706ms) ✔ insufficient verified task progress rolls back before reward or ledger mutation (0.87509ms) ✔ a committed idempotency key returns the original claim without a new transaction (0.447635ms) ✔ earning-restricted users cannot reserve inventory or receive a reward (5.560833ms) ✔ reject atomically refunds the full held gross amount, never only the net amount (3.764265ms) ✔ the first high-value approval remains under review and does not move money (0.303367ms) ✔ the required final approval transitions to approved with immutable approval evidence (0.516709ms) ✔ manual paid confirmation settles held gross into exact net payout and fee credits (0.848329ms) ✔ decrypted destination details are released only after stored hash verification (0.790732ms) ✔ payout confirmation rejects stale versions and non-approved states before settlement (1.043113ms) ✔ global and method rules combine using the stricter financial limits (1.569787ms) ✔ percentage fees round upward and all amounts stay decimal strings (0.580866ms) ✔ eligibility is derived from server account, task, referral, wallet, day, and cooldown state (0.932226ms) ✔ restricted and too-new accounts fail closed (0.181123ms) ✔ dynamic destination fields reject unknown values and produce a safe display mask (0.966427ms) ✔ dual approval is required only at or above the configured high-value threshold (0.158879ms) ✔ withdrawal payload schemas reject client-controlled totals and unsafe numeric amounts (4.66938ms) ✔ Admin method and setting schemas enforce consistent fees and optimistic versions (4.636009ms) ✔ invalid stored setting values fall back to conservative defaults (0.329237ms) ✔ quote derives fee and expiry on the server without posting ledger entries (15.495772ms) ✔ request atomically encrypts details, holds the gross amount, consumes quote, and records history (3.201267ms) ✔ a concurrent quote-consumption conflict rolls back the complete request transaction (1.44595ms) ✔ idempotent request replays must match the original canonical input fingerprint (0.58337ms) ✔ managed setting policy preserves the free-only Mystery Box boundary (0.909722ms) ✔ managed setting policy bounds pagination and normalizes allowlisted URLs (0.176496ms) ✔ theme payload accepts the closed token contract and rejects CSS injection (3.041676ms) ✔ feature flag mutation permits rollout only and rejects targeting objects (0.937905ms) ✔ currency input canonicalizes ISO-style codes and caps decimal precision (1.095322ms) ✔ maintenance windows require strictly ordered timestamps (1.003714ms) ✔ setting updates write an immutable next-version record in one transaction (1.707114ms) ✔ setting updates reject null when it violates the stored value type (0.73658ms) ✔ settlement currency precision cannot change after ledger setup (0.447144ms) ✔ publishing a theme retires the former active theme inside the transaction (0.632684ms) ✔ plain content is encoded into inert server-generated HTML (1.209694ms) ✔ banner validation requires verified-media identity and paired actions (2.327129ms) ✔ announcement targeting schema is strict and date ordered (1.781726ms) ✔ tutorial validation rejects client lifecycle and malformed slugs (0.845715ms) ✔ announcement targeting fails closed for missing or mismatched user attributes (0.193702ms) ✔ disabled banner feature avoids every content database read (0.820347ms) ✔ banner creation rejects media that is not verified and public (0.927718ms) ✔ future announcement publishing selects scheduled state on the server clock (1.312498ms) ✔ tutorial creation rejects a URL outside the deployment allowlist (0.806266ms) ✔ media resolution blocks storage paths that escape the public root (0.433483ms) ✔ Telegram templates preserve allowlisted markup and escape every variable (1.591689ms) ✔ Template buttons are HTTPS-only and expose one closed Telegram keyboard shape (0.714577ms) ✔ Internal Telegram payload contract rejects arbitrary methods, chats, and oversized text (2.665529ms) ✔ Outbox claims use leases and exponential retry is bounded and honors Telegram retry-after (0.76959ms) ✔ Outbox worker completes successes and records failures without logging payloads (0.475226ms) ✔ Telegram job rejects malformed success responses instead of recording a false delivery (0.394755ms) ✔ Reminder next-run calculation follows IANA local time and ISO weekdays (39.055562ms) ✔ Broadcast creator cannot approve their own draft (0.652003ms) ✔ Transactional amount placeholders format integer minor units without floating point (0.226811ms) ✔ analytics periods use closed UTC dates and ISO calendar boundaries (2.032204ms) ✔ earning-history cursors are scoped, signed, and reject tampering (1.257186ms) ✔ earning history emits only signed server ledger deltas and an opaque next cursor (0.572112ms) ✔ earning summary keeps integer minor units and reports reversals separately (0.47064ms) ✔ public leaderboard uses snapshots and never requests Telegram identifiers (0.496449ms) ✔ rollup is idempotent per closed date and builds every allowlisted snapshot (1.049002ms) ✔ Admin financial reports keep monetary values behind a separate service method (0.585052ms) ✔ profile contract accepts explicit leaderboard privacy without accepting identity fields (1.709697ms) ✔ miniapp money formatting preserves every BIGINT minor unit including negative fractions (15.897968ms) ✔ miniapp amount entry never uses floating point or accepts exponent notation (0.243858ms) ✔ miniapp navigation normalizes hashes and rejects malformed or traversal routes (0.98166ms) ✔ miniapp rejects credential-bearing and executable URLs (0.167092ms) ✔ withdrawal field validation mirrors allowed format and option contracts (1.071766ms) ✔ miniapp API rejects non-local paths before sending credentials (0.759265ms) ✔ miniapp shares CSRF retrieval and coalesces concurrent identical mutations (3.870405ms) ✔ failed CSRF requests can be retried and do not send a mutation (1.553743ms) ✔ uncertain financial mutations reuse the same key on deliberate retry (1.448614ms) ✔ API failures retain safe request references and distinguish timeout (1.702767ms) ✔ authentication never invents a development identity outside Telegram (0.642248ms) ✔ theme tokens reject CSS injection and reset stale per-theme overrides (1.171176ms) ✔ admin client rejects external and traversal destinations before sending credentials (1.98994ms) ✔ admin mutations coalesce and use the admin CSRF token without persisting credentials (3.505295ms) ✔ failed mutations are never automatically retried and preserve error context (0.586134ms) ✔ session invalidation discards late responses and does not send an awaiting mutation (0.525352ms) ✔ 401 invalidates authentication while 403 keeps an actionable permission error (0.872716ms) ✔ catalog hides ungranted resources and exact withdrawal decision controls (0.376978ms) ✔ minor units remain decimal strings and numeric configuration rejects unsafe integers (0.325411ms) ✔ forms preserve optional omission, explicit null, booleans and nested reward values (132.181403ms) ✔ create task form submits only supported server fields and keeps rewards precise (31.598628ms) ✔ editing plain content round-trips server HTML without double encoding (11.488838ms) ✔ reminder form reconstructs template keys and keeps nested audience rules (9.938719ms) ✔ template editor sends all strict fields and represents nullable button config (9.329955ms) ✔ settings editor fixes free-only protection and preserves server versions (12.213778ms) ✔ resource query only includes route-supported fields and identities are encoded (0.351653ms) ✔ login completes password challenge and TOTP without persisting a password (20.439588ms) ✔ withdrawal confirmation requires review and duplicate clicks share one request (16.084305ms) ✔ conflict keeps the draft visible and prevents immediate resubmission (23.324994ms) ✔ resource UI renders hostile text inert and ignores a disposed response (13.617315ms) ✔ dashboard renders daily chart and table from real response values and isolates financial reports (12.834358ms) ✔ search phrases with spaces and encoded URL punctuation stay on the local admin endpoint (0.568702ms) ✔ admin entry restores an authenticated shell and logout clears its private data (15.871873ms) ✔ administrator form loads named roles, reviews the request and displays a one-time invitation safely (107.780275ms) ✔ wallet correction editor creates a stable hidden idempotency key per draft (10.951ms) ✔ resolved fraud records offer no further review action (26.628176ms) ✔ enrollment accepts own password then verifies TOTP without retaining invitation or password fields (17.820835ms) ✔ closing enrollment while a response is pending cannot restore its secret (34.643113ms) ✔ enrollment API obtains anonymous admin CSRF and never exempts its mutations (1.33216ms) ✔ mobile authenticator app switching hides the setup key but permits returning with a code (14.789263ms) ✔ retry risk acknowledgement requires a deliberate checked choice (12.62769ms) ✔ administrative changes recheck active session and fresh permission before writing (3.848823ms) ✔ identity management cannot be delegated by assigning only a manage permission (0.964304ms) ✔ invitation stores only a token digest and does not provision active credentials (4.386553ms) ✔ self access changes and stale administrator versions cannot revoke the last operator (1.055301ms) ✔ administrator role/status change and session revocation commit together (2.060076ms) ✔ a cancelled, unenrolled administrator cannot be enabled through access editing (2.397955ms) ✔ built-in roles cannot be edited, while custom grants revoke assigned sessions (1.142373ms) ✔ account ban revokes sessions without leaving a permanent banned status after expiry (1.234061ms) ✔ unban removes only the selected scope and requires its separate permission (0.879846ms) ✔ competing fraud decisions have one winner and persist the review reason (1.111315ms) ✔ wallet correction preparation is idempotent and cannot change money (1.171566ms) ✔ wallet adjustment rejects self approval and posts exactly once under competing reviews (7.379356ms) ✔ insufficient debit rolls back review and ledger; rejection never changes money (0.595868ms) ✔ money and control inputs reject floats, forged actor fields and missing risk acknowledgement (5.481194ms) ✔ manual retry refuses sent, cancelled, unlinked, stale and permanent recipient failures (0.418971ms) ✔ manual retry retains attempt number/payload and only schedules one additional attempt (1.212918ms) ✔ retry rechecks delivery consent and cannot revive an ineligible campaign (0.229435ms) ✔ invitation enrollment consumes both tokens, encrypts TOTP, and returns recovery codes only once (6.850948ms) ✔ failed enrollment attempts commit their counter and stop verification after five codes (2.688414ms) ✔ outbox terminal failure records its linked job in the same executor and never writes for a lost lease (0.610991ms) ✔ administrative repositories bind arbitrary text and refuse arbitrary table names (0.359371ms) ✔ fraud evidence reveal redacts nested credentials and sensitive identity evidence (0.671613ms) ✔ release schema check is read-only and verifies the complete release (17.663901ms) ✔ release refuses missing schema history (20.622752ms) ✔ release refuses changed schema history (16.978597ms) ✔ release refuses missingSeed schema history (13.489708ms) ✔ release refuses partial schema history (9.282425ms) ✔ Redis fails immediately while offline and bounds queued commands (0.317429ms) ✔ production rejects unsafe DATABASE_QUEUE_LIMIT=0 (8.330399ms) ✔ production rejects unsafe REDIS_URL=redis://default:valid-pass@remote.internal:6379 (1.238347ms) ✔ production rejects unsafe REDIS_URL=redis://127.0.0.1:6379 (1.948087ms) ✔ live acceptance cannot select a production database or an unconfirmed target (0.504531ms) ✔ backup roundtrip preserves binary bytes and private output permissions (22.378439ms) ✔ backup rejects wrong-key and removes unauthenticated plaintext (12.214165ms) ✔ backup rejects ciphertext and removes unauthenticated plaintext (6.873593ms) ✔ backup rejects tag and removes unauthenticated plaintext (5.22696ms) ✔ backup rejects header and removes unauthenticated plaintext (2.695014ms) ✔ backup rejects truncated and removes unauthenticated plaintext (3.03115ms) ✔ backup rejects size-limit and removes unauthenticated plaintext (7.858979ms) ✔ backup and restore never overwrite an existing output (3.380467ms) ✔ backup key rejects malformed, ambiguous or short key material (0.362626ms) ✔ completed polling intervals release abort listeners over repeated cycles (28.213626ms) ✔ readiness times out even when the database connection queue never resolves (16.428563ms) ✔ database backup CLI publishes only a successful dump (failure=false) (82.115778ms) ✔ database backup CLI publishes only a successful dump (failure=true) (70.010742ms) ✔ admin user list schema caps page sizes and rejects deleted pseudo-filter (3.021816ms) ✔ admin user mappings preserve large numeric values as strings (0.876692ms) ✔ admin user list uses normalized pagination and parallel repository reads (0.524921ms) ✔ admin user detail combines profile, restrictions, wallets, and metrics (0.476589ms) ✔ cache returns a valid hit without invoking the loader (1.352249ms) ✔ cache fails open on malformed reads and write failures (0.340394ms) ✔ cache does not persist oversized responses (0.584071ms) ✔ local day and week boundaries are converted to UTC for Dhaka (13.96949ms) ✔ day boundaries respect daylight-saving transitions (0.560805ms) ✔ database and offset datetimes normalize to the same UTC representation (0.47058ms) ✔ theme tokens accept a closed safe schema and reject CSS injection (0.601917ms) ✔ setting guards accept only usable locale lists and IANA timezones (12.593457ms) ✔ bootstrap combines safe public configuration with user-scoped state (0.923993ms) ✔ dashboard returns decimal-safe strings and never exposes task destination URLs (2.676986ms) ✔ feature gates prevent disabled task and free-reward database reads (0.953277ms) ✔ database numeric guards reject unsafe representations (0.378691ms) ✔ free reward eligibility is display-only and honors frequency boundaries (0.204708ms) ✔ profile schema rejects Telegram-owned and financial fields (2.734502ms) ✔ profile reads expose Telegram IDs as strings and only public fields (2.156702ms) ✔ profile update validates flags/settings before opening a transaction (12.811946ms) ✔ disabled profile editing fails before a database transaction begins (0.621878ms) ✔ unsupported language and invalid timezone are rejected server-side (0.400354ms) ✔ memory rate-limit store increments and resets fixed windows (1.223725ms) ✔ Redis rate-limit store uses one atomic script and namespaced keys (0.442066ms) ✔ Redis client factory applies TLS verification and bounded reconnects (0.250518ms) ✔ Redis connection, readiness cache, and close lifecycle are bounded (0.454405ms) ✔ database readiness is cached and concurrent checks share one query (1.022732ms) ✔ database readiness fails closed without throwing dependency details (1.252689ms) ✔ migration runner applies each immutable migration once under a schema lock (2.565959ms) ✔ migration runner resumes after a partial DDL failure without replaying recorded statements (1.018045ms) ✔ migration runner rejects a changed file after it has been applied (0.818254ms) ✔ seeds require all migrations, run once, and rollback invalidates seed history (2.473289ms) ✔ validation middleware stores only schema-approved data and returns safe issues (6.745881ms) ✔ maintenance and ban gates use trusted server-side providers (0.642969ms) ✔ idempotency middleware hashes accepted keys and rejects duplicates (1.142563ms) ✔ audit middleware records completed mutations without delaying responses (8.238761ms) ✔ HMAC signatures are deterministic and reject modified input (1.226839ms) ✔ CSRF tokens are signed, session-bound, and time-limited (0.575097ms) ✔ secure random and idempotency helpers enforce bounded keys (0.349437ms) ✔ managed URL allowlist requires approved schemes, domains, and credential-free URLs (0.349557ms) ✔ HTML and plain-text helpers encode markup and remove unsafe controls (0.321455ms) ✔ SQL splitter preserves quoted semicolons and removes comments (0.830602ms) ✔ migration parser requires both sections and rejects session control (0.891905ms) ✔ seed parser accepts one section and checksum is deterministic (0.49101ms) ✔ all migration and seed files load in contiguous order (41.665757ms) ✔ Telegram exchange creates one user, first-touch referral, and opaque session atomically (2.439588ms) ✔ existing Telegram users retain their internal database ID during profile sync (0.333413ms) ✔ simultaneous first login recovers from a unique-user insert race (0.674016ms) ✔ Telegram API client sends JSON webhook settings and exposes no token on failure (2.19581ms) ✔ bot command routing is private-chat only and preserves a bounded referral payload (0.416768ms) ✔ Mini App keyboards require HTTPS and Telegram HTML is escaped (0.268695ms) ✔ webhook service acknowledges duplicates and retries failed processing safely (0.27844ms) ✔ failed webhook retries cannot replace the payload for an existing update ID (0.717442ms) ✔ Telegram initData validates HMAC, freshness, and bigint-safe identity strings (4.353674ms) ✔ Telegram initData rejects tampering, expiry, future dates, and duplicate protected fields (2.601232ms) ✔ Telegram initData rejects bot users and unsafe numeric identities (1.415674ms) ✔ user sessions store only a hash and emit an HttpOnly secure cookie (1.741166ms) ✔ cookie and IP parsing fail safely on malformed values (3.54857ms) ✔ session authentication maps public identity and rolls idle expiry server-side (0.462657ms) ✔ public IDs are 26-character sortable Crockford identifiers (0.376478ms) ℹ tests 437 ℹ suites 0 ℹ pass 437 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0 ℹ duration_ms 3329.297979 [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.0 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: 87/87 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.0 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 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.0 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.0 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.0 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.0 verify:project > node scripts/verify-project.js Phase 19 project verification passed: 81 directories, 510 required files, and 38 npm scripts. Phase 20 quality gate passed.