Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 11 additions & 1 deletion assets/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
"walletCreationEmptySeedError": "Seed should not be empty",
"walletCreationExistNameError": "Wallet name exists",
"walletCreationNameLengthError": "Name length should be between 1 and 40",
"walletCreationFormatPasswordError": "Password must contain at least 12 characters, with at least one lower-case, one upper-case and one special symbol.",
"walletCreationFormatPasswordError": "Password must contain at least 8 characters, with at least one digit, one lower-case, one upper-case and one special symbol. The password can't contain the same character 3 times in a row. The password can't contain the word 'password'",
"walletCreationConfirmPasswordError": "Your passwords do not match. Please try again.",
"incorrectPassword": "Incorrect password",
"importSeedEnterSeedPhraseHint": "Enter seed",
Expand Down Expand Up @@ -366,6 +366,16 @@
"currentPassword": "Current password",
"walletNotFound": "Wallet not found!",
"passwordIsEmpty": "Password is empty",
"passwordContainsTheWordPassword": "Password cannot contain the word 'password'",
"passwordTooShort": "Password must be at least 8 characters long",
"passwordMissingDigit": "Password must contain at least 1 digit",
"passwordMissingLowercase": "Password must contain at least 1 lowercase character",
"passwordMissingUppercase": "Password must contain at least 1 uppercase character",
"passwordMissingSpecialCharacter": "Password must contain at least 1 special character",
"passwordConsecutiveCharacters": "Password cannot contain the same character 3 times in a row",
"passwordSecurity": "Password Security",
"allowWeakPassword": "Allow weak password",
"allowWeakPasswordDescription": "For support and debugging purposes only. Bypasses password security requirements.",
"dexBalanceNotSufficientError": "{} balance is not sufficient. {} {} required",
"dexEnterPriceError": "Please enter price",
"dexZeroPriceError": "Price must be greater than 0",
Expand Down
33 changes: 26 additions & 7 deletions lib/bloc/auth_bloc/auth_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:komodo_defi_sdk/komodo_defi_sdk.dart';
import 'package:komodo_defi_types/komodo_defi_types.dart';
import 'package:logging/logging.dart';
import 'package:web_dex/app_config/app_config.dart';
import 'package:web_dex/bloc/settings/settings_repository.dart';
import 'package:web_dex/blocs/wallets_repository.dart';
import 'package:web_dex/model/authorize_mode.dart';
import 'package:web_dex/model/kdf_auth_metadata_extension.dart';
Expand All @@ -19,7 +20,7 @@ part 'auth_bloc_state.dart';
class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
/// Handles [AuthBlocEvent]s and emits [AuthBlocState]s.
/// [_kdfSdk] is an instance of [KomodoDefiSdk] used for authentication.
AuthBloc(this._kdfSdk, this._walletsRepository)
AuthBloc(this._kdfSdk, this._walletsRepository, this._settingsRepository)
: super(AuthBlocState.initial()) {
on<AuthModeChanged>(_onAuthChanged);
on<AuthStateClearRequested>(_onClearState);
Expand All @@ -33,6 +34,7 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {

final KomodoDefiSdk _kdfSdk;
final WalletsRepository _walletsRepository;
final SettingsRepository _settingsRepository;
StreamSubscription<KdfUser?>? _authChangesSubscription;
final _log = Logger('AuthBloc');

Expand All @@ -42,6 +44,11 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
await super.close();
}

Future<bool> _areWeakPasswordsAllowed() async {
final settings = await _settingsRepository.loadSettings();
return settings.weakPasswordsAllowed;
}

Future<void> _onLogout(
AuthSignOutRequested event,
Emitter<AuthBlocState> emit,
Expand All @@ -68,23 +75,27 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
);
}

_log.info('login from a wallet');
_log.info('login from a wallet');
emit(AuthBlocState.loading());

final weakPasswordsAllowed = await _areWeakPasswordsAllowed();

Comment thread
takenagain marked this conversation as resolved.
await _kdfSdk.auth.signIn(
walletName: event.wallet.name,
password: event.password,
options: AuthOptions(
derivationMethod: event.wallet.config.type == WalletType.hdwallet
? DerivationMethod.hdWallet
: DerivationMethod.iguana,
allowWeakPassword: weakPasswordsAllowed,
),
);
final KdfUser? currentUser = await _kdfSdk.auth.currentUser;
if (currentUser == null) {
return emit(AuthBlocState.error(AuthException.notSignedIn()));
}

_log.info('logged in from a wallet');
_log.info('logged in from a wallet');
emit(AuthBlocState.loggedIn(currentUser));
_listenToAuthStateChanges();
} catch (e, s) {
Expand Down Expand Up @@ -135,18 +146,22 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
return;
}

_log.info('register from a wallet');
_log.info('register from a wallet');

final weakPasswordsAllowed = await _areWeakPasswordsAllowed();

await _kdfSdk.auth.register(
password: event.password,
walletName: event.wallet.name,
options: AuthOptions(
derivationMethod: event.wallet.config.type == WalletType.hdwallet
? DerivationMethod.hdWallet
: DerivationMethod.iguana,
allowWeakPassword: weakPasswordsAllowed,
),
);

_log.info('registered from a wallet');
_log.info('registered from a wallet');
await _kdfSdk.setWalletType(event.wallet.config.type);
await _kdfSdk.confirmSeedBackup(hasBackup: false);
await _kdfSdk.addActivatedCoins(enabledByDefaultCoins);
Expand Down Expand Up @@ -179,7 +194,10 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
return;
}

_log.info('restore from a wallet');
_log.info('restore from a wallet');

final weakPasswordsAllowed = await _areWeakPasswordsAllowed();

await _kdfSdk.auth.register(
password: event.password,
walletName: event.wallet.name,
Expand All @@ -188,10 +206,11 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
derivationMethod: event.wallet.config.type == WalletType.hdwallet
? DerivationMethod.hdWallet
: DerivationMethod.iguana,
allowWeakPassword: weakPasswordsAllowed,
),
);

_log.info('restored from a wallet');
_log.info('restored from a wallet');
await _kdfSdk.setWalletType(event.wallet.config.type);
await _kdfSdk.confirmSeedBackup(hasBackup: event.wallet.config.hasBackup);
await _kdfSdk.addActivatedCoins(enabledByDefaultCoins);
Expand Down
11 changes: 11 additions & 0 deletions lib/bloc/settings/settings_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
on<ThemeModeChanged>(_onThemeModeChanged);
on<MarketMakerBotSettingsChanged>(_onMarketMakerBotSettingsChanged);
on<TestCoinsEnabledChanged>(_onTestCoinsEnabledChanged);
on<WeakPasswordsAllowedChanged>(_onWeakPasswordsAllowedChanged);
}

late StoredSettings _storedSettings;
Expand Down Expand Up @@ -56,4 +57,14 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
);
emitter(state.copyWith(testCoinsEnabled: event.testCoinsEnabled));
}

Future<void> _onWeakPasswordsAllowedChanged(
WeakPasswordsAllowedChanged event,
Emitter<SettingsState> emitter,
) async {
await _settingsRepo.updateSettings(
_storedSettings.copyWith(weakPasswordsAllowed: event.weakPasswordsAllowed),
);
emitter(state.copyWith(weakPasswordsAllowed: event.weakPasswordsAllowed));
}
}
8 changes: 8 additions & 0 deletions lib/bloc/settings/settings_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,11 @@ class MarketMakerBotSettingsChanged extends SettingsEvent {
@override
List<Object> get props => [settings];
}

class WeakPasswordsAllowedChanged extends SettingsEvent {
const WeakPasswordsAllowedChanged({required this.weakPasswordsAllowed});
final bool weakPasswordsAllowed;

@override
List<Object> get props => [weakPasswordsAllowed];
}
6 changes: 6 additions & 0 deletions lib/bloc/settings/settings_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,42 @@ class SettingsState extends Equatable {
required this.themeMode,
required this.mmBotSettings,
required this.testCoinsEnabled,
required this.weakPasswordsAllowed,
});

factory SettingsState.fromStored(StoredSettings stored) {
return SettingsState(
themeMode: stored.mode,
mmBotSettings: stored.marketMakerBotSettings,
testCoinsEnabled: stored.testCoinsEnabled,
weakPasswordsAllowed: stored.weakPasswordsAllowed,
);
}

final ThemeMode themeMode;
final MarketMakerBotSettings mmBotSettings;
final bool testCoinsEnabled;
final bool weakPasswordsAllowed;

@override
List<Object?> get props => [
themeMode,
mmBotSettings,
testCoinsEnabled,
weakPasswordsAllowed,
];

SettingsState copyWith({
ThemeMode? mode,
MarketMakerBotSettings? marketMakerBotSettings,
bool? testCoinsEnabled,
bool? weakPasswordsAllowed,
}) {
return SettingsState(
themeMode: mode ?? themeMode,
mmBotSettings: marketMakerBotSettings ?? mmBotSettings,
testCoinsEnabled: testCoinsEnabled ?? this.testCoinsEnabled,
weakPasswordsAllowed: weakPasswordsAllowed ?? this.weakPasswordsAllowed,
);
}
}
10 changes: 10 additions & 0 deletions lib/generated/codegen_loader.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,16 @@ abstract class LocaleKeys {
static const currentPassword = 'currentPassword';
static const walletNotFound = 'walletNotFound';
static const passwordIsEmpty = 'passwordIsEmpty';
static const passwordContainsTheWordPassword = 'passwordContainsTheWordPassword';
static const passwordTooShort = 'passwordTooShort';
static const passwordMissingDigit = 'passwordMissingDigit';
static const passwordMissingLowercase = 'passwordMissingLowercase';
static const passwordMissingUppercase = 'passwordMissingUppercase';
static const passwordMissingSpecialCharacter = 'passwordMissingSpecialCharacter';
static const passwordConsecutiveCharacters = 'passwordConsecutiveCharacters';
static const passwordSecurity = 'passwordSecurity';
static const allowWeakPassword = 'allowWeakPassword';
static const allowWeakPasswordDescription = 'allowWeakPasswordDescription';
static const dexBalanceNotSufficientError = 'dexBalanceNotSufficientError';
static const dexEnterPriceError = 'dexEnterPriceError';
static const dexZeroPriceError = 'dexZeroPriceError';
Expand Down
3 changes: 2 additions & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ class MyApp extends StatelessWidget {
return MultiBlocProvider(
providers: [
BlocProvider<AuthBloc>(
create: (_) => AuthBloc(komodoDefiSdk, walletsRepository),
create: (_) =>
AuthBloc(komodoDefiSdk, walletsRepository, SettingsRepository()),
Comment on lines 153 to +157
Copy link

Copilot AI May 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than instantiating SettingsRepository inline, consider injecting it via dependency injection to maintain consistency across the codebase.

Copilot uses AI. Check for mistakes.
),
],
child: BetterFeedback(
Expand Down
7 changes: 7 additions & 0 deletions lib/model/stored_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,22 @@ class StoredSettings {
required this.analytics,
required this.marketMakerBotSettings,
required this.testCoinsEnabled,
required this.weakPasswordsAllowed,
});

final ThemeMode mode;
final AnalyticsSettings analytics;
final MarketMakerBotSettings marketMakerBotSettings;
final bool testCoinsEnabled;
final bool weakPasswordsAllowed;

static StoredSettings initial() {
return StoredSettings(
mode: ThemeMode.dark,
analytics: AnalyticsSettings.initial(),
marketMakerBotSettings: MarketMakerBotSettings.initial(),
testCoinsEnabled: true,
weakPasswordsAllowed: false,
);
}

Expand All @@ -35,6 +38,7 @@ class StoredSettings {
json[storedMarketMakerSettingsKey],
),
testCoinsEnabled: json['testCoinsEnabled'] ?? true,
weakPasswordsAllowed: json['weakPasswordsAllowed'] ?? false,
);
}

Expand All @@ -44,6 +48,7 @@ class StoredSettings {
storedAnalyticsSettingsKey: analytics.toJson(),
storedMarketMakerSettingsKey: marketMakerBotSettings.toJson(),
'testCoinsEnabled': testCoinsEnabled,
'weakPasswordsAllowed': weakPasswordsAllowed,
};
}

Expand All @@ -52,13 +57,15 @@ class StoredSettings {
AnalyticsSettings? analytics,
MarketMakerBotSettings? marketMakerBotSettings,
bool? testCoinsEnabled,
bool? weakPasswordsAllowed,
}) {
return StoredSettings(
mode: mode ?? this.mode,
analytics: analytics ?? this.analytics,
marketMakerBotSettings:
marketMakerBotSettings ?? this.marketMakerBotSettings,
testCoinsEnabled: testCoinsEnabled ?? this.testCoinsEnabled,
weakPasswordsAllowed: weakPasswordsAllowed ?? this.weakPasswordsAllowed,
);
}
}
Loading
Loading