react-native-security-suite 0.6.7 → 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 (122) hide show
  1. package/android/src/main/AndroidManifest.xml +3 -48
  2. package/package.json +1 -1
  3. package/android/src/main/java/com/securitysuite/NetworkLogger.java +0 -25
  4. package/android/src/main/java/com/securitysuite/api/BodyDecoder.kt +0 -35
  5. package/android/src/main/java/com/securitysuite/api/Chucker.kt +0 -108
  6. package/android/src/main/java/com/securitysuite/api/ChuckerCollector.kt +0 -129
  7. package/android/src/main/java/com/securitysuite/api/ChuckerInterceptor.kt +0 -280
  8. package/android/src/main/java/com/securitysuite/api/ExportFormat.kt +0 -12
  9. package/android/src/main/java/com/securitysuite/api/RetentionManager.kt +0 -109
  10. package/android/src/main/java/com/securitysuite/internal/data/entity/HttpHeader.kt +0 -8
  11. package/android/src/main/java/com/securitysuite/internal/data/entity/HttpTransaction.kt +0 -344
  12. package/android/src/main/java/com/securitysuite/internal/data/entity/HttpTransactionTuple.kt +0 -62
  13. package/android/src/main/java/com/securitysuite/internal/data/har/Har.kt +0 -13
  14. package/android/src/main/java/com/securitysuite/internal/data/har/Log.kt +0 -24
  15. package/android/src/main/java/com/securitysuite/internal/data/har/log/Browser.kt +0 -11
  16. package/android/src/main/java/com/securitysuite/internal/data/har/log/Creator.kt +0 -11
  17. package/android/src/main/java/com/securitysuite/internal/data/har/log/Entry.kt +0 -49
  18. package/android/src/main/java/com/securitysuite/internal/data/har/log/Page.kt +0 -14
  19. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Cache.kt +0 -12
  20. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Header.kt +0 -17
  21. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Request.kt +0 -35
  22. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Response.kt +0 -33
  23. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Timings.kt +0 -25
  24. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/cache/SecondaryRequest.kt +0 -13
  25. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/request/PostData.kt +0 -20
  26. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/request/QueryString.kt +0 -23
  27. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/request/postdata/Params.kt +0 -13
  28. package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/response/Content.kt +0 -30
  29. package/android/src/main/java/com/securitysuite/internal/data/har/log/page/PageTimings.kt +0 -11
  30. package/android/src/main/java/com/securitysuite/internal/data/model/DialogData.kt +0 -8
  31. package/android/src/main/java/com/securitysuite/internal/data/repository/HttpTransactionDatabaseRepository.kt +0 -60
  32. package/android/src/main/java/com/securitysuite/internal/data/repository/HttpTransactionRepository.kt +0 -33
  33. package/android/src/main/java/com/securitysuite/internal/data/repository/RepositoryProvider.kt +0 -38
  34. package/android/src/main/java/com/securitysuite/internal/data/room/ChuckerDatabase.kt +0 -22
  35. package/android/src/main/java/com/securitysuite/internal/data/room/HttpTransactionDao.kt +0 -53
  36. package/android/src/main/java/com/securitysuite/internal/support/BitmapUtils.kt +0 -45
  37. package/android/src/main/java/com/securitysuite/internal/support/CacheDirectoryProvider.kt +0 -11
  38. package/android/src/main/java/com/securitysuite/internal/support/ChessboardDrawable.kt +0 -76
  39. package/android/src/main/java/com/securitysuite/internal/support/ChuckerFileProvider.kt +0 -9
  40. package/android/src/main/java/com/securitysuite/internal/support/ClearDatabaseJobIntentServiceReceiver.kt +0 -14
  41. package/android/src/main/java/com/securitysuite/internal/support/ClearDatabaseService.kt +0 -32
  42. package/android/src/main/java/com/securitysuite/internal/support/ContextExt.kt +0 -22
  43. package/android/src/main/java/com/securitysuite/internal/support/DepletingSource.kt +0 -37
  44. package/android/src/main/java/com/securitysuite/internal/support/FileFactory.kt +0 -30
  45. package/android/src/main/java/com/securitysuite/internal/support/FileSaver.kt +0 -41
  46. package/android/src/main/java/com/securitysuite/internal/support/FormatUtils.kt +0 -117
  47. package/android/src/main/java/com/securitysuite/internal/support/FormattedUrl.kt +0 -76
  48. package/android/src/main/java/com/securitysuite/internal/support/HarUtils.kt +0 -28
  49. package/android/src/main/java/com/securitysuite/internal/support/HttpUrlUtils.kt +0 -11
  50. package/android/src/main/java/com/securitysuite/internal/support/JsonConverter.kt +0 -19
  51. package/android/src/main/java/com/securitysuite/internal/support/LimitingSource.kt +0 -22
  52. package/android/src/main/java/com/securitysuite/internal/support/LiveDataUtils.kt +0 -68
  53. package/android/src/main/java/com/securitysuite/internal/support/Logger.kt +0 -43
  54. package/android/src/main/java/com/securitysuite/internal/support/NotificationHelper.kt +0 -149
  55. package/android/src/main/java/com/securitysuite/internal/support/OkHttpUtils.kt +0 -86
  56. package/android/src/main/java/com/securitysuite/internal/support/OkioUtils.kt +0 -34
  57. package/android/src/main/java/com/securitysuite/internal/support/PlainTextDecoder.kt +0 -30
  58. package/android/src/main/java/com/securitysuite/internal/support/ReportingSink.kt +0 -114
  59. package/android/src/main/java/com/securitysuite/internal/support/RequestProcessor.kt +0 -102
  60. package/android/src/main/java/com/securitysuite/internal/support/ResponseProcessor.kt +0 -170
  61. package/android/src/main/java/com/securitysuite/internal/support/SearchHighlightUtil.kt +0 -80
  62. package/android/src/main/java/com/securitysuite/internal/support/Sharable.kt +0 -86
  63. package/android/src/main/java/com/securitysuite/internal/support/SpanTextUtil.kt +0 -202
  64. package/android/src/main/java/com/securitysuite/internal/support/TeeSource.kt +0 -68
  65. package/android/src/main/java/com/securitysuite/internal/support/TransactionCurlCommandSharable.kt +0 -46
  66. package/android/src/main/java/com/securitysuite/internal/support/TransactionDetailsHarSharable.kt +0 -11
  67. package/android/src/main/java/com/securitysuite/internal/support/TransactionDetailsSharable.kt +0 -73
  68. package/android/src/main/java/com/securitysuite/internal/support/TransactionDiffCallback.kt +0 -26
  69. package/android/src/main/java/com/securitysuite/internal/support/TransactionListDetailsSharable.kt +0 -23
  70. package/android/src/main/java/com/securitysuite/internal/ui/BaseChuckerActivity.kt +0 -35
  71. package/android/src/main/java/com/securitysuite/internal/ui/MainActivity.kt +0 -375
  72. package/android/src/main/java/com/securitysuite/internal/ui/MainViewModel.kt +0 -47
  73. package/android/src/main/java/com/securitysuite/internal/ui/transaction/PayloadType.kt +0 -6
  74. package/android/src/main/java/com/securitysuite/internal/ui/transaction/ProtocolResources.kt +0 -14
  75. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionActivity.kt +0 -186
  76. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionAdapter.kt +0 -139
  77. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionOverviewFragment.kt +0 -100
  78. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionPagerAdapter.kt +0 -29
  79. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionPayloadAdapter.kt +0 -269
  80. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionPayloadFragment.kt +0 -529
  81. package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionViewModel.kt +0 -69
  82. package/android/src/main/res/A.java +0 -12
  83. package/android/src/main/res/color/chucker_fab_background_colour.xml +0 -5
  84. package/android/src/main/res/drawable/chucker_empty_payload.xml +0 -10
  85. package/android/src/main/res/drawable/chucker_ic_arrow_down.xml +0 -10
  86. package/android/src/main/res/drawable/chucker_ic_copy.xml +0 -12
  87. package/android/src/main/res/drawable/chucker_ic_decoded_url_white.xml +0 -10
  88. package/android/src/main/res/drawable/chucker_ic_delete_white.xml +0 -9
  89. package/android/src/main/res/drawable/chucker_ic_encoded_url_white.xml +0 -11
  90. package/android/src/main/res/drawable/chucker_ic_graphql.xml +0 -27
  91. package/android/src/main/res/drawable/chucker_ic_http.xml +0 -10
  92. package/android/src/main/res/drawable/chucker_ic_https.xml +0 -9
  93. package/android/src/main/res/drawable/chucker_ic_launcher_foreground.xml +0 -14
  94. package/android/src/main/res/drawable/chucker_ic_save_white.xml +0 -9
  95. package/android/src/main/res/drawable/chucker_ic_search_white.xml +0 -9
  96. package/android/src/main/res/drawable/chucker_ic_share_white.xml +0 -9
  97. package/android/src/main/res/drawable/chucker_ic_transaction_notification.xml +0 -9
  98. package/android/src/main/res/layout/activity_main.xml +0 -83
  99. package/android/src/main/res/layout/activity_transaction.xml +0 -48
  100. package/android/src/main/res/layout/fragment_transaction_overview.xml +0 -365
  101. package/android/src/main/res/layout/fragment_transaction_payload.xml +0 -132
  102. package/android/src/main/res/layout/list_item_transaction.xml +0 -122
  103. package/android/src/main/res/layout/transaction_item_body_line.xml +0 -13
  104. package/android/src/main/res/layout/transaction_item_copy.xml +0 -19
  105. package/android/src/main/res/layout/transaction_item_headers.xml +0 -12
  106. package/android/src/main/res/layout/transaction_item_image.xml +0 -16
  107. package/android/src/main/res/menu/chucker_transaction.xml +0 -46
  108. package/android/src/main/res/menu/chucker_transactions_list.xml +0 -41
  109. package/android/src/main/res/mipmap-anydpi-v26/chucker_ic_launcher.xml +0 -5
  110. package/android/src/main/res/mipmap-hdpi/chucker_ic_launcher.png +0 -0
  111. package/android/src/main/res/mipmap-xhdpi/chucker_ic_launcher.png +0 -0
  112. package/android/src/main/res/mipmap-xxhdpi/chucker_ic_launcher.png +0 -0
  113. package/android/src/main/res/mipmap-xxxhdpi/chucker_ic_launcher.png +0 -0
  114. package/android/src/main/res/values/chucker_ic_launcher_background.xml +0 -4
  115. package/android/src/main/res/values/colors.xml +0 -38
  116. package/android/src/main/res/values/dimens.xml +0 -10
  117. package/android/src/main/res/values/public.xml +0 -5
  118. package/android/src/main/res/values/strings.xml +0 -77
  119. package/android/src/main/res/values/styles.xml +0 -44
  120. package/android/src/main/res/values-es/strings.xml +0 -75
  121. package/android/src/main/res/values-night/colors.xml +0 -32
  122. package/android/src/main/res/xml/chucker_provider_paths.xml +0 -4
@@ -1,375 +0,0 @@
1
- package com.securitysuite.internal.ui
2
-
3
- import android.Manifest
4
- import android.content.Intent
5
- import android.content.pm.PackageManager
6
- import android.net.Uri
7
- import android.os.Build
8
- import android.os.Bundle
9
- import android.provider.Settings
10
- import android.text.method.LinkMovementMethod
11
- import android.view.Menu
12
- import android.view.MenuItem
13
- import android.widget.Toast
14
- import androidx.activity.result.contract.ActivityResultContracts
15
- import androidx.activity.viewModels
16
- import androidx.annotation.RequiresApi
17
- import androidx.annotation.StringRes
18
- import androidx.appcompat.widget.SearchView
19
- import androidx.core.content.ContextCompat
20
- import androidx.core.view.MenuCompat
21
- import androidx.core.view.isVisible
22
- import androidx.lifecycle.lifecycleScope
23
- import androidx.recyclerview.widget.DividerItemDecoration
24
- import com.securitysuite.R
25
- import com.securitysuite.api.Chucker
26
- import com.securitysuite.internal.data.entity.HttpTransaction
27
- import com.securitysuite.internal.data.model.DialogData
28
- import com.securitysuite.internal.support.FileSaver
29
- import com.securitysuite.internal.support.HarUtils
30
- import com.securitysuite.internal.support.Logger
31
- import com.securitysuite.internal.support.Sharable
32
- import com.securitysuite.internal.support.TransactionDetailsHarSharable
33
- import com.securitysuite.internal.support.TransactionListDetailsSharable
34
- import com.securitysuite.internal.support.shareAsFile
35
- import com.securitysuite.internal.support.showDialog
36
- import com.securitysuite.internal.ui.MainActivity.ExportType.HAR
37
- import com.securitysuite.internal.ui.MainActivity.ExportType.TEXT
38
- import com.securitysuite.internal.ui.transaction.TransactionActivity
39
- import com.securitysuite.internal.ui.transaction.TransactionAdapter
40
- import com.google.android.material.snackbar.Snackbar
41
- import com.securitysuite.databinding.ActivityMainBinding
42
- import kotlinx.coroutines.Dispatchers
43
- import kotlinx.coroutines.launch
44
- import kotlinx.coroutines.withContext
45
- import okio.Source
46
- import okio.buffer
47
- import okio.source
48
-
49
- internal class MainActivity :
50
- BaseChuckerActivity(),
51
- SearchView.OnQueryTextListener {
52
- private val viewModel: MainViewModel by viewModels()
53
-
54
- private lateinit var mainBinding: ActivityMainBinding
55
- private lateinit var transactionsAdapter: TransactionAdapter
56
-
57
- private val applicationName: CharSequence
58
- get() = applicationInfo.loadLabel(packageManager)
59
-
60
- private val permissionRequest =
61
- registerForActivityResult(
62
- ActivityResultContracts.RequestPermission(),
63
- ) { isPermissionGranted: Boolean ->
64
- if (!isPermissionGranted) {
65
- showToast(
66
- applicationContext.getString(R.string.chucker_notifications_permission_not_granted),
67
- Toast.LENGTH_LONG,
68
- )
69
- Logger.error("Notification permission denied. Can't show transactions info")
70
- }
71
- }
72
-
73
- private val saveTextToFile =
74
- registerForActivityResult(ActivityResultContracts.CreateDocument(TEXT.mimeType)) { uri ->
75
- onSaveToFileActivityResult(uri, TEXT)
76
- }
77
-
78
- private val saveHarToFile =
79
- registerForActivityResult(ActivityResultContracts.CreateDocument(HAR.mimeType)) { uri ->
80
- onSaveToFileActivityResult(uri, HAR)
81
- }
82
-
83
- override fun onCreate(savedInstanceState: Bundle?) {
84
- super.onCreate(savedInstanceState)
85
-
86
- mainBinding = ActivityMainBinding.inflate(layoutInflater)
87
- transactionsAdapter =
88
- TransactionAdapter(this) { transactionId ->
89
- TransactionActivity.start(this, transactionId)
90
- }
91
-
92
- with(mainBinding) {
93
- setContentView(root)
94
- setSupportActionBar(toolbar)
95
- toolbar.subtitle = applicationName
96
-
97
- tutorialLink.movementMethod = LinkMovementMethod.getInstance()
98
- transactionsRecyclerView.apply {
99
- setHasFixedSize(true)
100
- addItemDecoration(
101
- DividerItemDecoration(
102
- this@MainActivity,
103
- DividerItemDecoration.VERTICAL,
104
- ),
105
- )
106
- adapter = transactionsAdapter
107
- }
108
- }
109
-
110
- viewModel.transactions.observe(
111
- this,
112
- ) { transactionTuples ->
113
- transactionsAdapter.submitList(transactionTuples)
114
- mainBinding.tutorialGroup.isVisible = transactionTuples.isEmpty()
115
- }
116
-
117
- if (Chucker.showNotifications && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
118
- handleNotificationsPermission()
119
- }
120
- }
121
-
122
- @RequiresApi(Build.VERSION_CODES.TIRAMISU)
123
- private fun handleNotificationsPermission() {
124
- when {
125
- ContextCompat.checkSelfPermission(
126
- this,
127
- Manifest.permission.POST_NOTIFICATIONS,
128
- ) == PackageManager.PERMISSION_GRANTED -> {
129
- // We have permission, all good
130
- }
131
-
132
- shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS) -> {
133
- Snackbar.make(
134
- mainBinding.root,
135
- applicationContext.getString(R.string.chucker_notifications_permission_not_granted),
136
- Snackbar.LENGTH_LONG,
137
- ).setAction(applicationContext.getString(R.string.chucker_change)) {
138
- Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
139
- addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
140
- data = Uri.fromParts("package", packageName, null)
141
- }.also { intent ->
142
- startActivity(intent)
143
- }
144
- }.show()
145
- }
146
-
147
- else -> {
148
- permissionRequest.launch(Manifest.permission.POST_NOTIFICATIONS)
149
- }
150
- }
151
- }
152
-
153
- override fun onCreateOptionsMenu(menu: Menu): Boolean {
154
- menuInflater.inflate(R.menu.chucker_transactions_list, menu)
155
- MenuCompat.setGroupDividerEnabled(menu, true)
156
- setUpSearch(menu)
157
- return super.onCreateOptionsMenu(menu)
158
- }
159
-
160
- private fun setUpSearch(menu: Menu) {
161
- val searchMenuItem = menu.findItem(R.id.search)
162
- val searchView = searchMenuItem.actionView as SearchView
163
- searchView.setOnQueryTextListener(this)
164
- searchView.setIconifiedByDefault(true)
165
- }
166
-
167
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
168
- return when (item.itemId) {
169
- R.id.clear -> {
170
- showDialog(
171
- getClearDialogData(),
172
- onPositiveClick = {
173
- viewModel.clearTransactions()
174
- },
175
- onNegativeClick = null,
176
- )
177
- true
178
- }
179
-
180
- R.id.share_text -> {
181
- showDialog(
182
- getExportDialogData(R.string.chucker_export_text_http_confirmation),
183
- onPositiveClick = {
184
- exportTransactions(EXPORT_TXT_FILE_NAME) { transactions ->
185
- TransactionListDetailsSharable(transactions, encodeUrls = false)
186
- }
187
- },
188
- onNegativeClick = null,
189
- )
190
- true
191
- }
192
-
193
- R.id.share_har -> {
194
- showDialog(
195
- getExportDialogData(R.string.chucker_export_har_http_confirmation),
196
- onPositiveClick = {
197
- exportTransactions(EXPORT_HAR_FILE_NAME) { transactions ->
198
- TransactionDetailsHarSharable(
199
- HarUtils.harStringFromTransactions(
200
- transactions,
201
- getString(R.string.chucker_name),
202
- getString(R.string.chucker_version),
203
- ),
204
- )
205
- }
206
- },
207
- onNegativeClick = null,
208
- )
209
- true
210
- }
211
-
212
- R.id.save_text -> {
213
- showSaveDialog(TEXT)
214
- true
215
- }
216
-
217
- R.id.save_har -> {
218
- showSaveDialog(HAR)
219
- true
220
- }
221
-
222
- else -> {
223
- super.onOptionsItemSelected(item)
224
- }
225
- }
226
- }
227
-
228
- override fun onQueryTextSubmit(query: String): Boolean = true
229
-
230
- override fun onQueryTextChange(newText: String): Boolean {
231
- viewModel.updateItemsFilter(newText)
232
- return true
233
- }
234
-
235
- private fun exportTransactions(
236
- fileName: String,
237
- block: suspend (List<HttpTransaction>) -> Sharable,
238
- ) {
239
- val applicationContext = this.applicationContext
240
- lifecycleScope.launch {
241
- val transactions = viewModel.getAllTransactions()
242
- if (transactions.isEmpty()) {
243
- showToast(applicationContext.getString(R.string.chucker_export_empty_text))
244
- return@launch
245
- }
246
-
247
- val sharableTransactions = block(transactions)
248
- val shareIntent =
249
- withContext(Dispatchers.IO) {
250
- sharableTransactions.shareAsFile(
251
- activity = this@MainActivity,
252
- fileName = fileName,
253
- intentTitle = getString(R.string.chucker_share_all_transactions_title),
254
- intentSubject = getString(R.string.chucker_share_all_transactions_subject),
255
- clipDataLabel = "transactions",
256
- )
257
- }
258
- if (shareIntent != null) {
259
- startActivity(shareIntent)
260
- } else {
261
- showToast(applicationContext.getString(R.string.chucker_export_no_file))
262
- }
263
- }
264
- }
265
-
266
- private fun getClearDialogData(): DialogData =
267
- DialogData(
268
- title = getString(R.string.chucker_clear),
269
- message = getString(R.string.chucker_clear_http_confirmation),
270
- positiveButtonText = getString(R.string.chucker_clear),
271
- negativeButtonText = getString(R.string.chucker_cancel),
272
- )
273
-
274
- private fun getExportDialogData(
275
- @StringRes dialogMessage: Int,
276
- ): DialogData =
277
- DialogData(
278
- title = getString(R.string.chucker_export),
279
- message = getString(dialogMessage),
280
- positiveButtonText = getString(R.string.chucker_export),
281
- negativeButtonText = getString(R.string.chucker_cancel),
282
- )
283
-
284
- private fun getSaveDialogData(
285
- @StringRes dialogMessage: Int,
286
- ): DialogData =
287
- DialogData(
288
- title = getString(R.string.chucker_save),
289
- message = getString(dialogMessage),
290
- positiveButtonText = getString(R.string.chucker_save),
291
- negativeButtonText = getString(R.string.chucker_cancel),
292
- )
293
-
294
- private fun showSaveDialog(exportType: ExportType) {
295
- showDialog(
296
- getSaveDialogData(
297
- when (exportType) {
298
- TEXT -> R.string.chucker_save_text_http_confirmation
299
- HAR -> R.string.chucker_save_har_http_confirmation
300
- },
301
- ),
302
- onPositiveClick = {
303
- when (exportType) {
304
- TEXT -> saveTextToFile.launch(EXPORT_TXT_FILE_NAME)
305
- HAR -> saveHarToFile.launch(EXPORT_HAR_FILE_NAME)
306
- }
307
- },
308
- onNegativeClick = null,
309
- )
310
- }
311
-
312
- private fun onSaveToFileActivityResult(
313
- uri: Uri?,
314
- exportType: ExportType,
315
- ) {
316
- if (uri == null) {
317
- Toast.makeText(
318
- applicationContext,
319
- R.string.chucker_save_failed_to_open_document,
320
- Toast.LENGTH_SHORT,
321
- ).show()
322
- return
323
- }
324
- lifecycleScope.launch {
325
- val source =
326
- runCatching {
327
- prepareDataToSave(exportType)
328
- }.getOrNull() ?: return@launch
329
- val result = FileSaver.saveFile(source, uri, contentResolver)
330
- val toastMessageId =
331
- if (result) {
332
- R.string.chucker_file_saved
333
- } else {
334
- R.string.chucker_file_not_saved
335
- }
336
- Toast.makeText(applicationContext, toastMessageId, Toast.LENGTH_SHORT).show()
337
- }
338
- }
339
-
340
- private suspend fun prepareDataToSave(exportType: ExportType): Source? {
341
- val transactions = viewModel.getAllTransactions()
342
- if (transactions.isEmpty()) {
343
- showToast(applicationContext.getString(R.string.chucker_save_empty_text))
344
- return null
345
- }
346
- return withContext(Dispatchers.IO) {
347
- when (exportType) {
348
- TEXT -> {
349
- TransactionListDetailsSharable(
350
- transactions,
351
- encodeUrls = false,
352
- ).toSharableContent(this@MainActivity)
353
- }
354
-
355
- HAR -> {
356
- HarUtils.harStringFromTransactions(
357
- transactions,
358
- getString(R.string.chucker_name),
359
- getString(R.string.chucker_version),
360
- ).byteInputStream().source().buffer()
361
- }
362
- }
363
- }
364
- }
365
-
366
- private enum class ExportType(val mimeType: String) {
367
- TEXT("text/plain"),
368
- HAR("application/har+json"),
369
- }
370
-
371
- companion object {
372
- private const val EXPORT_TXT_FILE_NAME = "transactions.txt"
373
- private const val EXPORT_HAR_FILE_NAME = "transactions.har"
374
- }
375
- }
@@ -1,47 +0,0 @@
1
- package com.securitysuite.internal.ui
2
-
3
- import android.text.TextUtils
4
- import androidx.lifecycle.LiveData
5
- import androidx.lifecycle.MutableLiveData
6
- import androidx.lifecycle.ViewModel
7
- import androidx.lifecycle.switchMap
8
- import androidx.lifecycle.viewModelScope
9
- import com.securitysuite.internal.data.entity.HttpTransaction
10
- import com.securitysuite.internal.data.entity.HttpTransactionTuple
11
- import com.securitysuite.internal.data.repository.RepositoryProvider
12
- import com.securitysuite.internal.support.NotificationHelper
13
- import kotlinx.coroutines.launch
14
-
15
- internal class MainViewModel : ViewModel() {
16
- private val currentFilter = MutableLiveData("")
17
-
18
- val transactions: LiveData<List<HttpTransactionTuple>> =
19
- currentFilter.switchMap { searchQuery ->
20
- with(RepositoryProvider.transaction()) {
21
- when {
22
- searchQuery.isNullOrBlank() -> {
23
- getSortedTransactionTuples()
24
- }
25
- TextUtils.isDigitsOnly(searchQuery) -> {
26
- getFilteredTransactionTuples(searchQuery, "")
27
- }
28
- else -> {
29
- getFilteredTransactionTuples("", searchQuery)
30
- }
31
- }
32
- }
33
- }
34
-
35
- suspend fun getAllTransactions(): List<HttpTransaction> = RepositoryProvider.transaction().getAllTransactions()
36
-
37
- fun updateItemsFilter(searchQuery: String) {
38
- currentFilter.value = searchQuery
39
- }
40
-
41
- fun clearTransactions() {
42
- viewModelScope.launch {
43
- RepositoryProvider.transaction().deleteAllTransactions()
44
- }
45
- NotificationHelper.clearBuffer()
46
- }
47
- }
@@ -1,6 +0,0 @@
1
- package com.securitysuite.internal.ui.transaction
2
-
3
- internal enum class PayloadType {
4
- REQUEST,
5
- RESPONSE,
6
- }
@@ -1,14 +0,0 @@
1
- package com.securitysuite.internal.ui.transaction
2
-
3
- import androidx.annotation.ColorRes
4
- import androidx.annotation.DrawableRes
5
- import com.securitysuite.R
6
-
7
- internal sealed class ProtocolResources(
8
- @DrawableRes val icon: Int,
9
- @ColorRes val color: Int,
10
- ) {
11
- class Http : ProtocolResources(R.drawable.chucker_ic_http, R.color.chucker_color_error)
12
-
13
- class Https : ProtocolResources(R.drawable.chucker_ic_https, R.color.chucker_color_primary)
14
- }
@@ -1,186 +0,0 @@
1
- package com.securitysuite.internal.ui.transaction
2
-
3
- import android.content.Context
4
- import android.content.Intent
5
- import android.os.Bundle
6
- import android.view.Menu
7
- import android.view.MenuItem
8
- import android.widget.Toast
9
- import androidx.activity.viewModels
10
- import androidx.lifecycle.Observer
11
- import androidx.lifecycle.lifecycleScope
12
- import androidx.viewpager.widget.ViewPager
13
- import com.securitysuite.R
14
- import com.securitysuite.databinding.ActivityTransactionBinding
15
- import com.securitysuite.internal.data.entity.HttpTransaction
16
- import com.securitysuite.internal.support.HarUtils
17
- import com.securitysuite.internal.support.Sharable
18
- import com.securitysuite.internal.support.TransactionCurlCommandSharable
19
- import com.securitysuite.internal.support.TransactionDetailsHarSharable
20
- import com.securitysuite.internal.support.TransactionDetailsSharable
21
- import com.securitysuite.internal.support.shareAsFile
22
- import com.securitysuite.internal.support.shareAsUtf8Text
23
- import com.securitysuite.internal.ui.BaseChuckerActivity
24
- import kotlinx.coroutines.Dispatchers
25
- import kotlinx.coroutines.launch
26
- import kotlinx.coroutines.withContext
27
-
28
- internal class TransactionActivity : BaseChuckerActivity() {
29
- private val viewModel: TransactionViewModel by viewModels {
30
- TransactionViewModelFactory(intent.getLongExtra(EXTRA_TRANSACTION_ID, 0))
31
- }
32
-
33
- private lateinit var transactionBinding: ActivityTransactionBinding
34
-
35
- override fun onCreate(savedInstanceState: Bundle?) {
36
- super.onCreate(savedInstanceState)
37
- transactionBinding = ActivityTransactionBinding.inflate(layoutInflater)
38
-
39
- with(transactionBinding) {
40
- setContentView(root)
41
- setSupportActionBar(toolbar)
42
- setupViewPager(viewPager)
43
- tabLayout.setupWithViewPager(viewPager)
44
- }
45
-
46
- supportActionBar?.setDisplayHomeAsUpEnabled(true)
47
-
48
- viewModel.transactionTitle.observe(
49
- this,
50
- Observer { transactionBinding.toolbarTitle.text = it },
51
- )
52
- }
53
-
54
- override fun onCreateOptionsMenu(menu: Menu): Boolean {
55
- menuInflater.inflate(R.menu.chucker_transaction, menu)
56
- setUpUrlEncoding(menu)
57
- return super.onCreateOptionsMenu(menu)
58
- }
59
-
60
- private fun setUpUrlEncoding(menu: Menu) {
61
- val encodeUrlMenuItem = menu.findItem(R.id.encode_url)
62
- encodeUrlMenuItem.setOnMenuItemClickListener {
63
- viewModel.switchUrlEncoding()
64
- return@setOnMenuItemClickListener true
65
- }
66
- viewModel.encodeUrl.observe(
67
- this,
68
- Observer { encode ->
69
- val icon =
70
- if (encode) {
71
- R.drawable.chucker_ic_encoded_url_white
72
- } else {
73
- R.drawable.chucker_ic_decoded_url_white
74
- }
75
- encodeUrlMenuItem.setIcon(icon)
76
- },
77
- )
78
- }
79
-
80
- override fun onOptionsItemSelected(item: MenuItem) =
81
- when (item.itemId) {
82
- R.id.share_text ->
83
- shareTransactionAsText { transaction ->
84
- val encodeUrls = viewModel.encodeUrl.value!!
85
- TransactionDetailsSharable(transaction, encodeUrls)
86
- }
87
- R.id.share_curl ->
88
- shareTransactionAsText { transaction ->
89
- TransactionCurlCommandSharable(transaction)
90
- }
91
- R.id.share_file ->
92
- shareTransactionAsFile(EXPORT_TXT_FILE_NAME) { transaction ->
93
- val encodeUrls = viewModel.encodeUrl.value!!
94
- TransactionDetailsSharable(transaction, encodeUrls)
95
- }
96
- R.id.share_har ->
97
- shareTransactionAsFile(EXPORT_HAR_FILE_NAME) { transaction ->
98
- TransactionDetailsHarSharable(
99
- HarUtils.harStringFromTransactions(
100
- listOf(transaction),
101
- getString(R.string.chucker_name),
102
- getString(R.string.chucker_version),
103
- ),
104
- )
105
- }
106
- else -> super.onOptionsItemSelected(item)
107
- }
108
-
109
- private fun shareTransactionAsText(block: (HttpTransaction) -> Sharable): Boolean {
110
- val transaction = viewModel.transaction.value
111
- if (transaction == null) {
112
- showToast(getString(R.string.chucker_request_not_ready))
113
- return true
114
- }
115
- val sharable = block(transaction)
116
- lifecycleScope.launch {
117
- val shareIntent =
118
- sharable.shareAsUtf8Text(
119
- activity = this@TransactionActivity,
120
- intentTitle = getString(R.string.chucker_share_transaction_title),
121
- intentSubject = getString(R.string.chucker_share_transaction_subject),
122
- )
123
- startActivity(shareIntent)
124
- }
125
- return true
126
- }
127
-
128
- private fun shareTransactionAsFile(
129
- fileName: String,
130
- block: suspend (HttpTransaction) -> Sharable,
131
- ): Boolean {
132
- lifecycleScope.launch {
133
- val transaction = viewModel.transaction.value
134
- if (transaction == null) {
135
- showToast(getString(R.string.chucker_request_not_ready))
136
- return@launch
137
- }
138
-
139
- val sharable = block(transaction)
140
- val shareIntent =
141
- withContext(Dispatchers.IO) {
142
- sharable.shareAsFile(
143
- activity = this@TransactionActivity,
144
- fileName = fileName,
145
- intentTitle = getString(R.string.chucker_share_transaction_title),
146
- intentSubject = getString(R.string.chucker_share_transaction_subject),
147
- clipDataLabel = "transaction",
148
- )
149
- }
150
- if (shareIntent != null) {
151
- startActivity(shareIntent)
152
- } else {
153
- Toast.makeText(applicationContext, R.string.chucker_export_no_file, Toast.LENGTH_SHORT).show()
154
- }
155
- }
156
- return true
157
- }
158
-
159
- private fun setupViewPager(viewPager: ViewPager) {
160
- viewPager.adapter = TransactionPagerAdapter(this, supportFragmentManager)
161
- viewPager.addOnPageChangeListener(
162
- object : ViewPager.SimpleOnPageChangeListener() {
163
- override fun onPageSelected(position: Int) {
164
- selectedTabPosition = position
165
- }
166
- },
167
- )
168
- viewPager.currentItem = selectedTabPosition
169
- }
170
-
171
- companion object {
172
- private const val EXPORT_TXT_FILE_NAME = "transaction.txt"
173
- private const val EXPORT_HAR_FILE_NAME = "transaction.har"
174
- private const val EXTRA_TRANSACTION_ID = "transaction_id"
175
- private var selectedTabPosition = 0
176
-
177
- fun start(
178
- context: Context,
179
- transactionId: Long,
180
- ) {
181
- val intent = Intent(context, TransactionActivity::class.java)
182
- intent.putExtra(EXTRA_TRANSACTION_ID, transactionId)
183
- context.startActivity(intent)
184
- }
185
- }
186
- }