Skip to content

Commit

Permalink
feat(deriv_auth): [DERG-1396] akhil/1396/multi_user_level_authenticat…
Browse files Browse the repository at this point in the history
…ion_poc_master (#574)

Co-authored-by: ramin-deriv <[email protected]>
  • Loading branch information
akhil-deriv and ramin-deriv authored Sep 26, 2024
1 parent 673b90a commit 97ac800
Show file tree
Hide file tree
Showing 17 changed files with 232 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import 'package:deriv_auth/deriv_auth.dart';

class ExampleLoginRepository implements BaseAuthRepository {
@override
Future<AuthorizeResponseEntity> authorize(String? token) =>
Future<AuthorizeResponseEntity> authorize(
String? token, {
List<String>? tokenList,
}) =>
Future.value(const AuthorizeResponseEntity());

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ class ExampleLoginService extends BaseAuthService {
Future<AuthorizeEntity> onLoginRequest({
required GetTokensRequestModel request,
String? userAgent,
bool useMultiToken = false,
}) async =>
const AuthorizeEntity();

@override
Future<AuthorizeEntity> login(
String token, {
required List<AccountModel> accounts,
List<String>? tokenList,
String? signupProvider,
String? refreshToken,
}) async =>
Expand Down
66 changes: 64 additions & 2 deletions packages/deriv_auth/lib/features/auth/cubit/deriv_auth_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class DerivAuthCubit extends Cubit<DerivAuthState>
required String password,
String? otp,
String? userAgent,
bool useMultiToken = false,
}) async {
trackLoginWithEmailAndPassword();

Expand All @@ -56,6 +57,7 @@ class DerivAuthCubit extends Cubit<DerivAuthState>
),
isSocialLogin: false,
userAgent: userAgent,
useMultiToken: useMultiToken,
);
}

Expand All @@ -65,6 +67,7 @@ class DerivAuthCubit extends Cubit<DerivAuthState>
final String? signupProvider,
String? otp,
String? userAgent,
bool useMultiToken = false,
}) async {
emit(DerivAuthLoadingState());

Expand All @@ -77,6 +80,7 @@ class DerivAuthCubit extends Cubit<DerivAuthState>
),
isSocialLogin: true,
userAgent: userAgent,
useMultiToken: useMultiToken,
);
}

Expand All @@ -85,6 +89,7 @@ class DerivAuthCubit extends Cubit<DerivAuthState>
required SocialAuthDto socialAuthDto,
String? otp,
String? userAgent,
bool useMultiToken = false,
}) async {
emit(DerivAuthLoadingState());

Expand All @@ -96,6 +101,28 @@ class DerivAuthCubit extends Cubit<DerivAuthState>
),
isSocialLogin: true,
userAgent: userAgent,
useMultiToken: useMultiToken,
);
}

@override
Future<void> multiTokenAuthorize(String? token) async {
emit(DerivAuthLoadingState());

final List<AccountModel> accountList =
await authService.getLatestAccounts();
final List<String> tokenList = accountList
.where((AccountModel account) => account.token != null)
.map((AccountModel account) => account.token!)
.toList();

if (token != null && !tokenList.contains(token)) {
tokenList.add(token);
}
await _tokenLoginRequest(
'MULTI',
tokenList: tokenList,
accounts: accountList,
);
}

Expand All @@ -113,12 +140,15 @@ class DerivAuthCubit extends Cubit<DerivAuthState>
required GetTokensRequestModel request,
required bool isSocialLogin,
String? userAgent,
bool useMultiToken = false,
}) async {
try {
final AuthorizeEntity authorizeEntity = await authService.onLoginRequest(
request: request,
userAgent: userAgent,
useMultiToken: useMultiToken,
);

final LandingCompanyEntity landingCompanyEntity =
await authService.getLandingCompany(authorizeEntity.country);
_isUserMigrated = _checkUserMigrated(authorizeEntity);
Expand All @@ -143,10 +173,11 @@ class DerivAuthCubit extends Cubit<DerivAuthState>
Future<void> _tokenLoginRequest(
String token, {
required List<AccountModel> accounts,
List<String>? tokenList,
}) async {
try {
final AuthorizeEntity authorizeEntity =
await authService.login(token, accounts: accounts);
final AuthorizeEntity authorizeEntity = await authService.login(token,
accounts: accounts, tokenList: tokenList);
final LandingCompanyEntity landingCompanyEntity =
await authService.getLandingCompany(authorizeEntity.country);
_isUserMigrated = _checkUserMigrated(authorizeEntity);
Expand All @@ -170,6 +201,37 @@ class DerivAuthCubit extends Cubit<DerivAuthState>
}
}

@override
Future<void> multiAuthorizeAllAccounts() async {
emit(DerivAuthLoadingState());

List<String> tokenList = <String>[];
final List<AccountModel> accountList =
await authService.getLatestAccounts();
final String? defaultAccountToken =
(await authService.getDefaultAccount())?.token;

if (defaultAccountToken == null) {
emit(DerivAuthLoggedOutState());

return;
} else {
tokenList = accountList
.where((AccountModel account) => account.token != null)
.map((AccountModel account) => account.token!)
.toList();

if (!tokenList.contains(defaultAccountToken)) {
tokenList.add(defaultAccountToken);
}
}
await _tokenLoginRequest(
'MULTI',
accounts: accountList,
tokenList: tokenList,
);
}

@override
Future<void> authorizeDefaultAccount() async {
emit(DerivAuthLoadingState());
Expand Down
13 changes: 13 additions & 0 deletions packages/deriv_auth/lib/features/auth/deriv_auth_io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ abstract class DerivAuthIO {
required String email,
required String password,
String? otp,
bool useMultiToken = false,
});

/// Social login/signup with [oneAllConnectionToken] using one-all service.
Expand All @@ -18,23 +19,35 @@ abstract class DerivAuthIO {
Future<void> socialLogin({
required String oneAllConnectionToken,
String? otp,
bool useMultiToken = false,
});

/// Social login/signup using custom in-house service.
Future<void> socialAuth({
required SocialAuthDto socialAuthDto,
String? otp,
bool useMultiToken = false,
});

/// Log user in with [token] after reset password or sign up.
@deprecated
Future<void> tokenLogin(String token);

/// Log user in with multi token authorization
/// Add [token] to the list of authorized tokens.
/// And authorize the user with the new list of tokens.
Future<void> multiTokenAuthorize(String? token);

/// Log user out.
Future<void> logout();

/// Log default user in.
@deprecated
Future<void> authorizeDefaultAccount();

/// Uses multi authorization for all user accounts.
Future<void> multiAuthorizeAllAccounts();

/// Deriv auth output.
Stream<DerivAuthState> get output;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ import 'package:deriv_auth/core/models/landig_comany_model.dart';
/// Interface of all authentication functions required from client.
abstract class BaseAuthRepository {
/// Authorize user with [token].
Future<AuthorizeResponseEntity> authorize(String? token);
Future<AuthorizeResponseEntity> authorize(
String? token, {
List<String>? tokenList,
});

/// Client functionality after user logs in.
Future<void> onLogin(AuthorizeEntity authorizeEntity);

/// Log user out.
Future<void> logout();
Future<void> logout({
String? loginId,
});

/// Functionality on user logs out.
Future<void> onLogout();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ abstract class BaseAuthService {
Future<AuthorizeEntity> onLoginRequest({
required GetTokensRequestModel request,
String? userAgent,
bool useMultiToken = false,
});

/// Log in a user with [token].
Future<AuthorizeEntity> login(
String token, {
required List<AccountModel> accounts,
List<String>? tokenList,
String? signupProvider,
String? refreshToken,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ class DerivAuthService extends BaseAuthService {
required GetTokensRequestModel request,
String? userAgent,
Function? onInvalidJwtToken,
bool useMultiToken = false,
}) async {
try {
List<String> _tokenList = <String>[];
final String jwtToken = await jwtService.getJwtToken();

final GetTokensResponseModel _response = await tokenService.getUserTokens(
Expand All @@ -41,20 +43,44 @@ class DerivAuthService extends BaseAuthService {
final List<AccountModel> _supportedAccounts =
_filterSupportedAccounts(_response.accounts);

final String? _defaultAccountToken = _supportedAccounts.first.token;

if (_defaultAccountToken != null) {
return login(
_defaultAccountToken,
accounts: _supportedAccounts,
signupProvider: request.signupProvider,
refreshToken: _response.refreshToken,
);
if (useMultiToken == false) {
final String? _defaultAccountToken = _supportedAccounts.isNotEmpty
? _supportedAccounts.first.token
: null;

if (_defaultAccountToken != null) {
return login(
_defaultAccountToken,
accounts: _supportedAccounts,
signupProvider: request.signupProvider,
refreshToken: _response.refreshToken,
);
} else {
throw DerivAuthException(
message: accountUnavailableError,
type: AuthErrorType.accountUnavailable,
);
}
} else {
throw DerivAuthException(
message: accountUnavailableError,
type: AuthErrorType.accountUnavailable,
);
if (_supportedAccounts.isNotEmpty) {
_tokenList = _supportedAccounts
.map<String?>((AccountModel account) => account.token)
.whereNotNull()
.toList();

return login(
'MULTI',
tokenList: _tokenList.isEmpty ? null : _tokenList,
accounts: _supportedAccounts,
signupProvider: request.signupProvider,
refreshToken: _response.refreshToken,
);
} else {
throw DerivAuthException(
message: accountUnavailableError,
type: AuthErrorType.accountUnavailable,
);
}
}
} on HTTPClientException catch (error) {
if (error.errorCode == invalidJwtTokenError) {
Expand All @@ -73,12 +99,14 @@ class DerivAuthService extends BaseAuthService {
Future<AuthorizeEntity> login(
String token, {
required List<AccountModel> accounts,
List<String>? tokenList,
String? signupProvider,
String? refreshToken,
}) async {
try {
final AuthorizeEntity? responseAuthorizeEntity =
(await authRepository.authorize(token)).authorize;
(await authRepository.authorize(token, tokenList: tokenList))
.authorize;

_checkAuthorizeValidity(responseAuthorizeEntity);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:async';

import 'package:app_links/app_links.dart';
import 'package:deriv_auth/deriv_auth.dart';
import 'package:deriv_web_view/web_view.dart';
Expand Down
Loading

0 comments on commit 97ac800

Please sign in to comment.