From 1c9203b6c4a002cac1d00729bb44d9f2cefbf82d Mon Sep 17 00:00:00 2001 From: HuyNguyen Date: Tue, 4 Feb 2025 13:54:38 +0700 Subject: [PATCH 1/2] Integration federation lookup module --- ...federation_identity_lookup_datasource.dart | 20 +++ ...ation_identity_lookup_datasource_impl.dart | 45 +++++ .../network/federation_identity_endpoint.dart | 34 ++++ .../federation_identity_lookup_api.dart | 66 ++++++++ ...ation_identity_lookup_repository_impl.dart | 43 +++++ .../domain/models/federation_arguments.dart | 27 +++ .../federation_hash_details_response.dart | 26 +++ .../federation_lookup_mxid_request.dart | 28 ++++ .../federation_lookup_mxid_response.dart | 26 +++ .../models/federation_register_response.dart | 22 +++ ...federation_identity_lookup_repository.dart | 20 +++ .../federation_identity_lookup_state.dart | 52 ++++++ ...federation_identity_lookup_interactor.dart | 156 ++++++++++++++++++ .../federation_identity_lookup_manager.dart | 73 ++++++++ .../models/federation_token_information.dart | 32 ++++ .../models/federation_token_request.dart | 17 ++ 16 files changed, 687 insertions(+) create mode 100644 lib/modules/federation_identity_lookup/data/datasource/federation_identity_lookup_datasource.dart create mode 100644 lib/modules/federation_identity_lookup/data/datasource_impl/federation_identity_lookup_datasource_impl.dart create mode 100644 lib/modules/federation_identity_lookup/data/network/federation_identity_endpoint.dart create mode 100644 lib/modules/federation_identity_lookup/data/network/federation_identity_lookup_api.dart create mode 100644 lib/modules/federation_identity_lookup/data/repository_impl/federation_identity_lookup_repository_impl.dart create mode 100644 lib/modules/federation_identity_lookup/domain/models/federation_arguments.dart create mode 100644 lib/modules/federation_identity_lookup/domain/models/federation_hash_details_response.dart create mode 100644 lib/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_request.dart create mode 100644 lib/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_response.dart create mode 100644 lib/modules/federation_identity_lookup/domain/models/federation_register_response.dart create mode 100644 lib/modules/federation_identity_lookup/domain/repository/federation_identity_lookup_repository.dart create mode 100644 lib/modules/federation_identity_lookup/domain/state/federation_identity_lookup_state.dart create mode 100644 lib/modules/federation_identity_lookup/domain/usecase/federation_identity_lookup_interactor.dart create mode 100644 lib/modules/federation_identity_lookup/manager/federation_identity_lookup_manager.dart create mode 100644 lib/modules/federation_indetity_request_token/domain/models/federation_token_information.dart create mode 100644 lib/modules/federation_indetity_request_token/domain/models/federation_token_request.dart diff --git a/lib/modules/federation_identity_lookup/data/datasource/federation_identity_lookup_datasource.dart b/lib/modules/federation_identity_lookup/data/datasource/federation_identity_lookup_datasource.dart new file mode 100644 index 000000000..48d050f97 --- /dev/null +++ b/lib/modules/federation_identity_lookup/data/datasource/federation_identity_lookup_datasource.dart @@ -0,0 +1,20 @@ +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_hash_details_response.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_request.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_response.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_register_response.dart'; +import 'package:fluffychat/modules/federation_indetity_request_token/domain/models/federation_token_information.dart'; + +abstract class FederationIdentityLookupDatasource { + Future register({ + required FederationTokenInformation tokenInformation, + }); + + Future getHashDetails({ + required String token, + }); + + Future lookupMxid({ + required FederationLookupMxidRequest request, + required String token, + }); +} diff --git a/lib/modules/federation_identity_lookup/data/datasource_impl/federation_identity_lookup_datasource_impl.dart b/lib/modules/federation_identity_lookup/data/datasource_impl/federation_identity_lookup_datasource_impl.dart new file mode 100644 index 000000000..247dcd7d6 --- /dev/null +++ b/lib/modules/federation_identity_lookup/data/datasource_impl/federation_identity_lookup_datasource_impl.dart @@ -0,0 +1,45 @@ +import 'package:fluffychat/modules/federation_identity_lookup/data/datasource/federation_identity_lookup_datasource.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/data/network/federation_identity_lookup_api.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_hash_details_response.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_request.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_response.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_register_response.dart'; +import 'package:fluffychat/modules/federation_indetity_request_token/domain/models/federation_token_information.dart'; + +class FederationIdentityLookupDatasourceImpl + implements FederationIdentityLookupDatasource { + final FederationIdentityLookupApi federationIdentityLookupApi; + + FederationIdentityLookupDatasourceImpl({ + required this.federationIdentityLookupApi, + }); + + @override + Future getHashDetails({ + required String token, + }) { + return federationIdentityLookupApi.getHashDetails( + token, + ); + } + + @override + Future lookupMxid({ + required FederationLookupMxidRequest request, + required String token, + }) { + return federationIdentityLookupApi.lookupMxid( + request: request, + token: token, + ); + } + + @override + Future register({ + required FederationTokenInformation tokenInformation, + }) { + return federationIdentityLookupApi.register( + tokenInformation: tokenInformation, + ); + } +} diff --git a/lib/modules/federation_identity_lookup/data/network/federation_identity_endpoint.dart b/lib/modules/federation_identity_lookup/data/network/federation_identity_endpoint.dart new file mode 100644 index 000000000..db3cb3edf --- /dev/null +++ b/lib/modules/federation_identity_lookup/data/network/federation_identity_endpoint.dart @@ -0,0 +1,34 @@ +import 'package:fluffychat/data/network/service_path.dart'; + +class FederationIdentityEndpoint { + static const String federationIdentityRootPath = '/_matrix/identity'; + static const String federationIdentityAPIVersion = 'v2'; + + static const federationIdentityDioClientName = + 'federationIdentityDioClientName'; + + static const acceptHeaderDefault = 'application/json'; + + static const contentTypeHeaderDefault = 'application/json'; + + static final ServicePath lookupServicePath = ServicePath( + '/lookup', + ); + + static final ServicePath hashDetailsServicePath = ServicePath( + '/hash_details', + ); + + static final ServicePath registerServicePath = ServicePath( + '/register', + ); +} + +extension FederationServicePathExtensions on ServicePath { + String generateFederationIdentityEndpoint({ + String rootPath = FederationIdentityEndpoint.federationIdentityRootPath, + String apiVersion = FederationIdentityEndpoint.federationIdentityAPIVersion, + }) { + return '$rootPath/$apiVersion$path'; + } +} diff --git a/lib/modules/federation_identity_lookup/data/network/federation_identity_lookup_api.dart b/lib/modules/federation_identity_lookup/data/network/federation_identity_lookup_api.dart new file mode 100644 index 000000000..dd92c41ab --- /dev/null +++ b/lib/modules/federation_identity_lookup/data/network/federation_identity_lookup_api.dart @@ -0,0 +1,66 @@ +import 'dart:io'; + +import 'package:dio/dio.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/data/network/federation_identity_endpoint.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_hash_details_response.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_request.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_response.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_register_response.dart'; +import 'package:fluffychat/modules/federation_indetity_request_token/domain/models/federation_token_information.dart'; +import 'package:fluffychat/data/network/dio_client.dart'; + +class FederationIdentityLookupApi { + final DioClient client; + + FederationIdentityLookupApi(this.client); + + Future register({ + required FederationTokenInformation tokenInformation, + }) async { + final path = FederationIdentityEndpoint.registerServicePath + .generateFederationIdentityEndpoint(); + + final response = await client.postToGetBody( + path, + data: tokenInformation.toJson(), + ); + + return FederationRegisterResponse.fromJson(response); + } + + Future getHashDetails(String token) async { + final path = FederationIdentityEndpoint.hashDetailsServicePath + .generateFederationIdentityEndpoint(); + + final dioHeaders = client.getHeaders(); + + dioHeaders[HttpHeaders.authorizationHeader] = 'Bearer $token'; + + final response = await client.get( + path, + options: Options(headers: dioHeaders), + ); + + return FederationHashDetailsResponse.fromJson(response); + } + + Future lookupMxid({ + required FederationLookupMxidRequest request, + required String token, + }) async { + final path = FederationIdentityEndpoint.lookupServicePath + .generateFederationIdentityEndpoint(); + + final dioHeaders = client.getHeaders(); + + dioHeaders[HttpHeaders.authorizationHeader] = 'Bearer $token'; + + final response = await client.postToGetBody( + path, + data: request.toJson(), + options: Options(headers: dioHeaders), + ); + + return FederationLookupMxidResponse.fromJson(response); + } +} diff --git a/lib/modules/federation_identity_lookup/data/repository_impl/federation_identity_lookup_repository_impl.dart b/lib/modules/federation_identity_lookup/data/repository_impl/federation_identity_lookup_repository_impl.dart new file mode 100644 index 000000000..4b105766e --- /dev/null +++ b/lib/modules/federation_identity_lookup/data/repository_impl/federation_identity_lookup_repository_impl.dart @@ -0,0 +1,43 @@ +import 'package:fluffychat/modules/federation_identity_lookup/data/datasource/federation_identity_lookup_datasource.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_hash_details_response.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_request.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_response.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_register_response.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/repository/federation_identity_lookup_repository.dart'; +import 'package:fluffychat/modules/federation_indetity_request_token/domain/models/federation_token_information.dart'; + +class FederationIdentityLookupRepositoryImpl + implements FederationIdentityLookupRepository { + final FederationIdentityLookupDatasource datasource; + + FederationIdentityLookupRepositoryImpl({required this.datasource}); + + @override + Future getHashDetails({ + required String token, + }) { + return datasource.getHashDetails( + token: token, + ); + } + + @override + Future lookupMxid({ + required FederationLookupMxidRequest request, + required String token, + }) { + return datasource.lookupMxid( + request: request, + token: token, + ); + } + + @override + Future register({ + required FederationTokenInformation tokenInformation, + }) { + return datasource.register( + tokenInformation: tokenInformation, + ); + } +} diff --git a/lib/modules/federation_identity_lookup/domain/models/federation_arguments.dart b/lib/modules/federation_identity_lookup/domain/models/federation_arguments.dart new file mode 100644 index 000000000..c7fc5870f --- /dev/null +++ b/lib/modules/federation_identity_lookup/domain/models/federation_arguments.dart @@ -0,0 +1,27 @@ +import 'package:equatable/equatable.dart'; +import 'package:fluffychat/modules/federation_indetity_request_token/domain/models/federation_token_information.dart'; + +class FederationArguments with EquatableMixin { + final String federationUrl; + + final FederationTokenInformation tokenInformation; + + final Set? phoneNumbers; + + final Set? emailAddresses; + + FederationArguments({ + required this.federationUrl, + required this.tokenInformation, + this.phoneNumbers, + this.emailAddresses, + }); + + @override + List get props => [ + federationUrl, + tokenInformation, + phoneNumbers, + emailAddresses, + ]; +} diff --git a/lib/modules/federation_identity_lookup/domain/models/federation_hash_details_response.dart b/lib/modules/federation_identity_lookup/domain/models/federation_hash_details_response.dart new file mode 100644 index 000000000..102052e89 --- /dev/null +++ b/lib/modules/federation_identity_lookup/domain/models/federation_hash_details_response.dart @@ -0,0 +1,26 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'federation_hash_details_response.g.dart'; + +@JsonSerializable() +class FederationHashDetailsResponse extends Equatable { + @JsonKey(name: 'algorithms') + final Set? algorithms; + + @JsonKey(name: 'lookup_pepper') + final String? lookupPepper; + + const FederationHashDetailsResponse({ + this.algorithms, + this.lookupPepper, + }); + + @override + List get props => [algorithms, lookupPepper]; + + factory FederationHashDetailsResponse.fromJson(Map json) => + _$FederationHashDetailsResponseFromJson(json); + + Map toJson() => _$FederationHashDetailsResponseToJson(this); +} diff --git a/lib/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_request.dart b/lib/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_request.dart new file mode 100644 index 000000000..3ce40f5d0 --- /dev/null +++ b/lib/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_request.dart @@ -0,0 +1,28 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'federation_lookup_mxid_request.g.dart'; + +@JsonSerializable() +class FederationLookupMxidRequest extends Equatable { + @JsonKey(name: 'addresses') + final Set? addresses; + @JsonKey(name: 'algorithm') + final String? algorithm; + @JsonKey(name: 'pepper') + final String? pepper; + + const FederationLookupMxidRequest({ + this.addresses, + this.algorithm, + this.pepper, + }); + + factory FederationLookupMxidRequest.fromJson(Map json) => + _$FederationLookupMxidRequestFromJson(json); + + Map toJson() => _$FederationLookupMxidRequestToJson(this); + + @override + List get props => [addresses, algorithm, pepper]; +} diff --git a/lib/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_response.dart b/lib/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_response.dart new file mode 100644 index 000000000..93cd061bd --- /dev/null +++ b/lib/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_response.dart @@ -0,0 +1,26 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'federation_lookup_mxid_response.g.dart'; + +@JsonSerializable() +class FederationLookupMxidResponse extends Equatable { + @JsonKey(name: 'mappings') + final Map? mappings; + + @JsonKey(name: 'inactive_mappings') + final Map? inactiveMappings; + + const FederationLookupMxidResponse({ + this.mappings, + this.inactiveMappings, + }); + + factory FederationLookupMxidResponse.fromJson(Map json) => + _$FederationLookupMxidResponseFromJson(json); + + Map toJson() => _$FederationLookupMxidResponseToJson(this); + + @override + List get props => [mappings, inactiveMappings]; +} diff --git a/lib/modules/federation_identity_lookup/domain/models/federation_register_response.dart b/lib/modules/federation_identity_lookup/domain/models/federation_register_response.dart new file mode 100644 index 000000000..6ecfe6767 --- /dev/null +++ b/lib/modules/federation_identity_lookup/domain/models/federation_register_response.dart @@ -0,0 +1,22 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'federation_register_response.g.dart'; + +@JsonSerializable() +class FederationRegisterResponse extends Equatable { + @JsonKey(name: "token") + final String? token; + + const FederationRegisterResponse({ + this.token, + }); + + factory FederationRegisterResponse.fromJson(Map json) => + _$FederationRegisterResponseFromJson(json); + + Map toJson() => _$FederationRegisterResponseToJson(this); + + @override + List get props => [token]; +} diff --git a/lib/modules/federation_identity_lookup/domain/repository/federation_identity_lookup_repository.dart b/lib/modules/federation_identity_lookup/domain/repository/federation_identity_lookup_repository.dart new file mode 100644 index 000000000..cc0935d49 --- /dev/null +++ b/lib/modules/federation_identity_lookup/domain/repository/federation_identity_lookup_repository.dart @@ -0,0 +1,20 @@ +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_hash_details_response.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_request.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_response.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_register_response.dart'; +import 'package:fluffychat/modules/federation_indetity_request_token/domain/models/federation_token_information.dart'; + +abstract class FederationIdentityLookupRepository { + Future register({ + required FederationTokenInformation tokenInformation, + }); + + Future getHashDetails({ + required String token, + }); + + Future lookupMxid({ + required FederationLookupMxidRequest request, + required String token, + }); +} diff --git a/lib/modules/federation_identity_lookup/domain/state/federation_identity_lookup_state.dart b/lib/modules/federation_identity_lookup/domain/state/federation_identity_lookup_state.dart new file mode 100644 index 000000000..ceee907bc --- /dev/null +++ b/lib/modules/federation_identity_lookup/domain/state/federation_identity_lookup_state.dart @@ -0,0 +1,52 @@ +import 'package:fluffychat/app_state/failure.dart'; +import 'package:fluffychat/app_state/initial.dart'; +import 'package:fluffychat/app_state/success.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_response.dart'; + +class FederationIdentityLookupInitial extends Initial { + const FederationIdentityLookupInitial() : super(); + + @override + List get props => []; +} + +class FederationIdentityLookupLoading extends Success { + const FederationIdentityLookupLoading(); + + @override + List get props => []; +} + +class FederationIdentityLookupSuccess extends Success { + const FederationIdentityLookupSuccess({ + required this.federationLookupMxidResponse, + }); + + final FederationLookupMxidResponse federationLookupMxidResponse; + + @override + List get props => []; +} + +class FederationIdentityLookupFailure extends Failure { + final dynamic exception; + + const FederationIdentityLookupFailure({required this.exception}); + + @override + List get props => [exception]; +} + +class FederationIdentityCalculationHashesEmpty extends Failure { + const FederationIdentityCalculationHashesEmpty(); + + @override + List get props => []; +} + +class FederationIdentityGetTokenFailure extends Failure { + const FederationIdentityGetTokenFailure(); + + @override + List get props => []; +} diff --git a/lib/modules/federation_identity_lookup/domain/usecase/federation_identity_lookup_interactor.dart b/lib/modules/federation_identity_lookup/domain/usecase/federation_identity_lookup_interactor.dart new file mode 100644 index 000000000..0444218ae --- /dev/null +++ b/lib/modules/federation_identity_lookup/domain/usecase/federation_identity_lookup_interactor.dart @@ -0,0 +1,156 @@ +import 'dart:convert'; + +import 'package:crypto/crypto.dart'; +import 'package:dartz/dartz.dart'; +import 'package:fluffychat/app_state/failure.dart'; +import 'package:fluffychat/app_state/success.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_arguments.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_hash_details_response.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_request.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/repository/federation_identity_lookup_repository.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/state/federation_identity_lookup_state.dart'; +import 'package:fluffychat/utils/string_extension.dart'; +import 'package:matrix/encryption/utils/base64_unpadded.dart'; + +class FederationIdentityLookupInteractor { + final FederationIdentityLookupRepository federationIdentityLookupRepository; + + FederationIdentityLookupInteractor({ + required this.federationIdentityLookupRepository, + }); + + Stream> execute({ + required FederationArguments arguments, + }) async* { + try { + yield const Right(FederationIdentityLookupLoading()); + final registerResponse = + await federationIdentityLookupRepository.register( + tokenInformation: arguments.tokenInformation, + ); + + if (registerResponse.token == null && registerResponse.token!.isEmpty) { + yield const Left(FederationIdentityGetTokenFailure()); + } + + final hashDetails = + await federationIdentityLookupRepository.getHashDetails( + token: registerResponse.token!, + ); + + final addresses = _calculateHashes( + hashDetails: hashDetails, + arguments: arguments, + ); + + if (addresses.isEmpty) { + yield const Left(FederationIdentityCalculationHashesEmpty()); + } + + final lookupMxidResponse = + await federationIdentityLookupRepository.lookupMxid( + request: FederationLookupMxidRequest( + addresses: addresses, + algorithm: hashDetails.algorithms?.firstOrNull, + pepper: hashDetails.lookupPepper, + ), + token: registerResponse.token!, + ); + + yield Right( + FederationIdentityLookupSuccess( + federationLookupMxidResponse: lookupMxidResponse, + ), + ); + } catch (e) { + yield Left(FederationIdentityLookupFailure(exception: e)); + } + } + + Set _calculateHashes({ + required FederationHashDetailsResponse hashDetails, + required FederationArguments arguments, + }) { + final addresses = {}; + if (arguments.phoneNumbers != null && arguments.phoneNumbers!.isNotEmpty) { + for (final phoneNumber in arguments.phoneNumbers!) { + final hashes = calculateHashUsingAllPeppers( + hashDetails: hashDetails, + thirdPartyId: phoneNumber, + thirdPartyIdType: 'msisdn', + ); + addresses.addAll(hashes); + } + } + + if (arguments.emailAddresses != null && + arguments.emailAddresses!.isNotEmpty) { + for (final email in arguments.emailAddresses!) { + final hashes = calculateHashUsingAllPeppers( + hashDetails: hashDetails, + thirdPartyId: email, + thirdPartyIdType: 'email', + ); + addresses.addAll(hashes); + } + } + return addresses; + } + + String calculateHashWithAlgorithmSha256({ + required String pepper, + required String thirdPartyId, + required String thirdPartyIdType, + }) { + final input = [thirdPartyId, thirdPartyIdType, pepper].join(' '); + final bytes = utf8.encode(input); + final lookupHash = + encodeBase64Unpadded(sha256.convert(bytes).bytes).urlSafeBase64; + return lookupHash; + } + + String calculateHashWithoutAlgorithm({ + required String pepper, + required String thirdPartyId, + required String thirdPartyIdType, + }) { + return [thirdPartyId, thirdPartyIdType].join(' '); + } + + Set calculateHashUsingAllPeppers({ + required FederationHashDetailsResponse hashDetails, + required String thirdPartyId, + required String thirdPartyIdType, + }) { + final Set hashes = {}; + + if (hashDetails.algorithms == null || hashDetails.algorithms!.isEmpty) { + return hashes; + } + + for (final algorithm in hashDetails.algorithms!) { + final peppers = { + hashDetails.lookupPepper, + }; + + for (final pepper in peppers) { + if (algorithm == 'sha256') { + final hash = calculateHashWithAlgorithmSha256( + thirdPartyId: '', + thirdPartyIdType: '', + pepper: pepper ?? '', + ); + hashes.add(hash); + } else { + final hash = calculateHashWithoutAlgorithm( + thirdPartyId: '', + thirdPartyIdType: '', + pepper: pepper ?? '', + ); + hashes.add(hash); + } + } + } + return hashes; + } +} diff --git a/lib/modules/federation_identity_lookup/manager/federation_identity_lookup_manager.dart b/lib/modules/federation_identity_lookup/manager/federation_identity_lookup_manager.dart new file mode 100644 index 000000000..461194643 --- /dev/null +++ b/lib/modules/federation_identity_lookup/manager/federation_identity_lookup_manager.dart @@ -0,0 +1,73 @@ +import 'dart:io'; + +import 'package:dartz/dartz.dart'; +import 'package:dio/dio.dart'; +import 'package:fluffychat/app_state/failure.dart'; +import 'package:fluffychat/app_state/success.dart'; +import 'package:fluffychat/data/network/dio_client.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/data/datasource_impl/federation_identity_lookup_datasource_impl.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/data/network/federation_identity_endpoint.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/data/network/federation_identity_lookup_api.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/data/repository_impl/federation_identity_lookup_repository_impl.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_arguments.dart'; +import 'package:fluffychat/modules/federation_identity_lookup/domain/usecase/federation_identity_lookup_interactor.dart'; + +class FederationIdentityLookupManager { + final FederationArguments arguments; + + FederationIdentityLookupManager({ + required this.arguments, + }); + + DioClient _bindingDio() { + final headers = { + HttpHeaders.acceptHeader: FederationIdentityEndpoint.acceptHeaderDefault, + HttpHeaders.contentTypeHeader: + FederationIdentityEndpoint.contentTypeHeaderDefault, + }; + + return DioClient( + Dio( + BaseOptions( + baseUrl: arguments.federationUrl, + headers: headers, + ), + ), + ); + } + + FederationIdentityLookupApi _bindingAPI(DioClient dio) { + return FederationIdentityLookupApi(dio); + } + + FederationIdentityLookupDatasourceImpl _bindingDataSourceImpl( + FederationIdentityLookupApi federationIdentityLookupApi, + ) { + return FederationIdentityLookupDatasourceImpl( + federationIdentityLookupApi: federationIdentityLookupApi, + ); + } + + FederationIdentityLookupRepositoryImpl _bindingRepositoryImpl( + FederationIdentityLookupDatasourceImpl datasource, + ) { + return FederationIdentityLookupRepositoryImpl( + datasource: datasource, + ); + } + + FederationIdentityLookupInteractor _bindingInteractor() { + final dio = _bindingDio(); + final api = _bindingAPI(dio); + final datasource = _bindingDataSourceImpl(api); + final repository = _bindingRepositoryImpl(datasource); + + return FederationIdentityLookupInteractor( + federationIdentityLookupRepository: repository, + ); + } + + Stream> execute() { + return _bindingInteractor().execute(arguments: arguments); + } +} diff --git a/lib/modules/federation_indetity_request_token/domain/models/federation_token_information.dart b/lib/modules/federation_indetity_request_token/domain/models/federation_token_information.dart new file mode 100644 index 000000000..fea13c606 --- /dev/null +++ b/lib/modules/federation_indetity_request_token/domain/models/federation_token_information.dart @@ -0,0 +1,32 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'federation_token_information.g.dart'; + +@JsonSerializable() +class FederationTokenInformation extends Equatable { + @JsonKey(name: "access_token") + final String? accessToken; + @JsonKey(name: "token_type") + final String? tokenType; + @JsonKey(name: "matrix_server_name") + final String? matrixServerName; + @JsonKey(name: "expires_in") + final int? expiresIn; + + const FederationTokenInformation({ + this.accessToken, + this.tokenType, + this.matrixServerName, + this.expiresIn, + }); + + factory FederationTokenInformation.fromJson(Map json) => + _$FederationTokenInformationFromJson(json); + + Map toJson() => _$FederationTokenInformationToJson(this); + + @override + List get props => + [accessToken, tokenType, matrixServerName, expiresIn]; +} diff --git a/lib/modules/federation_indetity_request_token/domain/models/federation_token_request.dart b/lib/modules/federation_indetity_request_token/domain/models/federation_token_request.dart new file mode 100644 index 000000000..3d67ed779 --- /dev/null +++ b/lib/modules/federation_indetity_request_token/domain/models/federation_token_request.dart @@ -0,0 +1,17 @@ +import 'package:equatable/equatable.dart'; + +class FederationTokenRequest with EquatableMixin { + final String federationUrl; + final String mxid; + + FederationTokenRequest({ + required this.federationUrl, + required this.mxid, + }); + + @override + List get props => [ + federationUrl, + mxid, + ]; +} From 76cef7bd3c1e05cce832ed0243b531f5a442d5eb Mon Sep 17 00:00:00 2001 From: HuyNguyen Date: Tue, 4 Feb 2025 15:48:28 +0700 Subject: [PATCH 2/2] Integration federation request token module --- ...federation_identity_lookup_datasource.dart | 2 +- ...ation_identity_lookup_datasource_impl.dart | 2 +- .../federation_identity_lookup_api.dart | 2 +- ...ation_identity_lookup_repository_impl.dart | 2 +- .../domain/models/federation_arguments.dart | 2 +- ...federation_identity_lookup_repository.dart | 2 +- ...ion_identity_request_token_datasource.dart | 7 ++ ...dentity_request_token_datasource_impl.dart | 21 +++++ ...federation_identity_request_token_api.dart | 19 +++++ ...ation_identity_request_token_endpoint.dart | 28 +++++++ ...dentity_request_token_repository_impl.dart | 19 +++++ .../models/federation_token_information.dart | 0 .../models/federation_token_request.dart | 3 + ...ion_identity_request_token_repository.dart | 7 ++ ...deration_identity_request_token_state.dart | 38 +++++++++ ...ion_identity_request_token_interactor.dart | 33 ++++++++ ...ration_identity_request_token_manager.dart | 77 +++++++++++++++++++ 17 files changed, 258 insertions(+), 6 deletions(-) create mode 100644 lib/modules/federation_identity_request_token/data/datasource/federation_identity_request_token_datasource.dart create mode 100644 lib/modules/federation_identity_request_token/data/datasource_impl/federation_identity_request_token_datasource_impl.dart create mode 100644 lib/modules/federation_identity_request_token/data/network/federation_identity_request_token_api.dart create mode 100644 lib/modules/federation_identity_request_token/data/network/federation_identity_request_token_endpoint.dart create mode 100644 lib/modules/federation_identity_request_token/data/repository/federation_identity_request_token_repository_impl.dart rename lib/modules/{federation_indetity_request_token => federation_identity_request_token}/domain/models/federation_token_information.dart (100%) rename lib/modules/{federation_indetity_request_token => federation_identity_request_token}/domain/models/federation_token_request.dart (84%) create mode 100644 lib/modules/federation_identity_request_token/domain/repository/federation_identity_request_token_repository.dart create mode 100644 lib/modules/federation_identity_request_token/domain/state/federation_identity_request_token_state.dart create mode 100644 lib/modules/federation_identity_request_token/domain/usecase/federation_identity_request_token_interactor.dart create mode 100644 lib/modules/federation_identity_request_token/manager/federation_identity_request_token_manager.dart diff --git a/lib/modules/federation_identity_lookup/data/datasource/federation_identity_lookup_datasource.dart b/lib/modules/federation_identity_lookup/data/datasource/federation_identity_lookup_datasource.dart index 48d050f97..10849c61f 100644 --- a/lib/modules/federation_identity_lookup/data/datasource/federation_identity_lookup_datasource.dart +++ b/lib/modules/federation_identity_lookup/data/datasource/federation_identity_lookup_datasource.dart @@ -2,7 +2,7 @@ import 'package:fluffychat/modules/federation_identity_lookup/domain/models/fede import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_request.dart'; import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_response.dart'; import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_register_response.dart'; -import 'package:fluffychat/modules/federation_indetity_request_token/domain/models/federation_token_information.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/domain/models/federation_token_information.dart'; abstract class FederationIdentityLookupDatasource { Future register({ diff --git a/lib/modules/federation_identity_lookup/data/datasource_impl/federation_identity_lookup_datasource_impl.dart b/lib/modules/federation_identity_lookup/data/datasource_impl/federation_identity_lookup_datasource_impl.dart index 247dcd7d6..945a951e9 100644 --- a/lib/modules/federation_identity_lookup/data/datasource_impl/federation_identity_lookup_datasource_impl.dart +++ b/lib/modules/federation_identity_lookup/data/datasource_impl/federation_identity_lookup_datasource_impl.dart @@ -4,7 +4,7 @@ import 'package:fluffychat/modules/federation_identity_lookup/domain/models/fede import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_request.dart'; import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_response.dart'; import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_register_response.dart'; -import 'package:fluffychat/modules/federation_indetity_request_token/domain/models/federation_token_information.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/domain/models/federation_token_information.dart'; class FederationIdentityLookupDatasourceImpl implements FederationIdentityLookupDatasource { diff --git a/lib/modules/federation_identity_lookup/data/network/federation_identity_lookup_api.dart b/lib/modules/federation_identity_lookup/data/network/federation_identity_lookup_api.dart index dd92c41ab..d0e388c22 100644 --- a/lib/modules/federation_identity_lookup/data/network/federation_identity_lookup_api.dart +++ b/lib/modules/federation_identity_lookup/data/network/federation_identity_lookup_api.dart @@ -6,7 +6,7 @@ import 'package:fluffychat/modules/federation_identity_lookup/domain/models/fede import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_request.dart'; import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_response.dart'; import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_register_response.dart'; -import 'package:fluffychat/modules/federation_indetity_request_token/domain/models/federation_token_information.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/domain/models/federation_token_information.dart'; import 'package:fluffychat/data/network/dio_client.dart'; class FederationIdentityLookupApi { diff --git a/lib/modules/federation_identity_lookup/data/repository_impl/federation_identity_lookup_repository_impl.dart b/lib/modules/federation_identity_lookup/data/repository_impl/federation_identity_lookup_repository_impl.dart index 4b105766e..af2644a26 100644 --- a/lib/modules/federation_identity_lookup/data/repository_impl/federation_identity_lookup_repository_impl.dart +++ b/lib/modules/federation_identity_lookup/data/repository_impl/federation_identity_lookup_repository_impl.dart @@ -4,7 +4,7 @@ import 'package:fluffychat/modules/federation_identity_lookup/domain/models/fede import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_response.dart'; import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_register_response.dart'; import 'package:fluffychat/modules/federation_identity_lookup/domain/repository/federation_identity_lookup_repository.dart'; -import 'package:fluffychat/modules/federation_indetity_request_token/domain/models/federation_token_information.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/domain/models/federation_token_information.dart'; class FederationIdentityLookupRepositoryImpl implements FederationIdentityLookupRepository { diff --git a/lib/modules/federation_identity_lookup/domain/models/federation_arguments.dart b/lib/modules/federation_identity_lookup/domain/models/federation_arguments.dart index c7fc5870f..4ad0d6be6 100644 --- a/lib/modules/federation_identity_lookup/domain/models/federation_arguments.dart +++ b/lib/modules/federation_identity_lookup/domain/models/federation_arguments.dart @@ -1,5 +1,5 @@ import 'package:equatable/equatable.dart'; -import 'package:fluffychat/modules/federation_indetity_request_token/domain/models/federation_token_information.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/domain/models/federation_token_information.dart'; class FederationArguments with EquatableMixin { final String federationUrl; diff --git a/lib/modules/federation_identity_lookup/domain/repository/federation_identity_lookup_repository.dart b/lib/modules/federation_identity_lookup/domain/repository/federation_identity_lookup_repository.dart index cc0935d49..6a17acd70 100644 --- a/lib/modules/federation_identity_lookup/domain/repository/federation_identity_lookup_repository.dart +++ b/lib/modules/federation_identity_lookup/domain/repository/federation_identity_lookup_repository.dart @@ -2,7 +2,7 @@ import 'package:fluffychat/modules/federation_identity_lookup/domain/models/fede import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_request.dart'; import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_lookup_mxid_response.dart'; import 'package:fluffychat/modules/federation_identity_lookup/domain/models/federation_register_response.dart'; -import 'package:fluffychat/modules/federation_indetity_request_token/domain/models/federation_token_information.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/domain/models/federation_token_information.dart'; abstract class FederationIdentityLookupRepository { Future register({ diff --git a/lib/modules/federation_identity_request_token/data/datasource/federation_identity_request_token_datasource.dart b/lib/modules/federation_identity_request_token/data/datasource/federation_identity_request_token_datasource.dart new file mode 100644 index 000000000..263f307af --- /dev/null +++ b/lib/modules/federation_identity_request_token/data/datasource/federation_identity_request_token_datasource.dart @@ -0,0 +1,7 @@ +import 'package:fluffychat/modules/federation_identity_request_token/domain/models/federation_token_information.dart'; + +abstract class FederationIdentityRequestTokenDatasource { + Future requestToken({ + required String mxid, + }); +} diff --git a/lib/modules/federation_identity_request_token/data/datasource_impl/federation_identity_request_token_datasource_impl.dart b/lib/modules/federation_identity_request_token/data/datasource_impl/federation_identity_request_token_datasource_impl.dart new file mode 100644 index 000000000..11837dbe5 --- /dev/null +++ b/lib/modules/federation_identity_request_token/data/datasource_impl/federation_identity_request_token_datasource_impl.dart @@ -0,0 +1,21 @@ +import 'package:fluffychat/modules/federation_identity_request_token/data/datasource/federation_identity_request_token_datasource.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/data/network/federation_identity_request_token_api.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/domain/models/federation_token_information.dart'; + +class FederationIdentityRequestTokenDatasourceImpl + implements FederationIdentityRequestTokenDatasource { + final FederationIdentityRequestTokenApi federationIdentityRequestTokenApi; + + FederationIdentityRequestTokenDatasourceImpl({ + required this.federationIdentityRequestTokenApi, + }); + + @override + Future requestToken({ + required String mxid, + }) { + return federationIdentityRequestTokenApi.getToken( + mxid: mxid, + ); + } +} diff --git a/lib/modules/federation_identity_request_token/data/network/federation_identity_request_token_api.dart b/lib/modules/federation_identity_request_token/data/network/federation_identity_request_token_api.dart new file mode 100644 index 000000000..b2b49e00e --- /dev/null +++ b/lib/modules/federation_identity_request_token/data/network/federation_identity_request_token_api.dart @@ -0,0 +1,19 @@ +import 'package:fluffychat/data/network/dio_client.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/data/network/federation_identity_request_token_endpoint.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/domain/models/federation_token_information.dart'; + +class FederationIdentityRequestTokenApi { + final DioClient client; + + FederationIdentityRequestTokenApi(this.client); + + Future getToken({ + required String mxid, + }) async { + final path = + FederationIdentityRequestTokenEndpoint.requestTokenServicePath(mxid) + .generateFederationIdentityRequestTokenEndpoint(); + final response = await client.postToGetBody(path); + return response; + } +} diff --git a/lib/modules/federation_identity_request_token/data/network/federation_identity_request_token_endpoint.dart b/lib/modules/federation_identity_request_token/data/network/federation_identity_request_token_endpoint.dart new file mode 100644 index 000000000..eeee63cba --- /dev/null +++ b/lib/modules/federation_identity_request_token/data/network/federation_identity_request_token_endpoint.dart @@ -0,0 +1,28 @@ +import 'package:fluffychat/data/network/service_path.dart'; + +class FederationIdentityRequestTokenEndpoint { + static const String federationIdentityRootPath = '_matrix/client'; + static const String federationIdentityAPIVersion = 'v3'; + + static const federationIdentityDioClientName = + 'federationIdentityDioClientName'; + + static const acceptHeaderDefault = 'application/json'; + + static const contentTypeHeaderDefault = 'application/json'; + + static ServicePath requestTokenServicePath(String mxid) => ServicePath( + '/user/$mxid/openid/request_token', + ); +} + +extension FederationRequestTokenServicePathExtensions on ServicePath { + String generateFederationIdentityRequestTokenEndpoint({ + String rootPath = + FederationIdentityRequestTokenEndpoint.federationIdentityRootPath, + String apiVersion = + FederationIdentityRequestTokenEndpoint.federationIdentityAPIVersion, + }) { + return '$rootPath/$apiVersion$path'; + } +} diff --git a/lib/modules/federation_identity_request_token/data/repository/federation_identity_request_token_repository_impl.dart b/lib/modules/federation_identity_request_token/data/repository/federation_identity_request_token_repository_impl.dart new file mode 100644 index 000000000..5d344ca21 --- /dev/null +++ b/lib/modules/federation_identity_request_token/data/repository/federation_identity_request_token_repository_impl.dart @@ -0,0 +1,19 @@ +import 'package:fluffychat/modules/federation_identity_request_token/data/datasource/federation_identity_request_token_datasource.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/domain/models/federation_token_information.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/domain/repository/federation_identity_request_token_repository.dart'; + +class FederationIdentityRequestTokenRepositoryImpl + implements FederationIdentityRequestTokenRepository { + final FederationIdentityRequestTokenDatasource datasource; + + FederationIdentityRequestTokenRepositoryImpl({required this.datasource}); + + @override + Future requestToken({ + required String mxid, + }) { + return datasource.requestToken( + mxid: mxid, + ); + } +} diff --git a/lib/modules/federation_indetity_request_token/domain/models/federation_token_information.dart b/lib/modules/federation_identity_request_token/domain/models/federation_token_information.dart similarity index 100% rename from lib/modules/federation_indetity_request_token/domain/models/federation_token_information.dart rename to lib/modules/federation_identity_request_token/domain/models/federation_token_information.dart diff --git a/lib/modules/federation_indetity_request_token/domain/models/federation_token_request.dart b/lib/modules/federation_identity_request_token/domain/models/federation_token_request.dart similarity index 84% rename from lib/modules/federation_indetity_request_token/domain/models/federation_token_request.dart rename to lib/modules/federation_identity_request_token/domain/models/federation_token_request.dart index 3d67ed779..8c8a4fde2 100644 --- a/lib/modules/federation_indetity_request_token/domain/models/federation_token_request.dart +++ b/lib/modules/federation_identity_request_token/domain/models/federation_token_request.dart @@ -3,15 +3,18 @@ import 'package:equatable/equatable.dart'; class FederationTokenRequest with EquatableMixin { final String federationUrl; final String mxid; + final String token; FederationTokenRequest({ required this.federationUrl, required this.mxid, + required this.token, }); @override List get props => [ federationUrl, mxid, + token, ]; } diff --git a/lib/modules/federation_identity_request_token/domain/repository/federation_identity_request_token_repository.dart b/lib/modules/federation_identity_request_token/domain/repository/federation_identity_request_token_repository.dart new file mode 100644 index 000000000..9b939588e --- /dev/null +++ b/lib/modules/federation_identity_request_token/domain/repository/federation_identity_request_token_repository.dart @@ -0,0 +1,7 @@ +import 'package:fluffychat/modules/federation_identity_request_token/domain/models/federation_token_information.dart'; + +abstract class FederationIdentityRequestTokenRepository { + Future requestToken({ + required String mxid, + }); +} diff --git a/lib/modules/federation_identity_request_token/domain/state/federation_identity_request_token_state.dart b/lib/modules/federation_identity_request_token/domain/state/federation_identity_request_token_state.dart new file mode 100644 index 000000000..41b189767 --- /dev/null +++ b/lib/modules/federation_identity_request_token/domain/state/federation_identity_request_token_state.dart @@ -0,0 +1,38 @@ +import 'package:fluffychat/app_state/failure.dart'; +import 'package:fluffychat/app_state/initial.dart'; +import 'package:fluffychat/app_state/success.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/domain/models/federation_token_information.dart'; + +class FederationIdentityRequestTokenInitial extends Initial { + const FederationIdentityRequestTokenInitial() : super(); + + @override + List get props => []; +} + +class FederationIdentityRequestTokenLoading extends Success { + const FederationIdentityRequestTokenLoading(); + + @override + List get props => []; +} + +class FederationIdentityRequestTokenSuccess extends Success { + final FederationTokenInformation tokenInformation; + + const FederationIdentityRequestTokenSuccess({ + required this.tokenInformation, + }); + + @override + List get props => []; +} + +class FederationIdentityRequestTokenFailure extends Failure { + final dynamic exception; + + const FederationIdentityRequestTokenFailure({required this.exception}); + + @override + List get props => [exception]; +} diff --git a/lib/modules/federation_identity_request_token/domain/usecase/federation_identity_request_token_interactor.dart b/lib/modules/federation_identity_request_token/domain/usecase/federation_identity_request_token_interactor.dart new file mode 100644 index 000000000..d36d4a240 --- /dev/null +++ b/lib/modules/federation_identity_request_token/domain/usecase/federation_identity_request_token_interactor.dart @@ -0,0 +1,33 @@ +import 'package:dartz/dartz.dart'; +import 'package:fluffychat/app_state/failure.dart'; +import 'package:fluffychat/app_state/success.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/domain/repository/federation_identity_request_token_repository.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/domain/state/federation_identity_request_token_state.dart'; + +class FederationIdentityRequestTokenInteractor { + final FederationIdentityRequestTokenRepository repository; + + FederationIdentityRequestTokenInteractor({required this.repository}); + + Stream> execute({ + required String mxid, + }) async* { + try { + yield const Right(FederationIdentityRequestTokenLoading()); + final response = await repository.requestToken( + mxid: mxid, + ); + yield Right( + FederationIdentityRequestTokenSuccess( + tokenInformation: response, + ), + ); + } catch (e) { + yield Left( + FederationIdentityRequestTokenFailure( + exception: e, + ), + ); + } + } +} diff --git a/lib/modules/federation_identity_request_token/manager/federation_identity_request_token_manager.dart b/lib/modules/federation_identity_request_token/manager/federation_identity_request_token_manager.dart new file mode 100644 index 000000000..45f14364b --- /dev/null +++ b/lib/modules/federation_identity_request_token/manager/federation_identity_request_token_manager.dart @@ -0,0 +1,77 @@ +import 'dart:io'; + +import 'package:dartz/dartz.dart'; +import 'package:dio/dio.dart'; +import 'package:fluffychat/app_state/failure.dart'; +import 'package:fluffychat/app_state/success.dart'; +import 'package:fluffychat/data/network/dio_client.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/data/datasource_impl/federation_identity_request_token_datasource_impl.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/data/network/federation_identity_request_token_api.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/data/network/federation_identity_request_token_endpoint.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/data/repository/federation_identity_request_token_repository_impl.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/domain/models/federation_token_request.dart'; +import 'package:fluffychat/modules/federation_identity_request_token/domain/usecase/federation_identity_request_token_interactor.dart'; + +class FederationIdentityRequestTokenManager { + final FederationTokenRequest federationTokenRequest; + + FederationIdentityRequestTokenManager({ + required this.federationTokenRequest, + }); + + DioClient _bindingDio() { + final headers = { + HttpHeaders.acceptHeader: + FederationIdentityRequestTokenEndpoint.acceptHeaderDefault, + HttpHeaders.contentTypeHeader: + FederationIdentityRequestTokenEndpoint.contentTypeHeaderDefault, + HttpHeaders.authorizationHeader: 'Bearer ${federationTokenRequest.token}', + }; + + return DioClient( + Dio( + BaseOptions( + baseUrl: federationTokenRequest.federationUrl, + headers: headers, + ), + ), + ); + } + + FederationIdentityRequestTokenApi _bindingAPI(DioClient dio) { + return FederationIdentityRequestTokenApi(dio); + } + + FederationIdentityRequestTokenDatasourceImpl _bindingDataSourceImpl( + FederationIdentityRequestTokenApi federationIdentityRequestTokenApi, + ) { + return FederationIdentityRequestTokenDatasourceImpl( + federationIdentityRequestTokenApi: federationIdentityRequestTokenApi, + ); + } + + FederationIdentityRequestTokenRepositoryImpl _bindingRepositoryImpl( + FederationIdentityRequestTokenDatasourceImpl datasource, + ) { + return FederationIdentityRequestTokenRepositoryImpl( + datasource: datasource, + ); + } + + FederationIdentityRequestTokenInteractor _bindingInteractor() { + final dio = _bindingDio(); + final api = _bindingAPI(dio); + final datasource = _bindingDataSourceImpl(api); + final repository = _bindingRepositoryImpl(datasource); + + return FederationIdentityRequestTokenInteractor( + repository: repository, + ); + } + + Stream> execute() { + return _bindingInteractor().execute( + mxid: federationTokenRequest.mxid, + ); + } +}