@superfan-app/spotify-auth 0.1.81 → 0.1.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -10,9 +10,7 @@ final class SpotifyASWebAuthSession {
|
|
|
10
10
|
private var isAuthenticating = false
|
|
11
11
|
|
|
12
12
|
private func secureLog(_ message: String) {
|
|
13
|
-
|
|
14
|
-
print("[SpotifyASWebAuth] \(message)")
|
|
15
|
-
#endif
|
|
13
|
+
NSLog("[SpotifyASWebAuth] \(message)")
|
|
16
14
|
}
|
|
17
15
|
|
|
18
16
|
func startAuthFlow(
|
|
@@ -22,12 +20,14 @@ final class SpotifyASWebAuthSession {
|
|
|
22
20
|
completion: @escaping (Result<URL, Error>) -> Void
|
|
23
21
|
) {
|
|
24
22
|
guard !isAuthenticating else {
|
|
23
|
+
secureLog("Auth already in progress, ignoring duplicate start")
|
|
25
24
|
completion(.failure(SpotifyAuthError.authorizationError("Authentication already in progress")))
|
|
26
25
|
return
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
isAuthenticating = true
|
|
30
|
-
|
|
29
|
+
secureLog("Starting auth flow for URL: \(authUrl.absoluteString)")
|
|
30
|
+
|
|
31
31
|
// Create the auth session
|
|
32
32
|
authSession = ASWebAuthenticationSession(
|
|
33
33
|
url: authUrl,
|
|
@@ -37,17 +37,22 @@ final class SpotifyASWebAuthSession {
|
|
|
37
37
|
|
|
38
38
|
if let error = error {
|
|
39
39
|
if (error as NSError).code == ASWebAuthenticationSessionError.canceledLogin.rawValue {
|
|
40
|
+
self?.secureLog("User cancelled auth session")
|
|
40
41
|
completion(.failure(SpotifyAuthError.userCancelled))
|
|
41
42
|
} else {
|
|
43
|
+
self?.secureLog("Auth session error: \(error.localizedDescription)")
|
|
42
44
|
completion(.failure(SpotifyAuthError.networkError(error.localizedDescription)))
|
|
43
45
|
}
|
|
44
46
|
return
|
|
45
47
|
}
|
|
46
|
-
|
|
48
|
+
|
|
47
49
|
guard let callbackURL = callbackURL else {
|
|
50
|
+
self?.secureLog("Auth session returned no callback URL")
|
|
48
51
|
completion(.failure(SpotifyAuthError.authorizationError("No callback URL received")))
|
|
49
52
|
return
|
|
50
53
|
}
|
|
54
|
+
|
|
55
|
+
self?.secureLog("Auth session callback received: \(callbackURL.absoluteString)")
|
|
51
56
|
|
|
52
57
|
completion(.success(callbackURL))
|
|
53
58
|
}
|
|
@@ -62,9 +67,10 @@ final class SpotifyASWebAuthSession {
|
|
|
62
67
|
|
|
63
68
|
// Start the session
|
|
64
69
|
DispatchQueue.main.async { [weak self] in
|
|
65
|
-
guard let self = self,
|
|
70
|
+
guard let self = self,
|
|
66
71
|
let authSession = self.authSession,
|
|
67
72
|
authSession.start() else {
|
|
73
|
+
self?.secureLog("Failed to start ASWebAuthenticationSession")
|
|
68
74
|
self?.isAuthenticating = false
|
|
69
75
|
completion(.failure(SpotifyAuthError.authorizationError("Failed to start auth session")))
|
|
70
76
|
return
|
|
@@ -275,7 +275,7 @@ final class SpotifyAuthAuth: NSObject, SPTSessionManagerDelegate {
|
|
|
275
275
|
.accessibility(.afterFirstUnlock)
|
|
276
276
|
try keychain.set(refreshToken, key: keychainKey)
|
|
277
277
|
} catch {
|
|
278
|
-
|
|
278
|
+
NSLog("[SpotifyAuth] Failed to store refresh token securely: \(error)")
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
281
|
}
|
|
@@ -288,7 +288,7 @@ final class SpotifyAuthAuth: NSObject, SPTSessionManagerDelegate {
|
|
|
288
288
|
let keychain = Keychain(service: Bundle.main.bundleIdentifier ?? "com.superfan.app")
|
|
289
289
|
try keychain.remove(keychainKey)
|
|
290
290
|
} catch {
|
|
291
|
-
|
|
291
|
+
NSLog("[SpotifyAuth] Failed to clear previous refresh token: \(error)")
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
294
|
|
|
@@ -354,32 +354,35 @@ final class SpotifyAuthAuth: NSObject, SPTSessionManagerDelegate {
|
|
|
354
354
|
|
|
355
355
|
public func initAuth(config: AuthorizeConfig) {
|
|
356
356
|
do {
|
|
357
|
+
secureLog("initAuth called, showDialog=\(config.showDialog), campaign=\(config.campaign ?? "nil")")
|
|
357
358
|
guard let sessionManager = self.sessionManager else {
|
|
358
359
|
throw SpotifyAuthError.sessionError("Session manager not initialized")
|
|
359
360
|
}
|
|
360
|
-
|
|
361
|
+
|
|
361
362
|
// Get scopes from Info.plist and convert to SPTScope
|
|
362
363
|
let scopes = try self.scopes
|
|
364
|
+
secureLog("Scopes from Info.plist: \(scopes.joined(separator: ", "))")
|
|
363
365
|
let sptScopes = scopes.reduce(into: SPTScope()) { result, scopeString in
|
|
364
366
|
if let scope = stringToScope(scopeString: scopeString) {
|
|
365
367
|
result.insert(scope)
|
|
366
368
|
}
|
|
367
369
|
}
|
|
368
|
-
|
|
370
|
+
|
|
369
371
|
if sptScopes.isEmpty {
|
|
370
372
|
throw SpotifyAuthError.invalidConfiguration("No valid scopes found in configuration")
|
|
371
373
|
}
|
|
372
|
-
|
|
374
|
+
|
|
373
375
|
isAuthenticating = true
|
|
374
|
-
|
|
376
|
+
|
|
375
377
|
if sessionManager.isSpotifyAppInstalled {
|
|
378
|
+
secureLog("Spotify app is installed, using app-switch flow")
|
|
376
379
|
// Use the native app‑switch flow
|
|
377
380
|
if config.showDialog {
|
|
378
381
|
sessionManager.alwaysShowAuthorizationDialog = true
|
|
379
382
|
}
|
|
380
383
|
sessionManager.initiateSession(with: sptScopes, options: .default, campaign: config.campaign)
|
|
381
384
|
} else {
|
|
382
|
-
|
|
385
|
+
secureLog("Spotify app not installed, using web auth fallback")
|
|
383
386
|
// Get configuration from Info.plist before dispatching to main thread
|
|
384
387
|
let clientId = try self.clientID
|
|
385
388
|
let redirectUrl = try self.redirectURL
|
|
@@ -492,23 +495,23 @@ final class SpotifyAuthAuth: NSObject, SPTSessionManagerDelegate {
|
|
|
492
495
|
// URLComponents.percentEncodedQuery properly encodes the values
|
|
493
496
|
request.httpBody = components.percentEncodedQuery?.data(using: .utf8)
|
|
494
497
|
|
|
495
|
-
|
|
498
|
+
NSLog("[SpotifyAuth] exchangeCodeForToken: sending request to \(url)")
|
|
496
499
|
let task = URLSession.shared.dataTask(with: request) { [weak self] data, response, error in
|
|
497
|
-
|
|
500
|
+
NSLog("[SpotifyAuth] exchangeCodeForToken: dataTask callback fired, self=\(self != nil), error=\(String(describing: error))")
|
|
498
501
|
if let http = response as? HTTPURLResponse {
|
|
499
|
-
|
|
502
|
+
NSLog("[SpotifyAuth] exchangeCodeForToken: HTTP status \(http.statusCode)")
|
|
500
503
|
}
|
|
501
504
|
if let data = data, let body = String(data: data, encoding: .utf8) {
|
|
502
|
-
|
|
505
|
+
NSLog("[SpotifyAuth] exchangeCodeForToken: response body = \(body)")
|
|
503
506
|
}
|
|
504
507
|
do {
|
|
505
508
|
let responseData = try self?.validateHTTPResponse(data: data, response: response, error: error)
|
|
506
509
|
guard let responseData = responseData else {
|
|
507
|
-
|
|
510
|
+
NSLog("[SpotifyAuth] exchangeCodeForToken: responseData is nil (self may be nil)")
|
|
508
511
|
return
|
|
509
512
|
}
|
|
510
513
|
let parsed = try Self.parseTokenJSON(from: responseData)
|
|
511
|
-
|
|
514
|
+
NSLog("[SpotifyAuth] exchangeCodeForToken: parsed token OK, hasRefreshToken=\(parsed.refreshToken != nil)")
|
|
512
515
|
|
|
513
516
|
guard let refreshToken = parsed.refreshToken else {
|
|
514
517
|
throw SpotifyAuthError.tokenError("Missing refresh_token in response")
|
|
@@ -517,11 +520,11 @@ final class SpotifyAuthAuth: NSObject, SPTSessionManagerDelegate {
|
|
|
517
520
|
let expirationDate = Date(timeIntervalSinceNow: parsed.expiresIn)
|
|
518
521
|
let sessionData = SpotifySessionData(accessToken: parsed.accessToken, refreshToken: refreshToken, expirationDate: expirationDate, scope: parsed.scope)
|
|
519
522
|
DispatchQueue.main.async {
|
|
520
|
-
|
|
523
|
+
NSLog("[SpotifyAuth] exchangeCodeForToken: setting currentSession on main thread")
|
|
521
524
|
self?.currentSession = sessionData
|
|
522
525
|
}
|
|
523
526
|
} catch {
|
|
524
|
-
|
|
527
|
+
NSLog("[SpotifyAuth] exchangeCodeForToken: caught error: \(error)")
|
|
525
528
|
self?.handleError(error, context: "token_exchange")
|
|
526
529
|
}
|
|
527
530
|
}
|
|
@@ -702,19 +705,13 @@ final class SpotifyAuthAuth: NSObject, SPTSessionManagerDelegate {
|
|
|
702
705
|
}
|
|
703
706
|
|
|
704
707
|
// MARK: - Logging
|
|
705
|
-
|
|
708
|
+
|
|
706
709
|
private func secureLog(_ message: String, sensitive: Bool = false) {
|
|
707
|
-
#if DEBUG
|
|
708
710
|
if sensitive {
|
|
709
|
-
|
|
711
|
+
NSLog("[SpotifyAuth] ********")
|
|
710
712
|
} else {
|
|
711
|
-
|
|
712
|
-
}
|
|
713
|
-
#else
|
|
714
|
-
if !sensitive {
|
|
715
|
-
print("[SpotifyAuth] \(message)")
|
|
713
|
+
NSLog("[SpotifyAuth] \(message)")
|
|
716
714
|
}
|
|
717
|
-
#endif
|
|
718
715
|
}
|
|
719
716
|
|
|
720
717
|
deinit {
|
|
@@ -8,15 +8,15 @@ let spotifyAuthorizationEventName = "onSpotifyAuth"
|
|
|
8
8
|
#if DEBUG
|
|
9
9
|
func secureLog(_ message: String, sensitive: Bool = false) {
|
|
10
10
|
if sensitive {
|
|
11
|
-
|
|
11
|
+
NSLog("[SpotifyAuth] ********")
|
|
12
12
|
} else {
|
|
13
|
-
|
|
13
|
+
NSLog("[SpotifyAuth] \(message)")
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
#else
|
|
17
17
|
func secureLog(_ message: String, sensitive: Bool = false) {
|
|
18
18
|
if !sensitive {
|
|
19
|
-
|
|
19
|
+
NSLog("[SpotifyAuth] \(message)")
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
#endif
|
|
@@ -79,7 +79,9 @@ public class SpotifyAuthModule: Module {
|
|
|
79
79
|
|
|
80
80
|
// Update the dismissal function
|
|
81
81
|
AsyncFunction("dismissAuthSession") {
|
|
82
|
-
|
|
82
|
+
DispatchQueue.main.async {
|
|
83
|
+
self.spotifyAuth.cancelWebAuth()
|
|
84
|
+
}
|
|
83
85
|
}
|
|
84
86
|
}
|
|
85
87
|
|