Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Implement passkey #2256

Merged
merged 67 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
5a21062
support passkey, unsupport didKey and tezos
phuocbitmark Oct 24, 2024
ada0b2e
didRegisterPasskey config
phuocbitmark Oct 24, 2024
53044b8
refactor authService
phuocbitmark Oct 24, 2024
171bdca
redefine flow
phuocbitmark Oct 25, 2024
ac45cb3
login ui
phuocbitmark Oct 25, 2024
6b04cfa
upgrade kotlin version
phuocbitmark Oct 25, 2024
b46d7a5
update ui, model
phuocbitmark Oct 25, 2024
2b0c1fe
remove onboarding timeout
phuocbitmark Oct 25, 2024
e6623ce
fix finalize
phuocbitmark Oct 25, 2024
789fe1d
lint
phuocbitmark Oct 25, 2024
8915c51
update assets
phuocbitmark Oct 25, 2024
c4c43e3
add sentry
phuocbitmark Oct 25, 2024
a04e423
add ios associated domains
phuocbitmark Oct 25, 2024
6a45088
bring back setup timeout, update assets
phuocbitmark Oct 28, 2024
e911e41
register finalize response, remove log sensitive data
phuocbitmark Oct 28, 2024
4d0de74
refactor passkey service
phuocbitmark Oct 28, 2024
4d1a5c5
login finalize payload
phuocbitmark Oct 28, 2024
8eaca39
support send log
phuocbitmark Oct 28, 2024
d734202
fix feed back
phuocbitmark Oct 28, 2024
69ec74d
fix set jwt
phuocbitmark Oct 28, 2024
b965460
don't reduct response message
phuocbitmark Oct 28, 2024
c51c341
fix login model
phuocbitmark Oct 28, 2024
3b0613b
fix login finalize payload
phuocbitmark Oct 28, 2024
8f60336
fix unit test
phuocbitmark Oct 28, 2024
cc3bbed
fix authenticate android
phuocbitmark Oct 28, 2024
9b5c02f
add required enviroment
phuocbitmark Oct 28, 2024
cba4f95
don't authenticate when open app ios passkey
phuocbitmark Oct 28, 2024
d0b2541
fix ios syntax
phuocbitmark Oct 28, 2024
952d7ba
fix comment create wallet
phuocbitmark Oct 28, 2024
1198140
Merge branch 'develop' into 2989-implement-passkeys
phuocbitmark Oct 28, 2024
44602de
fix create wallet
phuocbitmark Oct 28, 2024
c323bb5
fix association link ios
phuocbitmark Oct 28, 2024
f931ec8
refactor saving passkey related key
phuocbitmark Oct 28, 2024
a0862fb
handle login error
phuocbitmark Oct 28, 2024
5fa0ada
rename param, organize import
phuocbitmark Oct 28, 2024
432df83
show authentication failed and option retry
phuocbitmark Oct 29, 2024
732a656
delete authentication failed pop up
phuocbitmark Oct 29, 2024
ba46e85
add more param to request/authenticate
phuocbitmark Oct 29, 2024
9158c84
check os version to support passkey
phuocbitmark Oct 29, 2024
6e23337
fix comment
phuocbitmark Oct 29, 2024
99c5d0b
Merge branch 'develop' into 2989-implement-passkeys
phuocbitmark Oct 29, 2024
974c8a2
Merge branch 'develop' into 2989-implement-passkeys
longbmk Oct 29, 2024
5c8358d
stop loading animation when open login dialog
phuocbitmark Oct 29, 2024
5c61bd5
store didRegisterPasskey android on blockStore
phuocbitmark Oct 29, 2024
078090c
migrate then login
phuocbitmark Oct 29, 2024
e832a14
Merge branch 'develop' into 2989-implement-passkeys
phuocbitmark Oct 29, 2024
228be25
fix cache primary address, text
phuocbitmark Oct 29, 2024
09d8591
bring back default color
phuocbitmark Oct 30, 2024
d660886
Merge branch 'develop' into 2989-implement-passkeys
phuocbitmark Oct 30, 2024
1887f51
Merge branch 'develop' into 2989-implement-passkeys
phuocbitmark Oct 30, 2024
dc60ebf
Merge branch 'develop' into 2989-implement-passkeys
longbmk Oct 30, 2024
0298953
feedback: remove text
phuocbitmark Oct 30, 2024
fffc0ea
feedback: loading button
phuocbitmark Oct 30, 2024
1747f8c
fix ask face id when open app
phuocbitmark Oct 30, 2024
8231bde
delete cache primary address
phuocbitmark Oct 30, 2024
41c22c1
auto login
phuocbitmark Oct 31, 2024
447badc
support anonymous
phuocbitmark Oct 29, 2024
ebdb5a7
reuse customer support anonymous issue id
phuocbitmark Oct 31, 2024
3c28a76
fix user id, text controller dispose, issue order
phuocbitmark Oct 31, 2024
d6b4a0b
hide error binding popup
phuocbitmark Oct 31, 2024
1890503
fix support authorization header
phuocbitmark Oct 31, 2024
a11daf1
fix onboarding loading
phuocbitmark Nov 1, 2024
64ee067
Merge pull request #2286 from bitmark-inc/anonymous-support
phuocbitmark Nov 1, 2024
42276a8
Merge branch 'develop' into 2989-implement-passkeys
longbmk Nov 1, 2024
6be9da8
fix comment
phuocbitmark Nov 1, 2024
a158021
fix comment
phuocbitmark Nov 1, 2024
3845213
Merge branch 'develop' into 2989-implement-passkeys
longbmk Nov 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/common/injector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ Future<void> setupInjector() async {
),
),
baseUrl: Environment.customerSupportURL),
injector(),
));

injector.registerLazySingleton<MerchandiseService>(
Expand Down
53 changes: 37 additions & 16 deletions lib/gateway/customer_support_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,59 @@ import 'package:retrofit/retrofit.dart';

part 'customer_support_api.g.dart';

@RestApi(baseUrl: "")
@RestApi(baseUrl: '')
abstract class CustomerSupportApi {
factory CustomerSupportApi(Dio dio, {String baseUrl}) = _CustomerSupportApi;

@GET("/v1/issues")
Future<List<Issue>> getIssues();
static const String issuesPath = '/v1/issues/';

@GET("/v1/issues/{issueID}")
static const String apiKeyHeader = 'x-api-key';
static const String deviceIdHeader = 'x-device-id';

@GET(issuesPath)
Future<List<Issue>> getIssues({
@Header('Authorization') required String token,
});

@GET(issuesPath)
Future<List<Issue>> getAnonymousIssues({
@Header(apiKeyHeader) required String apiKey,
@Header(deviceIdHeader) required String deviceId,
});

@GET('/v1/issues/{issueID}')
Future<IssueDetails> getDetails(
@Path("issueID") String issueID, {
@Query("reverse") bool reverse = true,
@Path('issueID') String issueID, {
@Query('reverse') bool reverse = true,
});

@POST("/v1/issues/")
@POST(issuesPath)
Future<PostedMessageResponse> createIssue(
@Body() Map<String, Object> body,
);
@Body() Map<String, Object> body, {
@Header('Authorization') required String token,
});

@POST(issuesPath)
Future<PostedMessageResponse> createAnonymousIssue(
@Body() Map<String, Object> body, {
@Header(apiKeyHeader) required String apiKey,
@Header(deviceIdHeader) required String deviceId,
});

@POST("/v1/issues/{issueID}")
@POST('/v1/issues/{issueID}')
Future<PostedMessageResponse> commentIssue(
@Path("issueID") String issueID,
@Path('issueID') String issueID,
@Body() Map<String, Object> body,
);

@PATCH("/v1/issues/{issueID}/reopen")
@PATCH('/v1/issues/{issueID}/reopen')
Future reOpenIssue(
@Path("issueID") String issueID,
@Path('issueID') String issueID,
);

@POST("/v1/issues/{issueID}/rate/{rating}")
@POST('/v1/issues/{issueID}/rate/{rating}')
Future<void> rateIssue(
@Path("issueID") String issueID,
@Path("rating") int rating,
@Path('issueID') String issueID,
@Path('rating') int rating,
);
}
87 changes: 82 additions & 5 deletions lib/gateway/customer_support_api.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions lib/model/customer_support.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class Issue implements ChatThread {
Message? firstMessage;
@JsonKey(name: 'announcement_content_id')
String? announcementContentId;
@JsonKey(name: 'user_id')
String? userId;

// only on local
@JsonKey(includeFromJson: false, includeToJson: false)
Expand All @@ -55,6 +57,7 @@ class Issue implements ChatThread {
required this.rating,
this.draft,
this.announcementContentId,
this.userId,
});

factory Issue.fromJson(Map<String, dynamic> json) => _$IssueFromJson(json);
Expand Down Expand Up @@ -85,6 +88,7 @@ class Issue implements ChatThread {
Message? firstMessage,
String? announcementContentId,
DraftCustomerSupport? draft,
String? userId,
}) =>
Issue(
issueID: issueID ?? this.issueID,
Expand All @@ -100,6 +104,7 @@ class Issue implements ChatThread {
announcementContentId:
announcementContentId ?? this.announcementContentId,
draft: draft ?? this.draft,
userId: userId ?? this.userId,
);

@override
Expand Down
2 changes: 2 additions & 0 deletions lib/model/customer_support.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion lib/screen/customer_support/support_thread_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,9 @@ class _SupportThreadPageState extends State<SupportThreadPage> {
return;
}
final issueDetails = await _customerSupportService.getDetails(_issueID!);
await _getUserId();
if (issueDetails.issue.userId != null) {
_userId = issueDetails.issue.userId;
}
final parsedMessages = (await Future.wait(
issueDetails.messages.map((e) => _convertChatMessage(e, null))))
.expand((i) => i)
Expand Down
34 changes: 34 additions & 0 deletions lib/service/configuration_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ import 'package:uuid/uuid.dart';
//ignore_for_file: constant_identifier_names

abstract class ConfigurationService {
String? getAnonymousDeviceId();

Future<String> createAnonymousDeviceId();

List<String> getAnonymousIssueIds();

Future<void> addAnonymousIssueId(List<String> issueIds);

bool didMigrateToAccountSetting();

Future<void> setMigrateToAccountSetting(bool value);
Expand Down Expand Up @@ -206,6 +214,8 @@ abstract class ConfigurationService {
}

class ConfigurationServiceImpl implements ConfigurationService {
static const String keyAnonymousDeviceId = 'anonymous_device_id';
static const String keyAnonymousIssueIds = 'anonymous_issue_ids';
static const String keyDidMigrateToAccountSetting =
'did_migrate_to_account_setting';
static const String keyDidShowLiveWithArt = 'did_show_live_with_art';
Expand Down Expand Up @@ -929,6 +939,30 @@ class ConfigurationServiceImpl implements ConfigurationService {
await _preferences.setString(
KEY_ANNOUNCEMENT_TO_ISSUE_MAP, jsonEncode(mapJson));
}

@override
String? getAnonymousDeviceId() =>
_preferences.getString(keyAnonymousDeviceId);

@override
Future<String> createAnonymousDeviceId() async {
final uuid = const Uuid().v4();
final anonymousDeviceId = 'device-$uuid';
await _preferences.setString(keyAnonymousDeviceId, anonymousDeviceId);
return anonymousDeviceId;
}

@override
Future<void> addAnonymousIssueId(List<String> issueIds) {
final currentIssueIds = getAnonymousIssueIds()
..addAll(issueIds)
..unique();
return _preferences.setStringList(keyAnonymousIssueIds, currentIssueIds);
}

@override
List<String> getAnonymousIssueIds() =>
_preferences.getStringList(keyAnonymousIssueIds) ?? <String>[];
}

enum ConflictAction {
Expand Down
36 changes: 32 additions & 4 deletions lib/service/customer_support_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:autonomy_flutter/common/environment.dart';
import 'package:autonomy_flutter/common/injector.dart';
import 'package:autonomy_flutter/database/dao/draft_customer_support_dao.dart';
import 'package:autonomy_flutter/database/entity/draft_customer_support.dart';
import 'package:autonomy_flutter/gateway/customer_support_api.dart';
import 'package:autonomy_flutter/model/announcement/announcement_local.dart';
import 'package:autonomy_flutter/model/customer_support.dart';
import 'package:autonomy_flutter/service/announcement/announcement_service.dart';
import 'package:autonomy_flutter/service/auth_service.dart';
import 'package:autonomy_flutter/service/configuration_service.dart';
import 'package:autonomy_flutter/util/device.dart';
import 'package:autonomy_flutter/util/log.dart';
import 'package:autonomy_flutter/view/user_agent_utils.dart';
Expand Down Expand Up @@ -74,6 +77,7 @@ class CustomerSupportServiceImpl extends CustomerSupportService {

final DraftCustomerSupportDao _draftCustomerSupportDao;
final CustomerSupportApi _customerSupportApi;
final ConfigurationService _configurationService;

@override
List<String> errorMessages = [];
Expand All @@ -92,15 +96,29 @@ class CustomerSupportServiceImpl extends CustomerSupportService {
CustomerSupportServiceImpl(
this._draftCustomerSupportDao,
this._customerSupportApi,
this._configurationService,
);

bool _isProcessingDraftMessages = false;

Future<List<Issue>> _getIssues() async {
final issues = <Issue>[];
try {
final listIssues = await _customerSupportApi.getIssues();
issues.addAll(listIssues);
final jwt = await injector<AuthService>().getAuthToken();
if (jwt != null) {
final listIssues = await _customerSupportApi.getIssues(
token: 'Bearer ${jwt.jwtToken}');
issues.addAll(listIssues);
}
final anonymousDeviceId = _configurationService.getAnonymousDeviceId();
if (anonymousDeviceId != null) {
final listAnonymousIssues =
await _customerSupportApi.getAnonymousIssues(
apiKey: Environment.supportApiKey,
deviceId: anonymousDeviceId,
);
issues.addAll(listAnonymousIssues);
}
} catch (e) {
log.info('[CS-Service] getIssues error: $e');
unawaited(Sentry.captureException(e));
Expand Down Expand Up @@ -428,8 +446,18 @@ class CustomerSupportServiceImpl extends CustomerSupportService {
if (artworkReportID != null && artworkReportID.isNotEmpty) {
payload['artwork_report_id'] = artworkReportID;
}

return await _customerSupportApi.createIssue(payload);
final jwt = await injector<AuthService>().getAuthToken();
if (jwt != null) {
return await _customerSupportApi.createIssue(payload,
token: jwt.jwtToken);
} else {
final anonymousDeviceId = _configurationService.getAnonymousDeviceId() ??
await _configurationService.createAnonymousDeviceId();
final issue = await _customerSupportApi.createAnonymousIssue(payload,
apiKey: Environment.supportApiKey, deviceId: anonymousDeviceId);
await _configurationService.addAnonymousIssueId([issue.issueID]);
return issue;
}
}

Future<PostedMessageResponse> commentIssue(String issueID, String? message,
Expand Down
Loading