refactor: update AuthenticatedUser model to require id and remove password, enhance server URI handling in AddNewServer widget

This commit is contained in:
Dr-Blank 2024-10-04 02:31:51 -04:00
parent eda45efbce
commit fa815ae206
No known key found for this signature in database
GPG key ID: 7452CC63F210A266
10 changed files with 297 additions and 72 deletions

View file

@ -1,5 +1,6 @@
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:shelfsdk/audiobookshelf_api.dart' as shelfsdk;
import 'package:vaani/settings/models/api_settings.dart';
import 'package:vaani/settings/models/audiobookshelf_server.dart';
import 'package:vaani/settings/models/authenticated_user.dart';
@ -67,7 +68,6 @@ extension ObfuscateAuthenticatedUser on AuthenticatedUser {
return this;
}
return copyWith(
password: password == null ? null : 'passwordObfuscated',
username: username == null ? null : 'usernameObfuscated',
authToken: 'authTokenObfuscated',
server: server.obfuscate(),
@ -116,10 +116,54 @@ extension ObfuscateResponse on http.Response {
return this;
}
return http.Response(
body,
obfuscateBody(),
statusCode,
headers: headers,
request: request?.obfuscate(),
);
}
String obfuscateBody() {
if (!kReleaseMode) {
return body;
}
// replace any email addresses with emailObfuscated
// replace any phone numbers with phoneObfuscated
// replace any urls with urlObfuscated
// replace any tokens with tokenObfuscated
// token regex is `"token": "..."`
return body
.replaceAll(
RegExp(r'(\b\w+@\w+\.\w+\b)|'
r'(\b\d{3}-\d{3}-\d{4}\b)|'
r'(\bhttps?://\S+\b)'),
'obfuscated',
)
.replaceAll(
RegExp(r'"?token"?:?\s*"[^"]+"'),
'"token": "tokenObfuscated"',
);
}
}
extension ObfuscateLoginResponse on shelfsdk.LoginResponse {
shelfsdk.LoginResponse obfuscate() {
if (!kReleaseMode) {
return this;
}
return copyWith(
user: user.obfuscate(),
);
}
}
extension ObfuscateUser on shelfsdk.User {
shelfsdk.User obfuscate() {
if (!kReleaseMode) {
return this;
}
return shelfsdk.User.fromJson(
toJson()..['token'] = 'tokenObfuscated',
);
}
}

View file

@ -2,6 +2,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:vaani/api/api_provider.dart';
import 'package:vaani/main.dart';
final httpUrlRegExp = RegExp('https?://');
class AddNewServer extends HookConsumerWidget {
const AddNewServer({
@ -25,7 +28,8 @@ class AddNewServer extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final myController = controller ?? useTextEditingController();
final myController =
controller ?? useTextEditingController(text: 'https://');
var newServerURI = useValueListenable(myController);
final isServerAlive = ref.watch(isServerAliveProvider(newServerURI.text));
bool isServerAliveValue = isServerAlive.when(
@ -34,15 +38,33 @@ class AddNewServer extends HookConsumerWidget {
error: (error, _) => false,
);
Uri parsedUri = Uri.parse('');
try {
parsedUri = Uri.parse(newServerURI.text);
} on FormatException {
// prepend https:// if not present
if (!newServerURI.text.startsWith(httpUrlRegExp)) {
myController.text = 'https://${newServerURI.text}';
parsedUri = Uri.parse(myController.text);
}
} catch (e) {
// do nothing
appLogger.severe('Error parsing URI: $e');
}
final canSubmit = !readOnly &&
(isServerAliveValue || (allowEmpty && newServerURI.text.isEmpty));
return TextFormField(
readOnly: readOnly,
controller: controller,
keyboardType: TextInputType.url,
autofillHints: const [AutofillHints.url],
textInputAction: TextInputAction.done,
onFieldSubmitted: (_) {
onPressed?.call();
},
onFieldSubmitted: canSubmit
? (_) {
onPressed?.call();
}
: null,
decoration: InputDecoration(
labelText: 'Server URI',
labelStyle: TextStyle(
@ -50,8 +72,8 @@ class AddNewServer extends HookConsumerWidget {
),
border: const OutlineInputBorder(),
prefixText:
myController.text.startsWith(RegExp('https?://')) ? '' : 'https://',
prefixIcon: ServerAliveIcon(server: Uri.parse(newServerURI.text)),
myController.text.startsWith(httpUrlRegExp) ? '' : 'https://',
prefixIcon: ServerAliveIcon(server: parsedUri),
// add server button
suffixIcon: onPressed == null
@ -65,10 +87,10 @@ class AddNewServer extends HookConsumerWidget {
focusColor: Theme.of(context).colorScheme.onSurface,
// should be enabled when
onPressed: !readOnly &&
(isServerAliveValue ||
(allowEmpty && newServerURI.text.isEmpty))
? onPressed
onPressed: canSubmit
? () {
onPressed?.call();
}
: null, // disable button if server is not alive
),
),