diff --git a/lib/provider/authentication/authentication.dart b/lib/provider/authentication/authentication.dart index 87eb7d42..13c83799 100644 --- a/lib/provider/authentication/authentication.dart +++ b/lib/provider/authentication/authentication.dart @@ -1,11 +1,9 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:io'; import 'package:collection/collection.dart'; import 'package:desktop_webview_window/desktop_webview_window.dart'; import 'package:dio/dio.dart'; -import 'package:dio/io.dart'; import 'package:dio_http2_adapter/dio_http2_adapter.dart'; import 'package:drift/drift.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart' @@ -20,6 +18,7 @@ import 'package:spotube/utils/platform.dart'; import 'package:otp_util/otp_util.dart'; // ignore: implementation_imports import 'package:otp_util/src/utils/generic_util.dart'; +import 'package:spotube/utils/service_utils.dart'; extension ExpirationAuthenticationTableData on AuthenticationTableData { bool get isExpired => DateTime.now().isAfter(expiration); @@ -169,7 +168,18 @@ class AuthenticationNotifier extends AsyncNotifier { final secret = base32FromBytes(secretBytes, secretSauce); - final res = await dio.get("https://open.spotify.com/server-time"); + final res = await dio.get( + "https://open.spotify.com/server-time", + options: Options( + headers: { + "Host": "open.spotify.com", + "User-Agent": ServiceUtils.randomUserAgent( + kIsDesktop ? UserAgentDevice.desktop : UserAgentDevice.mobile, + ), + "accept": "*/*", + }, + ), + ); final serverTimeSeconds = res.data["serverTime"] as int; final totp = TOTP( diff --git a/lib/utils/service_utils.dart b/lib/utils/service_utils.dart index b55af9e9..f0eeff05 100644 --- a/lib/utils/service_utils.dart +++ b/lib/utils/service_utils.dart @@ -1,6 +1,6 @@ +import 'dart:math'; import 'dart:typed_data'; -import 'package:auto_route/auto_route.dart'; import 'package:dio/dio.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; @@ -28,6 +28,11 @@ import 'package:spotube/collections/env.dart'; import 'package:version/version.dart'; +enum UserAgentDevice { + desktop, + mobile, +} + abstract class ServiceUtils { static final _englishMatcherRegex = RegExp( "^[a-zA-Z0-9\\s!\"#\$%&\\'()*+,-.\\/:;<=>?@\\[\\]^_`{|}~]*\$", @@ -417,4 +422,16 @@ abstract class ServiceUtils { return null; } } + + static int randomNumber(int min, int max) { + return min + Random().nextInt(max - min); + } + + static String randomUserAgent(UserAgentDevice type) { + if (type == UserAgentDevice.desktop) { + return "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_${randomNumber(11, 15)}_${randomNumber(4, 9)}) AppleWebKit/${randomNumber(530, 537)}.${randomNumber(30, 37)} (KHTML, like Gecko) Chrome/${randomNumber(80, 105)}.0.${randomNumber(3000, 4500)}.${randomNumber(60, 125)} Safari/${randomNumber(530, 537)}.${randomNumber(30, 36)}"; + } else { + return "Mozilla/5.0 (Linux; Android ${randomNumber(8, 13)}) AppleWebKit/${randomNumber(530, 537)}.${randomNumber(30, 36)} (KHTML, like Gecko) Chrome/${randomNumber(101, 116)}.0.${randomNumber(3000, 6000)}.${randomNumber(60, 125)} Mobile Safari/${randomNumber(530, 537)}.${randomNumber(30, 36)}"; + } + } }