Skip to content

Commit 6f85b1a

Browse files
committed
Fix Spotify services
1 parent 2da9850 commit 6f85b1a

File tree

1 file changed

+35
-12
lines changed

1 file changed

+35
-12
lines changed

Sources/LyricsServiceUI/Controller/SpotifyLoginManager.swift

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import SwiftOTP
77
private typealias Task = _Concurrency.Task
88

99
private enum TOTPGenerator {
10-
static func generate(serverTimeSeconds: Int) -> String? {
11-
let secretCipher = [12, 56, 76, 33, 88, 44, 88, 33, 78, 78, 11, 66, 22, 22, 55, 69, 54]
10+
static func generate(secretCipher: [UInt8], serverTimeSeconds: Int) -> String? {
11+
// let secretCipher = [12, 56, 76, 33, 88, 44, 88, 33, 78, 78, 11, 66, 22, 22, 55, 69, 54]
1212

1313
var processed = [UInt8]()
1414
for (i, byte) in secretCipher.enumerated() {
15-
processed.append(UInt8(byte ^ (i % 33 + 9)))
15+
processed.append(UInt8(byte ^ UInt8(i % 33 + 9)))
1616
}
1717

1818
let processedStr = processed.map { String($0) }.joined()
@@ -48,23 +48,42 @@ struct SpotifyAccessToken: Codable {
4848
struct ServerTime: Codable {
4949
var serverTime: Int
5050
}
51-
51+
struct SecretKeyEntry: Codable {
52+
let version: Int
53+
let secret: String
54+
}
5255
enum Error: Swift.Error {
5356
case totpGenerationFailed
5457
}
55-
56-
let serverTimeRequest = URLRequest(url: .init(string: "https://open.spotify.com/server-time")!)
58+
let secretKeyURL = URL(string: "https://raw.githubusercontent.com/Thereallo1026/spotify-secrets/refs/heads/main/secrets/secrets.json")!
59+
let serverTimeRequest = URLRequest(url: .init(string: "https://open.spotify.com/api/server-time")!)
5760
let serverTimeData = try await URLSession.shared.data(for: serverTimeRequest).0
5861
let serverTime = try JSONDecoder().decode(ServerTime.self, from: serverTimeData).serverTime
59-
60-
guard let totp = TOTPGenerator.generate(serverTimeSeconds: serverTime) else {
62+
let (data, _) = try await URLSession.shared.data(from: secretKeyURL)
63+
let secretEntries = try JSONDecoder().decode([SecretKeyEntry].self, from: data)
64+
guard let lastEntry = secretEntries.last else {
6165
throw Error.totpGenerationFailed
6266
}
63-
64-
let url = URL(string: "https://open.spotify.com/get_access_token?reason=transport&productType=web_player&totpVer=5&ts=\(Int(Date().timeIntervalSince1970))&totp=\(totp)")!
65-
var request = URLRequest(url: url)
67+
guard let totp = TOTPGenerator.generate(secretCipher: .init(lastEntry.secret.utf8), serverTimeSeconds: serverTime) else {
68+
throw Error.totpGenerationFailed
69+
}
70+
let tokenURL = URL(string: "https://open.spotify.com/api/token")!
71+
let params: [String: String] = [
72+
"reason": "transport",
73+
"productType": "web-player",
74+
"totp": totp,
75+
"totpVer": lastEntry.version.description,
76+
"ts": String(Int(Date().timeIntervalSince1970)),
77+
]
78+
var components = URLComponents(url: tokenURL, resolvingAgainstBaseURL: false)!
79+
components.queryItems = params.map { URLQueryItem(name: $0.key, value: $0.value) }
80+
81+
var request = URLRequest(url: components.url!)
82+
request.httpMethod = "GET"
6683
request.setValue("sp_dc=\(cookie)", forHTTPHeaderField: "Cookie")
84+
request.setValue("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", forHTTPHeaderField: "User-Agent")
6785
let accessTokenData = try await URLSession.shared.data(for: request).0
86+
try print(JSONSerialization.jsonObject(with: accessTokenData))
6887
return try JSONDecoder().decode(SpotifyAccessToken.self, from: accessTokenData)
6988
}
7089
}
@@ -214,7 +233,11 @@ public final class SpotifyLoginManager: NSObject, @unchecked Sendable {
214233
}
215234

216235
await secureStorage.setCookie(cookie)
217-
try await requestAccessToken()
236+
do {
237+
try await requestAccessToken()
238+
} catch {
239+
print(error)
240+
}
218241
await MainActor.run {
219242
loginWindowController.close()
220243
}

0 commit comments

Comments
 (0)