react-native-security-suite 0.6.7 → 0.7.0
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.
- package/android/build.gradle +0 -15
- package/android/src/main/AndroidManifest.xml +3 -48
- package/package.json +1 -1
- package/android/src/main/java/com/securitysuite/NetworkLogger.java +0 -25
- package/android/src/main/java/com/securitysuite/api/BodyDecoder.kt +0 -35
- package/android/src/main/java/com/securitysuite/api/Chucker.kt +0 -108
- package/android/src/main/java/com/securitysuite/api/ChuckerCollector.kt +0 -129
- package/android/src/main/java/com/securitysuite/api/ChuckerInterceptor.kt +0 -280
- package/android/src/main/java/com/securitysuite/api/ExportFormat.kt +0 -12
- package/android/src/main/java/com/securitysuite/api/RetentionManager.kt +0 -109
- package/android/src/main/java/com/securitysuite/internal/data/entity/HttpHeader.kt +0 -8
- package/android/src/main/java/com/securitysuite/internal/data/entity/HttpTransaction.kt +0 -344
- package/android/src/main/java/com/securitysuite/internal/data/entity/HttpTransactionTuple.kt +0 -62
- package/android/src/main/java/com/securitysuite/internal/data/har/Har.kt +0 -13
- package/android/src/main/java/com/securitysuite/internal/data/har/Log.kt +0 -24
- package/android/src/main/java/com/securitysuite/internal/data/har/log/Browser.kt +0 -11
- package/android/src/main/java/com/securitysuite/internal/data/har/log/Creator.kt +0 -11
- package/android/src/main/java/com/securitysuite/internal/data/har/log/Entry.kt +0 -49
- package/android/src/main/java/com/securitysuite/internal/data/har/log/Page.kt +0 -14
- package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Cache.kt +0 -12
- package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Header.kt +0 -17
- package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Request.kt +0 -35
- package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Response.kt +0 -33
- package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/Timings.kt +0 -25
- package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/cache/SecondaryRequest.kt +0 -13
- package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/request/PostData.kt +0 -20
- package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/request/QueryString.kt +0 -23
- package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/request/postdata/Params.kt +0 -13
- package/android/src/main/java/com/securitysuite/internal/data/har/log/entry/response/Content.kt +0 -30
- package/android/src/main/java/com/securitysuite/internal/data/har/log/page/PageTimings.kt +0 -11
- package/android/src/main/java/com/securitysuite/internal/data/model/DialogData.kt +0 -8
- package/android/src/main/java/com/securitysuite/internal/data/repository/HttpTransactionDatabaseRepository.kt +0 -60
- package/android/src/main/java/com/securitysuite/internal/data/repository/HttpTransactionRepository.kt +0 -33
- package/android/src/main/java/com/securitysuite/internal/data/repository/RepositoryProvider.kt +0 -38
- package/android/src/main/java/com/securitysuite/internal/data/room/ChuckerDatabase.kt +0 -22
- package/android/src/main/java/com/securitysuite/internal/data/room/HttpTransactionDao.kt +0 -53
- package/android/src/main/java/com/securitysuite/internal/support/BitmapUtils.kt +0 -45
- package/android/src/main/java/com/securitysuite/internal/support/CacheDirectoryProvider.kt +0 -11
- package/android/src/main/java/com/securitysuite/internal/support/ChessboardDrawable.kt +0 -76
- package/android/src/main/java/com/securitysuite/internal/support/ChuckerFileProvider.kt +0 -9
- package/android/src/main/java/com/securitysuite/internal/support/ClearDatabaseJobIntentServiceReceiver.kt +0 -14
- package/android/src/main/java/com/securitysuite/internal/support/ClearDatabaseService.kt +0 -32
- package/android/src/main/java/com/securitysuite/internal/support/ContextExt.kt +0 -22
- package/android/src/main/java/com/securitysuite/internal/support/DepletingSource.kt +0 -37
- package/android/src/main/java/com/securitysuite/internal/support/FileFactory.kt +0 -30
- package/android/src/main/java/com/securitysuite/internal/support/FileSaver.kt +0 -41
- package/android/src/main/java/com/securitysuite/internal/support/FormatUtils.kt +0 -117
- package/android/src/main/java/com/securitysuite/internal/support/FormattedUrl.kt +0 -76
- package/android/src/main/java/com/securitysuite/internal/support/HarUtils.kt +0 -28
- package/android/src/main/java/com/securitysuite/internal/support/HttpUrlUtils.kt +0 -11
- package/android/src/main/java/com/securitysuite/internal/support/JsonConverter.kt +0 -19
- package/android/src/main/java/com/securitysuite/internal/support/LimitingSource.kt +0 -22
- package/android/src/main/java/com/securitysuite/internal/support/LiveDataUtils.kt +0 -68
- package/android/src/main/java/com/securitysuite/internal/support/Logger.kt +0 -43
- package/android/src/main/java/com/securitysuite/internal/support/NotificationHelper.kt +0 -149
- package/android/src/main/java/com/securitysuite/internal/support/OkHttpUtils.kt +0 -86
- package/android/src/main/java/com/securitysuite/internal/support/OkioUtils.kt +0 -34
- package/android/src/main/java/com/securitysuite/internal/support/PlainTextDecoder.kt +0 -30
- package/android/src/main/java/com/securitysuite/internal/support/ReportingSink.kt +0 -114
- package/android/src/main/java/com/securitysuite/internal/support/RequestProcessor.kt +0 -102
- package/android/src/main/java/com/securitysuite/internal/support/ResponseProcessor.kt +0 -170
- package/android/src/main/java/com/securitysuite/internal/support/SearchHighlightUtil.kt +0 -80
- package/android/src/main/java/com/securitysuite/internal/support/Sharable.kt +0 -86
- package/android/src/main/java/com/securitysuite/internal/support/SpanTextUtil.kt +0 -202
- package/android/src/main/java/com/securitysuite/internal/support/TeeSource.kt +0 -68
- package/android/src/main/java/com/securitysuite/internal/support/TransactionCurlCommandSharable.kt +0 -46
- package/android/src/main/java/com/securitysuite/internal/support/TransactionDetailsHarSharable.kt +0 -11
- package/android/src/main/java/com/securitysuite/internal/support/TransactionDetailsSharable.kt +0 -73
- package/android/src/main/java/com/securitysuite/internal/support/TransactionDiffCallback.kt +0 -26
- package/android/src/main/java/com/securitysuite/internal/support/TransactionListDetailsSharable.kt +0 -23
- package/android/src/main/java/com/securitysuite/internal/ui/BaseChuckerActivity.kt +0 -35
- package/android/src/main/java/com/securitysuite/internal/ui/MainActivity.kt +0 -375
- package/android/src/main/java/com/securitysuite/internal/ui/MainViewModel.kt +0 -47
- package/android/src/main/java/com/securitysuite/internal/ui/transaction/PayloadType.kt +0 -6
- package/android/src/main/java/com/securitysuite/internal/ui/transaction/ProtocolResources.kt +0 -14
- package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionActivity.kt +0 -186
- package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionAdapter.kt +0 -139
- package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionOverviewFragment.kt +0 -100
- package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionPagerAdapter.kt +0 -29
- package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionPayloadAdapter.kt +0 -269
- package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionPayloadFragment.kt +0 -529
- package/android/src/main/java/com/securitysuite/internal/ui/transaction/TransactionViewModel.kt +0 -69
- package/android/src/main/res/A.java +0 -12
- package/android/src/main/res/color/chucker_fab_background_colour.xml +0 -5
- package/android/src/main/res/drawable/chucker_empty_payload.xml +0 -10
- package/android/src/main/res/drawable/chucker_ic_arrow_down.xml +0 -10
- package/android/src/main/res/drawable/chucker_ic_copy.xml +0 -12
- package/android/src/main/res/drawable/chucker_ic_decoded_url_white.xml +0 -10
- package/android/src/main/res/drawable/chucker_ic_delete_white.xml +0 -9
- package/android/src/main/res/drawable/chucker_ic_encoded_url_white.xml +0 -11
- package/android/src/main/res/drawable/chucker_ic_graphql.xml +0 -27
- package/android/src/main/res/drawable/chucker_ic_http.xml +0 -10
- package/android/src/main/res/drawable/chucker_ic_https.xml +0 -9
- package/android/src/main/res/drawable/chucker_ic_launcher_foreground.xml +0 -14
- package/android/src/main/res/drawable/chucker_ic_save_white.xml +0 -9
- package/android/src/main/res/drawable/chucker_ic_search_white.xml +0 -9
- package/android/src/main/res/drawable/chucker_ic_share_white.xml +0 -9
- package/android/src/main/res/drawable/chucker_ic_transaction_notification.xml +0 -9
- package/android/src/main/res/layout/activity_main.xml +0 -83
- package/android/src/main/res/layout/activity_transaction.xml +0 -48
- package/android/src/main/res/layout/fragment_transaction_overview.xml +0 -365
- package/android/src/main/res/layout/fragment_transaction_payload.xml +0 -132
- package/android/src/main/res/layout/list_item_transaction.xml +0 -122
- package/android/src/main/res/layout/transaction_item_body_line.xml +0 -13
- package/android/src/main/res/layout/transaction_item_copy.xml +0 -19
- package/android/src/main/res/layout/transaction_item_headers.xml +0 -12
- package/android/src/main/res/layout/transaction_item_image.xml +0 -16
- package/android/src/main/res/menu/chucker_transaction.xml +0 -46
- package/android/src/main/res/menu/chucker_transactions_list.xml +0 -41
- package/android/src/main/res/mipmap-anydpi-v26/chucker_ic_launcher.xml +0 -5
- package/android/src/main/res/mipmap-hdpi/chucker_ic_launcher.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/chucker_ic_launcher.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/chucker_ic_launcher.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/chucker_ic_launcher.png +0 -0
- package/android/src/main/res/values/chucker_ic_launcher_background.xml +0 -4
- package/android/src/main/res/values/colors.xml +0 -38
- package/android/src/main/res/values/dimens.xml +0 -10
- package/android/src/main/res/values/public.xml +0 -5
- package/android/src/main/res/values/strings.xml +0 -77
- package/android/src/main/res/values/styles.xml +0 -44
- package/android/src/main/res/values-es/strings.xml +0 -75
- package/android/src/main/res/values-night/colors.xml +0 -32
- package/android/src/main/res/xml/chucker_provider_paths.xml +0 -4
package/android/build.gradle
CHANGED
|
@@ -28,7 +28,6 @@ def isNewArchitectureEnabled() {
|
|
|
28
28
|
plugins {
|
|
29
29
|
id "com.android.library"
|
|
30
30
|
id "kotlin-android"
|
|
31
|
-
id "com.google.devtools.ksp" version "1.9.21-1.0.15"
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
if (isNewArchitectureEnabled()) {
|
|
@@ -112,19 +111,5 @@ dependencies {
|
|
|
112
111
|
implementation "com.squareup.okhttp3:okhttp:4.12.0"
|
|
113
112
|
implementation "com.scottyab:rootbeer-lib:0.1.0"
|
|
114
113
|
implementation "com.github.chuckerteam.chucker:library:4.1.0"
|
|
115
|
-
|
|
116
|
-
implementation "com.google.android.material:material:1.12.0"
|
|
117
|
-
implementation "com.google.code.gson:gson:2.11.0"
|
|
118
|
-
implementation "org.brotli:dec:0.1.2"
|
|
119
|
-
implementation "androidx.databinding:viewbinding:8.7.3"
|
|
120
|
-
implementation "androidx.constraintlayout:constraintlayout:2.2.0"
|
|
121
|
-
implementation "androidx.palette:palette-ktx:1.0.0"
|
|
122
|
-
implementation "androidx.activity:activity-ktx:1.9.3"
|
|
123
|
-
implementation "androidx.fragment:fragment-ktx:1.8.5"
|
|
124
|
-
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7"
|
|
125
|
-
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.7"
|
|
126
|
-
implementation "androidx.room:room-ktx:2.6.1"
|
|
127
|
-
implementation "androidx.room:room-runtime:2.6.1"
|
|
128
|
-
ksp "androidx.room:room-compiler:2.6.1"
|
|
129
114
|
}
|
|
130
115
|
|
|
@@ -1,49 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
<queries>
|
|
5
|
-
<intent>
|
|
6
|
-
<action android:name="android.intent.action.CREATE_DOCUMENT" />
|
|
7
|
-
<data android:mimeType="*/*" />
|
|
8
|
-
</intent>
|
|
9
|
-
</queries>
|
|
10
|
-
|
|
11
|
-
<uses-permission
|
|
12
|
-
android:name="android.permission.WAKE_LOCK"
|
|
13
|
-
android:maxSdkVersion="25" />
|
|
14
|
-
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
+
package="com.securitysuite">
|
|
15
3
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
16
|
-
|
|
17
|
-
<application>
|
|
18
|
-
<activity
|
|
19
|
-
android:name="com.securitysuite.internal.ui.MainActivity"
|
|
20
|
-
android:label="@string/chucker_name"
|
|
21
|
-
android:launchMode="singleTask"
|
|
22
|
-
android:taskAffinity="com.securitysuite.task"
|
|
23
|
-
android:theme="@style/Chucker.Theme" />
|
|
24
|
-
|
|
25
|
-
<activity
|
|
26
|
-
android:name="com.securitysuite.internal.ui.transaction.TransactionActivity"
|
|
27
|
-
android:parentActivityName="com.securitysuite.internal.ui.MainActivity"
|
|
28
|
-
android:theme="@style/Chucker.Theme" />
|
|
29
|
-
|
|
30
|
-
<service
|
|
31
|
-
android:name="com.securitysuite.internal.support.ClearDatabaseService"
|
|
32
|
-
android:exported="false"
|
|
33
|
-
android:permission="android.permission.BIND_JOB_SERVICE" />
|
|
34
|
-
|
|
35
|
-
<receiver
|
|
36
|
-
android:name="com.securitysuite.internal.support.ClearDatabaseJobIntentServiceReceiver"
|
|
37
|
-
android:exported="false" />
|
|
38
|
-
|
|
39
|
-
<provider
|
|
40
|
-
android:name="com.securitysuite.internal.support.ChuckerFileProvider"
|
|
41
|
-
android:authorities="${applicationId}.com.securitysuite.provider"
|
|
42
|
-
android:exported="false"
|
|
43
|
-
android:grantUriPermissions="true">
|
|
44
|
-
<meta-data
|
|
45
|
-
android:name="android.support.FILE_PROVIDER_PATHS"
|
|
46
|
-
android:resource="@xml/chucker_provider_paths" />
|
|
47
|
-
</provider>
|
|
48
|
-
</application>
|
|
49
|
-
</manifest>
|
|
4
|
+
</manifest>
|
package/package.json
CHANGED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
package com.securitysuite;
|
|
2
|
-
|
|
3
|
-
import android.content.Context;
|
|
4
|
-
|
|
5
|
-
import com.facebook.react.modules.network.OkHttpClientFactory;
|
|
6
|
-
import com.facebook.react.modules.network.ReactCookieJarContainer;
|
|
7
|
-
import com.securitysuite.api.ChuckerInterceptor;
|
|
8
|
-
|
|
9
|
-
import okhttp3.OkHttpClient;
|
|
10
|
-
public class NetworkLogger implements OkHttpClientFactory {
|
|
11
|
-
private Context context;
|
|
12
|
-
|
|
13
|
-
public NetworkLogger(Context context) {
|
|
14
|
-
this.context = context;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
public OkHttpClient createNewNetworkModuleClient() {
|
|
18
|
-
OkHttpClient client = new OkHttpClient.Builder()
|
|
19
|
-
.addInterceptor(new ChuckerInterceptor.Builder(context).build())
|
|
20
|
-
.cookieJar(new ReactCookieJarContainer())
|
|
21
|
-
.build();
|
|
22
|
-
|
|
23
|
-
return client;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
package com.securitysuite.api
|
|
2
|
-
|
|
3
|
-
import okhttp3.Request
|
|
4
|
-
import okhttp3.Response
|
|
5
|
-
import okio.ByteString
|
|
6
|
-
import okio.IOException
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Decodes HTTP request and response bodies to human–readable texts.
|
|
10
|
-
*/
|
|
11
|
-
public interface BodyDecoder {
|
|
12
|
-
/**
|
|
13
|
-
* Returns a text representation of [body] that will be displayed in Chucker UI transaction,
|
|
14
|
-
* or `null` if [request] cannot be handled by this decoder. [Body][body] is no longer than
|
|
15
|
-
* [max content length][ChuckerInterceptor.Builder.maxContentLength] and is guaranteed to be
|
|
16
|
-
* uncompressed even if [request] has gzip or br header.
|
|
17
|
-
*/
|
|
18
|
-
@Throws(IOException::class)
|
|
19
|
-
public fun decodeRequest(
|
|
20
|
-
request: Request,
|
|
21
|
-
body: ByteString,
|
|
22
|
-
): String?
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Returns a text representation of [body] that will be displayed in Chucker UI transaction,
|
|
26
|
-
* or `null` if [response] cannot be handled by this decoder. [Body][body] is no longer than
|
|
27
|
-
* [max content length][ChuckerInterceptor.Builder.maxContentLength] and is guaranteed to be
|
|
28
|
-
* uncompressed even if [response] has gzip or br header.
|
|
29
|
-
*/
|
|
30
|
-
@Throws(IOException::class)
|
|
31
|
-
public fun decodeResponse(
|
|
32
|
-
response: Response,
|
|
33
|
-
body: ByteString,
|
|
34
|
-
): String?
|
|
35
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
package com.securitysuite.api
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import android.content.Intent
|
|
5
|
-
import android.content.pm.ShortcutInfo
|
|
6
|
-
import android.content.pm.ShortcutManager
|
|
7
|
-
import android.graphics.drawable.Icon
|
|
8
|
-
import android.os.Build
|
|
9
|
-
import android.util.Log
|
|
10
|
-
import androidx.core.content.getSystemService
|
|
11
|
-
import com.securitysuite.R
|
|
12
|
-
import com.securitysuite.internal.support.Logger
|
|
13
|
-
import com.securitysuite.internal.support.NotificationHelper
|
|
14
|
-
import com.securitysuite.internal.ui.MainActivity
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Chucker methods and utilities to interact with the library.
|
|
18
|
-
*/
|
|
19
|
-
public object Chucker {
|
|
20
|
-
private const val SHORTCUT_ID = "chuckerShortcutId"
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Keep track of latest show notifications value from ChuckerCollector.
|
|
24
|
-
*/
|
|
25
|
-
internal var showNotifications: Boolean = true
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Check if this instance is the operation one or no-op.
|
|
29
|
-
* @return `true` if this is the operation instance.
|
|
30
|
-
*/
|
|
31
|
-
@Suppress("MayBeConst ") // https://github.com/ChuckerTeam/chucker/pull/169#discussion_r362341353
|
|
32
|
-
public val isOp: Boolean = true
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Get an Intent to launch the Chucker UI directly.
|
|
36
|
-
* @param context An Android [Context].
|
|
37
|
-
* @return An Intent for the main Chucker Activity that can be started with [Context.startActivity].
|
|
38
|
-
*/
|
|
39
|
-
@JvmStatic
|
|
40
|
-
public fun getLaunchIntent(context: Context): Intent {
|
|
41
|
-
return Intent(context, MainActivity::class.java)
|
|
42
|
-
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Create a shortcut to launch Chucker UI.
|
|
47
|
-
* @param context An Android [Context].
|
|
48
|
-
*/
|
|
49
|
-
internal fun createShortcut(context: Context) {
|
|
50
|
-
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
|
|
51
|
-
return
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
val shortcutManager = context.getSystemService<ShortcutManager>() ?: return
|
|
55
|
-
if (shortcutManager.dynamicShortcuts.any { it.id == SHORTCUT_ID }) {
|
|
56
|
-
return
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
val shortcut =
|
|
60
|
-
ShortcutInfo.Builder(context, SHORTCUT_ID)
|
|
61
|
-
.setShortLabel(context.getString(R.string.chucker_shortcut_label))
|
|
62
|
-
.setLongLabel(context.getString(R.string.chucker_shortcut_label))
|
|
63
|
-
.setIcon(Icon.createWithResource(context, R.mipmap.chucker_ic_launcher))
|
|
64
|
-
.setIntent(getLaunchIntent(context).setAction(Intent.ACTION_VIEW))
|
|
65
|
-
.build()
|
|
66
|
-
try {
|
|
67
|
-
shortcutManager.addDynamicShortcuts(listOf(shortcut))
|
|
68
|
-
} catch (e: IllegalArgumentException) {
|
|
69
|
-
Logger.warn("ShortcutManager addDynamicShortcuts failed ", e)
|
|
70
|
-
} catch (e: IllegalStateException) {
|
|
71
|
-
Logger.warn("ShortcutManager addDynamicShortcuts failed ", e)
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Dismisses all previous Chucker notifications.
|
|
77
|
-
*/
|
|
78
|
-
@JvmStatic
|
|
79
|
-
public fun dismissNotifications(context: Context) {
|
|
80
|
-
NotificationHelper(context).dismissNotifications()
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
internal var logger: Logger =
|
|
84
|
-
object : Logger {
|
|
85
|
-
val TAG = "Chucker"
|
|
86
|
-
|
|
87
|
-
override fun info(
|
|
88
|
-
message: String,
|
|
89
|
-
throwable: Throwable?,
|
|
90
|
-
) {
|
|
91
|
-
Log.i(TAG, message, throwable)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
override fun warn(
|
|
95
|
-
message: String,
|
|
96
|
-
throwable: Throwable?,
|
|
97
|
-
) {
|
|
98
|
-
Log.w(TAG, message, throwable)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
override fun error(
|
|
102
|
-
message: String,
|
|
103
|
-
throwable: Throwable?,
|
|
104
|
-
) {
|
|
105
|
-
Log.e(TAG, message, throwable)
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
package com.securitysuite.api
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import android.net.Uri
|
|
5
|
-
import com.securitysuite.R
|
|
6
|
-
import com.securitysuite.internal.data.entity.HttpTransaction
|
|
7
|
-
import com.securitysuite.internal.data.har.log.Creator
|
|
8
|
-
import com.securitysuite.internal.data.repository.RepositoryProvider
|
|
9
|
-
import com.securitysuite.internal.support.HarUtils
|
|
10
|
-
import com.securitysuite.internal.support.JsonConverter
|
|
11
|
-
import com.securitysuite.internal.support.NotificationHelper
|
|
12
|
-
import com.securitysuite.internal.support.TransactionDetailsHarSharable
|
|
13
|
-
import com.securitysuite.internal.support.TransactionListDetailsSharable
|
|
14
|
-
import com.securitysuite.internal.support.writeToFile
|
|
15
|
-
import kotlinx.coroutines.Dispatchers
|
|
16
|
-
import kotlinx.coroutines.MainScope
|
|
17
|
-
import kotlinx.coroutines.launch
|
|
18
|
-
import kotlinx.coroutines.withContext
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* The collector responsible of collecting data from a [ChuckerInterceptor] and
|
|
22
|
-
* storing it/displaying push notification. You need to instantiate one of those and
|
|
23
|
-
* provide it to
|
|
24
|
-
*
|
|
25
|
-
* @param context An Android Context
|
|
26
|
-
* @param showNotification Control whether a notification is shown while HTTP activity
|
|
27
|
-
* is recorded.
|
|
28
|
-
* @param retentionPeriod Set the retention period for HTTP transaction data captured
|
|
29
|
-
* by this collector. The default is one week.
|
|
30
|
-
*/
|
|
31
|
-
public class ChuckerCollector
|
|
32
|
-
@JvmOverloads
|
|
33
|
-
constructor(
|
|
34
|
-
context: Context,
|
|
35
|
-
public var showNotification: Boolean = true,
|
|
36
|
-
retentionPeriod: RetentionManager.Period = RetentionManager.Period.ONE_WEEK,
|
|
37
|
-
) {
|
|
38
|
-
private val retentionManager: RetentionManager = RetentionManager(context, retentionPeriod)
|
|
39
|
-
private val notificationHelper: NotificationHelper = NotificationHelper(context)
|
|
40
|
-
private val scope = MainScope()
|
|
41
|
-
|
|
42
|
-
init {
|
|
43
|
-
RepositoryProvider.initialize(context)
|
|
44
|
-
Chucker.showNotifications = showNotification
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Call this method when you send an HTTP request.
|
|
49
|
-
* @param transaction The HTTP transaction sent
|
|
50
|
-
*/
|
|
51
|
-
internal fun onRequestSent(transaction: HttpTransaction) {
|
|
52
|
-
scope.launch {
|
|
53
|
-
withContext(Dispatchers.IO) {
|
|
54
|
-
RepositoryProvider.transaction().insertTransaction(transaction)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (showNotification) {
|
|
58
|
-
notificationHelper.show(transaction)
|
|
59
|
-
}
|
|
60
|
-
withContext(Dispatchers.IO) {
|
|
61
|
-
retentionManager.doMaintenance()
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Call this method when you received the response of an HTTP request.
|
|
68
|
-
* It must be called after [ChuckerCollector.onRequestSent].
|
|
69
|
-
* @param transaction The sent HTTP transaction completed with the response
|
|
70
|
-
*/
|
|
71
|
-
internal fun onResponseReceived(transaction: HttpTransaction) {
|
|
72
|
-
scope.launch {
|
|
73
|
-
val updated =
|
|
74
|
-
withContext(Dispatchers.IO) {
|
|
75
|
-
RepositoryProvider.transaction().updateTransaction(transaction)
|
|
76
|
-
}
|
|
77
|
-
if (showNotification && updated > 0) {
|
|
78
|
-
notificationHelper.show(transaction)
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Export the Chucker transactions to a file. Please note that this function is blocking
|
|
85
|
-
* and performs Disk I/O. Make sure you run it on a separate thread or coroutine.
|
|
86
|
-
*
|
|
87
|
-
* @param context Application context
|
|
88
|
-
* @param startTimestamp The timestamp to read transactions from. Passing null means
|
|
89
|
-
* transactions will not be limited by timestamp
|
|
90
|
-
* @param exportFormat The export format: LOG or HAR
|
|
91
|
-
* @return The content uri of a file with the transactions in or null if the export failed.
|
|
92
|
-
*/
|
|
93
|
-
public fun writeTransactions(
|
|
94
|
-
context: Context,
|
|
95
|
-
startTimestamp: Long?,
|
|
96
|
-
exportFormat: ExportFormat = ExportFormat.LOG,
|
|
97
|
-
): Uri? {
|
|
98
|
-
val transactions =
|
|
99
|
-
RepositoryProvider.transaction().getTransactionsInTimeRange(startTimestamp)
|
|
100
|
-
if (transactions.isEmpty()) {
|
|
101
|
-
return null
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
val sharableTransactions =
|
|
105
|
-
when (exportFormat) {
|
|
106
|
-
ExportFormat.LOG -> {
|
|
107
|
-
TransactionListDetailsSharable(transactions, encodeUrls = false)
|
|
108
|
-
}
|
|
109
|
-
ExportFormat.HAR -> {
|
|
110
|
-
TransactionDetailsHarSharable(
|
|
111
|
-
JsonConverter.nonNullSerializerInstance
|
|
112
|
-
.toJson(
|
|
113
|
-
HarUtils.fromHttpTransactions(
|
|
114
|
-
transactions,
|
|
115
|
-
Creator(
|
|
116
|
-
context.getString(R.string.chucker_name),
|
|
117
|
-
context.getString(R.string.chucker_version),
|
|
118
|
-
),
|
|
119
|
-
),
|
|
120
|
-
),
|
|
121
|
-
)
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return sharableTransactions.writeToFile(
|
|
125
|
-
context = context,
|
|
126
|
-
fileName = "api_transactions.${exportFormat.extension}",
|
|
127
|
-
)
|
|
128
|
-
}
|
|
129
|
-
}
|
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
package com.securitysuite.api
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import androidx.annotation.VisibleForTesting
|
|
5
|
-
import com.securitysuite.internal.data.entity.HttpTransaction
|
|
6
|
-
import com.securitysuite.internal.support.CacheDirectoryProvider
|
|
7
|
-
import com.securitysuite.internal.support.PlainTextDecoder
|
|
8
|
-
import com.securitysuite.internal.support.RequestProcessor
|
|
9
|
-
import com.securitysuite.internal.support.ResponseProcessor
|
|
10
|
-
import com.securitysuite.internal.support.addNonBlankPathSegments
|
|
11
|
-
import okhttp3.HttpUrl
|
|
12
|
-
import okhttp3.Interceptor
|
|
13
|
-
import okhttp3.Response
|
|
14
|
-
import java.io.IOException
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* An OkHttp Interceptor which persists and displays HTTP activity
|
|
18
|
-
* in your application for later inspection.
|
|
19
|
-
*/
|
|
20
|
-
public class ChuckerInterceptor private constructor(
|
|
21
|
-
builder: Builder,
|
|
22
|
-
) : Interceptor {
|
|
23
|
-
/**
|
|
24
|
-
* An OkHttp Interceptor which persists and displays HTTP activity
|
|
25
|
-
* in your application for later inspection.
|
|
26
|
-
*
|
|
27
|
-
* This constructor is a shorthand for `ChuckerInterceptor.Builder(context).build()`.
|
|
28
|
-
*
|
|
29
|
-
* @param context An Android [Context]
|
|
30
|
-
* @see ChuckerInterceptor.Builder
|
|
31
|
-
*/
|
|
32
|
-
public constructor(context: Context) : this(Builder(context))
|
|
33
|
-
|
|
34
|
-
private val headersToRedact = builder.headersToRedact.toMutableSet()
|
|
35
|
-
|
|
36
|
-
private val decoders = builder.decoders + BUILT_IN_DECODERS
|
|
37
|
-
|
|
38
|
-
private val collector = builder.collector ?: ChuckerCollector(builder.context)
|
|
39
|
-
|
|
40
|
-
private val requestProcessor =
|
|
41
|
-
RequestProcessor(
|
|
42
|
-
builder.context,
|
|
43
|
-
collector,
|
|
44
|
-
builder.maxContentLength,
|
|
45
|
-
headersToRedact,
|
|
46
|
-
decoders,
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
private val responseProcessor =
|
|
50
|
-
ResponseProcessor(
|
|
51
|
-
collector,
|
|
52
|
-
builder.cacheDirectoryProvider ?: CacheDirectoryProvider { builder.context.filesDir },
|
|
53
|
-
builder.maxContentLength,
|
|
54
|
-
headersToRedact,
|
|
55
|
-
builder.alwaysReadResponseBody,
|
|
56
|
-
decoders,
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
private val skipPaths = builder.skipPaths.toSet()
|
|
60
|
-
private val skipPathsRegex = builder.skipPathsRegex.toSet()
|
|
61
|
-
private val skipDomains = builder.skipDomains.toSet()
|
|
62
|
-
private val skipDomainRegex = builder.skipDomainRegex.toSet()
|
|
63
|
-
|
|
64
|
-
init {
|
|
65
|
-
if (builder.createShortcut) {
|
|
66
|
-
Chucker.createShortcut(builder.context)
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/** Adds [headerName] into [headersToRedact] */
|
|
71
|
-
public fun redactHeader(vararg headerName: String) {
|
|
72
|
-
headersToRedact.addAll(headerName)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
@Throws(IOException::class)
|
|
76
|
-
override fun intercept(chain: Interceptor.Chain): Response {
|
|
77
|
-
val transaction = HttpTransaction()
|
|
78
|
-
val request = chain.request()
|
|
79
|
-
val path = request.url.encodedPath
|
|
80
|
-
val host = request.url.host
|
|
81
|
-
val shouldSkipPath = skipPaths.contains(path) || skipPathsRegex.any { it.matches(path) }
|
|
82
|
-
// Skip evaluation of domain if the path is already skipped
|
|
83
|
-
val shouldSkipDomain =
|
|
84
|
-
shouldSkipPath || skipDomains.contains(host) || skipDomainRegex.any { it.matches(host) }
|
|
85
|
-
val shouldProcessTheRequest = !(shouldSkipPath || shouldSkipDomain)
|
|
86
|
-
|
|
87
|
-
if (shouldProcessTheRequest) {
|
|
88
|
-
requestProcessor.process(request, transaction)
|
|
89
|
-
}
|
|
90
|
-
val response =
|
|
91
|
-
try {
|
|
92
|
-
chain.proceed(request)
|
|
93
|
-
} catch (e: IOException) {
|
|
94
|
-
transaction.error = e.toString()
|
|
95
|
-
collector.onResponseReceived(transaction)
|
|
96
|
-
throw e
|
|
97
|
-
}
|
|
98
|
-
return if (shouldProcessTheRequest) {
|
|
99
|
-
responseProcessor.process(response, transaction)
|
|
100
|
-
} else {
|
|
101
|
-
response
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Assembles a new [ChuckerInterceptor].
|
|
107
|
-
*
|
|
108
|
-
* @param context An Android [Context].
|
|
109
|
-
*/
|
|
110
|
-
@Suppress("TooManyFunctions")
|
|
111
|
-
public class Builder(internal var context: Context) {
|
|
112
|
-
internal var collector: ChuckerCollector? = null
|
|
113
|
-
internal var maxContentLength = MAX_CONTENT_LENGTH
|
|
114
|
-
internal var cacheDirectoryProvider: CacheDirectoryProvider? = null
|
|
115
|
-
internal var alwaysReadResponseBody = false
|
|
116
|
-
internal var headersToRedact = emptySet<String>()
|
|
117
|
-
internal var decoders = emptyList<BodyDecoder>()
|
|
118
|
-
internal var createShortcut = true
|
|
119
|
-
internal val skipPaths = mutableSetOf<String>()
|
|
120
|
-
internal val skipPathsRegex = mutableSetOf<Regex>()
|
|
121
|
-
internal val skipDomains = mutableSetOf<String>()
|
|
122
|
-
internal val skipDomainRegex = mutableSetOf<Regex>()
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Sets the [ChuckerCollector] to customize data retention.
|
|
126
|
-
*/
|
|
127
|
-
public fun collector(collector: ChuckerCollector): Builder =
|
|
128
|
-
apply {
|
|
129
|
-
this.collector = collector
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Sets the maximum length for requests and responses content before their truncation.
|
|
134
|
-
*
|
|
135
|
-
* Warning: setting this value too high may cause unexpected results.
|
|
136
|
-
*/
|
|
137
|
-
public fun maxContentLength(length: Long): Builder =
|
|
138
|
-
apply {
|
|
139
|
-
this.maxContentLength = length
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Sets headers that will be redacted if their names match.
|
|
144
|
-
* They will be replaced with the `**` symbols in the Chucker UI.
|
|
145
|
-
*/
|
|
146
|
-
public fun redactHeaders(headerNames: Iterable<String>): Builder =
|
|
147
|
-
apply {
|
|
148
|
-
this.headersToRedact = headerNames.toSet()
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Sets headers that will be redacted if their names match.
|
|
153
|
-
* They will be replaced with the `**` symbols in the Chucker UI.
|
|
154
|
-
*/
|
|
155
|
-
public fun redactHeaders(vararg headerNames: String): Builder =
|
|
156
|
-
apply {
|
|
157
|
-
this.headersToRedact = headerNames.toSet()
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* If set to `true` [ChuckerInterceptor] will read full content of response
|
|
162
|
-
* bodies even in case of parsing errors or closing the response body without reading it.
|
|
163
|
-
*
|
|
164
|
-
* Warning: enabling this feature may potentially cause different behaviour from the
|
|
165
|
-
* production application.
|
|
166
|
-
*/
|
|
167
|
-
public fun alwaysReadResponseBody(enable: Boolean): Builder =
|
|
168
|
-
apply {
|
|
169
|
-
this.alwaysReadResponseBody = enable
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Adds a [decoder] into Chucker's processing pipeline. Decoders are applied in an order they were added in.
|
|
174
|
-
* Request and response bodies are set to the first non–null value returned by any of the decoders.
|
|
175
|
-
*/
|
|
176
|
-
public fun addBodyDecoder(decoder: BodyDecoder): Builder =
|
|
177
|
-
apply {
|
|
178
|
-
this.decoders += decoder
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* If set to `true`, [ChuckerInterceptor] will create a shortcut for your app
|
|
183
|
-
* to access list of transaction in Chucker.
|
|
184
|
-
*/
|
|
185
|
-
public fun createShortcut(enable: Boolean): Builder =
|
|
186
|
-
apply {
|
|
187
|
-
this.createShortcut = enable
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Sets provider of a directory where Chucker will save temporary responses
|
|
192
|
-
* before processing them.
|
|
193
|
-
*/
|
|
194
|
-
@VisibleForTesting
|
|
195
|
-
internal fun cacheDirectorProvider(provider: CacheDirectoryProvider): Builder =
|
|
196
|
-
apply {
|
|
197
|
-
this.cacheDirectoryProvider = provider
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Sets a list of [String] to skip paths. When any of the [String] matches
|
|
202
|
-
* a request path, the request will be skipped.
|
|
203
|
-
*
|
|
204
|
-
* **Note:** An empty path will be treated as the '/'.
|
|
205
|
-
* '//' will also be treated as the '/' path.
|
|
206
|
-
*/
|
|
207
|
-
public fun skipPaths(vararg paths: String): Builder =
|
|
208
|
-
apply {
|
|
209
|
-
paths.forEach { candidatePath ->
|
|
210
|
-
val httpUrl =
|
|
211
|
-
HttpUrl.Builder()
|
|
212
|
-
.scheme("https")
|
|
213
|
-
.host("example.com")
|
|
214
|
-
.addNonBlankPathSegments(candidatePath)
|
|
215
|
-
.build()
|
|
216
|
-
this@Builder.skipPaths.add(httpUrl.encodedPath)
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Sets a list of [Regex] to skip paths. When any of the [Regex] matches a
|
|
222
|
-
* request path, the request will be skipped. Include [RegexOption] where
|
|
223
|
-
* necessary.
|
|
224
|
-
*
|
|
225
|
-
* ```
|
|
226
|
-
* ".*(jpg|jpeg|png|gif|webp|svg|bmp|ico)$".toRegex(), // Ignore all image requests
|
|
227
|
-
* ".*iGnOrE.*"toRegex(RegexOption.IGNORE_CASE), // Case insensitive
|
|
228
|
-
* ".*path/to/skip.*".toRegex(),
|
|
229
|
-
* ".*path/ends/with/dev$".toRegex(),
|
|
230
|
-
* ```
|
|
231
|
-
*/
|
|
232
|
-
public fun skipPaths(paths: Regex): Builder =
|
|
233
|
-
apply {
|
|
234
|
-
this.skipPathsRegex.add(paths)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* Sets a list of [String] to skip domains. Domain names are evaluated in
|
|
239
|
-
* lowercase format. When any of the [String] matches a request domain, the
|
|
240
|
-
* request will be skipped.
|
|
241
|
-
*
|
|
242
|
-
* ```
|
|
243
|
-
* example.com, subdomain.example.com, exam-ple.com, eXaMpLe.CoM, example.co.uk
|
|
244
|
-
* ```
|
|
245
|
-
*/
|
|
246
|
-
public fun skipDomains(vararg domains: String): Builder =
|
|
247
|
-
apply {
|
|
248
|
-
this@Builder.skipDomains.addAll(domains.map { it.lowercase() })
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Sets a list of [Regex] to skip domains. Domain names are evaluated in
|
|
253
|
-
* lowercase format. When any of the [Regex] matches a request domain,
|
|
254
|
-
* the request will be skipped. Include [RegexOption] where necessary.
|
|
255
|
-
*
|
|
256
|
-
* ```
|
|
257
|
-
* ".*iGnOrE.*"toRegex(RegexOption.IGNORE_CASE),
|
|
258
|
-
* "ignoresubdomain.*".toRegex(),
|
|
259
|
-
* "domainname.*".toRegex(),
|
|
260
|
-
* ".*.dev$".toRegex(),
|
|
261
|
-
* ```
|
|
262
|
-
*/
|
|
263
|
-
public fun skipDomains(domains: Regex): Builder =
|
|
264
|
-
apply {
|
|
265
|
-
this.skipDomainRegex.add(domains)
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Creates a new [ChuckerInterceptor] instance with values defined in this
|
|
270
|
-
* builder.
|
|
271
|
-
*/
|
|
272
|
-
public fun build(): ChuckerInterceptor = ChuckerInterceptor(this)
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
private companion object {
|
|
276
|
-
private const val MAX_CONTENT_LENGTH = 250_000L
|
|
277
|
-
|
|
278
|
-
private val BUILT_IN_DECODERS = listOf(PlainTextDecoder)
|
|
279
|
-
}
|
|
280
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
package com.securitysuite.api
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* The supported export format for transactions file exports.
|
|
5
|
-
*/
|
|
6
|
-
public enum class ExportFormat(public val extension: String) {
|
|
7
|
-
/** LOG Format with txt extension */
|
|
8
|
-
LOG("txt"),
|
|
9
|
-
|
|
10
|
-
/** HAR format with har extension */
|
|
11
|
-
HAR("har"),
|
|
12
|
-
}
|