Skip to content

Commit

Permalink
Standardize HTML sanitizing when preview email
Browse files Browse the repository at this point in the history
  • Loading branch information
dab246 committed Oct 23, 2024
1 parent 124c4ce commit 94e2c31
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 26 deletions.
9 changes: 9 additions & 0 deletions contact/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,15 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.2.1"
sanitize_html:
dependency: transitive
description:
path: sanitize_html
ref: twake-supported
resolved-ref: "5b9986c42cc86c7e565c941648f875f2e1d2f7bd"
url: "https://github.com/dab246/dart-neats.git"
source: git
version: "2.1.0"
shelf:
dependency: transitive
description:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,12 @@ class MessageContentTransformer {
Map<String, String>? mapUrlDownloadCID
}) async {
await Future.wait([
if (_configuration.domTransformers.isNotEmpty)
..._configuration.domTransformers.map((domTransformer) async =>
domTransformer.process(
document: document,
dioClient: _dioClient,
mapUrlDownloadCID: mapUrlDownloadCID,
)
..._configuration.domTransformers.map((domTransformer) async =>
domTransformer.process(
document: document,
dioClient: _dioClient,
mapUrlDownloadCID: mapUrlDownloadCID,
)
)
]);
}
Expand All @@ -38,24 +37,32 @@ class MessageContentTransformer {
required String message,
Map<String, String>? mapUrlDownloadCID
}) async {
final document = parse(message);
await _transformDocument(
document: document,
mapUrlDownloadCID: mapUrlDownloadCID,
);
final newMessage = _configuration.textTransformers.isNotEmpty
? _transformMessage(message)
: message;

final document = parse(newMessage);

if (_configuration.domTransformers.isNotEmpty) {
await _transformDocument(
document: document,
mapUrlDownloadCID: mapUrlDownloadCID,
);
}

return document;
}

String _transformMessage(String message) {
if (_configuration.textTransformers.isNotEmpty) {
for (var transformer in _configuration.textTransformers) {
message = transformer.process(message, _htmlEscape);
}
for (var transformer in _configuration.textTransformers) {
message = transformer.process(message, _htmlEscape);
}
return message;
}

String toMessage(String message) {
return _transformMessage(message);
return _configuration.textTransformers.isNotEmpty
? _transformMessage(message)
: message;
}
}
20 changes: 20 additions & 0 deletions core/lib/presentation/utils/html_transformer/sanitize_html.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'package:core/utils/app_logger.dart';
import 'package:sanitize_html/sanitize_html.dart';

class SanitizeHtml {
String process({
required String inputHtml,
List<String>? allowAttributes,
List<String>? allowTags,
List<String>? allowClassNames,
}) {
final outputHtml = sanitizeHtml(
inputHtml,
allowAttributes: allowAttributes,
allowTags: allowTags,
allowClassName: (className) =>
allowClassNames?.contains(className.toLowerCase()) == true
);
return outputHtml;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import 'dart:convert';
import 'package:core/presentation/utils/html_transformer/base/text_transformer.dart';
import 'package:core/presentation/utils/html_transformer/sanitize_html.dart';

class StandardizeHtmlSanitizingTransformers extends TextTransformer {

static const List<String> mailAllowedHtmlAttributes = [
'style',
'public-asset-id',
'data-filename',
'bgcolor',
];

static const List<String> mailAllowedHtmlTags = [
'font',
'u',
'mcourbo@linagora.com',
'center',
];

static const List<String> mailAllowedHtmlClassNames = [
'tmail-signature',
'tmail-signature-blocked',
'tmail-signature-button',
'tmail-signature-content',
'tmail_signature_prefix',
];

const StandardizeHtmlSanitizingTransformers();

@override
String process(String text, HtmlEscape htmlEscape) =>
SanitizeHtml().process(
inputHtml: text,
allowAttributes: mailAllowedHtmlAttributes,
allowTags: mailAllowedHtmlTags,
allowClassNames: mailAllowedHtmlClassNames,
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import 'package:core/presentation/utils/html_transformer/dom/remove_tooltip_link
import 'package:core/presentation/utils/html_transformer/dom/sanitize_hyper_link_tag_in_html_transformers.dart';
import 'package:core/presentation/utils/html_transformer/dom/script_transformers.dart';
import 'package:core/presentation/utils/html_transformer/dom/signature_transformers.dart';
import 'package:core/presentation/utils/html_transformer/text/sanitize_autolink_html_transformers.dart';
import 'package:core/presentation/utils/html_transformer/text/standardize_html_sanitizing_transformers.dart';
import 'package:core/utils/platform_info.dart';

/// Contains the configuration for all transformations.
Expand All @@ -37,7 +37,9 @@ class TransformConfiguration {

factory TransformConfiguration.fromDomTransformers(List<DomTransformer> domTransformers) => TransformConfiguration(domTransformers, []);

factory TransformConfiguration.empty() => const TransformConfiguration([], []);
factory TransformConfiguration.fromTextTransformers(
List<TextTransformer> textTransformers
) => TransformConfiguration([], textTransformers);

factory TransformConfiguration.forReplyForwardEmail() => TransformConfiguration.fromDomTransformers([
if (PlatformInfo.isWeb)
Expand All @@ -46,10 +48,15 @@ class TransformConfiguration {
const RemoveCollapsedSignatureButtonTransformer(),
]);

factory TransformConfiguration.forDraftsEmail() => TransformConfiguration.fromDomTransformers([const ImageTransformer()]);
factory TransformConfiguration.forEditDraftsEmail() => TransformConfiguration.fromDomTransformers([
...TransformConfiguration.forDraftsEmail().domTransformers,
const HideDraftSignatureTransformer()]);
factory TransformConfiguration.forDraftsEmail() => TransformConfiguration.create(
customDomTransformers: [const ImageTransformer()]
);
factory TransformConfiguration.forEditDraftsEmail() => TransformConfiguration.create(
customDomTransformers: [
...TransformConfiguration.forDraftsEmail().domTransformers,
const HideDraftSignatureTransformer()
]
);

factory TransformConfiguration.forPreviewEmailOnWeb() => TransformConfiguration.create(
customDomTransformers: [
Expand All @@ -65,7 +72,9 @@ class TransformConfiguration {

factory TransformConfiguration.forPreviewEmail() => TransformConfiguration.standardConfiguration;

factory TransformConfiguration.forRestoreEmail() => TransformConfiguration.fromDomTransformers([const ImageTransformer()]);
factory TransformConfiguration.forRestoreEmail() => TransformConfiguration.create(
customDomTransformers: [const ImageTransformer()]
);

factory TransformConfiguration.forPrintEmail() => TransformConfiguration.fromDomTransformers([
if (PlatformInfo.isWeb)
Expand Down Expand Up @@ -115,6 +124,6 @@ class TransformConfiguration {
];

static const List<TextTransformer> standardTextTransformers = [
SanitizeAutolinkHtmlTransformers()
StandardizeHtmlSanitizingTransformers(),
];
}
9 changes: 9 additions & 0 deletions core/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,15 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.1"
sanitize_html:
dependency: "direct main"
description:
path: sanitize_html
ref: twake-supported
resolved-ref: "5b9986c42cc86c7e565c941648f875f2e1d2f7bd"
url: "https://github.com/dab246/dart-neats.git"
source: git
version: "2.1.0"
shelf:
dependency: transitive
description:
Expand Down
6 changes: 6 additions & 0 deletions core/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ dependencies:
url: https://github.com/dab246/languagetool_textfield.git
ref: twake-supported

sanitize_html:
git:
url: https://github.com/dab246/dart-neats.git
ref: twake-supported
path: sanitize_html

### Dependencies from pub.dev ###
cupertino_icons: 1.0.6

Expand Down
5 changes: 4 additions & 1 deletion lib/features/email/data/local/html_analyzer.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:collection/collection.dart';
import 'package:core/data/constants/constant.dart';
import 'package:core/presentation/utils/html_transformer/html_transform.dart';
import 'package:core/presentation/utils/html_transformer/text/sanitize_autolink_html_transformers.dart';
import 'package:core/presentation/utils/html_transformer/transform_configuration.dart';
import 'package:core/utils/app_logger.dart';
import 'package:dartz/dartz.dart';
Expand Down Expand Up @@ -35,7 +36,9 @@ class HtmlAnalyzer {
case EmailContentType.textPlain:
final message = _htmlTransform.transformToTextPlain(
content: emailContent.content,
transformConfiguration: transformConfiguration
transformConfiguration: TransformConfiguration.fromTextTransformers([
const SanitizeAutolinkHtmlTransformers()
]),
);
return EmailContent(emailContent.type, message);
default:
Expand Down
9 changes: 9 additions & 0 deletions model/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,15 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.2.1"
sanitize_html:
dependency: transitive
description:
path: sanitize_html
ref: twake-supported
resolved-ref: "5b9986c42cc86c7e565c941648f875f2e1d2f7bd"
url: "https://github.com/dab246/dart-neats.git"
source: git
version: "2.1.0"
shelf:
dependency: transitive
description:
Expand Down
9 changes: 9 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1714,6 +1714,15 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.27.7"
sanitize_html:
dependency: transitive
description:
path: sanitize_html
ref: twake-supported
resolved-ref: "5b9986c42cc86c7e565c941648f875f2e1d2f7bd"
url: "https://github.com/dab246/dart-neats.git"
source: git
version: "2.1.0"
server_settings:
dependency: "direct main"
description:
Expand Down

0 comments on commit 94e2c31

Please sign in to comment.