mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2024-11-19 07:09:14 +00:00
feat: obscure/remove auth headers from console logs
This commit is contained in:
parent
dfef56c25f
commit
efd3dfbde5
|
@ -10,10 +10,6 @@ enum ConsoleLogSeverity {
|
|||
}
|
||||
|
||||
/// Base entity for console logs.
|
||||
///
|
||||
/// TODO(misterfourtytwo): should we add?
|
||||
///
|
||||
/// * equality override
|
||||
sealed class ConsoleLog {
|
||||
ConsoleLog({
|
||||
final String? customTitle,
|
||||
|
@ -75,6 +71,8 @@ class RestApiRequestConsoleLog extends ConsoleLog {
|
|||
super.severity,
|
||||
});
|
||||
|
||||
static const blacklistedHeaders = ['Authorization'];
|
||||
|
||||
final String? method;
|
||||
final Uri? uri;
|
||||
final Map<String, dynamic>? headers;
|
||||
|
@ -82,10 +80,18 @@ class RestApiRequestConsoleLog extends ConsoleLog {
|
|||
|
||||
@override
|
||||
String get title => 'Rest API Request';
|
||||
|
||||
Map<String, dynamic> get filteredHeaders => Map.fromEntries(
|
||||
headers?.entries.where(
|
||||
(final entry) => !blacklistedHeaders.contains(entry.key),
|
||||
) ??
|
||||
const [],
|
||||
);
|
||||
|
||||
@override
|
||||
String get content => '"method": "$method",\n'
|
||||
'"uri": "$uri",\n'
|
||||
'"headers": ${jsonEncode(headers)},\n'
|
||||
'"headers": ${jsonEncode(filteredHeaders)},\n' // censor header to not expose API keys
|
||||
'"data": $data';
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/logic/models/console_log.dart';
|
||||
import 'package:selfprivacy/utils/platform_adapter.dart';
|
||||
|
@ -202,23 +203,81 @@ class _SectionRow extends StatelessWidget {
|
|||
class _KeyValueRow extends StatelessWidget {
|
||||
const _KeyValueRow(this.title, this.value);
|
||||
|
||||
static const List<String> hideList = ['Authorization'];
|
||||
|
||||
final String title;
|
||||
final String? value;
|
||||
|
||||
@override
|
||||
Widget build(final BuildContext context) => hideList.contains(title)
|
||||
? _ObscuredKeyValueRow(title, value)
|
||||
: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: SelectableText.rich(
|
||||
TextSpan(
|
||||
style: DefaultTextStyle.of(context).style,
|
||||
children: <TextSpan>[
|
||||
TextSpan(
|
||||
text: '$title: ',
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
TextSpan(text: value ?? ''),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class _ObscuredKeyValueRow extends StatefulWidget {
|
||||
const _ObscuredKeyValueRow(this.title, this.value);
|
||||
|
||||
final String title;
|
||||
final String? value;
|
||||
|
||||
@override
|
||||
State<_ObscuredKeyValueRow> createState() => _ObscuredKeyValueRowState();
|
||||
}
|
||||
|
||||
class _ObscuredKeyValueRowState extends State<_ObscuredKeyValueRow> {
|
||||
static const obscuringCharacter = '•';
|
||||
bool _obscureValue = true;
|
||||
|
||||
@override
|
||||
Widget build(final BuildContext context) => Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: SelectableText.rich(
|
||||
TextSpan(
|
||||
style: DefaultTextStyle.of(context).style,
|
||||
children: <TextSpan>[
|
||||
TextSpan(
|
||||
text: '$title: ',
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SelectableText.rich(
|
||||
TextSpan(
|
||||
style: DefaultTextStyle.of(context).style,
|
||||
children: <TextSpan>[
|
||||
TextSpan(
|
||||
text: '${widget.title}: ',
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
TextSpan(
|
||||
text: _obscureValue
|
||||
? obscuringCharacter * (widget.value?.length ?? 4)
|
||||
: widget.value ?? '',
|
||||
style: const TextStyle(
|
||||
fontFeatures: [FontFeature.tabularFigures()],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
TextSpan(text: value ?? ''),
|
||||
],
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
_obscureValue ? CupertinoIcons.eye : CupertinoIcons.eye_slash,
|
||||
),
|
||||
onPressed: () {
|
||||
_obscureValue ^= true; // toggle value
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -257,6 +257,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
cupertino_icons:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: cupertino_icons
|
||||
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.8"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -55,6 +55,7 @@ dependencies:
|
|||
dev_dependencies:
|
||||
auto_route_generator: ^8.0.0
|
||||
build_runner: ^2.4.9
|
||||
cupertino_icons: ^1.0.8
|
||||
flutter_launcher_icons: ^0.13.1
|
||||
flutter_lints: ^3.0.2
|
||||
flutter_test:
|
||||
|
|
Loading…
Reference in a new issue