zacharyandClaude Opus 5.5 e13d43d186 feat(auth): authentification par proxy (oauth2-proxy, Authelia…)
Derrière un proxy d'authentification, FanKarr demandait une seconde
connexion. Avec PROXY_AUTH_HEADER, la session est ouverte à partir du nom
d'utilisateur transmis par le proxy.

- server/lib/proxy-auth.ts : lecture de l'en-tête, uniquement pour les
  connexions venant de PROXY_AUTH_TRUSTED_PROXIES (adresse du socket, pas
  X-Forwarded-For) ; fonction désactivée si cette liste est vide
- compte rapproché par nom (sans casse) ; création d'un compte utilisateur
  sans mot de passe avec PROXY_AUTH_AUTO_CREATE ; premier compte toujours
  créé par l'assistant
- server/auth.ts : middleware proxyAuth avant les routes, qui ouvre ou
  remplace la session ; /api/auth/status expose proxyAuth et logoutUrl
- déconnexion : redirection vers PROXY_AUTH_LOGOUT_URL si défini
- profil et gestion des utilisateurs : libellés pour les comptes sans mot
  de passe qui ne viennent pas de Jellyfin
- tests vitest du module ; fichiers de test exclus de la compilation serveur

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 22:01:57 +02:00
2026-06-09 21:42:14 +02:00
2026-05-08 01:59:26 +02:00
2026-03-10 22:36:34 +01:00
2026-03-10 22:36:34 +01:00

FanKarr

Version Docker Image Size Docker Pulls GitHub Actions License Vue Bun

Gestionnaire de téléchargements pour le catalogue Fankai
Inspiré de Radarr et Sonarr, pour les éditions Kai et Yabai

Banner


Aperçu

Accueil

Accueil : le dernier import, les séries ajoutées récemment et les chiffres de la médiathèque. L'administrateur y retrouve ce qui attend une action : demandes, imports en erreur, dossiers à renommer.


Médiathèque

Médiathèque : tout le catalogue Fankai. Chaque affiche indique l'état de la série (importée, partielle, en téléchargement, dossier à renommer, nouveauté), avec des filtres, un tri et plusieurs tailles d'affiches.


Série

Fiche d'une série : l'import saison par saison et épisode par épisode, avec le téléchargement d'un épisode, d'une saison ou de toute la série, l'import manuel et la surveillance des nouveaux épisodes.


Activité

Activité : un torrent par ligne, du téléchargement à l'import, avec le détail des erreurs et un bouton pour relancer l'import.


Accueil sur mobile Fiche d'une série sur mobile Activité sur mobile

Sur mobile : l'interface s'adapte au téléphone, avec une barre d'onglets en bas de l'écran.


Fonctionnalités

Téléchargement

  • Tout le catalogue Fankai, avec les affiches et l'état de chaque série
  • Envoi au client torrent par épisode, par saison ou en intégrale
  • Choix de la source quand plusieurs torrents existent (qualité, pack)
  • Bouton « Tout télécharger » : l'intégrale choisie, complétée par les packs des épisodes qu'elle ne contient pas
  • Progression par épisode, même pour un fichier contenu dans un pack (si le client torrent l'indique)
  • Surveillance : les nouveaux épisodes des séries surveillées sont envoyés au client (vérification toutes les 6 heures)

Organisation

  • Import automatique des téléchargements terminés dans la médiathèque (vérification toutes les 5 minutes)
  • Trois modes d'import : Hardlink (recommandé), Copier ou Déplacer. Avec un hardlink, le client torrent continue de partager le fichier.
  • Analyse de la médiathèque : les épisodes déjà présents sur le disque sont reconnus sans être déplacés
  • En option, les épisodes dont le fichier a disparu sont retirés de la médiathèque
  • Quand vous retirez une série de la médiathèque en supprimant ses fichiers, son dossier est effacé et ses torrents sont retirés du client

Demandes

  • Les invités demandent une série, une saison ou des épisodes, depuis FanKarr ou depuis le plugin Jellyfin
  • Les administrateurs approuvent, refusent (avec un message) ou marquent une demande comme disponible
  • Approbation automatique, pour tous les invités ou certains seulement : la demande est approuvée et le torrent part aussitôt au client
  • Bouton « Tout supprimer » pour vider la liste
  • Une demande passe à « disponible » quand des épisodes de la série sont importés, et les demandes disponibles sont supprimées quand la série est retirée de la médiathèque

Métadonnées et affichage

  • Badges de langue VOSTFR et MULTI sur chaque épisode, détectés automatiquement
  • Fichiers NFO et images en option, pour Infuse ou les lecteurs sans agent Fankai
  • Plex : connexion au compte, installation de l'agent de métadonnées Fankai et création de la bibliothèque (Plex Media Server 1.43 ou plus récent pour l'agent)
  • Jellyfin, Emby et Kodi : métadonnées Fankai avec le plugin Jellyfin Fankai ou l'add-on Fankai pour Kodi (Kodi 20 ou plus récent)

Utilisateurs et Jellyfin

  • Plusieurs comptes, avec deux rôles (administrateur et invité) et des liens d'invitation
  • Import des utilisateurs Jellyfin, au choix ou automatiquement toutes les heures
  • Connexion à FanKarr avec le compte Jellyfin, depuis l'interface web ou le plugin Jellyfin
  • Un jeton d'API personnel par utilisateur pour l'API publique

Système

  • Journaux filtrables par niveau et par source, avec rotation automatique, que vous pouvez vider depuis l'interface
  • Authentification par mot de passe FanKarr ou Jellyfin, session JWT, tentatives limitées
  • Clients torrent pris en charge : qBittorrent, Transmission, Deluge, rTorrent, uTorrent, Synology Download Station et Real-Debrid. Vous pouvez en configurer plusieurs.
  • Installation avec Docker, Runtipi ou un binaire autonome

Données des torrents (scraper)

Les données du catalogue viennent du dépôt fankarr-scraper.

Ce dépôt récupère les torrents Fankai sur les trackers publics, les associe aux épisodes grâce à l'API Fankai et publie le résultat toutes les 6 heures avec GitHub Actions : un fichier par série dans le dossier series/, et des fichiers d'index à la racine (available.json, infohash_map.json).

FanKarr lit ces données au démarrage et les garde une heure en cache. Pour les recharger tout de suite, utilisez Synchroniser maintenant dans Paramètres › Catalogue Fankai. Les séries qui ne sont pas encore dans le scraper sont complétées par l'API Fankai, sans torrents. La collecte des torrents ne se fait pas sur votre serveur.


Installation

Docker Compose (recommandé)

Prérequis : Docker et Docker Compose, et un client torrent joignable depuis FanKarr.

services:
  fankarr:
    image: masutayunikon/fankarr:latest
    container_name: fankarr
    environment:
      - PUID=1000        # UID de votre utilisateur (id -u)
      - PGID=1000        # GID de votre utilisateur (id -g)
      - TZ=Europe/Paris  # Fuseau horaire
    volumes:
      - ./config:/config  # Configuration, journaux et données
      - /votre/chemin:/media  # Dossier parent de la médiathèque et des téléchargements (nécessaire aux hardlinks)
    ports:
      - 9898:9898
    restart: unless-stopped
docker compose up -d

Hardlinks : le dossier des téléchargements terminés et la médiathèque doivent être sur le même système de fichiers. Montez un seul volume parent qui contient les deux (ex. /votre/chemin:/media), puis choisissez vos dossiers à l'intérieur, comme avec Radarr et Sonarr.

Vous pouvez monter plusieurs volumes, mais les hardlinks ne fonctionnent pas d'un volume à l'autre ; FanKarr copie alors les fichiers.

Si le client torrent tourne dans un autre conteneur ou sur une autre machine, renseignez dans ses réglages le chemin distant (le dossier tel que le client le voit) et le chemin local (le même dossier tel que FanKarr le voit).


Binaire autonome (Windows, Linux, macOS)

Téléchargez l'archive de votre système depuis les Releases GitHub :

Système Archive
Windows x64 fankarr-windows-x64.zip
Windows x64, anciens processeurs fankarr-windows-x64-legacy.zip
Linux x64 fankarr-linux-x64.zip
Linux ARM64 fankarr-linux-arm64.zip
macOS (Apple Silicon) fankarr-macos.zip

Extrayez l'archive dans un dossier. Tous les fichiers doivent rester ensemble :

fankarr/
├── fankarr.exe          # à lancer (fankarr sous Linux et macOS)
├── organize-worker.js   # tâche d'import, à garder à côté du binaire
├── public/              # fichiers de l'interface, à garder à côté du binaire
├── version.txt
└── .env                 # facultatif, à créer (voir Variables d'environnement)

Le fichier .env sert à régler le port, la durée des sessions, etc. sans passer par les variables d'environnement du système. S'il est présent à côté du binaire, il est chargé au démarrage. Le fichier .env.example du dépôt sert de modèle.

Linux et macOS : dans l'archive, le binaire est rangé dans un sous-dossier binaries/. Placez-le à côté de public/ et rendez-le exécutable avant le premier lancement :

wget https://github.com/masutayunikon/fankarr/releases/latest/download/fankarr-linux-x64.zip
unzip fankarr-linux-x64.zip -d fankarr
cd fankarr
# Le binaire est extrait dans binaries/ : le placer à côté de public/ et de organize-worker.js
mv binaries/fankarr .
chmod +x fankarr
./fankarr

Pour Linux ARM64 ou macOS, remplacez le nom de l'archive.

FanKarr est alors accessible sur http://localhost:9898. La configuration, les journaux et les données sont enregistrés dans un dossier config/, créé automatiquement à côté du binaire.


Variables d'environnement

Variable Défaut Description
PUID 1000 UID propriétaire des fichiers de /config (Docker)
PGID 1000 GID propriétaire des fichiers de /config (Docker)
TZ non défini Fuseau horaire (ex. Europe/Paris)
PORT 9898 Port d'écoute du serveur
JWT_SECRET généré Secret des sessions, généré dans secret.key (dossier de configuration) si absent
AUTH_TOKEN_EXPIRY 30d Durée de validité de la session (ex. 7d, 1y ; never ou 0 : pas d'expiration)
GITHUB_BASE dépôt scraper Adresse de base des données du scraper, si vous hébergez votre propre copie
BASE_URL non défini Sous-dossier derrière un reverse proxy (ex. /fankarr)
PROXY_AUTH_HEADER non défini En-tête contenant le nom d'utilisateur authentifié par le proxy (ex. Remote-User)
PROXY_AUTH_TRUSTED_PROXIES non défini Adresses autorisées à envoyer cet en-tête (IP ou plages IPv4 CIDR, séparées par des virgules)
PROXY_AUTH_AUTO_CREATE false Crée un compte utilisateur à la première connexion d'un nom inconnu
PROXY_AUTH_LOGOUT_URL non défini Page de déconnexion du proxy, ouverte par « Se déconnecter » (ex. /oauth2/sign_out)

Par défaut, GITHUB_BASE vaut https://raw.githubusercontent.com/masutayunikon/fankarr-scraper/main.


Reverse proxy en sous-dossier

Par défaut, FanKarr est servi à la racine du domaine. Pour l'héberger sous un sous-dossier (https://exemple.tld/fankarr), renseignez BASE_URL :

environment:
  - BASE_URL=/fankarr

L'application, l'API et l'API publique v1 sont alors servies sous ce préfixe (/fankarr/api/v1/...), et une requête sur / y est redirigée. Aucune reconstruction de l'image n'est nécessaire : le préfixe est appliqué au démarrage.

Côté proxy, transmettez l'URL sans réécrire le chemin :

location /fankarr/ {
    proxy_pass http://127.0.0.1:9898;   # pas de / final : le chemin est conservé
    proxy_set_header Host              $host;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Laissez BASE_URL vide pour un sous-domaine dédié (https://fankarr.exemple.tld).


Authentification par proxy (oauth2-proxy, Authelia…)

Si un proxy d'authentification (oauth2-proxy devant Keycloak, Authelia, Authentik…) contrôle déjà l'accès à FanKarr, FanKarr peut ouvrir la session directement à partir du nom d'utilisateur qu'il transmet, sans second écran de connexion :

environment:
  - PROXY_AUTH_HEADER=X-Forwarded-Preferred-Username  # en-tête posé par le proxy
  - PROXY_AUTH_TRUSTED_PROXIES=172.18.0.0/16          # adresse(s) du reverse proxy
  - PROXY_AUTH_LOGOUT_URL=/oauth2/sign_out            # facultatif
  # - PROXY_AUTH_AUTO_CREATE=true                     # facultatif
  • Le nom transmis est rapproché d'un compte FanKarr existant, sans tenir compte de la casse. Un nom inconnu est refusé (avertissement dans les journaux), sauf avec PROXY_AUTH_AUTO_CREATE=true : un compte utilisateur sans mot de passe est alors créé. Les rôles se gèrent dans Paramètres › Utilisateurs.
  • L'en-tête n'est lu que pour les connexions venant de PROXY_AUTH_TRUSTED_PROXIES : sans cette variable, la fonction reste désactivée. Ne publiez pas le port de FanKarr au-delà du proxy et des applications qui utilisent l'API.
  • Le premier compte administrateur se crée toujours avec l'assistant.
  • La connexion par mot de passe et par Jellyfin reste possible, ainsi que les jetons d'API.

Exemple avec NPMplus et oauth2-proxy : choisissez oauth2proxy dans « Auth Request » de la location FanKarr. L'en-tête X-User que NPMplus transmet contient l'identifiant interne de l'utilisateur (sub, un UUID avec Keycloak) et non son nom de connexion. Transmettez plutôt ce dernier en ajoutant dans la configuration avancée de la location :

auth_request_set $preferred_username $upstream_http_x_auth_request_preferred_username;
proxy_set_header X-Forwarded-Preferred-Username $preferred_username;

puis PROXY_AUTH_HEADER=X-Forwarded-Preferred-Username. oauth2-proxy doit tourner avec --set-xauthrequest.


Premier lancement

  1. Ouvrez http://localhost:9898 (ou l'adresse de votre serveur).
  2. Créez le compte administrateur.
  3. Suivez l'assistant de configuration :
    • dossiers : téléchargements terminés, médiathèque et mode d'import (Hardlink, recommandé, Copier ou Déplacer) ;
    • client torrent ;
    • options d'import : import automatique, nommage des dossiers, fichiers NFO ;
    • serveur multimédia, Jellyfin ou Plex (facultatif) ;
    • catalogue : synchronisation des séries Fankai, puis analyse de la médiathèque si elle contient déjà des épisodes.
  4. Terminez avec la visite guidée, qui présente les écrans principaux, ou passez-la.

Assistant de configuration

Tous ces réglages restent modifiables dans les paramètres, et l'assistant peut être relancé.

Paramètres


Organisation des fichiers

FanKarr range les fichiers terminés selon la structure attendue par Jellyfin et Plex :

Black Lagoon Henshū/
├── Saison 1/
│   ├── Black Lagoon Henshū.S01E01.MULTI.1080p.x264-FANKAI.mkv
│   ├── Black Lagoon Henshū.S01E02.MULTI.1080p.x264-FANKAI.mkv
│   ├── Black Lagoon Henshū.S01E03.MULTI.1080p.x264-FANKAI.mkv
│   └── Black Lagoon Henshū.S01E04.MULTI.1080p.x264-FANKAI.mkv
├── Saison 2/
│   ├── Black Lagoon Henshū.S02E05.MULTI.1080p.x264-FANKAI.mkv
│   ├── Black Lagoon Henshū.S02E06.MULTI.1080p.x264-FANKAI.mkv
│   └── Black Lagoon Henshū.S02E07.MULTI.1080p.x264-FANKAI.mkv
└── Saison 3/
    └── Black Lagoon Henshū.S03E08.MULTI.1080p.x264-FANKAI.mkv

Une option permet de nommer les dossiers de saison « Season 01 » plutôt que « Saison 1 ».

Le mode Hardlink est recommandé quand le dossier des téléchargements et la médiathèque sont sur le même système de fichiers : le fichier n'est pas copié et le client torrent continue de le partager.

L'import se lance :

  • automatiquement, si l'import automatique est activé : FanKarr cherche les téléchargements terminés toutes les 5 minutes ;
  • à la main, avec le bouton Importer de la page Activité.

L'analyse de la médiathèque (Paramètres › Gestion des médias › Analyser la médiathèque) reconnaît les fichiers déjà présents sur le disque sans les déplacer, utile pour une médiathèque existante.


Journaux

Journaux

Les journaux sont dans Paramètres › Journaux. Chaque événement est horodaté et filtrable par niveau (info, warn, error, debug) et par source : api, organize, rss-sync, requests, jellyfin, plex, auth, torrent-clients, une source par client torrent (qbittorrent, transmission…), etc.

Le fichier garde environ les 2 000 dernières lignes. Les messages debug ne sont pas enregistrés quand NODE_ENV=production, ce qui est le cas dans l'image Docker.


Comptes Jellyfin

Vos utilisateurs Jellyfin peuvent se connecter à FanKarr avec leurs identifiants Jellyfin. Il faut renseigner l'adresse du serveur et une clé API dans Paramètres › Jellyfin et API.

Import des utilisateurs

Un utilisateur Jellyfin importé reçoit un compte invité, sans mot de passe FanKarr. Si un compte FanKarr porte déjà son nom, ce compte est lié à l'utilisateur Jellyfin au lieu d'être recréé. Pour importer :

  • choisissez les comptes depuis Paramètres › Jellyfin et API › Importer des utilisateurs ;
  • ou laissez l'import automatique, qui importe toutes les heures chaque utilisateur Jellyfin actif (activé par défaut).

Connexion

Sur l'écran de connexion, un utilisateur importé saisit son nom et son mot de passe Jellyfin. FanKarr les fait vérifier par Jellyfin et ne les conserve pas. Deux réglages dans Paramètres › Jellyfin et API :

  • Connexion à FanKarr avec un compte Jellyfin (activé par défaut) ;
  • Autoriser les comptes pas encore importés (désactivé par défaut) : un compte invité est créé à la première connexion.

Un compte FanKarr qui n'a pas été importé ou lié ne peut pas s'ouvrir avec un mot de passe Jellyfin. Après 5 échecs en 15 minutes pour un même nom d'utilisateur depuis la même adresse, FanKarr bloque les tentatives jusqu'à la fin de ces 15 minutes. Un mot de passe erroné saisi dans FanKarr compte aussi comme un échec dans Jellyfin. Si le verrouillage après plusieurs échecs est activé pour un utilisateur dans Jellyfin (désactivé par défaut), son compte y est désactivé une fois la limite atteinte.


Un plugin Jellyfin intègre la recherche FanKarr à l'interface de votre serveur : vos utilisateurs parcourent le catalogue et demandent des séries sans quitter Jellyfin.

jellyfin-plugin-fankarr-search

Le plugin nécessite Jellyfin JavaScript Injector. Les instructions d'installation sont dans le README du plugin.

Les utilisateurs se connectent au plugin avec leur compte Jellyfin : le plugin échange leur session Jellyfin contre leur jeton FanKarr. Le compte doit être importé (voir Comptes Jellyfin), sauf si les comptes pas encore importés sont autorisés.


API publique

FanKarr expose une API publique, sous /api/v1, utilisée par le plugin Jellyfin et ouverte aux intégrations tierces.

Authentification : Authorization: Bearer <jeton> (jeton visible dans Paramètres › Mon profil › Jeton d'API)

Méthode Route Description
POST /api/v1/auth/jellyfin Échange une session Jellyfin contre le jeton FanKarr de l'utilisateur
GET /api/v1/auth/me Compte associé au jeton
GET /api/v1/series/search?q= Recherche par titre ; renvoie note, année, description et demande en cours
GET /api/v1/series/:id Détail d'une série : saisons et épisodes
POST /api/v1/requests Crée une demande ou complète la demande en cours
GET /api/v1/requests Demandes de l'utilisateur du jeton

Connexion avec Jellyfin

POST /api/v1/auth/jellyfin
Content-Type: application/json

{ "jellyfinUserId": "...", "jellyfinToken": "..." }

Renvoie { token, username, role }. Le token s'utilise ensuite en Bearer pour tous les autres appels. FanKarr vérifie auprès de Jellyfin (/Users/Me) que le jeton appartient bien à jellyfinUserId. Si l'utilisateur Jellyfin n'est pas encore importé, la réponse est une erreur 404, sauf si les comptes pas encore importés sont autorisés : le compte est alors créé.

Recherche

GET /api/v1/series/search?q=dragon+ball
Authorization: Bearer <jeton>
[
  {
    "id": 42,
    "title": "Dragon Ball Z Kai",
    "original_title": "DRAGON BALL Z KAI",
    "image": "https://...",
    "year": 2009,
    "rating": 8.5,
    "description": "Suite de Dragon Ball...",
    "request": {
      "id": "uuid",
      "status": "pending",
      "seasons": [1, 2],
      "episodes": []
    }
  }
]

La recherche porte sur le titre et le titre original, sans tenir compte de la casse, parmi les séries présentes dans les données du scraper. Elle renvoie 50 résultats au maximum ; sans q, elle renvoie les 50 premières séries.

Le champ request vaut null si l'utilisateur n'a pas de demande en cours pour cette série.

Détail d'une série (saisons et épisodes)

GET /api/v1/series/42
Authorization: Bearer <jeton>
{
  "id": 42,
  "title": "Dragon Ball Z Kai",
  "original_title": "DRAGON BALL Z KAI",
  "image": "https://...",
  "seasons": [
    {
      "season_number": 1,
      "episodes": [
        { "id": 101, "episode_number": 1, "title": "...", "image": "https://..." }
      ]
    }
  ]
}

Créer une demande

POST /api/v1/requests
Authorization: Bearer <jeton>
Content-Type: application/json

{ "serieId": 42, "serieName": "Dragon Ball Z Kai", "seasons": [1, 2] }
  • serieId et serieName sont obligatoires.
  • seasons : numéros de saison (season_number). Sans saison ni épisode, la demande porte sur toute la série.
  • episodes : identifiants d'épisodes (episode.id). Prioritaires sur seasons s'ils sont renseignés.
  • Si une demande est déjà en cours pour cette série, les saisons et épisodes sont fusionnés.
  • Si l'approbation automatique est activée pour l'utilisateur, la demande est approuvée et le torrent envoyé au client.

Runtipi

FanKarr est disponible dans le dépôt d'applications Runtipi de Masutayunikon. Pour l'installer :

  1. Dans Runtipi, ouvrez Paramètres › App Stores.
  2. Ajoutez l'adresse https://github.com/Masutayunikon/runtipi-appstore.
  3. FanKarr apparaît dans la liste des applications : cliquez sur Installer.

Technologies

Partie Technologie
Interface Vue 3, Vite, Tailwind CSS v4
Serveur Express 5, TypeScript
Authentification JWT, bcrypt
Import Worker threads Node (import en arrière-plan)
Image Docker node:22-slim, pnpm, gosu (PUID/PGID)
Binaire Bun (exécutable autonome, sans Node)

Liens

S
Description
No description provided
Readme
13 MiB
0 Stars 1 Watchers 0 Forks
Languages
Vue 50.7%
TypeScript 48%
CSS 1%
Dockerfile 0.2%