mirror of
https://github.com/Shineii86/MiruroAPI.git
synced 2026-10-22 18:25:11 +00:00
pipe.js now tries 3 methods in order with automatic fallback: 1. Direct — mirror rotation (.ru → .to → .bz → .tv) with browser headers 2. ScraperAPI — free proxy (1K req/mo, no CC required) 3. FlareSolverr — self-hosted browser proxy (solves Cloudflare Turnstile) When one method fails (403/timeout), the next is tried automatically. Zero-config: works without any env vars. Add SCRAPER_API_KEY or FLARESOLVERR_URL for Cloudflare bypass. New endpoint: /api/pipe-health — tests all configured methods, reports latency and working/failed status, recommends preferred method. Files changed: - src/helpers/pipe.js — methodDirect(), methodScraperAPI(), methodFlareSolverr(), pipeHealthCheck() - src/routes/apiRoutes.js — added /api/pipe-health endpoint - .env.example — documented SCRAPER_API_KEY, FLARESOLVERR_URL Version bumped to 2.3.0 across package.json, server.js, /api/health, /api/openapi, public/openapi.json. CHANGELOG updated.
350 lines
17 KiB
Markdown
350 lines
17 KiB
Markdown
# Changelog
|
|
|
|
## v2.3.0
|
|
### Self-Healing Fallback System — Auto-Recovery from Cloudflare Blocks
|
|
|
|
#### New: Multi-Method Fallback System
|
|
Pipe requests now try **3 methods in order** with automatic fallback:
|
|
1. **Direct** — mirror rotation across `.ru` → `.to` → `.bz` → `.tv` with browser headers
|
|
2. **ScraperAPI** — proxy through `api.scraperapi.com` (free 1,000 req/month, no CC)
|
|
3. **FlareSolverr** — self-hosted browser proxy that solves Cloudflare Turnstile
|
|
|
|
When one method fails (403/timeout), the next is tried automatically. No manual intervention needed.
|
|
|
|
#### New Endpoint: `/api/pipe-health`
|
|
Diagnostic endpoint that tests all configured methods and reports:
|
|
- Which methods are working/failed
|
|
- Latency for each method
|
|
- Recommendation on preferred method
|
|
|
|
```
|
|
GET /api/pipe-health
|
|
→ { methods: { direct: {status:"ok"}, scraperapi: {status:"skipped"} }, working: 1, ... }
|
|
```
|
|
|
|
#### Configuration (all optional, zero-config to start)
|
|
| Env Var | Purpose | Free? |
|
|
|---------|---------|-------|
|
|
| `SCRAPER_API_KEY` | ScraperAPI proxy | Yes (1K req/mo) |
|
|
| `FLARESOLVERR_URL` | FlareSolverr browser | Yes (self-hosted) |
|
|
| `PIPE_OBF_KEY` | XOR decode key | N/A |
|
|
|
|
#### How it works
|
|
```
|
|
Client → /api/episodes/20
|
|
↓ pipeRequest()
|
|
├─ Try direct → 403 (Cloudflare block)
|
|
├─ Try ScraperAPI → 200 ✓ (returns data)
|
|
└─ Cache result, return to client
|
|
```
|
|
|
|
#### Files Changed
|
|
- `src/helpers/pipe.js` — rewritten with `methodDirect()`, `methodScraperAPI()`, `methodFlareSolverr()`, `pipeHealthCheck()`
|
|
- `src/routes/apiRoutes.js` — added `/api/pipe-health` endpoint
|
|
- `.env.example` — documented `SCRAPER_API_KEY`, `FLARESOLVERR_URL`
|
|
|
|
#### Notes
|
|
- Zero-config: works without any env vars (direct only)
|
|
- Add `SCRAPER_API_KEY` for free Cloudflare bypass (no server needed)
|
|
- Add `FLARESOLVERR_URL` for self-hosted browser bypass (needs Docker/VPS)
|
|
- All methods use the same pipe protocol (base64+gzip, x-obfuscated header)
|
|
|
|
## v2.2.0
|
|
### Critical Fix — Miruro Pipe Protocol Migration (Streaming Endpoints Restored)
|
|
|
|
#### Diagnostic Summary
|
|
- **Full diagnostic sweep** of all live `/api/*` endpoints against `mirurotvapi.vercel.app`
|
|
- **AniList-backed endpoints** (`/search`, `/trending`, `/info`, `/popular`, `/top`, …) — confirmed **all 200/healthy**
|
|
- **Streaming endpoints** (`/episodes`, `/sources`, `/stream`, `/watch`, `/download`) — **all 500**
|
|
- Deep-scanned the Miruro frontend (`miruro.to/.bz/.ru`) bundles + `env2.js` to reverse-engineer the new pipe contract
|
|
|
|
#### Root Cause (streaming failure)
|
|
1. **Dead data source** — `pipe.js` targeted `https://www.miruro.tv/api/secure/pipe`, which is now hard-blocked by Cloudflare (returns 403 "Sorry, you have been blocked" page).
|
|
2. **Stale decode protocol** — the old `decode()` always did `base64url → XOR(PIPE_OBF_KEY) → gunzip`. Miruro's pipe now **signals the scheme via a response header**:
|
|
- `x-obfuscated` absent → plain JSON
|
|
- `x-obfuscated: 1` → `base64url(gzip(json))` (**no XOR**)
|
|
- `x-obfuscated: 2` → `base64url(XOR(gzip(json)))` with `PIPE_OBF_KEY`
|
|
- The hard-coded always-XOR decode corrupted the new `:1` payloads.
|
|
|
|
#### Fixes
|
|
- **`src/helpers/pipe.js`**
|
|
- New **mirror rotation** list: `miruro.ru` → `miruro.to` → `miruro.bz` → `miruro.tv`, iterating one mirror per retry.
|
|
- **New header-driven `decodePipeResponse(text, obfHeader)`** supporting plain / scheme-1 / scheme-2.
|
|
- **Browser-accurate request headers** (UA + `Accept`, `Accept-Language`, full `sec-ch-ua` / `sec-fetch-*` family) to pass Cloudflare bot fingerprinting rather than just UA+Referer.
|
|
- Request payload reverted to **plain base64url of the JSON** (no XOR on the request) matching the current client.
|
|
- Subtitle-proxy referer updated to canonical `https://www.miruro.to/`.
|
|
- Default `maxRetries` bumped 3 → 4 so each mirror gets an attempt; 403/444 now rotate instead of failing.
|
|
- **`api/proxy.js`** — default CDN referer/Origin switched from the dead `miruro.tv` to the canonical `miruro.to`.
|
|
- **Version bump** to `2.2.0` across `package.json`, `server.js` banner, `/api/health`, `/api/openapi`, and `public/openapi.json`.
|
|
|
|
#### Notes
|
|
- Streaming endpoints depend on Miruro's upstream pipe, which sits behind Cloudflare bot protection and may intermittently rate-limit datacenter egress IPs. The new rotation + browser headers + retry logic maximizes success; AniList endpoints are unaffected and remain fully healthy.
|
|
|
|
## v2.1.4
|
|
### Security Hardening, Bug Fixes, Code Quality Improvements
|
|
|
|
#### Security
|
|
- **XOR keys moved to env vars** — `PRU_PROXY_KEY` and `PIPE_OBF_KEY` no longer hardcoded in source (proxy.js, pipe.js)
|
|
- **CORS restricted in production** — returns 403 when `ALLOWED_ORIGINS` is set and origin doesn't match
|
|
- **Input sanitization** — new `sanitizeId()` and `sanitizeString()` helpers applied to all route params (character, staff, studio, genre, year, status, format, season)
|
|
- **Security headers in vercel.json** — added at CDN level for faster response
|
|
|
|
#### Bug Fixes
|
|
- **multi-search** — now actually combines query + filters (was ignoring `q` when filters present)
|
|
- **`filterAnime`** — added `search` parameter and `SEARCH_MATCH` sort option
|
|
- **`getTrendingWeekly`** — now returns 40 results (was identical to daily with 20)
|
|
- **`calendar`** — fetches 200 results instead of 50 (was missing late-month shows)
|
|
- **`getBestStream`** — improved quality matching (checks quality/label fields), supports HLS+DASH, better fallback
|
|
- **`deepTranslate`** — now returns deep clone instead of mutating in-place (prevents cache corruption)
|
|
- **Version strings** — updated to 2.1.3 in server.js and test.js
|
|
|
|
#### Code Quality
|
|
- **Deleted `server.py`** — dead Flask code, not used on Vercel
|
|
- **Rate limiter** — aggressive cleanup on serverless (prunes empty entries every request)
|
|
- **`stats/genre`** — uses `Promise.allSettled` for parallel execution (faster, safer)
|
|
|
|
#### Config
|
|
- **vercel.json** — added security headers at CDN level
|
|
- **.env.example** — added `PRU_PROXY_KEY`, `PIPE_OBF_KEY` documentation
|
|
|
|
## v2.1.3
|
|
### Diagnostic Sweep — Bug fixes, security, AniList query corrections
|
|
|
|
#### Full Diagnostic Sweep Results
|
|
- Tested all 44 endpoints across 10 sections
|
|
- Found and fixed 5 bugs
|
|
- Added missing security headers
|
|
|
|
#### Bug Fixes
|
|
- **Tags endpoint**: `data.TagCollection` → `data.MediaTagCollection` (was returning empty array)
|
|
- **Random endpoint**: Added `Cache-Control: no-store` headers + `Date.now() % 499` for true randomness (CDN was caching rapid requests)
|
|
- **Character/Staff 404**: Now returns HTTP 404 instead of 500 on not-found
|
|
- **Character query**: Removed `dateOfDeath` (not in AniList schema), `role` → `characterRole`
|
|
- **Staff query**: Removed `dateOfDeath` and invalid `role` field
|
|
- **Studio query**: Removed `type: ANIME` from `Studio.media` (not supported by AniList)
|
|
- **Tags query**: `TagCollection` → `MediaTagCollection`, removed `rank` field
|
|
- **Trending**: Removed invalid `trending: 7/30` args (not in AniList schema)
|
|
|
|
#### Security
|
|
- Added `X-XSS-Protection: 1; mode=block` header
|
|
|
|
#### Pipe Resilience
|
|
- Added `pipeRequest()` helper with retry logic and exponential backoff (3 attempts: 1s, 2s, 4s delays)
|
|
- Cached episodes (5 min) and sources (10 min) responses
|
|
- Confirmed kiwi/bonk CDNs serve real content, bee/ally serve decoys
|
|
- Fixed `getWatchSources` slug matching for both raw and slugged episode IDs
|
|
|
|
#### Performance
|
|
- Fastest: `/providers` ~0.8s (static data)
|
|
- Average: Most endpoints ~1.0-2.0s
|
|
- Slowest: `/stats/genre` ~5.7s (10 AniList queries)
|
|
|
|
## v2.1.2
|
|
### Streaming Architecture — pru proxy + raw CDN URLs
|
|
|
|
#### Streaming Pipeline Discovery
|
|
- Decoded pru.ultracloud.cc URL format: `base64url(XOR(url, key))~base64url(XOR(referer, key))/pl.m3u8`
|
|
- Key: `a54d389c18527d9fd3e7f0643e27edbe` (16-byte XOR)
|
|
- pru rewrites ALL M3U8 URLs (master, variant, segments) to proxy through itself
|
|
- CDN at mt.nekostream.site serves decoy PNG images to all server-side requests
|
|
|
|
#### Proxy Changes
|
|
- `/api/proxy` now handles both pru-encoded URLs (decodes + re-encodes) and direct CDN URLs (for subtitles)
|
|
- Stream URLs returned as raw CDN URLs (browser loads directly — CDN has CORS *)
|
|
- Subtitle URLs proxied through `/api/proxy` (third-party CDNs may lack CORS)
|
|
- Added `Origin: https://www.miruro.tv` header to pipe requests
|
|
|
|
#### Known Limitations
|
|
- Pipe sources endpoint returns 444 from Cloudflare for datacenter IPs
|
|
- Client-side pipe blocked by CORS (only allows miruro.tv origin)
|
|
- CDN segments serve PNG decoys to server IPs
|
|
- Video playback requires further investigation — likely needs miruro.tv domain or alternative streaming source
|
|
|
|
## v2.1.1
|
|
### Bug Fix — Pipe response XOR decoding
|
|
|
|
#### Fix
|
|
- `decodePipeResponse` now XOR-decodes with obfuscation key before gzip decompression — pipe was returning XOR+gzip, not plain gzip
|
|
- Updated pipe version from `0.1.0` to `0.2.0` to match miruro.tv
|
|
- `getWatchSources` now properly returns streams (was always failing before this fix)
|
|
|
|
## v2.1.0
|
|
### Major Feature Update — Provider capabilities, enriched metadata, skip times
|
|
|
|
#### New Endpoints
|
|
- GET /api/providers — Provider capabilities and configuration (12 providers with full metadata)
|
|
|
|
#### Anime Info Enrichment
|
|
- Added `alternateName` — multiple language titles from synonyms
|
|
- Added `aggregateRating` — rating with count, mean score
|
|
- Added `sameAs` — external links (AniList, MAL, official sites)
|
|
- Added `externalLinks` — structured external links with site/type
|
|
- Added `productionCompany` — non-animation studios
|
|
- Added `animationStudio` — animation studios
|
|
- Added `trailer` — anime trailer info
|
|
- Added `nextAiringEpisode` — next episode air time
|
|
- Added `tags` — simplified tag names array
|
|
|
|
#### Streaming Improvements
|
|
- Added `extractSkipTimes` — extract OP/ED skip timestamps from sources
|
|
- Added `skipTimes` field to /stream and /watch responses
|
|
- Episode thumbnails already included in pipe response
|
|
|
|
#### Provider Capabilities (from miruro.tv __SSR_CONFIG__)
|
|
- kiwi: sub, download
|
|
- pewe: sub
|
|
- bonk: sub, ssub, download, skip_times
|
|
- bee: ssub
|
|
- ally: sub, download, thumbnails
|
|
- moo: sub, download
|
|
- hop: ssub, thumbnails
|
|
- nun: sub (embed of ally)
|
|
- bun: ssub (embed of bee)
|
|
- twin: sub, ssub (embed of bonk)
|
|
- cog: sub (embed of moo)
|
|
- telli: sub (embed of kiwi, hidden)
|
|
|
|
---
|
|
|
|
## v2.0.1
|
|
### Streaming Improvements — Better subtitle extraction, quality fallback
|
|
|
|
#### Streaming Enhancements
|
|
- Improved `extractSubtitles` — now handles multiple provider formats (bonk: file/label/kind/language, others: url/name/lang)
|
|
- Updated `getBestStream` — falls back to first active HLS stream when quality metadata is missing
|
|
- Updated `getDownloadUrl` — now returns subtitles and bestStream in response
|
|
- Added subtitle fields: url, label, language, kind, format, encoding, isDefault
|
|
|
|
#### Provider Improvements
|
|
- Bonk provider confirmed to return subtitles (English, VTT format, captions kind)
|
|
- Better handling of providers without quality metadata (bonk, ally, bee return undefined quality)
|
|
|
|
#### Verified
|
|
- Subtitle extraction working: bonk provider returns 1 English subtitle per episode
|
|
- Download URL working: bonk provider returns direct download link
|
|
- Batch sources: subtitles included in batch responses
|
|
|
|
---
|
|
|
|
## v2.0.0
|
|
### Major Release — 35 endpoints, streaming improvements, new features
|
|
|
|
#### Technical Foundation
|
|
- Added gzip compression middleware (30-70% response size reduction)
|
|
- Added request logging with method, path, status, duration, IP
|
|
- Added Cache-Control headers for API responses (varies by endpoint type)
|
|
- Improved CORS with preflight caching (24h max-age)
|
|
- Health endpoint now includes memory stats (heap, RSS), cache size, node version
|
|
|
|
#### New AniList Helpers (11 new functions)
|
|
- getAllGenres — complete genre list from AniList
|
|
- getAllTags — complete tag list with metadata
|
|
- getTopAnime — top-rated anime of all time (SCORE_DESC)
|
|
- getTrendingDaily — trending anime (last 7 days)
|
|
- getTrendingWeekly — trending anime (last 30 days)
|
|
- getSeasonalAnime — anime by year + season (e.g., 2025/Spring)
|
|
- getAnimeByStudio — anime produced by a specific studio
|
|
- getCharacterInfo — character detail with anime list
|
|
- getStaffInfo — staff detail with anime list
|
|
- searchCharacters — search characters by name
|
|
- searchStaff — search staff by name
|
|
|
|
#### New Streaming & Download Features
|
|
- extractSubtitles — extract subtitle URLs from sources
|
|
- getBestStream — automatic quality fallback (1080p → 720p → 360p)
|
|
- getDownloadUrl — dedicated download URL endpoint
|
|
- getBatchSources — fetch multiple episode sources in parallel
|
|
|
|
#### New API Endpoints (17 new)
|
|
- GET /api/trending/daily — daily trending anime
|
|
- GET /api/trending/weekly — weekly trending anime
|
|
- GET /api/top — top anime by score
|
|
- GET /api/random — random anime of the day
|
|
- GET /api/multi-search — combined query + filters
|
|
- GET /api/season/:year/:season — seasonal anime
|
|
- GET /api/studio/:name — anime by studio
|
|
- GET /api/genres — all genres list
|
|
- GET /api/tags — all tags list
|
|
- GET /api/genre/:name — anime by genre
|
|
- GET /api/year/:year — anime by year
|
|
- GET /api/status/:status — anime by status
|
|
- GET /api/format/:format — anime by format
|
|
- GET /api/character/:id — character detail
|
|
- GET /api/staff/:id — staff detail
|
|
- GET /api/characters — search characters
|
|
- GET /api/staff — search staff
|
|
- GET /api/episodes/:id/batch — batch episode sources
|
|
- GET /api/stream — streaming with quality fallback
|
|
- GET /api/download — download URL
|
|
- GET /api/compare/:id1/:id2 — compare two anime
|
|
- GET /api/stats/genre — genre statistics
|
|
- GET /api/calendar — monthly airing calendar
|
|
- GET /api/timeline/:id — anime release timeline
|
|
|
|
#### Streaming Improvements
|
|
- Subtitle URL extraction from pipe responses
|
|
- Quality fallback: tries 1080p → 720p → 480p → 360p automatically
|
|
- Batch episode fetching (up to 5 parallel requests)
|
|
- Dedicated download endpoint with provider metadata
|
|
- Cache headers: episodes/sources (2min), info (5min), genres/tags (24h)
|
|
|
|
#### Version synced to 2.0.0 across all files
|
|
|
|
## v1.4.0
|
|
- Added creator attribution middleware — injects author info into every response
|
|
- Fixed Vercel deployment: replaced legacy `builds`/`routes` config with modern `functions` config
|
|
- Added `api/index.js` serverless entry point
|
|
- Security headers: removed deprecated `X-XSS-Protection`, added `Strict-Transport-Security` (HSTS)
|
|
- Rate limiter: uses `x-forwarded-for` header for correct IP detection on Vercel
|
|
- Rate limiter: added periodic IP entry pruning when >200 IPs tracked
|
|
- Cache: added periodic expired entry cleanup when cache reaches 80% capacity
|
|
- Version synced to 1.4.0
|
|
|
|
## v1.3.0
|
|
- Full landing page upgrade to match AniKotoAPI style
|
|
- Added canvas particle effects with cyan-colored floating particles
|
|
- Added scroll-reveal animations (IntersectionObserver)
|
|
- Added animated stat counters that count up on scroll
|
|
- Added infinite scrolling marquee with 8 feature badges
|
|
- Added live interactive API console with 5 preset endpoint buttons
|
|
- Added sidebar endpoint explorer with 16 endpoints and multi-language code tabs
|
|
- Added 4 interactive playground cards (Search, Info, Episodes, Trending)
|
|
- Added custom scrollbar styling
|
|
- Added JetBrains Mono font for code blocks
|
|
- Added 4-column grid footer
|
|
- Added fixed header with scroll-aware blur/glass effect
|
|
- Added ambient orb gradient animations
|
|
- Added CTA section with gradient overlay
|
|
- Color scheme updated to match MiruroAPI brand (cyan #38bdf8 + indigo #818cf8)
|
|
- All branding updated: AniKotoAPI references → MiruroAPI
|
|
- OG/Twitter meta tags updated for mirurotvapi.vercel.app
|
|
- JSON-LD structured data updated
|
|
- Real Miruro SVG favicons used in header and footer
|
|
|
|
## v1.2.0
|
|
- Fixed critical response format bug: all endpoints now return {success: true, results: data}
|
|
- Root cause: createApiRoutes() had (app, jsonResponse, jsonError) but was called with (jsonResponse, jsonError), shifting all params
|
|
- Every jsonResponse() call was actually calling jsonError(), returning {success: false, message: data}
|
|
- Health endpoint worked because it used res.json() directly, bypassing the wrapper
|
|
- All 18 endpoints verified working
|
|
|
|
## v1.1.0
|
|
- Added Swagger UI interactive docs at /docs
|
|
- Added OpenAPI 3.0 spec at /openapi.json
|
|
- Added mappings field in episodes response
|
|
- Added Docker support (Dockerfile + .dockerignore)
|
|
- Improved landing page with premium design
|
|
- Added "Try it" buttons on all endpoints
|
|
- Health endpoint now includes version, providers list, and endpoint count
|
|
- Version bump to 1.1.0
|
|
|
|
## v1.0.0
|
|
- Initial release
|
|
- AniList GraphQL integration for anime metadata
|
|
- Miruro pipe integration for streaming sources
|
|
- 16 API endpoints: search, suggestions, trending, popular, upcoming, recent, spotlight, schedule, filter, info, characters, relations, recommendations, episodes, sources, watch
|
|
- In-memory caching with TTL
|
|
- CORS support
|
|
- Health endpoint
|
|
- Deployed on Vercel
|