mirror of
https://github.com/spotiflacapp/SpotiFLAC-Mobile.git
synced 2026-06-01 03:15:17 +07:00
fix: handle extension oauth callback on ios
This commit is contained in:
parent
ed020c9303
commit
7405855e01
2 changed files with 23 additions and 17 deletions
|
|
@ -70,21 +70,22 @@ import Gobackend // Import Go framework
|
|||
|
||||
GeneratedPluginRegistrant.register(with: self)
|
||||
if let url = launchOptions?[.url] as? URL {
|
||||
handleExtensionOAuthRedirect(url: url)
|
||||
_ = handleExtensionOAuthRedirect(url: url)
|
||||
}
|
||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||
}
|
||||
|
||||
/// PKCE OAuth return URL: spotiflac://callback?code=...&state=<extension_id>
|
||||
private func handleExtensionOAuthRedirect(url: URL) {
|
||||
guard let scheme = url.scheme?.lowercased(), scheme == "spotiflac" else { return }
|
||||
@discardableResult
|
||||
private func handleExtensionOAuthRedirect(url: URL) -> Bool {
|
||||
guard let scheme = url.scheme?.lowercased(), scheme == "spotiflac" else { return false }
|
||||
let host = (url.host ?? "").lowercased()
|
||||
let path = url.path.lowercased()
|
||||
let ok =
|
||||
host == "callback" || host == "spotify-callback" || path.contains("callback")
|
||||
guard ok else { return }
|
||||
guard ok else { return false }
|
||||
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false) else {
|
||||
return
|
||||
return false
|
||||
}
|
||||
let q = components.queryItems ?? []
|
||||
let code =
|
||||
|
|
@ -93,10 +94,10 @@ import Gobackend // Import Go framework
|
|||
let state =
|
||||
q.first { $0.name == "state" }?.value?.trimmingCharacters(
|
||||
in: .whitespacesAndNewlines) ?? ""
|
||||
if code.isEmpty { return }
|
||||
if code.isEmpty { return false }
|
||||
if state.isEmpty {
|
||||
NSLog("SpotiFLAC: Extension OAuth redirect missing state (extension id)")
|
||||
return
|
||||
return false
|
||||
}
|
||||
streamQueue.async {
|
||||
var err: NSError?
|
||||
|
|
@ -107,6 +108,7 @@ import Gobackend // Import Go framework
|
|||
"SpotiFLAC: Extension OAuth complete failed: \(err.localizedDescription)")
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override func application(
|
||||
|
|
@ -114,7 +116,9 @@ import Gobackend // Import Go framework
|
|||
open url: URL,
|
||||
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
|
||||
) -> Bool {
|
||||
handleExtensionOAuthRedirect(url: url)
|
||||
if handleExtensionOAuthRedirect(url: url) {
|
||||
return true
|
||||
}
|
||||
return super.application(app, open: url, options: options)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -443,7 +443,9 @@ class _ExtensionDetailPageState extends ConsumerState<ExtensionDetailPage> {
|
|||
}
|
||||
|
||||
/// Extensions may return `setting_updates` from button actions (e.g. OAuth URL field).
|
||||
Future<void> _handleExtensionActionPayload(Map<String, dynamic> payload) async {
|
||||
Future<void> _handleExtensionActionPayload(
|
||||
Map<String, dynamic> payload,
|
||||
) async {
|
||||
final raw = payload['setting_updates'];
|
||||
if (raw is! Map) return;
|
||||
final partial = <String, dynamic>{};
|
||||
|
|
@ -511,19 +513,19 @@ class _OauthLoginLinkPreview extends StatelessWidget {
|
|||
return Text(
|
||||
'Tap Connect to Spotify to fill this field.',
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
fontStyle: FontStyle.italic,
|
||||
),
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
fontStyle: FontStyle.italic,
|
||||
),
|
||||
);
|
||||
}
|
||||
return SelectionArea(
|
||||
child: Text(
|
||||
text,
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: colorScheme.primary,
|
||||
fontFamily: 'monospace',
|
||||
fontSize: 11,
|
||||
),
|
||||
color: colorScheme.primary,
|
||||
fontFamily: 'monospace',
|
||||
fontSize: 11,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -878,7 +880,7 @@ class _SettingItemState extends State<_SettingItem> {
|
|||
Map<String, dynamic> payload = result;
|
||||
final nested = result['result'];
|
||||
if (nested is Map) {
|
||||
payload = Map<String, dynamic>.from(nested as Map);
|
||||
payload = Map<String, dynamic>.from(nested);
|
||||
}
|
||||
|
||||
final success = payload['success'] as bool? ?? false;
|
||||
|
|
|
|||
Loading…
Reference in a new issue