react-native-security-suite 0.6.6 → 0.6.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/android/build.gradle +1 -0
  2. package/android/src/main/AndroidManifest.xml +3 -48
  3. package/android/src/main/java/com/securitysuite/Sslpinning.java +2 -1
  4. package/package.json +1 -1
  5. package/android/src/main/java/com/securitysuite/NetworkLogger.java +0 -25
  6. package/android/src/main/java/com/securitysuite/api/BodyDecoder.kt +0 -35
  7. package/android/src/main/java/com/securitysuite/api/Chucker.kt +0 -108
  8. package/android/src/main/java/com/securitysuite/api/ChuckerCollector.kt +0 -129
  9. package/android/src/main/java/com/securitysuite/api/ChuckerInterceptor.kt +0 -280
  10. package/android/src/main/java/com/securitysuite/api/ExportFormat.kt +0 -12
  11. package/android/src/main/java/com/securitysuite/api/RetentionManager.kt +0 -109
  12. package/android/src/main/java/com/securitysuite/internal/data/entity/HttpHeader.kt +0 -8
  13. package/android/src/main/java/com/securitysuite/internal/data/entity/HttpTransaction.kt +0 -344
  14. package/android/src/main/java/com/securitysuite/internal/data/entity/HttpTransactionTuple.kt +0 -62
  15. package/android/src/main/java/com/securitysuite/internal/data/har/Har.kt +0 -13
  16. package/android/src/main/java/com/securitysuite/internal/data/har/Log.kt +0 -24
  17. package/android/src/main/java/com/securitysuite/internal/data/har/log/Browser.kt +0 -11
  18. package/android/src/main/java/com/securitysuite/internal/data/har/log/Creator.kt +0 -11
  19. package/android/src/main/java/com/securitysuite/internal/data/har/log/Entry.kt +0 -49
  20. package/android/src/main/java/com/securitysuite/internal/data/har/log/Page.kt +0 -14
  21. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Cache.kt +0 -12
  22. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Header.kt +0 -17
  23. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Request.kt +0 -35
  24. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Response.kt +0 -33
  25. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Timings.kt +0 -25
  26. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/cache/SecondaryRequest.kt +0 -13
  27. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/request/PostData.kt +0 -20
  28. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/request/QueryString.kt +0 -23
  29. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/request/postdata/Params.kt +0 -13
  30. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/response/Content.kt +0 -30
  31. package/android/src/main/java/com/securitysuite/internal/data/har/log/page/PageTimings.kt +0 -11
  32. package/android/src/main/java/com/securitysuite/internal/data/model/DialogData.kt +0 -8
  33. package/android/src/main/java/com/securitysuite/internal/data/repository/HttpTransactionDatabaseRepository.kt +0 -60
  34. package/android/src/main/java/com/securitysuite/internal/data/repository/HttpTransactionRepository.kt +0 -33
  35. package/android/src/main/java/com/securitysuite/internal/data/repository/RepositoryProvider.kt +0 -38
  36. package/android/src/main/java/com/securitysuite/internal/data/room/ChuckerDatabase.kt +0 -22
  37. package/android/src/main/java/com/securitysuite/internal/data/room/HttpTransactionDao.kt +0 -53
  38. package/android/src/main/java/com/securitysuite/internal/support/BitmapUtils.kt +0 -45
  39. package/android/src/main/java/com/securitysuite/internal/support/CacheDirectoryProvider.kt +0 -11
  40. package/android/src/main/java/com/securitysuite/internal/support/ChessboardDrawable.kt +0 -76
  41. package/android/src/main/java/com/securitysuite/internal/support/ChuckerFileProvider.kt +0 -9
  42. package/android/src/main/java/com/securitysuite/internal/support/ClearDatabaseJobIntentServiceReceiver.kt +0 -14
  43. package/android/src/main/java/com/securitysuite/internal/support/ClearDatabaseService.kt +0 -32
  44. package/android/src/main/java/com/securitysuite/internal/support/ContextExt.kt +0 -22
  45. package/android/src/main/java/com/securitysuite/internal/support/DepletingSource.kt +0 -37
  46. package/android/src/main/java/com/securitysuite/internal/support/FileFactory.kt +0 -30
  47. package/android/src/main/java/com/securitysuite/internal/support/FileSaver.kt +0 -41
  48. package/android/src/main/java/com/securitysuite/internal/support/FormatUtils.kt +0 -117
  49. package/android/src/main/java/com/securitysuite/internal/support/FormattedUrl.kt +0 -76
  50. package/android/src/main/java/com/securitysuite/internal/support/HarUtils.kt +0 -28
  51. package/android/src/main/java/com/securitysuite/internal/support/HttpUrlUtils.kt +0 -11
  52. package/android/src/main/java/com/securitysuite/internal/support/JsonConverter.kt +0 -19
  53. package/android/src/main/java/com/securitysuite/internal/support/LimitingSource.kt +0 -22
  54. package/android/src/main/java/com/securitysuite/internal/support/LiveDataUtils.kt +0 -68
  55. package/android/src/main/java/com/securitysuite/internal/support/Logger.kt +0 -43
  56. package/android/src/main/java/com/securitysuite/internal/support/NotificationHelper.kt +0 -149
  57. package/android/src/main/java/com/securitysuite/internal/support/OkHttpUtils.kt +0 -86
  58. package/android/src/main/java/com/securitysuite/internal/support/OkioUtils.kt +0 -34
  59. package/android/src/main/java/com/securitysuite/internal/support/PlainTextDecoder.kt +0 -30
  60. package/android/src/main/java/com/securitysuite/internal/support/ReportingSink.kt +0 -114
  61. package/android/src/main/java/com/securitysuite/internal/support/RequestProcessor.kt +0 -102
  62. package/android/src/main/java/com/securitysuite/internal/support/ResponseProcessor.kt +0 -170
  63. package/android/src/main/java/com/securitysuite/internal/support/SearchHighlightUtil.kt +0 -80
  64. package/android/src/main/java/com/securitysuite/internal/support/Sharable.kt +0 -86
  65. package/android/src/main/java/com/securitysuite/internal/support/SpanTextUtil.kt +0 -202
  66. package/android/src/main/java/com/securitysuite/internal/support/TeeSource.kt +0 -68
  67. package/android/src/main/java/com/securitysuite/internal/support/TransactionCurlCommandSharable.kt +0 -46
  68. package/android/src/main/java/com/securitysuite/internal/support/TransactionDetailsHarSharable.kt +0 -11
  69. package/android/src/main/java/com/securitysuite/internal/support/TransactionDetailsSharable.kt +0 -73
  70. package/android/src/main/java/com/securitysuite/internal/support/TransactionDiffCallback.kt +0 -26
  71. package/android/src/main/java/com/securitysuite/internal/support/TransactionListDetailsSharable.kt +0 -23
  72. package/android/src/main/java/com/securitysuite/internal/ui/BaseChuckerActivity.kt +0 -35
  73. package/android/src/main/java/com/securitysuite/internal/ui/MainActivity.kt +0 -375
  74. package/android/src/main/java/com/securitysuite/internal/ui/MainViewModel.kt +0 -47
  75. package/android/src/main/java/com/securitysuite/internal/ui/transaction/PayloadType.kt +0 -6
  76. package/android/src/main/java/com/securitysuite/internal/ui/transaction/ProtocolResources.kt +0 -14
  77. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionActivity.kt +0 -186
  78. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionAdapter.kt +0 -139
  79. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionOverviewFragment.kt +0 -100
  80. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionPagerAdapter.kt +0 -29
  81. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionPayloadAdapter.kt +0 -269
  82. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionPayloadFragment.kt +0 -529
  83. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionViewModel.kt +0 -69
  84. package/android/src/main/res/A.java +0 -12
  85. package/android/src/main/res/color/chucker_fab_background_colour.xml +0 -5
  86. package/android/src/main/res/drawable/chucker_empty_payload.xml +0 -10
  87. package/android/src/main/res/drawable/chucker_ic_arrow_down.xml +0 -10
  88. package/android/src/main/res/drawable/chucker_ic_copy.xml +0 -12
  89. package/android/src/main/res/drawable/chucker_ic_decoded_url_white.xml +0 -10
  90. package/android/src/main/res/drawable/chucker_ic_delete_white.xml +0 -9
  91. package/android/src/main/res/drawable/chucker_ic_encoded_url_white.xml +0 -11
  92. package/android/src/main/res/drawable/chucker_ic_graphql.xml +0 -27
  93. package/android/src/main/res/drawable/chucker_ic_http.xml +0 -10
  94. package/android/src/main/res/drawable/chucker_ic_https.xml +0 -9
  95. package/android/src/main/res/drawable/chucker_ic_launcher_foreground.xml +0 -14
  96. package/android/src/main/res/drawable/chucker_ic_save_white.xml +0 -9
  97. package/android/src/main/res/drawable/chucker_ic_search_white.xml +0 -9
  98. package/android/src/main/res/drawable/chucker_ic_share_white.xml +0 -9
  99. package/android/src/main/res/drawable/chucker_ic_transaction_notification.xml +0 -9
  100. package/android/src/main/res/layout/activity_main.xml +0 -83
  101. package/android/src/main/res/layout/activity_transaction.xml +0 -48
  102. package/android/src/main/res/layout/fragment_transaction_overview.xml +0 -365
  103. package/android/src/main/res/layout/fragment_transaction_payload.xml +0 -132
  104. package/android/src/main/res/layout/list_item_transaction.xml +0 -122
  105. package/android/src/main/res/layout/transaction_item_body_line.xml +0 -13
  106. package/android/src/main/res/layout/transaction_item_copy.xml +0 -19
  107. package/android/src/main/res/layout/transaction_item_headers.xml +0 -12
  108. package/android/src/main/res/layout/transaction_item_image.xml +0 -16
  109. package/android/src/main/res/menu/chucker_transaction.xml +0 -46
  110. package/android/src/main/res/menu/chucker_transactions_list.xml +0 -41
  111. package/android/src/main/res/mipmap-anydpi-v26/chucker_ic_launcher.xml +0 -5
  112. package/android/src/main/res/mipmap-hdpi/chucker_ic_launcher.png +0 -0
  113. package/android/src/main/res/mipmap-xhdpi/chucker_ic_launcher.png +0 -0
  114. package/android/src/main/res/mipmap-xxhdpi/chucker_ic_launcher.png +0 -0
  115. package/android/src/main/res/mipmap-xxxhdpi/chucker_ic_launcher.png +0 -0
  116. package/android/src/main/res/values/chucker_ic_launcher_background.xml +0 -4
  117. package/android/src/main/res/values/colors.xml +0 -38
  118. package/android/src/main/res/values/dimens.xml +0 -10
  119. package/android/src/main/res/values/public.xml +0 -5
  120. package/android/src/main/res/values/strings.xml +0 -77
  121. package/android/src/main/res/values/styles.xml +0 -44
  122. package/android/src/main/res/values-es/strings.xml +0 -75
  123. package/android/src/main/res/values-night/colors.xml +0 -32
  124. package/android/src/main/res/xml/chucker_provider_paths.xml +0 -4
@@ -1,22 +0,0 @@
1
- package com.securitysuite.internal.support
2
-
3
- import android.content.Context
4
- import com.securitysuite.internal.data.model.DialogData
5
- import com.google.android.material.dialog.MaterialAlertDialogBuilder
6
-
7
- internal fun Context.showDialog(
8
- dialogData: DialogData,
9
- onPositiveClick: (() -> Unit)?,
10
- onNegativeClick: (() -> Unit)?,
11
- ) {
12
- MaterialAlertDialogBuilder(this)
13
- .setTitle(dialogData.title)
14
- .setMessage(dialogData.message)
15
- .setPositiveButton(dialogData.positiveButtonText) { _, _ ->
16
- onPositiveClick?.invoke()
17
- }
18
- .setNegativeButton(dialogData.negativeButtonText) { _, _ ->
19
- onNegativeClick?.invoke()
20
- }
21
- .show()
22
- }
@@ -1,37 +0,0 @@
1
- package com.securitysuite.internal.support
2
-
3
- import okio.Buffer
4
- import okio.ForwardingSource
5
- import okio.Source
6
- import okio.blackholeSink
7
- import okio.buffer
8
- import java.io.IOException
9
-
10
- internal class DepletingSource(delegate: Source) : ForwardingSource(delegate) {
11
- private var shouldDeplete = true
12
-
13
- override fun read(
14
- sink: Buffer,
15
- byteCount: Long,
16
- ) = try {
17
- val bytesRead = super.read(sink, byteCount)
18
- if (bytesRead == -1L) shouldDeplete = false
19
- bytesRead
20
- } catch (e: IOException) {
21
- shouldDeplete = false
22
- throw e
23
- }
24
-
25
- override fun close() {
26
- if (shouldDeplete) {
27
- try {
28
- delegate.buffer().readAll(blackholeSink())
29
- } catch (e: IOException) {
30
- Logger.error("An error occurred while depleting the source", e)
31
- }
32
- }
33
- shouldDeplete = false
34
-
35
- super.close()
36
- }
37
- }
@@ -1,30 +0,0 @@
1
- package com.securitysuite.internal.support
2
-
3
- import java.io.File
4
- import java.io.IOException
5
- import java.util.concurrent.atomic.AtomicLong
6
-
7
- internal object FileFactory {
8
- private val uniqueIdGenerator = AtomicLong()
9
-
10
- fun create(directory: File) = create(directory, fileName = "chucker-${uniqueIdGenerator.getAndIncrement()}")
11
-
12
- fun create(
13
- directory: File,
14
- fileName: String,
15
- ): File? =
16
- try {
17
- File(directory, fileName).apply {
18
- if (exists() && !delete()) {
19
- throw IOException("Failed to delete file $this")
20
- }
21
- parentFile?.mkdirs()
22
- if (!createNewFile()) {
23
- throw IOException("File $this already exists")
24
- }
25
- }
26
- } catch (e: IOException) {
27
- Logger.error("An error occurred while creating a file", e)
28
- null
29
- }
30
- }
@@ -1,41 +0,0 @@
1
- package com.securitysuite.internal.support
2
-
3
- import android.content.ContentResolver
4
- import android.net.Uri
5
- import kotlinx.coroutines.Dispatchers
6
- import kotlinx.coroutines.withContext
7
- import okio.Source
8
- import okio.buffer
9
- import okio.sink
10
-
11
- /**
12
- * Utility class to save a file from a [Source] to a [Uri].
13
- */
14
- public object FileSaver {
15
- /**
16
- * Saves the data from the [source] to the file at the [uri] using the [contentResolver].
17
- *
18
- * @param source The source of the data to save.
19
- * @param uri The URI of the file to save the data to.
20
- * @param contentResolver The content resolver to use to save the data.
21
- * @return `true` if the data was saved successfully, `false` otherwise.
22
- */
23
- public suspend fun saveFile(
24
- source: Source,
25
- uri: Uri,
26
- contentResolver: ContentResolver,
27
- ): Boolean =
28
- withContext(Dispatchers.IO) {
29
- runCatching {
30
- contentResolver.openOutputStream(uri)?.use { outputStream ->
31
- outputStream.sink().buffer().use { sink ->
32
- sink.writeAll(source)
33
- }
34
- }
35
- }.onFailure {
36
- Logger.error("Failed to save data to a file", it)
37
- return@withContext false
38
- }
39
- return@withContext true
40
- }
41
- }
@@ -1,117 +0,0 @@
1
- package com.securitysuite.internal.support
2
-
3
- import com.securitysuite.internal.data.entity.HttpHeader
4
- import com.google.gson.JsonParseException
5
- import com.google.gson.JsonParser
6
- import org.w3c.dom.Document
7
- import org.xml.sax.InputSource
8
- import org.xml.sax.SAXParseException
9
- import java.io.ByteArrayInputStream
10
- import java.io.IOException
11
- import java.io.StringWriter
12
- import java.io.UnsupportedEncodingException
13
- import java.net.URLDecoder
14
- import java.nio.charset.Charset
15
- import java.util.Locale
16
- import javax.xml.XMLConstants
17
- import javax.xml.parsers.DocumentBuilder
18
- import javax.xml.parsers.DocumentBuilderFactory
19
- import javax.xml.transform.OutputKeys
20
- import javax.xml.transform.TransformerException
21
- import javax.xml.transform.TransformerFactory
22
- import javax.xml.transform.dom.DOMSource
23
- import javax.xml.transform.stream.StreamResult
24
- import kotlin.math.ln
25
- import kotlin.math.pow
26
-
27
- internal object FormatUtils {
28
- private const val SI_MULTIPLE = 1000
29
- private const val BASE_TWO_MULTIPLE = 1024
30
-
31
- fun formatHeaders(
32
- httpHeaders: List<HttpHeader>?,
33
- withMarkup: Boolean,
34
- ): String {
35
- return httpHeaders?.joinToString(separator = "") { header ->
36
- if (withMarkup) {
37
- "<b> ${header.name}: </b>${header.value} <br />"
38
- } else {
39
- "${header.name}: ${header.value}\n"
40
- }
41
- } ?: ""
42
- }
43
-
44
- fun formatByteCount(
45
- bytes: Long,
46
- si: Boolean,
47
- ): String {
48
- val unit = if (si) SI_MULTIPLE else BASE_TWO_MULTIPLE
49
-
50
- if (bytes < unit) {
51
- return "$bytes B"
52
- }
53
-
54
- val exp = (ln(bytes.toDouble()) / ln(unit.toDouble())).toInt()
55
- val pre = (if (si) "kMGTPE" else "KMGTPE")[exp - 1] + if (si) "" else "i"
56
-
57
- return String.format(Locale.US, "%.1f %sB", bytes / unit.toDouble().pow(exp.toDouble()), pre)
58
- }
59
-
60
- fun formatJson(json: String): String {
61
- return try {
62
- val je = JsonParser.parseString(json)
63
- JsonConverter.instance.toJson(je)
64
- } catch (e: JsonParseException) {
65
- json
66
- }
67
- }
68
-
69
- fun formatXml(xml: String): String {
70
- return try {
71
- val documentFactory: DocumentBuilderFactory = DocumentBuilderFactory.newInstance()
72
- // This flag is required for security reasons
73
- documentFactory.isExpandEntityReferences = false
74
-
75
- val documentBuilder: DocumentBuilder = documentFactory.newDocumentBuilder()
76
- val inputSource = InputSource(ByteArrayInputStream(xml.toByteArray(Charset.defaultCharset())))
77
- val document: Document = documentBuilder.parse(inputSource)
78
-
79
- val domSource = DOMSource(document)
80
- val writer = StringWriter()
81
- val result = StreamResult(writer)
82
-
83
- TransformerFactory.newInstance().apply {
84
- setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true)
85
- }.newTransformer().apply {
86
- setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2")
87
- setOutputProperty(OutputKeys.INDENT, "yes")
88
- transform(domSource, result)
89
- }
90
- writer.toString()
91
- } catch (ignore: SAXParseException) {
92
- xml
93
- } catch (ignore: IOException) {
94
- xml
95
- } catch (ignore: TransformerException) {
96
- xml
97
- }
98
- }
99
-
100
- fun formatUrlEncodedForm(form: String): String {
101
- return try {
102
- if (form.isBlank()) {
103
- return form
104
- }
105
- form.split("&").joinToString(separator = "\n") { entry ->
106
- val keyValue = entry.split("=")
107
- val key = keyValue[0]
108
- val value = if (keyValue.size > 1) URLDecoder.decode(keyValue[1], "UTF-8") else ""
109
- "$key: $value"
110
- }
111
- } catch (ignore: IllegalArgumentException) {
112
- form
113
- } catch (ignore: UnsupportedEncodingException) {
114
- form
115
- }
116
- }
117
- }
@@ -1,76 +0,0 @@
1
- package com.securitysuite.internal.support
2
-
3
- import okhttp3.HttpUrl
4
-
5
- internal class FormattedUrl private constructor(
6
- val scheme: String,
7
- val host: String,
8
- val port: Int,
9
- val path: String,
10
- val query: String,
11
- ) {
12
- val pathWithQuery: String
13
- get() =
14
- if (query.isBlank()) {
15
- path
16
- } else {
17
- "$path?$query"
18
- }
19
-
20
- val url: String
21
- get() {
22
- return if (shouldShowPort()) {
23
- "$scheme://$host:$port$pathWithQuery"
24
- } else {
25
- "$scheme://$host$pathWithQuery"
26
- }
27
- }
28
-
29
- private fun shouldShowPort(): Boolean {
30
- if (scheme == "https" && port == HTTPS_PORT) {
31
- return false
32
- }
33
- if (scheme == "http" && port == HTTP_PORT) {
34
- return false
35
- }
36
- return true
37
- }
38
-
39
- companion object {
40
- private const val HTTPS_PORT = 443
41
- private const val HTTP_PORT = 80
42
-
43
- fun fromHttpUrl(
44
- httpUrl: HttpUrl,
45
- encoded: Boolean,
46
- ): FormattedUrl {
47
- return if (encoded) {
48
- encodedUrl(httpUrl)
49
- } else {
50
- decodedUrl(httpUrl)
51
- }
52
- }
53
-
54
- private fun encodedUrl(httpUrl: HttpUrl): FormattedUrl {
55
- val path = httpUrl.encodedPathSegments.joinToString("/")
56
- return FormattedUrl(
57
- httpUrl.scheme,
58
- httpUrl.host,
59
- httpUrl.port,
60
- if (path.isNotBlank()) "/$path" else "",
61
- httpUrl.encodedQuery.orEmpty(),
62
- )
63
- }
64
-
65
- private fun decodedUrl(httpUrl: HttpUrl): FormattedUrl {
66
- val path = httpUrl.pathSegments.joinToString("/")
67
- return FormattedUrl(
68
- httpUrl.scheme,
69
- httpUrl.host,
70
- httpUrl.port,
71
- if (path.isNotBlank()) "/$path" else "",
72
- httpUrl.query.orEmpty(),
73
- )
74
- }
75
- }
76
- }
@@ -1,28 +0,0 @@
1
- package com.securitysuite.internal.support
2
-
3
- import com.securitysuite.internal.data.entity.HttpTransaction
4
- import com.securitysuite.internal.data.har.Har
5
- import com.securitysuite.internal.data.har.log.Creator
6
- import kotlinx.coroutines.Dispatchers
7
- import kotlinx.coroutines.withContext
8
-
9
- // http://www.softwareishard.com/blog/har-12-spec/
10
- // https://github.com/ahmadnassri/har-spec/blob/master/versions/1.2.md
11
- internal object HarUtils {
12
- suspend fun harStringFromTransactions(
13
- transactions: List<HttpTransaction>,
14
- name: String,
15
- version: String,
16
- ): String =
17
- withContext(Dispatchers.Default) {
18
- JsonConverter.nonNullSerializerInstance
19
- .toJson(fromHttpTransactions(transactions, Creator(name, version)))
20
- }
21
-
22
- internal fun fromHttpTransactions(
23
- transactions: List<HttpTransaction>,
24
- creator: Creator,
25
- ): Har {
26
- return Har(transactions, creator)
27
- }
28
- }
@@ -1,11 +0,0 @@
1
- package com.securitysuite.internal.support
2
-
3
- import okhttp3.HttpUrl
4
-
5
- private const val PATH_SEGMENTS_DELIMITER = "/"
6
-
7
- public fun HttpUrl.Builder.addNonBlankPathSegments(candidatePath: String): HttpUrl.Builder =
8
- apply {
9
- candidatePath.split(PATH_SEGMENTS_DELIMITER).filter { it.isNotBlank() }
10
- .forEach { item -> addPathSegment(item) }
11
- }
@@ -1,19 +0,0 @@
1
- package com.securitysuite.internal.support
2
-
3
- import com.google.gson.Gson
4
- import com.google.gson.GsonBuilder
5
-
6
- internal object JsonConverter {
7
- val nonNullSerializerInstance: Gson by lazy {
8
- GsonBuilder()
9
- .disableHtmlEscaping()
10
- .setPrettyPrinting()
11
- .create()
12
- }
13
-
14
- val instance: Gson by lazy {
15
- nonNullSerializerInstance.newBuilder()
16
- .serializeNulls()
17
- .create()
18
- }
19
- }
@@ -1,22 +0,0 @@
1
- package com.securitysuite.internal.support
2
-
3
- import okio.Buffer
4
- import okio.ForwardingSource
5
- import okio.Source
6
-
7
- internal class LimitingSource(
8
- delegate: Source,
9
- private val bytesCountThreshold: Long,
10
- ) : ForwardingSource(delegate) {
11
- private var bytesRead = 0L
12
- val isThresholdReached get() = bytesRead >= bytesCountThreshold
13
-
14
- override fun read(
15
- sink: Buffer,
16
- byteCount: Long,
17
- ) = if (!isThresholdReached) {
18
- super.read(sink, byteCount).also { bytesRead += it }
19
- } else {
20
- -1L
21
- }
22
- }
@@ -1,68 +0,0 @@
1
- package com.securitysuite.internal.support
2
-
3
- import android.annotation.SuppressLint
4
- import androidx.arch.core.executor.ArchTaskExecutor
5
- import androidx.lifecycle.LiveData
6
- import androidx.lifecycle.MediatorLiveData
7
- import java.util.concurrent.Executor
8
-
9
- internal fun <T1, T2, R> LiveData<T1>.combineLatest(
10
- other: LiveData<T2>,
11
- func: (T1, T2) -> R,
12
- ): LiveData<R> {
13
- return MediatorLiveData<R>().apply {
14
- var lastA: T1? = null
15
- var lastB: T2? = null
16
-
17
- addSource(this@combineLatest) {
18
- lastA = it
19
- val observedB = lastB
20
- if (it == null && value != null) {
21
- value = null
22
- } else if (it != null && observedB != null) {
23
- value = func(it, observedB)
24
- }
25
- }
26
-
27
- addSource(other) {
28
- lastB = it
29
- val observedA = lastA
30
- if (it == null && value != null) {
31
- value = null
32
- } else if (observedA != null && it != null) {
33
- value = func(observedA, it)
34
- }
35
- }
36
- }
37
- }
38
-
39
- internal fun <T1, T2> LiveData<T1>.combineLatest(other: LiveData<T2>): LiveData<Pair<T1, T2>> {
40
- return combineLatest(other) { a, b -> a to b }
41
- }
42
-
43
- // Unlike built-in extension operation is performed on a provided thread pool.
44
- // This is needed in our case since we compare requests and responses which can be big
45
- // and result in frame drops.
46
- internal fun <T> LiveData<T>.distinctUntilChanged(
47
- executor: Executor = ioExecutor(),
48
- areEqual: (old: T, new: T) -> Boolean = { old, new -> old == new },
49
- ): LiveData<T> {
50
- val distinctMediator = MediatorLiveData<T>()
51
- var old = uninitializedToken
52
- distinctMediator.addSource(this) { new ->
53
- executor.execute {
54
- @Suppress("UNCHECKED_CAST")
55
- if (old === uninitializedToken || !areEqual(old as T, new)) {
56
- old = new
57
- distinctMediator.postValue(new)
58
- }
59
- }
60
- }
61
- return distinctMediator
62
- }
63
-
64
- private val uninitializedToken: Any? = Any()
65
-
66
- // It is lesser evil than providing a custom executor.
67
- @SuppressLint("RestrictedApi")
68
- private fun ioExecutor() = ArchTaskExecutor.getIOThreadExecutor()
@@ -1,43 +0,0 @@
1
- package com.securitysuite.internal.support
2
-
3
- import com.securitysuite.api.Chucker
4
-
5
- internal interface Logger {
6
- fun info(
7
- message: String,
8
- throwable: Throwable? = null,
9
- )
10
-
11
- fun warn(
12
- message: String,
13
- throwable: Throwable? = null,
14
- )
15
-
16
- fun error(
17
- message: String,
18
- throwable: Throwable? = null,
19
- )
20
-
21
- companion object : Logger {
22
- override fun info(
23
- message: String,
24
- throwable: Throwable?,
25
- ) {
26
- Chucker.logger.info(message, throwable)
27
- }
28
-
29
- override fun warn(
30
- message: String,
31
- throwable: Throwable?,
32
- ) {
33
- Chucker.logger.warn(message, throwable)
34
- }
35
-
36
- override fun error(
37
- message: String,
38
- throwable: Throwable?,
39
- ) {
40
- Chucker.logger.error(message, throwable)
41
- }
42
- }
43
- }
@@ -1,149 +0,0 @@
1
- package com.securitysuite.internal.support
2
-
3
- import android.app.NotificationChannel
4
- import android.app.NotificationManager
5
- import android.app.PendingIntent
6
- import android.content.Context
7
- import android.content.Intent
8
- import android.os.Build
9
- import android.util.LongSparseArray
10
- import androidx.core.app.NotificationCompat
11
- import androidx.core.content.ContextCompat
12
- import com.securitysuite.R
13
- import com.securitysuite.api.Chucker
14
- import com.securitysuite.internal.data.entity.HttpTransaction
15
- import com.securitysuite.internal.ui.BaseChuckerActivity
16
- import java.util.HashSet
17
-
18
- internal class NotificationHelper(val context: Context) {
19
- companion object {
20
- private const val TRANSACTIONS_CHANNEL_ID = "chucker_transactions"
21
-
22
- private const val TRANSACTION_NOTIFICATION_ID = 1138
23
-
24
- private const val BUFFER_SIZE = 10
25
- private const val INTENT_REQUEST_CODE = 11
26
- private val transactionBuffer = LongSparseArray<HttpTransaction>()
27
- private val transactionIdsSet = HashSet<Long>()
28
-
29
- fun clearBuffer() {
30
- synchronized(transactionBuffer) {
31
- transactionBuffer.clear()
32
- transactionIdsSet.clear()
33
- }
34
- }
35
- }
36
-
37
- private val notificationManager: NotificationManager =
38
- context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
39
-
40
- private val transactionsScreenIntent by lazy {
41
- PendingIntent.getActivity(
42
- context,
43
- TRANSACTION_NOTIFICATION_ID,
44
- Chucker.getLaunchIntent(context),
45
- PendingIntent.FLAG_UPDATE_CURRENT or immutableFlag(),
46
- )
47
- }
48
-
49
- init {
50
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
51
- val transactionsChannel =
52
- NotificationChannel(
53
- TRANSACTIONS_CHANNEL_ID,
54
- context.getString(R.string.chucker_network_notification_category),
55
- NotificationManager.IMPORTANCE_LOW,
56
- )
57
- notificationManager.createNotificationChannels(listOf(transactionsChannel))
58
- }
59
- }
60
-
61
- private fun addToBuffer(transaction: HttpTransaction) {
62
- if (transaction.id == 0L) {
63
- // Don't store Transactions with an invalid ID (0).
64
- // Transaction with an Invalid ID will be shown twice in the notification
65
- // with both the invalid and the valid ID and we want to avoid this.
66
- return
67
- }
68
- synchronized(transactionBuffer) {
69
- transactionIdsSet.add(transaction.id)
70
- transactionBuffer.put(transaction.id, transaction)
71
- if (transactionBuffer.size() > BUFFER_SIZE) {
72
- transactionBuffer.removeAt(0)
73
- }
74
- }
75
- }
76
-
77
- private fun canShowNotifications(): Boolean {
78
- return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
79
- notificationManager.areNotificationsEnabled()
80
- } else {
81
- true
82
- }
83
- }
84
-
85
- fun show(transaction: HttpTransaction) {
86
- addToBuffer(transaction)
87
- if (!BaseChuckerActivity.isInForeground && canShowNotifications()) {
88
- val builder =
89
- NotificationCompat.Builder(context, TRANSACTIONS_CHANNEL_ID)
90
- .setContentIntent(transactionsScreenIntent)
91
- .setLocalOnly(true)
92
- .setSmallIcon(R.drawable.chucker_ic_transaction_notification)
93
- .setColor(ContextCompat.getColor(context, R.color.chucker_color_primary))
94
- .setContentTitle(context.getString(R.string.chucker_http_notification_title))
95
- .setAutoCancel(true)
96
- .addAction(createClearAction())
97
- val inboxStyle = NotificationCompat.InboxStyle()
98
- synchronized(transactionBuffer) {
99
- var count = 0
100
- for (i in transactionBuffer.size() - 1 downTo 0) {
101
- val bufferedTransaction = transactionBuffer.valueAt(i)
102
- if ((bufferedTransaction != null) && count < BUFFER_SIZE) {
103
- if (count == 0) {
104
- builder.setContentText(bufferedTransaction.notificationText)
105
- }
106
- inboxStyle.addLine(bufferedTransaction.notificationText)
107
- }
108
- count++
109
- }
110
- builder.setStyle(inboxStyle)
111
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
112
- builder.setSubText(transactionIdsSet.size.toString())
113
- } else {
114
- builder.setNumber(transactionIdsSet.size)
115
- }
116
- }
117
- notificationManager.notify(TRANSACTION_NOTIFICATION_ID, builder.build())
118
- }
119
- }
120
-
121
- private fun createClearAction(): NotificationCompat.Action {
122
- val clearTitle = context.getString(R.string.chucker_clear)
123
- val clearTransactionsBroadcastIntent =
124
- Intent(context, ClearDatabaseJobIntentServiceReceiver::class.java)
125
- val pendingBroadcastIntent =
126
- PendingIntent.getBroadcast(
127
- context,
128
- INTENT_REQUEST_CODE,
129
- clearTransactionsBroadcastIntent,
130
- PendingIntent.FLAG_ONE_SHOT or immutableFlag(),
131
- )
132
- return NotificationCompat.Action(
133
- R.drawable.chucker_ic_delete_white,
134
- clearTitle,
135
- pendingBroadcastIntent,
136
- )
137
- }
138
-
139
- fun dismissNotifications() {
140
- notificationManager.cancel(TRANSACTION_NOTIFICATION_ID)
141
- }
142
-
143
- private fun immutableFlag() =
144
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
145
- PendingIntent.FLAG_IMMUTABLE
146
- } else {
147
- 0
148
- }
149
- }