mirror of
https://github.com/immich-app/immich.git
synced 2026-03-10 20:03:44 -04:00
use constants
This commit is contained in:
parent
c23c21c4aa
commit
5e095bd96e
@ -39,6 +39,17 @@ private const val PREFS_CERT_ALIAS = "immich.client_cert"
|
||||
private const val PREFS_HEADERS = "immich.request_headers"
|
||||
private const val PREFS_SERVER_URLS = "immich.server_urls"
|
||||
private const val PREFS_COOKIES = "immich.cookies"
|
||||
private const val COOKIE_EXPIRY_DAYS = 400L
|
||||
|
||||
private enum class AuthCookie(val cookieName: String, val httpOnly: Boolean) {
|
||||
ACCESS_TOKEN("immich_access_token", httpOnly = true),
|
||||
IS_AUTHENTICATED("immich_is_authenticated", httpOnly = false),
|
||||
AUTH_TYPE("immich_auth_type", httpOnly = true);
|
||||
|
||||
companion object {
|
||||
val names = entries.map { it.cookieName }.toSet()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages a shared OkHttpClient with SSL configuration support.
|
||||
@ -189,18 +200,19 @@ object HttpClientManager {
|
||||
|
||||
if (token != null) {
|
||||
val url = serverUrls.firstNotNullOfOrNull { it.toHttpUrlOrNull() } ?: return
|
||||
val expiry = System.currentTimeMillis() + 400L * 24 * 60 * 60 * 1000
|
||||
fun cookie(name: String, value: String, httpOnly: Boolean) =
|
||||
Cookie.Builder().name(name).value(value).domain(url.host).path("/").expiresAt(expiry)
|
||||
val expiry = System.currentTimeMillis() + COOKIE_EXPIRY_DAYS * 24 * 60 * 60 * 1000
|
||||
val values = mapOf(
|
||||
AuthCookie.ACCESS_TOKEN to token,
|
||||
AuthCookie.IS_AUTHENTICATED to "true",
|
||||
AuthCookie.AUTH_TYPE to "password",
|
||||
)
|
||||
cookieJar.saveFromResponse(url, values.map { (cookie, value) ->
|
||||
Cookie.Builder().name(cookie.cookieName).value(value).domain(url.host).path("/").expiresAt(expiry)
|
||||
.apply {
|
||||
if (url.isHttps) secure()
|
||||
if (httpOnly) httpOnly()
|
||||
if (cookie.httpOnly) httpOnly()
|
||||
}.build()
|
||||
cookieJar.saveFromResponse(url, listOf(
|
||||
cookie("immich_access_token", token, httpOnly = true),
|
||||
cookie("immich_is_authenticated", "true", httpOnly = false),
|
||||
cookie("immich_auth_type", "password", httpOnly = true),
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -300,9 +312,6 @@ object HttpClientManager {
|
||||
private var serverUrls = listOf<HttpUrl>()
|
||||
private var prefs: SharedPreferences? = null
|
||||
|
||||
companion object {
|
||||
val AUTH_COOKIE_NAMES = setOf("immich_access_token", "immich_is_authenticated", "immich_auth_type")
|
||||
}
|
||||
|
||||
fun init(prefs: SharedPreferences) {
|
||||
this.prefs = prefs
|
||||
@ -344,11 +353,11 @@ object HttpClientManager {
|
||||
val serverHosts = serverUrls.map { it.host }.toSet()
|
||||
val now = System.currentTimeMillis()
|
||||
val sourceCookies = store
|
||||
.filter { it.name in AUTH_COOKIE_NAMES && it.domain in serverHosts && it.expiresAt > now }
|
||||
.filter { it.name in AuthCookie.names && it.domain in serverHosts && it.expiresAt > now }
|
||||
.associateBy { it.name }
|
||||
|
||||
if (sourceCookies.isEmpty()) {
|
||||
return store.removeAll { it.name in AUTH_COOKIE_NAMES && it.domain in serverHosts }
|
||||
return store.removeAll { it.name in AuthCookie.names && it.domain in serverHosts }
|
||||
}
|
||||
|
||||
var changed = false
|
||||
|
||||
@ -62,27 +62,27 @@ class NetworkApiImpl: NetworkApi {
|
||||
URLSessionManager.setServerUrls(serverUrls)
|
||||
|
||||
if let token = token {
|
||||
let expiry = Date().addingTimeInterval(400 * 24 * 60 * 60)
|
||||
let expiry = Date().addingTimeInterval(COOKIE_EXPIRY_DAYS * 24 * 60 * 60)
|
||||
for serverUrl in serverUrls {
|
||||
guard let url = URL(string: serverUrl), let domain = url.host else { continue }
|
||||
let isSecure = serverUrl.hasPrefix("https")
|
||||
let cookies: [(String, String, Bool)] = [
|
||||
("immich_access_token", token, true),
|
||||
("immich_is_authenticated", "true", false),
|
||||
("immich_auth_type", "password", true),
|
||||
let values: [AuthCookie: String] = [
|
||||
.accessToken: token,
|
||||
.isAuthenticated: "true",
|
||||
.authType: "password",
|
||||
]
|
||||
for (name, value, httpOnly) in cookies {
|
||||
for (cookie, value) in values {
|
||||
var properties: [HTTPCookiePropertyKey: Any] = [
|
||||
.name: name,
|
||||
.name: cookie.name,
|
||||
.value: value,
|
||||
.domain: domain,
|
||||
.path: "/",
|
||||
.expires: expiry,
|
||||
]
|
||||
if isSecure { properties[.secure] = "TRUE" }
|
||||
if httpOnly { properties[.init("HttpOnly")] = "TRUE" }
|
||||
if let cookie = HTTPCookie(properties: properties) {
|
||||
URLSessionManager.cookieStorage.setCookie(cookie)
|
||||
if cookie.httpOnly { properties[.init("HttpOnly")] = "TRUE" }
|
||||
if let httpCookie = HTTPCookie(properties: properties) {
|
||||
URLSessionManager.cookieStorage.setCookie(httpCookie)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,28 @@ let CLIENT_CERT_LABEL = "app.alextran.immich.client_identity"
|
||||
let HEADERS_KEY = "immich.request_headers"
|
||||
let SERVER_URLS_KEY = "immich.server_urls"
|
||||
let APP_GROUP = "group.app.immich.share"
|
||||
let COOKIE_EXPIRY_DAYS: TimeInterval = 400
|
||||
|
||||
enum AuthCookie: CaseIterable {
|
||||
case accessToken, isAuthenticated, authType
|
||||
|
||||
var name: String {
|
||||
switch self {
|
||||
case .accessToken: return "immich_access_token"
|
||||
case .isAuthenticated: return "immich_is_authenticated"
|
||||
case .authType: return "immich_auth_type"
|
||||
}
|
||||
}
|
||||
|
||||
var httpOnly: Bool {
|
||||
switch self {
|
||||
case .accessToken, .authType: return true
|
||||
case .isAuthenticated: return false
|
||||
}
|
||||
}
|
||||
|
||||
static let names: Set<String> = Set(allCases.map(\.name))
|
||||
}
|
||||
|
||||
extension UserDefaults {
|
||||
static let group = UserDefaults(suiteName: APP_GROUP)!
|
||||
@ -48,9 +70,9 @@ class URLSessionManager: NSObject {
|
||||
Self.serverUrls = UserDefaults.group.stringArray(forKey: SERVER_URLS_KEY) ?? []
|
||||
NotificationCenter.default.addObserver(
|
||||
Self.self,
|
||||
selector: #selector(cookiesDidChange),
|
||||
selector: #selector(Self.cookiesDidChange),
|
||||
name: NSHTTPCookieManagerCookiesChangedNotification,
|
||||
object: cookieStorage
|
||||
object: Self.cookieStorage
|
||||
)
|
||||
}
|
||||
|
||||
@ -71,13 +93,12 @@ class URLSessionManager: NSObject {
|
||||
}
|
||||
|
||||
private static func syncAuthCookies() {
|
||||
let authCookieNames: Set<String> = ["immich_access_token", "immich_is_authenticated", "immich_auth_type"]
|
||||
let serverHosts = Set(serverUrls.compactMap { URL(string: $0)?.host })
|
||||
let allCookies = cookieStorage.cookies ?? []
|
||||
let now = Date()
|
||||
|
||||
let serverAuthCookies = allCookies.filter {
|
||||
authCookieNames.contains($0.name) && serverHosts.contains($0.domain)
|
||||
AuthCookie.names.contains($0.name) && serverHosts.contains($0.domain)
|
||||
}
|
||||
|
||||
var sourceCookies: [String: HTTPCookie] = [:]
|
||||
@ -111,7 +132,7 @@ class URLSessionManager: NSObject {
|
||||
.value: source.value,
|
||||
.domain: domain,
|
||||
.path: "/",
|
||||
.expires: source.expiresDate ?? Date().addingTimeInterval(400 * 24 * 60 * 60),
|
||||
.expires: source.expiresDate ?? Date().addingTimeInterval(COOKIE_EXPIRY_DAYS * 24 * 60 * 60),
|
||||
]
|
||||
if isSecure { properties[.secure] = "TRUE" }
|
||||
if source.isHTTPOnly { properties[.init("HttpOnly")] = "TRUE" }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user