Skip to content

AllAnime [EN]: Support mkissa stream encryption and move site domain to mkissa.to - #619

Merged
Alpha-782 merged 8 commits into
yuzono:masterfrom
Red1tum:allanime-mkissa-encryption
Jul 26, 2026
Merged

AllAnime [EN]: Support mkissa stream encryption and move site domain to mkissa.to#619
Alpha-782 merged 8 commits into
yuzono:masterfrom
Red1tum:allanime-mkissa-encryption

Conversation

@Red1tum

@Red1tum Red1tum commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Checklist:

  • Updated extVersionCode value in build.gradle for individual extensions
  • Updated overrideVersionCode or baseVersionCode as needed for all multisrc extensions
  • Referenced all related issues in the PR body (e.g. "Closes #xyz")
  • Added the isNsfw = true flag in build.gradle when appropriate
  • Have not changed source names
  • Have explicitly kept the id if a source's name or language were changed
  • Have tested the modifications by compiling and running the extension through Android Studio
  • Have removed web_hi_res_512.png when adding a new extension
  • This PR is AI-assisted, I have reviewed the changes manually and confirmed they are not slop
  • Have made sure all the icons are in png format

Closes #607

AllAnime broke video playback after moving to mkissa and reworking how it serves stream sources. This updates the extension to fetch and decrypt sources the new way, and switches off the dead allmanga.to domain to mkissa.to.

Add a 👍 reaction to pull requests you find important.

Summary by Sourcery

Update the AllAnime extension to work with mkissa.to’s new encrypted stream API and updated site URLs.

New Features:

  • Add aaReq key management and AES-GCM crypto support for fetching encrypted stream sources from mkissa.to.
  • Expose episode watch-page URLs for WebView using the new /anime/{showId}/p-{episodeString}-{translationType} path.

Bug Fixes:

  • Restore video playback by correctly fetching and decrypting stream source URLs after AllAnime’s backend changes.

Enhancements:

  • Switch the default site domain from allmanga.to to mkissa.to and migrate existing preferences transparently.
  • Simplify player iframe handling by using the site’s default player domain instead of runtime version discovery.
  • Improve resilience to server-side crypto rotations by caching key material and auto-healing the client mask when it changes.

Build:

  • Bump the AllAnime extension version code to 56.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @Red1tum, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@Red1tum
Red1tum marked this pull request as draft July 11, 2026 06:27
@Red1tum Red1tum changed the title Allanime [EN]: Add support for new mkissa stream encryption AllAnime [EN]: Support mkissa stream encryption and move site domain to mkissa.to Jul 11, 2026
@Red1tum
Red1tum force-pushed the allanime-mkissa-encryption branch from 9b858db to 430488c Compare July 11, 2026 07:47
@Red1tum
Red1tum force-pushed the allanime-mkissa-encryption branch from 430488c to a1e03d4 Compare July 11, 2026 08:08
@Red1tum
Red1tum marked this pull request as ready for review July 11, 2026 08:14
@sourcery-ai

sourcery-ai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Updates the AllAnime extension to work with mkissa.to’s new encrypted stream API by introducing an aaReq key manager/crypto helper, switching site domain and URLs, and refactoring video list fetching and decryption logic around the new scheme.

Sequence diagram for AllAnime encrypted stream fetching with aaReq

sequenceDiagram
    actor User
    participant AllAnime
    participant AllAnimeKeyManager
    participant AllAnimeCrypto
    participant AllAnimeApi

    User ->> AllAnime: getVideoList(episode)
    AllAnime ->> AllAnime: fetchSourceUrls(episode)

    loop up to MAX_KEY_ATTEMPTS
        AllAnime ->> AllAnimeKeyManager: material(forceRefresh)
        AllAnimeKeyManager ->> AllAnimeCrypto: deriveKey(mask, partB)
        AllAnimeCrypto -->> AllAnimeKeyManager: SecretKeySpec
        AllAnimeKeyManager -->> AllAnime: Material

        AllAnime ->> AllAnimeKeyManager: aaReq(material)
        AllAnimeKeyManager -->> AllAnime: aaReq token

        AllAnime ->> AllAnimeApi: videoListRequest(episode, material)
        AllAnimeApi -->> AllAnime: responseBody

        alt encrypted payload present
            AllAnime ->> AllAnimeKeyManager: decrypt(tobeparsed, material)
            AllAnimeKeyManager ->> AllAnimeCrypto: decrypt(base64Payload, material.key)
            AllAnimeCrypto -->> AllAnimeKeyManager: decrypted JSON
            AllAnimeKeyManager -->> AllAnime: DecryptedEpisodeResult
        else unencrypted and not isCryptoError(responseBody)
            AllAnime -->> AllAnime: EpisodeResult
        end

        alt sourceUrls parsed
            AllAnime -->> User: List<Video>
            break exit loop
            end
        else isCryptoError(responseBody)
            AllAnime ->> AllAnimeKeyManager: healMask()
            AllAnimeKeyManager ->> AllAnimeCrypto: hexToBytesOrNull(hex)
            AllAnimeCrypto -->> AllAnimeKeyManager: mask bytes
            AllAnimeKeyManager -->> AllAnime: healed
        end

        AllAnime ->> AllAnimeKeyManager: invalidate()
    end

    AllAnime -->> User: error if no sourceUrls
Loading

File-Level Changes

Change Details Files
Implement mkissa aaReq key management and AES-GCM crypto utilities for fetching and decrypting stream sources.
  • Introduce AllAnimeKeyManager to fetch window.__aaCrypto bootstrap from mkissa, derive a client AES key from mask XOR partB, cache it with TTL, and expose aaReq and decrypt helpers.
  • Add AllAnimeCrypto utility to derive keys, build aaReq payloads with time-bucketed IVs, decrypt encrypted payloads using both legacy and new keys, and handle hex mask conversion.
  • Add DTOs for aaReq payload, crypto bootstrap, GraphQL error envelopes, and episode variables used in new API calls.
src/en/allanime/src/eu/kanade/tachiyomi/animeextension/en/allanime/AllAnimeKeyManager.kt
src/en/allanime/src/eu/kanade/tachiyomi/animeextension/en/allanime/AllAnimeCrypto.kt
src/en/allanime/src/eu/kanade/tachiyomi/animeextension/en/allanime/AllAnimeDto.kt
Refactor video fetching to use aaReq-based API calls, new episode URL formats, and improved error handling instead of the old static decryptTobeparsed path.
  • Replace videoListRequest with a new overload that injects aaReq from AllAnimeKeyManager into GraphQL extensions and returns a built HttpUrl instead of String.
  • Introduce fetchSourceUrls to loop over key material attempts, call the new videoListRequest, handle encrypted vs plaintext responses, detect AA_CRYPTO error codes, and try mask healing before failing.
  • Remove legacy decryptTobeparsed and static crypto constants now superseded by AllAnimeCrypto.
  • Change getEpisodeUrl to construct mkissa watch URLs from parsed EpisodeVariables instead of old slug/time format and mark the original videoListRequest override as unsupported.
  • Stop querying /getVersion for episode iframe domain and use a fixed PLAYER_DOMAIN constant for iframeEndpoint when resolving servers.
src/en/allanime/src/eu/kanade/tachiyomi/animeextension/en/allanime/AllAnime.kt
src/en/allanime/src/eu/kanade/tachiyomi/animeextension/en/allanime/extractors/AllAnimeExtractor.kt
Switch the site domain configuration from allmanga.to to mkissa.to and adjust preference handling and URLs accordingly.
  • Update PREF_SITE_DOMAIN_DEFAULT and preference entries/values from https://allmanga.to to https://mkissa.to and add LEGACY_SITE_DOMAIN constant.
  • Add a preferences lazy initializer side-effect that automatically migrates stored preferred_site_domain from the legacy domain to mkissa.to.
  • Update getAnimeUrl to use the new /anime/{id} path and simplify url parsing to only use the id segment.
  • Change PLAYER_DOMAIN constant to https://allanime.day for iframe hosts and remove FALLBACK_PLAYER_DOMAIN.
  • Wire SourceUrl type alias import where source URLs are consumed.
src/en/allanime/src/eu/kanade/tachiyomi/animeextension/en/allanime/AllAnime.kt
Update extension metadata and clean up unused types tied to the old implementation.
  • Remove VersionResponse from AllAnimeExtractor since episodeIframeHead is no longer fetched from /getVersion.
  • Bump extVersionCode from 55 to 56 to reflect the new mkissa stream support.
src/en/allanime/src/eu/kanade/tachiyomi/animeextension/en/allanime/extractors/AllAnimeExtractor.kt
src/en/allanime/build.gradle

Assessment against linked issues

Issue Objective Addressed Explanation
#607 Restore video playback for AllAnime (EN) episodes by supporting the new mkissa stream API/encryption so that opening any episode yields playable videos instead of 'No available video'.
#607 Update the AllAnime (EN) extension to use the new mkissa.to site domain and associated URLs instead of the outdated allmanga.to domain, aligning episode and site URLs with the current backend.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The override of videoListRequest(episode: SEpisode) now throws UnsupportedOperationException; if any existing code paths still call this method (e.g., external features or tooling expecting a request URL), consider either keeping a minimal implementation or documenting that it is intentionally unusable to avoid unexpected crashes.
  • In AllAnimeKeyManager.resolveMask, the chunkBase and appEntryUrl parsing rely on specific entry/app.*.js and ../chunks/*.js patterns; consider adding a fallback or explicit error when these patterns fail to match, so future site changes surface a clear failure instead of silently preventing mask rotation healing.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The override of `videoListRequest(episode: SEpisode)` now throws `UnsupportedOperationException`; if any existing code paths still call this method (e.g., external features or tooling expecting a request URL), consider either keeping a minimal implementation or documenting that it is intentionally unusable to avoid unexpected crashes.
- In `AllAnimeKeyManager.resolveMask`, the `chunkBase` and `appEntryUrl` parsing rely on specific `entry/app.*.js` and `../chunks/*.js` patterns; consider adding a fallback or explicit error when these patterns fail to match, so future site changes surface a clear failure instead of silently preventing mask rotation healing.

## Individual Comments

### Comment 1
<location path="src/en/allanime/src/eu/kanade/tachiyomi/animeextension/en/allanime/AllAnime.kt" line_range="505-514" />
<code_context>
+        var lastError: Throwable? = null
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Error propagation in fetchSourceUrls can surface a misleading exception in mixed failure scenarios.

`lastError` is only updated on HTTP failures, not when decryption or JSON parsing fails. In a sequence where an initial network error is followed by decryption/parsing errors, the thrown exception will still be the network error, which misrepresents the latest failure. To keep the surfaced error aligned with the actual failure, update `lastError` on decryption/parsing errors as well, or track the failure reason per attempt and throw the most recent/most relevant one.

Suggested implementation:

```
    private suspend fun fetchSourceUrls(episode: SEpisode): List<SourceUrl> {
        var lastError: Throwable? = null
        var maskHealed = false

        repeat(MAX_KEY_ATTEMPTS) { attempt ->
            var attemptError: Throwable? = null
            val material = keyManager.material(forceRefresh = attempt > 0)

```

To fully implement the suggestion, you should also:
1. In the body of the `repeat(MAX_KEY_ATTEMPTS)` loop, set `attemptError` in *every* failure path, not just HTTP failures. For example:
   - In the HTTP error catch block: `attemptError = httpException`.
   - In the decryption error catch block: `attemptError = decryptionException`.
   - In the JSON parsing error catch block: `attemptError = jsonException`.
2. After handling an attempt’s failure (inside the loop), assign `lastError = attemptError ?: lastError` so the most recent non-success attempt updates `lastError`.
3. Ensure that when the function finally throws after exhausting attempts, it throws `lastError` (or wraps it) so the surfaced exception corresponds to the last failure, regardless of whether it was HTTP, decryption, or parsing.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@justq7628

Copy link
Copy Markdown

Please Marge this to repo as fast as possible

Comment on lines +580 to +581
// The site's default iframe host, for the legacy internal/player servers.
private const val PLAYER_DOMAIN = "https://allanime.day"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where does this come from, can't see it in the previously used code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the old code this host came from /getVersion, but that endpoint doesn't exist anymore, so it's hardcoded. allanime.day is the current player/clock host, and mkissa's own player still loads /player.html and /apivtwo/clock.json from there, so we're matching the site. It's only used by the internal servers, which from a quick look only show up on older titles like One Piece

@7heMech

7heMech commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@Red1tum overall, good work, tested and it works nicely, I'd be good if you can address the last sourcery comment

@Red1tum

Red1tum commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

@7heMech Fixed the sourcery comment.

Also moved the API domain to api.mkissa.net (with its stream query hash, since it differs from allanime's) after noticing mkissa serves its own API now

@7heMech

7heMech commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

@7heMech Fixed the sourcery comment.

great, merging soon

@Alpha-782

Copy link
Copy Markdown
Collaborator

@Red1tum Update the branch and bump version to 57.

Red1tum added 2 commits July 26, 2026 08:53
…allanime-mkissa-encryption

# Conflicts:
#	src/en/allanime/build.gradle
@Red1tum

Red1tum commented Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

@Alpha-782 Done

@Alpha-782
Alpha-782 merged commit 92eb445 into yuzono:master Jul 26, 2026
4 checks passed
@Red1tum
Red1tum deleted the allanime-mkissa-encryption branch July 26, 2026 18:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AllAnime[EN]: No video found

5 participants