api.service.dart 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import 'dart:convert';
  2. import 'package:flutter/material.dart';
  3. import 'package:immich_mobile/shared/models/store.dart';
  4. import 'package:immich_mobile/utils/url_helper.dart';
  5. import 'package:openapi/api.dart';
  6. import 'package:http/http.dart';
  7. class ApiService {
  8. late ApiClient _apiClient;
  9. late UserApi userApi;
  10. late AuthenticationApi authenticationApi;
  11. late OAuthApi oAuthApi;
  12. late AlbumApi albumApi;
  13. late AssetApi assetApi;
  14. late SearchApi searchApi;
  15. late ServerInfoApi serverInfoApi;
  16. late PartnerApi partnerApi;
  17. late PersonApi personApi;
  18. ApiService() {
  19. final endpoint = Store.tryGet(StoreKey.serverEndpoint);
  20. if (endpoint != null && endpoint.isNotEmpty) {
  21. setEndpoint(endpoint);
  22. }
  23. }
  24. String? _authToken;
  25. setEndpoint(String endpoint) {
  26. _apiClient = ApiClient(basePath: endpoint);
  27. if (_authToken != null) {
  28. setAccessToken(_authToken!);
  29. }
  30. userApi = UserApi(_apiClient);
  31. authenticationApi = AuthenticationApi(_apiClient);
  32. oAuthApi = OAuthApi(_apiClient);
  33. albumApi = AlbumApi(_apiClient);
  34. assetApi = AssetApi(_apiClient);
  35. serverInfoApi = ServerInfoApi(_apiClient);
  36. searchApi = SearchApi(_apiClient);
  37. partnerApi = PartnerApi(_apiClient);
  38. personApi = PersonApi(_apiClient);
  39. }
  40. Future<String> resolveAndSetEndpoint(String serverUrl) async {
  41. final endpoint = await _resolveEndpoint(serverUrl);
  42. setEndpoint(endpoint);
  43. // Save in hivebox for next startup
  44. Store.put(StoreKey.serverEndpoint, endpoint);
  45. return endpoint;
  46. }
  47. /// Takes a server URL and attempts to resolve the API endpoint.
  48. ///
  49. /// Input: [schema://]host[:port][/path]
  50. /// schema - optional (default: https)
  51. /// host - required
  52. /// port - optional (default: based on schema)
  53. /// path - optional
  54. Future<String> _resolveEndpoint(String serverUrl) async {
  55. final url = sanitizeUrl(serverUrl);
  56. // Check for /.well-known/immich
  57. final wellKnownEndpoint = await _getWellKnownEndpoint(url);
  58. if (wellKnownEndpoint.isNotEmpty) return wellKnownEndpoint;
  59. // Otherwise, assume the URL provided is the api endpoint
  60. return url;
  61. }
  62. Future<String> _getWellKnownEndpoint(String baseUrl) async {
  63. final Client client = Client();
  64. try {
  65. final res = await client.get(
  66. Uri.parse("$baseUrl/.well-known/immich"),
  67. headers: {"Accept": "application/json"},
  68. );
  69. if (res.statusCode == 200) {
  70. final data = jsonDecode(res.body);
  71. final endpoint = data['api']['endpoint'].toString();
  72. if (endpoint.startsWith('/')) {
  73. // Full URL is relative to base
  74. return "$baseUrl$endpoint";
  75. }
  76. return endpoint;
  77. }
  78. } catch (e) {
  79. debugPrint("Could not locate /.well-known/immich at $baseUrl");
  80. }
  81. return "";
  82. }
  83. setAccessToken(String accessToken) {
  84. _authToken = accessToken;
  85. _apiClient.addDefaultHeader('Authorization', 'Bearer $accessToken');
  86. }
  87. ApiClient get apiClient => _apiClient;
  88. }