Files
claude 9e33a343ab
Some checks failed
release / build-release (push) Has been cancelled
Floatplane channel plugin for Jellyfin 10.10.x: browse, HLS proxy, cookie session, CI release
- IChannel: creators -> sub-channels -> video posts (public listing API, search mapped)
- IRequiresMediaInfoCallback -> signed proxy URLs; stream controller rewrites HLS so the
  AES-128 key is fetched server-side with the session cookie, segments stay on the CDN
- delivery/info cached per token lifetime and throttled (~2/min)
- config page: paste sails.sid + validate, extra creators, quality, search test
- scripts/package.sh -> plugin folder + zip + md5 + manifest.json; Gitea release workflow
- research docs, HAR analysis (HAR itself gitignored), install-pi5.sh

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-25 09:42:27 +01:00

62 lines
2.3 KiB
Swift

import Foundation
import FloatplaneAPIClient
import Vapor
extension FloatplaneAPIClientAPI {
private static var FloatplaneURL = URL(string: "https://www.floatplane.com")!
private static var SailsSidCookieName = "sails.sid"
public static var rawCookieValue: String = ""
static func loadAuthenticationCookiesFromStorage() {
let storedCookies = HTTPCookieStorage.shared.cookies(for: FloatplaneURL)
if let sailsSidCookie = storedCookies?.first(where: { $0.name == SailsSidCookieName }) {
FloatplaneAPIClientAPI.customHeaders.cookie = [
SailsSidCookieName: Vapor.HTTPCookies.Value(string: sailsSidCookie.value),
]
rawCookieValue = sailsSidCookie.value
// Cookies were previously stored for `www.floatplane.com` instead of `.floatplane.com`.
// On app startup/loading auth cookies, detect if this cookie is old and re-save it
// with the proper domain
if sailsSidCookie.domain == "www.floatplane.com" {
HTTPCookieStorage.shared.deleteCookie(sailsSidCookie)
let newSailsSidCookie = HTTPCookie(properties: [
.domain: ".floatplane.com",
.path: "/",
.name: SailsSidCookieName,
.value: sailsSidCookie.value,
.secure: "Secure",
.expires: sailsSidCookie.expiresDate as Any,
])!
HTTPCookieStorage.shared.setCookies([newSailsSidCookie], for: FloatplaneURL, mainDocumentURL: nil)
}
}
}
static func storeAuthentifcationCookies(from clientResponse: ClientResponse) {
if let sailsSidCookie = clientResponse.headers.setCookie?[SailsSidCookieName] {
FloatplaneAPIClientAPI.customHeaders.cookie = [SailsSidCookieName: sailsSidCookie]
let httpCookie = HTTPCookie(properties: [
.domain: ".floatplane.com",
.path: "/",
.name: SailsSidCookieName,
.value: sailsSidCookie.string,
.secure: "Secure",
.expires: NSDate(timeIntervalSince1970: sailsSidCookie.expires!.timeIntervalSince1970),
])
HTTPCookieStorage.shared.setCookies([httpCookie!], for: FloatplaneURL, mainDocumentURL: nil)
rawCookieValue = sailsSidCookie.string
}
}
static func removeAuthenticationCookies() {
let storedCookies = HTTPCookieStorage.shared.cookies(for: FloatplaneURL)
if let sailsSidCookie = storedCookies?.first(where: { $0.name == SailsSidCookieName }) {
HTTPCookieStorage.shared.deleteCookie(sailsSidCookie)
}
FloatplaneAPIClientAPI.customHeaders.cookie = [:]
}
}